04-12-2010 09:20 PM
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
04-12-2010 11:10 PM
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
05-07-2010 02:04 AM
05-07-2010 03:01 AM
02-11-2013 01:58 AM
I tried this on CPLD. it's not working.
Thank you..
02-11-2013 11:43 AM
@sanjay464 wrote:
I tried this on CPLD. it's not working.
thanks for sharing!