PS2键盘:明确接线关系,只需接4根线,VCC要+5V,刚刚又测试过,3.3V也可以用。时钟和数据线要用bidir双向口线,FPGA可以不用外接上拉电阻。另外,USB键盘也可以用,只要用一个转接头转成PS2即可。
键值查表
PS2键盘解码
其中detect.v模块
1 module detect
2 (
3 input clk,
4 input rst_n,
5 input ps2_clk_pin_in,
6 output H2L_sig
7 );
8
9 reg H2L_F1,H2L_F2;
10
11 always @ ( posedge clk, negedge rst_n)
12 begin
13 if ( ! rst_n)
14 begin
15 H2L_F1 <= 1 ' b1;
16 H2L_F2 <= 1 ' b1;
17 end
18 else
19 begin
20 H2L_F1 <= ps2_clk_pin_in;
21 H2L_F2 <= H2L_F1;
22 end
23 end
24
25 assign H2L_sig = H2L_F2 & ( ~ H2L_F1);
26
27 endmodule
解码模块--ps2接受模块
1 module decode
2 (
3 input clk,
4 input rst_n,
5 input H2L_Sig,
6 input data_in,
7 output [ 7 : 0 ] ps2_data,
8 output ps2_done_sig
9 );
10
11 reg [ 7 : 0 ] rdata;
12 reg [ 4 : 0 ] i;
13 reg isshift;
14 reg isdone;
15
16 always @ ( posedge clk, negedge rst_n)
17 begin
18 if ( ! rst_n)
19 begin
20 rdata <= 8 ' b0;
21 i <= 5 ' b0;
22 isdone <= 1 ' b0;
23 end
24 else
25 case (i)
26 5 ' d0:
27 if (H2L_Sig)
28 i <= i + 1 ' b1;
29 5 ' d1,5 ' d2, 5 ' d3,5 ' d4, 5 ' d5,5 ' d6, 5 ' d7,5 ' d8:
30 if (H2L_Sig)
31 begin
32 i <= i + 1 ' b1;
33 rdata[i - 1 ] <= data_in;
34 end
35 5 ' d9,5 ' d10:
36 if (H2L_Sig)
37 i <= i + 1 ' b1;
38 5 ' d11:
39 if (rdata == 8 ' hF0)
40 i <= 5 ' d12;
41 else
42 i <= 5 ' d23;
43 5 ' d12,5 ' d13, 5 ' d14,5 ' d15, 5 ' d16,5 ' d17, 5 ' d18,5 ' d19, 5 ' d20,5 ' d21, 5 ' d22:
44 if (H2L_Sig)
45 i <= i + 1 ' b1;
46 5 ' d23:
47 begin
48 i <= i + 1 ' b1;
49 isdone <= 1 ' b1;
50 end
51 5 ' d24:
52 begin
53 i <= 5 ' d0;
54 isdone <= 1 ' b0;
55 end
56 endcase
57 end
58
59 assign ps2_data = rdata;
60 assign ps2_done_sig = isdone;
61
62 endmodule
控制模块--与FIFO的接口模块
1 module control
2 (
3 input clk,
4 input rst_n,
5 input done_sig,
6 input [ 7 : 0 ] ps2_data,
7 input full_sig,
8 output write_req,
9 output [ 7 : 0 ] fifo_write_data
10 );
11
12 reg [ 1 : 0 ] i;
13 reg isreq;
14
15 always @ ( posedge clk, negedge rst_n)
16 if ( ! rst_n)
17 begin
18 i <= 2 ' b0;
19 isreq <= 1 ' b0;
20 end
21 else
22 case (i)
23 0 :
24 if (done_sig && ( ! full_sig))
25 i <= i + 1 ' b1;
26 1 :
27 begin
28 isreq <= 1 ' b1;
29 i <= i + 1 ' b1;
30 end
31 2 :
32 begin
33 isreq <= 1 ' b0;
34 i <= 2 ' b0;
35 end
36 endcase
37
38 assign fifo_write_data = ps2_data;
39 assign write_req = isreq;
40
41 endmodule
//Listing 9.1 module ps2_rx ( input wire clk, reset, input wire ps2d, //ps2 data input wire ps2c, //ps2 clk input wire rx_en, output reg rx_done_tick, output wire [7:0] dout ); // symbolic state declaration localparam [1:0] idle = 2'b00, dps = 2'b01, load = 2'b10; // signal declaration reg [1:0] state_reg, state_next; reg [7:0] filter_reg; wire [7:0] filter_next; reg f_ps2c_reg; wire f_ps2c_next; reg [3:0] n_reg, n_next; reg [10:0] b_reg, b_next; wire fall_edge; // body //================================================= // filter and falling-edge tick generation for ps2c //================================================= always @(posedge clk, posedge reset) if (reset) begin filter_reg <= 0; f_ps2c_reg <= 0; end else begin filter_reg <= filter_next; f_ps2c_reg <= f_ps2c_next; end assign filter_next = {ps2c, filter_reg[7:1]}; assign f_ps2c_next = (filter_reg==8'b11111111) ? 1'b1 : (filter_reg==8'b00000000) ? 1'b0 : f_ps2c_reg; assign fall_edge = f_ps2c_reg & ~f_ps2c_next; //================================================= // FSMD //================================================= // FSMD state & data registers always @(posedge clk, posedge reset) if (reset) begin state_reg <= idle; n_reg <= 0; b_reg <= 0; end else begin state_reg <= state_next; n_reg <= n_next; b_reg <= b_next; end // FSMD next-state logic always @* begin state_next = state_reg; rx_done_tick = 1'b0; n_next = n_reg; b_next = b_reg; case (state_reg) idle: if (fall_edge & rx_en) begin // shift in start bit b_next = {ps2d, b_reg[10:1]}; n_next = 4'b1001; state_next = dps; end dps: // 8 data + 1 parity + 1 stop if (fall_edge) begin b_next = {ps2d, b_reg[10:1]}; if (n_reg==0) state_next = load; else n_next = n_reg - 1; end load: // 1 extra clock to complete the last shift begin state_next = idle; rx_done_tick = 1'b1; end endcase end // output assign dout = b_reg[8:1]; // data bits endmodule