如何在 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 找出键盘,请参考以下内容: