I'm designing a number exchange module, and so far I've been able to make it display on Seven Segment Display (S-S-D), like if I press 0 it shows 0... etc. I'm using 2 sets of 4-bits S-S-D (Common Anode).
Now I want to do like:
- default states :
0000_0000
- Now if I press 1 :
0000_0001
- If I press 2 :
0000_0012
- etc.
Whichever key I press, the display will not erase the already displaying number, it will shift it to the left...
And when all 8 S-S-D is full of displaying numbers like: 486C_8763
, at this moment, when I press a key enter a number, like 1
it should be like : 86C8_7631
; it should keep shifting to the left.
Here's my attempted code, and only been able to display it on S-S-D, and display all S-S-D 0000_0000
... still not able to do what's been describe above...
module keydata
(
input clk, //input clk 50MHz
output reg [3:0]keyout=4'b1110, //Default scan value 4bits
input [3:0]keyin, //Keypad receive value
output reg [7:0]SegOut, //Seven Segment Display output
output reg [15:0]scano //Seven Segment Display Scans
);
integer z1=0,zz=0; //Registers for frequency dividing
reg dclk; //Divided frequency clock
reg [7:0]bcdz; //register for saving keypad's number value
reg [3:0]scan; //scan states
always@(posedge clk)
begin
//---------------------
if(z1==50000) //frequency divider
begin
z1<=0;
scan<={scan[2:0],scan[3]}; //scanning pattern shifting resgister
keyout<={keyout[2:0],keyout[3]}; //keypad column scanning 1110->1101->1011->0111->1110(loop)
end
else
z1<=z1+1;
//---------------------
//---------------------
if(zz==10000) //frequency divider for scanning
begin
zz<=0;
dclk<=~dclk;
end
else
zz<=zz+1;
//---------------------
end
always@(posedge dclk) //Seven Segment Scanning
begin
case(scan)
0: scano<=scano[3:0];
1: scano<=scano[7:4];
2: scano<=scano[11:8];
3: scano<=scano[15:12];
endcase
end
always@(posedge dclk) //4x4 Keypad detecting
begin
if (keyout==4'b1110) //Detecting which keyout is currently at scanning
begin
if(keyin==4'b0111) //Tell which key it is
begin
bcdz<=4'b1100;//C //the key's value,save by a register
end
else if(keyin==4'b1011)
begin
bcdz<=4'b1101; //D
end
else if(keyin==4'b1101)
begin
bcdz<=4'b1110; //E
end
else if(keyin==4'b1110)
begin
bcdz<=4'b1111;//F
end
end
else if (keyout==4'b1101) //Using **else if** to differentiate priorities.
begin
if(keyin==4'b0111)
begin
bcdz<=4'b1000; //8
end
else if(keyin==4'b1011)
begin
bcdz<=4'b1001; //9
end
else if(keyin==4'b1101)
begin
bcdz<=4'b1010; //A
end
else if(keyin==4'b1110)
begin
bcdz<=4'b1011; //B
end
end
else if (keyout==4'b1011) //4 scanning possibilities
begin
if(keyin==4'b0111)
begin
bcdz<=4'b0100; //4
end
else if(keyin==4'b1011)
begin
bcdz<=4'b0101; //5
end
else if(keyin==4'b1101)
begin
bcdz<=4'b0110; //6
end
else if(keyin==4'b1110)
begin
bcdz<=4'b0111; //7
end
end
else if (keyout==4'b0111)
begin
if(keyin==4'b0111)
begin
bcdz<=4'b0000; //0
end
else if(keyin==4'b1011)
begin
bcdz<=4'b0001; //1
end
else if(keyin==4'b1101)
begin
bcdz<=4'b0010; //2
end
else if(keyin==4'b1110)
begin
bcdz<=4'b0011; //3
end
end
end
always@(bcdz) //Seven Segment Decoder
begin
case(bcdz)
0 : SegOut <= 8'hC0;
1 : SegOut <= 8'hF9;
2 : SegOut <= 8'hA4;
3 : SegOut <= 8'hB0;
4 : SegOut <= 8'h99;
5 : SegOut <= 8'h92;
6 : SegOut <= 8'h82;
7 : SegOut <= 8'hF8;
8 : SegOut <= 8'h80;
9 : SegOut <= 8'h98;
10 : SegOut <= 8'h88;
11 : SegOut <= 8'h83;
12 : SegOut <= 8'hC6;
13 : SegOut <= 8'hA1;
14 : SegOut <= 8'h86;
15 : SegOut <= 8'h8E;
default : SegOut <= 8'hFF;
endcase
end
endmodule
1 Answer 1
I can see several problems. First, scan
is never initialized, and you're shifting it and not incrementing it, so it doesn't match the case statement that looks at scan
and sets scano
. Second, scano
is also not initialized, and the case statement that sets scano
from segments of scano
makes no sense. Third, you never actually store and shift the values anywhere. You'll need to have a memory location per digit, and I don't see that. They key scanning code also needs work. You'll want to have some delay between when keyout
is changed and when you check keyin
. Perhaps what you could do is have 'shift' and 'check' control lines that get pulses at different times, and you update keyout
when 'shift' pulses and you check for a key press when 'check' pulses. You also need to detect both when a key is pressed and when a key is released, so you can register the key presses as separate events as opposed to just filling all the displays with '7' the moment the '7' key is pressed. Baasically, you need to detect the press, then ignore the keypad until the key is released. You could also turn that nested if statement into a single case statement by concatenating keyout and keyin like so: case ({keyout, keyin})
Try writing some code that just displays '123456' or simiar, ignoring the keyboard. Make that work first, then build on top of it.
Explore related questions
See similar questions with these tags.