Verilog 如何在FPGA的PMOD键盘上保存按键输入

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;

我有一个带有数字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

模块键盘(输入时钟,输入[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