如何在 FPGA 的 PMOD 键盘上保存按键条目
How do I save key-press entries on a PMOD keypad for FPGA
我有一个带 Digilent PMOD 键盘的 DE-10 lite FPGA,每次按下键盘上的按钮时,我都会尝试增加一个计数器。我正在尝试增加一个计数器,以便我可以知道在当前状态下按下了多少个按钮。我遵循了 Digilent 的示例代码,并尝试通过如下所示的轮询技术检测按键:
module keypad(input clk, input [3:0] row, output reg [3:0] column, output reg [3:0] decode);
reg [19:0] clock_count;
always @ (posedge clk)
begin
////////////////////////
if (clock_count == 20'd50000) // column 0 check
begin
column <= 4'b0111;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd50008) // column 0 rows check after column activated
begin
if (row == 4'b0111) decode <= 4'b0001; // row 0 -> key '1'
else if(row == 4'b1011) decode <= 4'b0100; // row 1 -> key '4'
else if(row == 4'b1101) decode <= 4'b0111; // row 2 -> key '7'
else if(row == 4'b1110) decode <= 4'b0000; // row 3 -> key '0'
clock_count <= clock_count + 1'b1;
end
////////////////////////
else if (clock_count == 20'd100000) // column 1 check
begin
column <= 4'b1011;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd100008) // column 1 rows check after column activated
begin
if (row == 4'b0111) decode <= 4'b0010; // row 0 -> key '2'
else if(row == 4'b1011) decode <= 4'b0101; // row 1 -> key '5'
else if(row == 4'b1101) decode <= 4'b1000; // row 2 -> key '8'
else if(row == 4'b1110) decode <= 4'b1111; // row 3 -> key 'F'
clock_count <= clock_count + 1'b1;
end
////////////////////////
else if(clock_count == 20'd150000) // column 2 check
begin
column <= 4'b1101;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd150008) // column 2 rows check after column activated
begin
if(row == 4'b0111) decode <= 4'b0011; // row 0 -> key '3'
else if(row == 4'b1011) decode <= 4'b0110; // row 1 -> key '6'
else if(row == 4'b1101) decode <= 4'b1001; // row 2 -> key '9'
else if(row == 4'b1110) decode <= 4'b1110; // row 3 -> key 'E'
clock_count <= clock_count + 1'b1;
end
////////////////////////
else if(clock_count == 20'd200000) // column 3 check
begin
column <= 4'b1110;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd200008) // column 3 rows check after column activated
begin
if(row == 4'b0111) decode <= 4'b1010; // row 0 -> key 'A'
else if(row == 4'b1011) decode <= 4'b1011; // row 1 -> key 'B'
else if(row == 4'b1101) decode <= 4'b1100; // row 2 -> key 'C'
else if(row == 4'b1110) decode <= 4'b1101; // row 3 -> key 'D'
clock_count <= 20'd0; // restart clock counting
end
else begin
clock_count <= clock_count + 1'b1;
end
end
endmodule
我的包装程序如下所示,我遇到的最大问题是我无法在 state0[= 中获取 input_counter 24=] 每次按下按钮时增加:
module calc_top(input fifty_MHz, input [3:0] row, output [3:0] column, input bttn1, output [47:0] hex, output [9:0] leds);
wire twentyfive_mhz;
twentyfive_mhz c0 (.clk(fifty_MHz), .twentyfive_mhz(twentyfive_mhz));
wire [3:0] keypad;
wire [3:0] keypad_decode;
reg [3:0] state_place = 4'd0;
wire [3:0] next_state;
reg [47:0] hex_disp;
reg reset = 1'b1;
always@(posedge twentyfive_mhz or negedge reset)
begin
if(~reset) state_place = 4'd0;
else state_place = next_state;
end
keypad k0 (.clk(twentyfive_mhz), .row(row), .column(column), .decode(keypad));
state0 a0 (.clk(clk), .state_place(state_place), .keypad_decode(keypad), .leds(leds));
endmodule
module state0(input clk, input [3:0] state_place, input [3:0] keypad_decode, output reg [9:0] leds, output reg [3:0] next_state);
reg [3:0] input_counter = 4'd0;
always@(keypad_decode)
begin
if(state_place == 4'd0)
begin
input_counter = input_counter + 4'd1;
case (keypad_decode)
4'h0 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd0; // 0
leds <= 10'b0000000000;
next_state = 4'd0;
end
4'h1 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd1; // 1
leds <= 10'b0000000001;
next_state = 4'd0;
end
4'h2 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd2; // 2
leds <= 10'b0000000010;
next_state = 4'd0;
end
4'h3 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd3; // 3
leds <= 10'b0000000011;
next_state = 4'd0;
end
4'h4 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd4; // 4
leds <= 10'b0000000100;
next_state = 4'd0;
end
4'h5 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd5; // 5
leds <= 10'b0000000101;
next_state = 4'd0;
end
4'h6 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd6; // 6
leds <= 10'b0000000110;
next_state = 4'd0;
end
4'h7 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd7; // 7
leds <= 10'b0000000111;
next_state = 4'd0;
end
4'h8 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd8; // 8
leds <= 10'b0000001000;
next_state = 4'd0;
end
4'h9 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd9; // 9
leds <= 10'b0000001001;
next_state = 4'd0;
end
4'hF : begin
leds <= 10'b0000001111;
next_state <= 4'd1;
end
default : begin
leds <= 10'b0000000000;
end
endcase
end
end
endmodule
我想我知道发生了什么......我想我需要去抖动才能让它工作,但我无法让去抖动在当前的实现中正常工作。
如果可以请帮忙!
谢谢。
编辑//////////
我刚刚让我的去抖动电路工作,但计数器值仍然不会更新。
初看你的代码,你没有使用那么多输入端口,FSM逻辑是错误的,我根据你的意图修改了,你现在可以看一下代码
module calc_top(
input fifty_MHz
, input [3:0] row
, input bttn1
, output [47:0] hex
, output [9:0] leds
, output [3:0] column
);
wire twentyfive_mhz;
wire [3:0] keypad;
twentyfive_mhz c0 (
.clk (fifty_MHz)
,.twentyfive_mhz(twentyfive_mhz)
);
keypad k0 (
.clk (twentyfive_mhz)
,.row (row)
,.column (column)
,.decode (keypad)
);
state0 a0 (
.clk (twentyfive_mhz)
,.keypad_decode(keypad)
,.leds (leds)
);
endmodule
module state0(
input clk
,input [3:0] keypad_decode
,output reg [9:0] leds
);
always @(posedge clk) leds <= keypad_decode;
endmodule
module keypad(
input clk
,input [3:0] row
,output reg [3:0] column
,output reg [3:0] decode
);
reg [19:0] clock_count;
always @ (posedge clk)
clock_count <= (clock_count == 20'd200008) ? 20'd0 : clock_count + 1'b1;
always @ (posedge clk)
if (clock_count == 20'd050_000)column <= 4'b0111; // column 0 check
else if (clock_count == 20'd100_000)column <= 4'b1011; // column 1 check
else if (clock_count == 20'd150_000)column <= 4'b1101; // column 2 check
else if (clock_count == 20'd200_000)column <= 4'b1110; // column 3 check
always @ (posedge clk) begin
if(clock_count == 20'd50008)// column 0 rows check after column activated
if (row == 4'b0111) decode <= 4'b0001; // row 0 -> key '1'
else if (row == 4'b1011) decode <= 4'b0100; // row 1 -> key '4'
else if (row == 4'b1101) decode <= 4'b0111; // row 2 -> key '7'
else if (row == 4'b1110) decode <= 4'b0000; // row 3 -> key '0'
else if(clock_count == 20'd100008)// column 1 rows check after column activated
if (row == 4'b0111) decode <= 4'b0010; // row 0 -> key '2'
else if (row == 4'b1011) decode <= 4'b0101; // row 1 -> key '5'
else if (row == 4'b1101) decode <= 4'b1000; // row 2 -> key '8'
else if (row == 4'b1110) decode <= 4'b1111; // row 3 -> key 'F'
else if(clock_count == 20'd150008)// column 2 rows check after column activated
if(row == 4'b0111) decode <= 4'b0011; // row 0 -> key '3'
else if(row == 4'b1011) decode <= 4'b0110; // row 1 -> key '6'
else if(row == 4'b1101) decode <= 4'b1001; // row 2 -> key '9'
else if(row == 4'b1110) decode <= 4'b1110; // row 3 -> key 'E'
else if(clock_count == 20'd200008)// column 3 rows check after column activated
if(row == 4'b0111) decode <= 4'b1010; // row 0 -> key 'A'
else if(row == 4'b1011) decode <= 4'b1011; // row 1 -> key 'B'
else if(row == 4'b1101) decode <= 4'b1100; // row 2 -> key 'C'
else if(row == 4'b1110) decode <= 4'b1101; // row 3 -> key 'D'
end
endmodule
我的计数器出现问题,因为我的去抖动效果不佳。我的去抖动在键盘按钮释放时无法正常工作,所以我的计数器实际上会在按下按钮后不受控制地计数。
我完成了项目并将其放在 Github 上。如果其他人有兴趣尝试用 FPGA 找出键盘,请参考以下内容:
FPGA 上的去抖按钮按下:https://www.fpga4student.com/2017/04/simple-debouncing-verilog-code-for.html
-
您可以在我的 Github 项目中通过“keypad.v”和“debounce.v”查看小键盘的 verilog 代码功能。
我有一个带 Digilent PMOD 键盘的 DE-10 lite FPGA,每次按下键盘上的按钮时,我都会尝试增加一个计数器。我正在尝试增加一个计数器,以便我可以知道在当前状态下按下了多少个按钮。我遵循了 Digilent 的示例代码,并尝试通过如下所示的轮询技术检测按键:
module keypad(input clk, input [3:0] row, output reg [3:0] column, output reg [3:0] decode);
reg [19:0] clock_count;
always @ (posedge clk)
begin
////////////////////////
if (clock_count == 20'd50000) // column 0 check
begin
column <= 4'b0111;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd50008) // column 0 rows check after column activated
begin
if (row == 4'b0111) decode <= 4'b0001; // row 0 -> key '1'
else if(row == 4'b1011) decode <= 4'b0100; // row 1 -> key '4'
else if(row == 4'b1101) decode <= 4'b0111; // row 2 -> key '7'
else if(row == 4'b1110) decode <= 4'b0000; // row 3 -> key '0'
clock_count <= clock_count + 1'b1;
end
////////////////////////
else if (clock_count == 20'd100000) // column 1 check
begin
column <= 4'b1011;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd100008) // column 1 rows check after column activated
begin
if (row == 4'b0111) decode <= 4'b0010; // row 0 -> key '2'
else if(row == 4'b1011) decode <= 4'b0101; // row 1 -> key '5'
else if(row == 4'b1101) decode <= 4'b1000; // row 2 -> key '8'
else if(row == 4'b1110) decode <= 4'b1111; // row 3 -> key 'F'
clock_count <= clock_count + 1'b1;
end
////////////////////////
else if(clock_count == 20'd150000) // column 2 check
begin
column <= 4'b1101;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd150008) // column 2 rows check after column activated
begin
if(row == 4'b0111) decode <= 4'b0011; // row 0 -> key '3'
else if(row == 4'b1011) decode <= 4'b0110; // row 1 -> key '6'
else if(row == 4'b1101) decode <= 4'b1001; // row 2 -> key '9'
else if(row == 4'b1110) decode <= 4'b1110; // row 3 -> key 'E'
clock_count <= clock_count + 1'b1;
end
////////////////////////
else if(clock_count == 20'd200000) // column 3 check
begin
column <= 4'b1110;
clock_count <= clock_count + 1'b1;
end
else if(clock_count == 20'd200008) // column 3 rows check after column activated
begin
if(row == 4'b0111) decode <= 4'b1010; // row 0 -> key 'A'
else if(row == 4'b1011) decode <= 4'b1011; // row 1 -> key 'B'
else if(row == 4'b1101) decode <= 4'b1100; // row 2 -> key 'C'
else if(row == 4'b1110) decode <= 4'b1101; // row 3 -> key 'D'
clock_count <= 20'd0; // restart clock counting
end
else begin
clock_count <= clock_count + 1'b1;
end
end
endmodule
我的包装程序如下所示,我遇到的最大问题是我无法在 state0[= 中获取 input_counter 24=] 每次按下按钮时增加:
module calc_top(input fifty_MHz, input [3:0] row, output [3:0] column, input bttn1, output [47:0] hex, output [9:0] leds);
wire twentyfive_mhz;
twentyfive_mhz c0 (.clk(fifty_MHz), .twentyfive_mhz(twentyfive_mhz));
wire [3:0] keypad;
wire [3:0] keypad_decode;
reg [3:0] state_place = 4'd0;
wire [3:0] next_state;
reg [47:0] hex_disp;
reg reset = 1'b1;
always@(posedge twentyfive_mhz or negedge reset)
begin
if(~reset) state_place = 4'd0;
else state_place = next_state;
end
keypad k0 (.clk(twentyfive_mhz), .row(row), .column(column), .decode(keypad));
state0 a0 (.clk(clk), .state_place(state_place), .keypad_decode(keypad), .leds(leds));
endmodule
module state0(input clk, input [3:0] state_place, input [3:0] keypad_decode, output reg [9:0] leds, output reg [3:0] next_state);
reg [3:0] input_counter = 4'd0;
always@(keypad_decode)
begin
if(state_place == 4'd0)
begin
input_counter = input_counter + 4'd1;
case (keypad_decode)
4'h0 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd0; // 0
leds <= 10'b0000000000;
next_state = 4'd0;
end
4'h1 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd1; // 1
leds <= 10'b0000000001;
next_state = 4'd0;
end
4'h2 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd2; // 2
leds <= 10'b0000000010;
next_state = 4'd0;
end
4'h3 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd3; // 3
leds <= 10'b0000000011;
next_state = 4'd0;
end
4'h4 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd4; // 4
leds <= 10'b0000000100;
next_state = 4'd0;
end
4'h5 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd5; // 5
leds <= 10'b0000000101;
next_state = 4'd0;
end
4'h6 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd6; // 6
leds <= 10'b0000000110;
next_state = 4'd0;
end
4'h7 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd7; // 7
leds <= 10'b0000000111;
next_state = 4'd0;
end
4'h8 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd8; // 8
leds <= 10'b0000001000;
next_state = 4'd0;
end
4'h9 : begin
//hex_disp <= (hex_disp << (4*input_counter)) + 4'd9; // 9
leds <= 10'b0000001001;
next_state = 4'd0;
end
4'hF : begin
leds <= 10'b0000001111;
next_state <= 4'd1;
end
default : begin
leds <= 10'b0000000000;
end
endcase
end
end
endmodule
我想我知道发生了什么......我想我需要去抖动才能让它工作,但我无法让去抖动在当前的实现中正常工作。
如果可以请帮忙! 谢谢。
编辑////////// 我刚刚让我的去抖动电路工作,但计数器值仍然不会更新。
初看你的代码,你没有使用那么多输入端口,FSM逻辑是错误的,我根据你的意图修改了,你现在可以看一下代码
module calc_top(
input fifty_MHz
, input [3:0] row
, input bttn1
, output [47:0] hex
, output [9:0] leds
, output [3:0] column
);
wire twentyfive_mhz;
wire [3:0] keypad;
twentyfive_mhz c0 (
.clk (fifty_MHz)
,.twentyfive_mhz(twentyfive_mhz)
);
keypad k0 (
.clk (twentyfive_mhz)
,.row (row)
,.column (column)
,.decode (keypad)
);
state0 a0 (
.clk (twentyfive_mhz)
,.keypad_decode(keypad)
,.leds (leds)
);
endmodule
module state0(
input clk
,input [3:0] keypad_decode
,output reg [9:0] leds
);
always @(posedge clk) leds <= keypad_decode;
endmodule
module keypad(
input clk
,input [3:0] row
,output reg [3:0] column
,output reg [3:0] decode
);
reg [19:0] clock_count;
always @ (posedge clk)
clock_count <= (clock_count == 20'd200008) ? 20'd0 : clock_count + 1'b1;
always @ (posedge clk)
if (clock_count == 20'd050_000)column <= 4'b0111; // column 0 check
else if (clock_count == 20'd100_000)column <= 4'b1011; // column 1 check
else if (clock_count == 20'd150_000)column <= 4'b1101; // column 2 check
else if (clock_count == 20'd200_000)column <= 4'b1110; // column 3 check
always @ (posedge clk) begin
if(clock_count == 20'd50008)// column 0 rows check after column activated
if (row == 4'b0111) decode <= 4'b0001; // row 0 -> key '1'
else if (row == 4'b1011) decode <= 4'b0100; // row 1 -> key '4'
else if (row == 4'b1101) decode <= 4'b0111; // row 2 -> key '7'
else if (row == 4'b1110) decode <= 4'b0000; // row 3 -> key '0'
else if(clock_count == 20'd100008)// column 1 rows check after column activated
if (row == 4'b0111) decode <= 4'b0010; // row 0 -> key '2'
else if (row == 4'b1011) decode <= 4'b0101; // row 1 -> key '5'
else if (row == 4'b1101) decode <= 4'b1000; // row 2 -> key '8'
else if (row == 4'b1110) decode <= 4'b1111; // row 3 -> key 'F'
else if(clock_count == 20'd150008)// column 2 rows check after column activated
if(row == 4'b0111) decode <= 4'b0011; // row 0 -> key '3'
else if(row == 4'b1011) decode <= 4'b0110; // row 1 -> key '6'
else if(row == 4'b1101) decode <= 4'b1001; // row 2 -> key '9'
else if(row == 4'b1110) decode <= 4'b1110; // row 3 -> key 'E'
else if(clock_count == 20'd200008)// column 3 rows check after column activated
if(row == 4'b0111) decode <= 4'b1010; // row 0 -> key 'A'
else if(row == 4'b1011) decode <= 4'b1011; // row 1 -> key 'B'
else if(row == 4'b1101) decode <= 4'b1100; // row 2 -> key 'C'
else if(row == 4'b1110) decode <= 4'b1101; // row 3 -> key 'D'
end
endmodule
我的计数器出现问题,因为我的去抖动效果不佳。我的去抖动在键盘按钮释放时无法正常工作,所以我的计数器实际上会在按下按钮后不受控制地计数。
我完成了项目并将其放在 Github 上。如果其他人有兴趣尝试用 FPGA 找出键盘,请参考以下内容:
FPGA 上的去抖按钮按下:https://www.fpga4student.com/2017/04/simple-debouncing-verilog-code-for.html
您可以在我的 Github 项目中通过“keypad.v”和“debounce.v”查看小键盘的 verilog 代码功能。