cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
11,035 Views
Registered: ‎04-12-2010

Verilog question

Hey guys, I've been working on this assignment for my digital logic class for a few weeks, but there are still some kinks when my Spartan board is programmed.  Here is what the program is supposed to do: 

 

Write Verilog code that will debounce your 4x4 Matrix Keypad and add the value of the
button you press to the current LED outputs. Use your Lab5.v as a starting point. To
debounce your 4x4 Matrix Keypad, the following steps are suggested:
1. Read your 4x4 Matrix Keypad
2. Save the value to a register called oldkeypadmemory
3. Wait for some clock cycles using a counter
4. Read your 4x4 Matrix Keypad again
5. Save the value to a register called keypadmemory
6. See whether or not oldkeypadmemory is equal to keypadmemory
7. If it is equal then add the value of the button you pushed to your LED outputs
8. If it is not equal then do nothing
9. Make sure that no button is being pressed before going back to step 1.

 

Here is the code I have so far.  

 

module Lab6(LEDoutput, keypadscan, keypadread, clk);

   output [7:0] LEDoutput;
   output [3:0] keypadscan;

   input [3:0] keypadread;
   input clk;

   reg [7:0] LEDoutput;
   reg [3:0] keypadscan;
   reg [15:0] keypadmemory;
    reg [15:0] oldkeypadmemory;
    reg [7:0] LEDoutput2; 
    reg [31:0] counter;
    reg [15:0] keyhold;
   
   integer icheck;
    integer bouncechk;
    integer clearchk;
    integer keyholdguard;

   
   always @(posedge clk) begin //This block is used to scan the columns independently of button press on 4x4 pad
   
      case(keypadscan)

         4'b0111 : begin       
                     keypadmemory[3:0] = ~keypadread; // ~ means to invert
                     keypadscan =  4'b1011;
                     icheck = 0;
                   end
         4'b1011 : begin           
                     keypadmemory[7:4] = ~keypadread;
                     keypadscan =  4'b1101;
                     icheck = 0;
                   end
         4'b1101 : begin           
                     keypadmemory[11:8] = ~keypadread;
                     keypadscan =  4'b1110;
                     icheck = 0;
                   end
         4'b1110 : begin               
                     keypadmemory[15:12] = ~keypadread;
                            if (bouncechk == 0)
                               begin
                               keypadscan = 4'b0000;
                               end
                            if (bouncechk == 1);
                               begin
                                    keypadscan = 4'b0010;
                               end
                     icheck = 1;
                   end
            4'b0000 : begin
                        if (clearchk == 1)
                            begin
                               keypadscan = 4'b0100;
                            end
                            if (clearchk == 0)
                            begin
                               bouncechk = 1;
                        oldkeypadmemory = keypadmemory;
                               keypadscan = 4'b0001;
                            end
                   end
         4'b0001 : begin
                     counter = counter + 1;
                     if (counter > 2048)
                     begin
                            keypadscan = 4'b0111;
                     end                           
                   end
        4'b0010 : begin
                        if (keypadmemory == oldkeypadmemory) begin
                            if(keypadguard == 0)
                            begin
                               keyhold = keypadmemory;
                            end
                            if (keypadguard == 1)
                           case(keypadmemory)
       
                     //Keypad Decoder
                     16'b0000000000000001 : LEDoutput2 = 8'b00000001; //This will turn on the first LED when "1" is pressed
                         16'b0000000000000010 : LEDoutput2 = 8'b00000100; //4
                         16'b0000000000000100 : LEDoutput2 = 8'b00000111; //7
                         16'b0000000000001000 : LEDoutput2 = 8'b00001110; //*
               
                         16'b0000000000010000 : LEDoutput2 = 8'b00000010; //2
                         16'b0000000000100000 : LEDoutput2 = 8'b00000101; //5
                         16'b0000000001000000 : LEDoutput2 = 8'b00001000; //8
                         16'b0000000010000000 : LEDoutput2 = 8'b00000000; //0
               
                         16'b0000000100000000 : LEDoutput2 = 8'b00000011; //3
                         16'b0000001000000000 : LEDoutput2 = 8'b00000110; //6
                         16'b0000010000000000 : LEDoutput2 = 8'b00001001; //9
                         16'b0000100000000000 : LEDoutput2 = 8'b00001111; //#
               
                         16'b0001000000000000 : LEDoutput2 = 8'b00001010; //A
                         16'b0010000000000000 : LEDoutput2 = 8'b00001011; //B
                         16'b0100000000000000 : LEDoutput2 = 8'b00001100; //C
                         16'b1000000000000000 : LEDoutput2 = 8'b00001101; //D

                     default : LEDoutput2 = 8'b00000000;
                            endcase
 
                     if (keyhold != keypadmemory)
                            begin
                               LEDoutput = (LEDoutput + LEDoutput2);
                        keypadscan = 4'b0011;
                            end
                  end
                       
                        if (keypadmemory != oldkeypadmemory) begin
                           keypadscan = 4'b0111;
                            icheck = 0;
                            bouncechk = 0;
                            clearchk = 0;
                       end
                    end   
            4'b0011 : begin
                    clearchk = 1;
                      keypadscan = 4'b0111;
                      end
            4'b0100 : begin
                     
                   if (keypadmemory == 16'b0000000000000000)
                      begin
                         keypadscan = 4'b0111;
                         icheck = 0;
                         bouncechk = 0;
                      end
                   end                         
                       
         default : begin
                     keypadscan =  4'b0111;
                     icheck = 0;
                            bouncechk = 0;
                            counter = 0;
                            clearchk = 0;
                            keypadguard = 0;
                   end
     
      endcase   
   
   end

endmodule

 

I'm still not getting the right values output to my LED's even with one button press.  I also need to implement a way to make sure that if a button is pressed, the value won't be added to the LED output over and over, but I wasn't sure how to do this.  Any fingers in the right direction would be very appreciated, 

 

Regards,

Ben

0 Kudos
5 Replies
Highlighted
Teacher
Teacher
11,025 Views
Registered: ‎08-14-2007

Hi,

I'm not a verilog guy, so I can't help you with your code, but with your last question:

 

also need to implement a way to make sure that if a button is pressed, the value won't be added to the LED output over and over, but I wasn't sure how to do this. 

Any fingers in the right direction would be very appreciated, 

 

 The answer is simple.

You need to implement a small state machine (FSM).

 

For the input it has to know, whether a key is pressed or not.

If a key is pressed it enables a single addition using either some clock enable on the accumulator register, or by masking the adder input with and-gates, to set them zero (A+0 = A).

Then it waits for the key to become released.

Then it starts again, waiting for the next key-press.

 

 

Have a nice synthesis

  Eilert

 

 

 

 

 

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
10,867 Views
Registered: ‎09-07-2009

I wrote code for you. this code can do all you want. And I find that you made a mistake: The 8 bit LED should be decode to drive. //clk=1MHz module Lab6(LEDoutput, keypadscan, keypadread, clk, rst_n); output [7:0] LEDoutput; output [3:0] keypadscan; input [3:0] keypadread; input clk,rst_n; reg [7:0] LEDoutput; //to drive LED reg [3:0] LED_number,Key_number; //LED_number is sum, Key_number is what you input reg [13:0] key_press_counter; //count the time of the press, about 20mS reg [3:0] keypadscan; reg Key_press_trig; // a trig signal, shows the key has been pressed reg [1:0] Key_Scan_State; //======== Key Scan ========== always @(posedge clk) if(!rst_n) begin Key_Scan_State <= 0; keypadscan <= 4'b0001; key_press_counter <=0; Key_press_trig <=0; end else case(Key_Scan_State) 0: if(|keypadread==0) //no key press keypadscan <= {keypadscan[2:0],keypadscan[3]}; else Key_Scan_State <= 1; 1: begin key_press_counter<= 1; Key_Scan_State <= 2; end 2: begin key_press_counter<= key_press_counter+1; if(|keypadread==0) Key_Scan_State<=0; //release the key else if(key_press_counter==0) begin //enough time Key_Scan_State<=3; Key_press_trig <= 1; end end 3: begin Key_press_trig <= 0; if(|keypadread==0) //release the key Key_Scan_State<=0; end endcase always @(keypadscan or keypadread) //Key Decoder case({keypadscan,keypadread}) 8'h11: Key_number = 4'h0; 8'h12: Key_number = 4'h1; 8'h14: Key_number = 4'h2; 8'h18: Key_number = 4'h3; 8'h21: Key_number = 4'h4; 8'h22: Key_number = 4'h5; 8'h24: Key_number = 4'h6; 8'h28: Key_number = 4'h7; 8'h41: Key_number = 4'h8; 8'h42: Key_number = 4'h9; 8'h44: Key_number = 4'hA; 8'h48: Key_number = 4'hB; 8'h81: Key_number = 4'hC; 8'h82: Key_number = 4'hD; 8'h84: Key_number = 4'hE; 8'h88: Key_number = 4'hF; default: Key_number = 0; endcase //==== LED display ===== always @(posedge clk) if(!rst_n) LED_number <= 0; else if(Key_press_trig) LED_number <= LED_number+Key_number; always @(LED_number) //LED Decoder case(LED_number) 8'h0: LEDoutput = 8'h7E; 8'h1: LEDoutput = 8'h0C; 8'h2: LEDoutput = 8'hB6; 8'h3: LEDoutput = 8'h9E; 8'h4: LEDoutput = 8'hCC; 8'h5: LEDoutput = 8'hDA; 8'h6: LEDoutput = 8'hFA; 8'h7: LEDoutput = 8'h0E; 8'h8: LEDoutput = 8'hFE; 8'h9: LEDoutput = 8'hDE; 8'hA: LEDoutput = 8'hEE; 8'hB: LEDoutput = 8'hF8; 8'hC: LEDoutput = 8'h72; 8'hD: LEDoutput = 8'hBC; 8'hE: LEDoutput = 8'hF2; 8'hF: LEDoutput = 8'hE2; default: LEDoutput = 0; endcase end module
Tags (1)
0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
10,865 Views
Registered: ‎09-07-2009

Sorry, I don't know why the code turn to that.

Instead, I attach the Verilog file.

This code can do all you want.

And I find that you may have made a mistake: The 8 bit LED drive signal should be decode to drive.

0 Kudos
Highlighted
Visitor
Visitor
8,891 Views
Registered: ‎02-11-2013

I tried this on CPLD. it's not working.

 

 

                                            Thank you..

Tags (1)
0 Kudos
Highlighted
Historian
Historian
8,878 Views
Registered: ‎02-25-2008


@sanjay464 wrote:

I tried this on CPLD. it's not working.

 


thanks for sharing!

----------------------------Yes, I do this for a living.
0 Kudos