Verilog 如何在FPGA的PMOD键盘上保存按键输入
我有一个带有数字PMOD键盘的DE-10 lite FPGA,每次按下键盘上的按钮时,我都会尝试增加一个计数器。我试图增加一个计数器,这样我就可以知道在当前状态下按下了多少个按钮。我遵循Digilent的示例代码,尝试通过如下所示的轮询技术检测按键:Verilog 如何在FPGA的PMOD键盘上保存按键输入,verilog,intel-fpga,Verilog,Intel Fpga,我有一个带有数字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;
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
模块键盘(输入时钟,输入[3:0]行,输出寄存器[3:0]列,输出寄存器[3:0]解码);
reg[19:0]时钟计数;
始终@(posedge clk)
开始
////////////////////////
if(clock_count==20'd50000)//第0列检查
开始
列键“5”
否则,如果(行==4'b1101)解码键“6”
否则,如果(行==4'b1101)解码键“B”
否则,如果(row==4'b1101)从最初看代码时解码您没有使用这么多输入端口,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
模块计算顶部(
输入50_MHz
,输入[3:0]行
,输入bttn1
,输出[47:0]十六进制
,输出[9:0]个LED
,输出[3:0]列
);
电线二十五兆赫;
有线[3:0]键盘;
二十五兆赫c0(
.clk(五十兆赫)
,.twentyfive_mhz(twentyfive_mhz)
);
键盘k0(
.clk(二十五兆赫)
,.世界其他地区(世界其他地区)
,.列(列)
,.解码(键盘)
);
state0 a0(
.clk(二十五兆赫)
,.键盘解码(键盘)
,.发光二极管(LED)
);
端模
模块状态0(
输入时钟
,输入[3:0]键盘\u解码
,输出调节[9:0]指示灯
);
始终@(posedge clk)LED键“6”
如果(行==4'b1101)解码键“A”
否则,如果(row==4'b1011)解码我的计数器有问题,因为我的去抖动没有声音。我的去抖动功能在键盘按钮释放时无法正常工作,所以我的计数器在按下按钮后会无法控制地计数
我完成了这个项目并把它放到Github上。如果其他人有兴趣尝试使用FPGA设计键盘,请参考以下内容:
- FPGA上的去抖动按钮按下:
- 我的项目:
- 在我的Github项目中,您可以通过“keypad.v”和“debounce.v”看到verilog代码如何为键盘工作
正常的程序是采取一些小步骤:编写和测试代码,只需一次输入(按键)即可消除反弹并切换LED。这样小得多的代码对我们来说也更容易查看和评论。@Oldfart谢谢您的回复。我当前的实现确实做到了这一点:只需按一次键,取消反弹,然后打开对应的LED,以二进制形式显示按钮编号。我只想这样做,我可以输入'1',然后输入'2',并将计数器增加1。谢谢您的评论。每个人都有自己编写程序的方式,我很欣赏你的方式,但我完全同意自己的方式。我使用了频谱分析仪(最后),发现唯一的问题是按钮释放时反弹。这很好,你的项目正在按预期工作!!是的,我完全同意你的代码,只是让我们知道,编码风格将帮助我们理解代码在一个简单的一瞥。
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