I am designing a shift key detector.I wrote a test bench. The test showed that my implementation was incorrect.
Here is the simulation in ModelSim.
The red line indicated UNDEFINED. This behavior only occurred twice.
What puzzled me is: why is there such a big gap between those two values? If you look at the test bench, the 3rd and 4th procedures are using the format used for the 1st and 2rd.
Test bench is here: http://pastebin.com/BJVFFgGr
The detector code is here: http://pastebin.com/di42FLqT
As you can see. I have two states in my design. PS2 receiver will filter and generate clean 8-bit make code when a key is pressed (or released). The break code is simply F0 follow by the make code of the key just released. My state machine uses two extra bits to keep track of which shift key has been pressed.
I went through debug, and when we entered the 3rd test values, SHIFT = U instead of 1 from the previous value.
-- release left shift
hex <= "11110000";
wait for 5 ns;
clk <= NOT clk;
wait for 50 ns;
clk <= NOT clk;
wait for 50 ns;
hex <= "00010010"; <----- when I am here shift is already U
wait for 5 ns;
clk <= NOT clk;
wait for 50 ns;
clk <= NOT clk;
wait for 50 ns;
if (shift /= '0')then
error <= '1';
end if;
left_pressed and right_pressed are signals, not variables. So they should have the a value at any instance. If one of them changes, the connection to shift signal will be updated automatically.
Can someone please help me? Thanks.
Thanks.
I expect you're getting the 'U' output because
shift <= left_pressed or right_pressed;
and right_pressed is undefined, so when left_pressed becomes '0' the 'U' in right_pressed shows through.
Remember that
1 or x == 1
0 or x == x
where x can be '0', '1', 'U', 'X', 'Z', '-', 'H', 'L'
There are a few problems with your code that stand out to me
At the moment left_pressed and right_pressed are latches as they will carry their value from one cycle to the next in some conditions, but they're not in a clocked process. If you want them to be plain signals, then you need to give them default values at the start of the process. If you want them to be registers, they need to be in a clocked process.
This is also true of next_state. It should have a default value.
next_state <= current_state;
current_state needs to be in the sensitivity list of the asynchronous process.
Use a separate process to generate your clock in your test bench. At the moment it's mixed in with the stimulus which is messing up your clock period. It also makes it difficult to read.
process p_clkgen
begin
repeat begin
clk <= NOT clk;
wait for 50 ns;
end;
end process;
Then the other process is only dealing with when the input transitions. (I can't remember if repeat is a valid keyword in VHDL, but you get the idea)
I suspect your thinking about your state is mixed up. Probably the state should be that the left or right shift key is pressed, and a make or break on each of them is the transition between states. I think this mix-up is part of the reason why left_pressed and right_pressed are currently latches.