-1

I have a DE-10 lite FPGA with the Digilent PMOD Keypad and I'm trying to increment a counter every time a button on the keypad is pressed. I'm trying to increase a counter so that I may know how many buttons have been pressed while in the current state. I followed the example code from Digilent and am trying to detect keypresses through a polling technique shown below:

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

My wrapping program is displayed below, and the biggest issue I am having is that I can't get input_counter in state0 to increase every time a button is pressed:

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

I think I know what's happening... I think I'm required to have debouncing in order for this to work but I couldn't get the debouncing to work correctly with the current implementation.

Please help if you can! Thank you.

EDIT////////// I just got my debouncing circuit to work but the counter value still wont update.

nick n
  • 1
  • 2
  • The normal procedure is to take little steps: write and test code, which takes a single input (key-press) de-bounces that and toggles a LED. Much smaller code code like that would also be easier for us to look at and comment upon. – Oldfart Mar 20 '20 at 09:23
  • @Oldfart Thank you for your response. My current implementation does do exactly that: takes a single key-press, de-bounces, and turns on the corresponding leds to the buttons number in binary. I just would like to make it so that I could enter '1' then '2' and have a counter increase by 1. – nick n Mar 20 '20 at 10:42

2 Answers2

1

From initial glance at your code you are not using so many input ports,FSM logic is wrong i modified based on your intention, you can have glance at the code now

    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
  • Thanks for your comment. Everyone has their own way of writing programs, and I appreciate yours but I'm perfectly okay with my own. I used a spectrum analyzer (finally) and found the only problem is bouncing from button release. – nick n Mar 24 '20 at 07:35
  • That's good to hear ,your project is working as expected!! yeah i am perfectly ok with your code just letting know that coding styles will help us to understand the code at a simple glance. – Rama Krishna Meda Mar 24 '20 at 07:58
0

I was having problems with my counter because my debouncing was not sound. My debouncing was not working properly on keypad button release, so my counter would actually count up uncontrollably after pressing a button.

I finished the project and put it on Github. If anyone else is interested in trying to figure out a keypad with an FPGA then please reference the following:

nick n
  • 1
  • 2