In my waveform diagram, I am wondering why my "rdy" value does not change to 1 after 400ns. And why does my "d" value not output anything after the first two outputs? I've tried finding the error for hours but to no avail. Please help, thank you in advance.
Here is my waveform diagram:
And here is my main code.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity GCD is
port(st , clk: in std_logic; --clk temporarily taken out
d1, d2 : in std_logic_vector(7 downto 0);
dout : out std_logic_vector(7 downto 0);
rdy : out std_logic);
end GCD;
architecture behav of GCD is
type state is (S0, S1, S2, S3, S4, S5, S6, S7);
--temporary clk
--signal clk : std_logic;
signal new_state : state;
signal eq : boolean;
signal eq1 : boolean;
signal lt : boolean;
begin
--State transition
process is
variable curr_state : state:= S0;
begin
if clk = '1' then
case curr_state is
when S0 =>
if st = '1' then curr_state := S1;
end if;
when S1 =>
curr_state := S2;
when S2 =>
if eq and not lt then curr_state := S7;
elsif lt and not eq then curr_state := S4;
elsif not eq and not lt then curr_state := S3;
end if;
when S3 =>
curr_state := S4;
when S4 =>
curr_state := S5;
when S5 =>
if eq1 = true then curr_state := S7;
else curr_state := S6;
end if;
when S6 =>
curr_state := S1;
when S7 =>
if st = '0' then curr_state := S0;
end if;
end case;
new_state <= curr_state;
end if;
wait on clk;
end process;
--Asserted Output Process
process is
variable M, N, dout_val, tmp: std_logic_vector(7 downto 0);
variable rdy_val : std_logic;
variable lt_val, eq_val, eq1_val : boolean;
begin
rdy_val := '0';
case new_state is
when S0 =>
M := d1;
N := d2;
when S1 =>
if (to_integer(M) = to_integer(N)) then eq_val := true;
elsif (to_integer(M) < to_integer(N)) then lt_val := true;
end if;
when S2 =>
when S3 =>
M := N;
N := M;
when S4 =>
if (to_integer(M) = 1) then eq1_val := true;
end if;
when S5 =>
when S6 =>
N := (N - M);
when S7 =>
rdy_val := '1';
dout_val := M;
end case;
dout <= dout_val;
rdy <= rdy_val;
lt <= lt_val;
eq <= eq_val;
eq1 <= eq1_val;
wait on new_state;
end process;
end behav;
And here is my testbench:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use work.all;
entity test_GCD is
end test_GCD;
architecture testbench of test_GCD is
signal m, n ,d: std_logic_vector(7 downto 0);
signal clk, st, rdy : std_logic;
begin
--Component Instantiation
device : GCD
port map( clk => clk, st => st, d1 => m,
d2 => n, dout => d, rdy => rdy);
--Process to Generate Test Data
process is
begin
st <= '0';
wait for 10ns;
m <= "00001001"; --9 , 15
n <= "00001111";
wait for 10ns;
st <= '1';
wait until rdy = '1';
wait for 10ns;
st <= '0';
wait for 10ns;
m <= "00001111"; --15, 9
n <= "00001001";
wait for 10ns;
st <= '1';
wait until rdy = '1';
wait for 10ns;
st <= '0';
wait for 10ns; --15 , 14
m <= "00001111";
n <= "00001110";
wait for 10ns;
st <= '1';
wait until rdy = '1';
wait for 10ns;
st <= '0';
wait for 10ns;
m <= "00010010"; --18 , 36
n <= "00100100";
wait for 30ns;
st <= '1';
wait until rdy = '1';
wait for 10ns;
st <= '0';
wait for 10ns;
m <= "01011011"; --91 = 01011011 , 39 = 00100111
n <= "00100111";
wait for 10ns;
st <= '1';
--wait for 10ns;
wait until rdy = '1';
wait for 10ns;
st <= '0';
wait for 10ns;
m <= "01111111"; --127, 127
n <= "01111111";
wait for 10ns;
st <= '1';
wait until rdy = '1';
wait for 10ns;
wait;
end process;
process is
begin
clk <= '0', '1' after 15ns;
wait for 30ns;
end process;
end testbench;
You're the second one to ask a question here today with the same assignment.
In the third st/rdy set you've upset the timing relation:
st <= '0';
wait for 10ns;
m <= "00010010"; --18 , 36
n <= "00100100";
wait for 30ns;
st <= '1';
wait until rdy = '1';
wait for 10ns;
The previous two sets have wait for 10 ns. This one has 30 ns. What does that do?
You're state machine in the unlabelled state transition process is missing the st <= '1', because it's not looking for it when it occurs, add waveforms down in GCD, try new_state.
There's a fine balance between helping someone and doing their assignment for them.
Can you elaborate what you mean by I am missing the st<='1' in my state transition? I've declared st as a std_logic so I can't use the "<=" assignment for it. Do you mean I am missing the st<='1' in my testbench?
The idea was to get you to look at the operation of the state machine spread across two unlabelled processes.
Your state machine is operating on the positive clock edge even though your code is not written to be synthesis eligible. The process is driven by only one event, clk
and the expression clk = '1'
is evaluated in the first if statement condition.
if you add new_state
to your waveform dump (show it in the waveform display):
(you can open the image in a separate tab or window, it's a link to itself)
(And notice the first GCD 'answer' is all U
's. The second 'answer' also doesn't appear to be the greatest common denominator between 15 and 9, either.)
You'll see your state machine quits transitioning, remaining stuck in S2 which evaluates lt
and eq
but doesn't modify them in the Asserted Output Process (and you could use labels instead of comments, any statement can be labelled in VHDL).
We look to the previous state S1, where eq_val
and lt_val
are assigned. They are dependent on M
and N
, which are assigned from d1
and d2
in S0.
Back in S2 notice:
when S2 =>
if eq and not lt then
curr_state := S7;
elsif lt and not eq then
curr_state := S4;
elsif not eq and not lt then
curr_state := S3;
end if;
And if you look at eq
and lt
in the above waveform you see they are both true
. How can that be? There is to transition condition for that, you stick in S2
.
So how can both conditions be true
at the same time?
when S1 =>
if (to_integer(M) = to_integer(N)) then
eq_val := true;
elsif (to_integer(M) < to_integer(N)) then
lt_val := true;
end if;
You are only assigning one of them.
However, the other one remains in it's previous state, latched by new_state
.
As a short term demonstration I assigned eq_val
and lt_val
both false
right before they are evaluated. That will leave at most only one true
.
Unfortunately that reveals another flaw in your design:
And that's not the subject of your question.
You appear to use a Euclid (GCD) algorithm shown in the flow chart (figure 1) in the PDF found in the link. The Boolean types appears to be an assignment requirement (the other student used them as well). The resulting VHDL expresses this algorithm with at least one more error.
You use N
as an accumulator in finding the GCD, and you also change the contents of M
. N
has three sources, d2, the result of N-M
in S6 and swapping
Mand
Nin
S3(which has the effect of assigning
Nto
M, and
N` to itself, variable assignment is immediate). M and N should be signals, or you need an intermediary value to swap through. (They should be signals).
You can use your waveform display to troubleshoot your design. You should also be aware when you are inferring latches, which occur when you have conditional assignments without the equivalent of an 'else'.
The open source tools I used looking at your design (ghdl and gtkwave) don't capture variables in waveform dumps. I'd suspect DesignWorks 5 doesn't either (and could be wrong).
The impact of this is you can't see what the data is doing during the simulation. Your design is small enough you could have used signals throughout without impacting simulation time significantly. Assigning to eq
and lt
directly in S1
would require else assignments (false
). If you're required to use variables for the assignment you can assign them to signals so they are visible, should DesignWorks 5 not display variables. Once you're done you can remove the signals.
The answer to Why doesn't my “rdy” value change to 1? is that you have inferred latches creating a case you don't detect for branching out of S2
.
Once you straighten out the M
and N
swap in S3
it looks like it may have a good chance or working (there could be another gotcha or two in there).
And when you use tmp
to hold the value of M (not using signals):
when S3 =>
tmp := M;
M := N;
N := tmp;
You start getting the right answers:
Without seeing the handout you were given for your project I'd anticipate you worked from pseudo code like found in the linked PDF's figure 1. It may have been written in the anticipation of the use of signals.