UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
10,707 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
Advisor eilert
Advisor
10,697 Views
Registered: ‎08-14-2007

Re: Verilog question

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
Xilinx Employee
Xilinx Employee
10,539 Views
Registered: ‎09-07-2009

Re: Verilog question

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
Xilinx Employee
Xilinx Employee
10,537 Views
Registered: ‎09-07-2009

Re: Verilog question

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 sanjay464
Visitor
8,563 Views
Registered: ‎02-11-2013

Re: Verilog question

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

 

 

                                            Thank you..

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

Re: Verilog question


@sanjay464 wrote:

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

 


thanks for sharing!

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