VHDL - iSIM output uninitialised, doesn't change states - vhdl

Hi I am a new Xilinx user and been having trouble with how to write stimulus/simulate in a test bench. My output(Kd) isn't giving me any sensible values and gives 'u' for the first few clock cycles before moving and staying at '1' throughout.
Not sure if I have written the correct stimulus but hoping someone would help me out here!
My VHDL code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity codeFig2b is
Port ( R0 : in STD_LOGIC;
R1 : in STD_LOGIC;
R2 : in STD_LOGIC;
R3 : in STD_LOGIC;
Kd : out STD_LOGIC;
clock : in STD_LOGIC);
end codeFig2b;
architecture Behavioral of codeFig2b is
signal Qa, Qb: STD_LOGIC;
begin
process(clock, R0, R1, R2, R3)
begin
if clock = '1' and clock'event then
Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
Qb <= Qa;
end if;
end process;
Kd <= Qa and Qb;
end Behavioral;
My Testbench ##
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
ENTITY codeFig2b_test IS
END codeFig2b_test;
ARCHITECTURE behavior OF codeFig2b_test IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT codeFig2b
PORT(
R0 : IN std_logic;
R1 : IN std_logic;
R2 : IN std_logic;
R3 : IN std_logic;
Kd : OUT std_logic;
clock : IN std_logic
);
END COMPONENT;
--Inputs
signal R0 : std_logic := '0';
signal R1 : std_logic := '0';
signal R2 : std_logic := '0';
signal R3 : std_logic := '0';
signal clock : std_logic := '0';
--Outputs
signal Kd : std_logic;
-- Clock period definitions
constant clock_period : time := 100 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: codeFig2b PORT MAP (
R0 => R0,
R1 => R1,
R2 => R2,
R3 => R3,
Kd => Kd,
clock => clock
);
-- Clock process definitions
clock_process :process
begin
clock <= '0';
wait for clock_period/2;
clock <= '1';
wait for clock_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '0';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '0';
R1 <= '1';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '0';
R2 <= '1';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '0';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '0';
R3 <= '1';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '1';
R3 <= '0';
wait for 100 ns;
R0 <= '1';
R1 <= '1';
R2 <= '1';
R3 <= '1';
wait for clock_period*10;
-- insert stimulus here
wait;
end process;
END;

This can be answered without simulating. Kd's output will go to a '1' and stay there.
process(clock, R0, R1, R2, R3)
begin
if clock = '1' and clock'event then
Qa <= (R0 or R1 or R2 or R3) or (Qa and Qb);
Qb <= Qa;
end if;
end process;
Kd <= Qa and Qb;
Qa goes high for any of R0, R1, R2 or R2 or (Qa and Qb);
So once Qa and Qb goes high Qa stays high.
Qb goes high one clock after the first occurrence of Qa going high.
The way this happens is o consecutive '1' inputs on any of R0, R1, R2 or R3.
You clock period is 100 ns and your stimulus interval is too.
You have no stimulus following the first clock where all of R0, R1, R2 and R3 are all low at the same time to demonstrate.
Unfortunately the waveform image on your Xilinx post (iSIM output Unintialised, doesn't change states.) doesn't show QA and Qb to see that they both go high and stay there:
(clickable)
When you add them this point comes through:
clickable)

What you built is a sequential logic, meaning that the outputs depend on the previous hystory of the inputs/outputs. In your case we have Qa, and Qb which is the last value of Qa.
Keeping this in mind, the approach you have used in the testbench is not optimal, because you are trying every combination of the inputs without taking into account that the last Qa is actually important.
This is what happens:
Start : Qa = U Qb = U => Kb = U
Inputs 1: Qa = 1 Qb = U => Kb = U
Inputs 2: Qa = 1 Qb = 1 => Kb = 1
Inputs 3: Qa = 1 Qb = 1 => Kb = 1
Inputs 4: Qa = 1 Qb = 1 => Kb = 1
....
As soon as one of the Rs goes high, Qa is high. Given the order of your combinations of inputs, there is no case where Qa goes low again.
This means that after the second input combination, Qb gets a known value and Kb goes high.
Sensitivity list
This is not part of the answer but it's a consideration on the code you have written: you have put on the sensitivity list R0, R1, R2, R3 but, given what you have written after that, this is not necessary.
The process does something only if
if clock'event and clock = 1 then
this means that any event on the Rs are ignored. I'm sure that the synthetizer actually realizes that and ignores it, but it's a good practice to set a proper sensitivity list and, when possible, only use clocked processes for sequential logic and finite state machines.
I also suggest that you use the more readable rising_edge(clock) and falling_edge(clock) functions:
process(clock)
begin
if rising_edge(clock) then
Qa <= R0 or R1 or R2 or R3 or (Qa and Qb);
Qb <= Qa;
end if;
end process;
Signals and processes
Another thing you should know is how the process work: you are not assigning new values to the signals, but rather planning values for them. If you reprogram a certain signal you are just overwriting the previous planning, and the first value is never assigned. The values are finally assigned at the end of the process.
Here is a simple example:
-- Let's assume A = 0 and B = 0 at startup
clocked_process : process(clk)
begin
if rising_edge(clk) then
A <= '1';
B <= A;
A <= '0';
end if;
end process;
At the end B is still 0, this because A = 0 for the whole process and only gets a planned value of 1, actually never assigned because it is overwritten before the end of the process (in this specific case the synthetizer will ignore A <= '1' for the implementation).
Overwriting the planned value can be used to simplify the logic: what I usually do is setting some default values and then overwriting them only when I need to.
So, instead of writing
...
case A is
when "00" =>
B <= '0';
when "01" =>
B <= '0';
when "10" =>
B <= '0';
when "11" =>
B <= '1';
end case;
...
I write this (I may retain the case structure if I need it for other signals, typically in Finite State Machines):
...
B <= '0';
if A = "11" then
B <= '1';
end if;
...
For this simple examples the synthetizer may be able to infer the semplification. However, you should get used to think in logic level ports because the same thing written in two equivalent ways from a behavioral point of view, is actually implemented differently.

Related

"several sources for unresolved signal" in a Master/Slave JK Flip-flop (GHDL)

I'm trying to implement a clk Master/Slave JK Flip-flop with two CLK SR Flip-flop components based on NAND Logic in GHDL.
I stumble upon the following error:
several sources for unresolved signal
error during elaboration
I know, as a matter of fact, that the issue is on the Slave latch input SR (S <= Q (Master latch output); R <= nQ (Master latch output)) because of the initial value.
I tried to initialize the values in many ways but didn't manage to pass that error.
I really appreciate any help you can provide.
enter image description here
JK FF Component:
library ieee;
use ieee.std_logic_1164.all;
entity jkff_ms is
port
(
J, K, clk : in std_ulogic;
Q, nQ : inout std_ulogic
);
end entity;
architecture behave of jkff_ms is
component srff
port
(
S, R, clk : in std_ulogic;
Q, nQ : inout std_ulogic -- Q <= (S nand clk) nand nQ; / nQ <= (R nand clk) nand Q;
);
end component;
signal S, R, SRQ, SRnQ : std_ulogic;
signal t0, t1, t2, t3, t4 : std_ulogic;
begin
SRQ <= '1';
SRnQ <= '0';
t0 <= clk nand clk; -- NOT
t1 <= J nand nQ;
t2 <= t1 nand t1; -- NOT
t3 <= K nand Q;
t4 <= t3 nand t3; -- NOT
SR0: srff port map (t2, t4, clk, SRQ, SRnQ);
SR1: srff port map (SRQ, SRnQ, t0, Q, nQ);
end architecture;
JK FF Testbench:
library ieee;
use ieee.std_logic_1164.all;
entity jkff_ms_tb is
end entity;
architecture rtl of jkff_ms_tb is
procedure clk_gen(signal clk0 : out std_ulogic; constant freq : real) is
constant T : time := 1000 ms/freq;
constant ht : time := T/2; -- High_Time
constant lt : time := T - ht; -- Low_Time
begin
assert (ht /= 0 fs) report "clk_plain: High_Time = 0; time resolution to large for freq" severity FAILURE;
loop
clk0 <= '1';
wait for ht;
clk0 <= '0';
wait for lt;
end loop;
end procedure;
component jkff_ms
port
(
J, K, clk : in std_ulogic;
Q, nQ : inout std_ulogic
);
end component;
signal J, K, Q, nQ : std_ulogic;
signal clk_100 : std_ulogic;
begin
clk_gen(clk_100, 100.000e6); -- 100 MHz
assert FALSE report "Time resolution:" & time'image(time'succ(0 fs)) severity NOTE;
JK: jkff_ms port map (J, K, clk_100, Q, nQ);
process
begin
J <= 'X';
K <= 'X';
wait for 10 ns;
J <= '0';
K <= '0';
wait for 10 ns;
J <= '0';
K <= '0';
wait for 10 ns;
J <= '1';
K <= '0';
wait for 10 ns;
J <= '0';
K <= '0';
wait for 10 ns;
J <= '0';
K <= '1';
wait for 10 ns;
J <= '1';
K <= '0';
wait for 10 ns;
J <= '0';
K <= '0';
wait for 10 ns;
J <= '0';
K <= '1';
wait for 10 ns;
assert false report "End of Test";
wait;
end process;
end architecture;

VHDL Error: Net is driven by multiple primitive gates

I've been trying to write some code for a lab i need to do this week but ran into the error mentioned in the title (image below). The code just needs to cycle new inputs through 4 registers and checking to see which is the largest and smallest of the set. The following code is what I was using when i got the errors;
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity max_min is
port(
din : in std_logic_vector(3 downto 0);
reset : in std_logic;
clk : in std_logic;
sel : in std_logic_vector(1 downto 0);
max_out : out std_logic_vector(3 downto 0);
min_out : out std_logic_vector(3 downto 0);
reg_out : out std_logic_vector(3 downto 0)
);
end max_min ;
architecture arch of max_min is
signal R0,R1,R2,R3 : std_logic_vector(3 downto 0);
begin
--Reset and register cycle
process(clk,reset)
begin
if(reset = '1') then
R0 <= "1000";
R1 <= "1000";
R2 <= "1000";
R3 <= "1000";
max_out <= "0000";
min_out <= "0000";
elsif(clk'event and clk = '1') then
if(R0 /= din) then
R3 <= R2;
R2 <= R1;
R1 <= R0;
R0 <= din;
end if;
end if;
end process;
--Greater Than logic
process(clk)
begin
if(clk'event and clk = '1') then
if(R0 >= R1 and R0 >= R2 and R0 >= R3) then
max_out <= R0;
elsif(R1 >= R0 and R1 >= R2 and R1 >= R3) then
max_out <= R1;
elsif(R2 >= R0 and R2 >= R1 and R2 >= R3) then
max_out <= R2;
elsif(R3 >= R0 and R3 >= R1 and R3 >= R2) then
max_out <= R3;
end if;
end if;
end process;
--Less Than logic
process(clk)
begin
if(clk'event and clk = '1') then
if(R0 <= R1 and R0 <= R2 and R0 <= R3) then
min_out <= R0;
elsif(R1 <= R0 and R1 <= R2 and R1 <= R3) then
min_out <= R1;
elsif(R2 <= R0 and R2 <= R1 and R2 <= R3) then
min_out <= R2;
elsif(R3 <= R0 and R3 <= R1 and R3 <= R2) then
min_out <= R3;
end if;
end if;
end process;
--Register Select
process(clk,sel)
begin
if(clk'event and clk = '1') then
case sel is
when "00" =>
reg_out <= R0;
when "01" =>
reg_out <= R1;
when "10" =>
reg_out <= R2;
when "11" =>
reg_out <= R3;
when others =>
reg_out <= "0000";
end case;
end if;
end process;
end arch;
The following is the set of errors i got when running the above code in Precision RTL;
I'm not very experienced with VHDL yet, so i'm not sure what these errors mean or what i may have done wrong. The code didn't seem to have any errors when i ran it through Modelsim.
Problem solved. I had max_out and min_out in two separate processes. Once i merged them all into one process it fixed itself.
Thank you to all the commenters for their advice.

FSM Mealy Machine Sequence Detector. How to use multiple flip flops?

Right now I am working on a small project in Vivado, a Mealy FSM. The program must detect a 6 bits sequence 001011, and output "1" when the sequence is detected.
The code concerning the sequence detection is doing just fine, but besides that, it must also use Three Flip Flops: JK, D, and T.
Any advice or suggestions on how to add them?
Thank you for your time.
This is the FSM code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity sequence is
port(
clk : in std_logic;
reset : in std_logic;
x: in std_logic;
z : out std_logic;
a : out std_logic;
b : out std_logic;
c : out std_logic;
d : out std_logic;
e : out std_logic;
f : out std_logic);
end sequence;
architecture behavioral of sequence is
type state_type is (Q0, Q1, Q2, Q3, Q4, Q5);
signal state, next_state : state_type;
begin
state_register: process (clk, reset)
begin
if (reset = '1') then --if reset is high, goto state Q0
state <= Q0;
elsif (clk'event and clk = '1') then --if not, and rising
state <= next_state; --edge, go to next state
end if;
end process;
next_state_func: process (x, state)
begin
case state is
when Q0 =>
if x = '0' then
next_state <= Q1;
else
next_state <= Q0;
end if;
when Q1 =>
if x = '0' then
next_state <= Q2;
else
next_state <= Q0;
end if;
when Q2 =>
if x = '1' then
next_state <= Q3;
else
next_state <= Q2;
end if;
when Q3 =>
if x ='0' then
next_state <= Q4;
else
next_state <= Q0;
end if;
when Q4 =>
if x = '1' then
next_state <= Q5;
else
next_state <= Q2;
end if;
when Q5 =>
if x = '1' then
next_state <= Q0;
else
next_state <= Q1;
end if;
end case;
end process;
-- This process controls the output of the sequence detector.
-- Each state has it's own output along with 'z' which indicates
-- the entire sequence 001011 has been detected.
output_func: process (x, state)
begin
case state is
when Q0 => z <= '0';
a <= '1';
b <= '0';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
when Q1 => z <= '0';
a <= '0';
b <= '1';
c <= '0';
d <= '0';
e <= '0';
f <= '0';
when Q2 => z <= '0';
a <= '0';
b <= '0';
c <= '1';
d <= '0';
e <= '0';
f <= '0';
when Q3 => z <= '0';
a <= '0';
b <= '0';
c <= '0';
d <= '1';
e <= '0';
f <= '0';
when Q4 => z <= '0';
a <= '0';
b <= '0';
c <= '0';
d <= '0';
e <= '1';
f <= '0';
when Q5 => z <= '1';
a <= '0';
b <= '0';
c <= '0';
d <= '0';
e <= '0';
f <= '1';
end case;
end process;
end behavioral;
[1]: https://i.stack.imgur.com/pVwxL.jpg - and here is the table that contains the State Diagram Table of the FSM.
Your code is wrong. Take a look at the output_func process; this is combinatorial, and just decodes the current state, without looking at x. The a to f outputs aren't necessary, and are just a 6-bit decode of the current state - why? The z output is set when the current state is Q5, which isn't what you want - the whole process is redundant. You need to set z in your main FSM, when the current state is Q5, and x is 1 - ie. on the next_state <= Q0 transition.
On your actual question - you can't force selection of any particular F/F type with this code - the synthesiser will do whatever it wants, which means that it will implement the whole thing in D types, since JKs have been obsolete for the last 20 years. The same is probably true of T types. You need to start again, and pretend that you have a technology and a library with T, D, and JK. Write these yourself as separate entities, and re-write your code to instantiate these components, instead of allowing the synthesiser to infer them. Re-write your FSM to use JKs - the diagram you gave shows you how. In other words, derive the J and K inputs to each F/F. The z output can be a D-type. You should be able to fit in a T somewhere - I've left that as an exercise for you.

VHDL traffic lights FSM using LPM counter: where to set/reset counter?

This one has been boggling my mind for the last two days so i've came to the internets for help.
Bit of background info first...
I'm working on a traffic lights project for uni using an Altera DE0 board. I'm a complete n00b with regards to VHDL and this first assignment was more or less a case of "here's an example of a finite state machine and an example of an LPM counter, go make some traffic lights". I think the idea's just to get a feel for using VHDL and mess about with the code to get something working.
We were given an example from a textbook (Free Range VHDL p93 iirc) on an FSM then shown how to make an LPM counter using the Megawizard Plugin Manager in Quartus and basically just had to merge/expand them. Its the first thing i've done using VHDL.
The traffic lights are supposed to be for an intersection of a major road and minor road. The default state will be major road green and minor road red. It should stay in this state until it detects a pushbutton (i.e. a car at the minor road) then go amber then red, then the minor road will go from red to green and stay in green for 10 seconds. It will stay in each other state for 1 second.
I've used 9 states (A-I) and one LPM counter and i'm just looking for a 1 in bit 26 and 29 of the "q" output(?) of the counter for the 1 and 10 second delay.
My problem is that i'm not sure where to set and reset the timer. Technically it should be reset after moving into each state then set (i.e. allowed to count) when moving to the next state.
I'll paste my code below, currently the timer_rst bits are commented out. I've tried placing them in all different lines in the code but the closest i've came to having it work is setting and resetting the timer where those commented out set and reset parts are. When i un-comment them out one at a time and run it each time it'll go from state A to B then C but after that it'll just skip to E then it moves through states so quick all the LEDs light and it seems to jump randomly through different states. Obviously this isn't how it should be done!
Can anyone help me out then?
I hope i've given a decent enough explanation here. I'll paste a link to a video of the board running my code and you can check the code out below too.
Thanks for any help provided!
--Finite state machine using DE0 board implementing a set
--of traffic tights at a major road/minor road junction.
--Major road is green until car present at minor road
--then goes to red while minor road goes to green.
--8 states, A-H. A is 'default' state
--1 sec delay: state B,C,D,F,G,H, 10 sec delay: state E,I.
--Maj Rd lights: LEDG(5 downto 3) Red/Amber/Green.
--Min Rd lights: LEDG(2 downto 0) Red/Amber/Green.
--State vector printed on LEDG(9 downto 6) in binary
--library declarations
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY lpm; --allows use of Altera LPM functions
USE lpm.all;
--entity
entity TRAFFICLIGHTS is
port(
KEY : in std_logic_vector(1 downto 0); --minor rd car present KEY(1) & reset KEY(0)-ACTIVE LOW!
CLOCK_50 : in std_logic;
LEDG : out std_logic_vector(9 downto 0); --6 lights 2 * (red/amber/green) & state vector
HEX0 : out std_LOGIC_VECTOR(7 downto 0) --display current state
);
end TRAFFICLIGHTS;
-- architecture
architecture TRAFFICLIGHTS_arch of TRAFFICLIGHTS is
type state_type is (A,B,C,D,E,F,G,H,I);
signal PS, NS : state_type;
signal timer_rst : std_logic; --wiring to delay components , one_sec, ten_sec
signal timer_q : std_logic_vector(29 downto 0); --output from timer
--LPM counter
component timer
PORT
(
aclr : IN STD_LOGIC ;
clock : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (29 DOWNTO 0) --uses bit 29 for 10 secs, bit 26 for 1 sec
);
end component;
begin
--wiring up LPM counter to signals
U1 : timer
PORT MAP (
aclr => timer_rst,
clock => clock_50,
q => timer_q
);
--detects change in clock, next state or reset key press
sync_proc: process (clock_50, NS, KEY(0))
begin
if (KEY(0)='0') then --if reset pressed, return to state A
PS <= A;
elsif (rising_edge(clock_50)) then --else put present state in next state
PS <= NS;
end if;
end process sync_proc;
--detect change in present state or KEY(1) i.e. minor road car present
comb_proc: process (PS, KEY(1))
begin
case PS is
when A => --when in A: MajRd green, MinRd red, no delay
--show state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0001";
HEX0(7 downto 0) <= "10001000"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (KEY(1) = '0') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= B; --if car present #MinRd, next state is B
else NS <= A;
end if;
when B => --when in B: MajRd amber, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0010";
HEX0(7 downto 0) <= "10000011"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '1'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= C;
else NS <= B;
end if;
when C => --when in C: MajRd red, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0011";
HEX0(7 downto 0) <= "11000110"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= D;
else NS <= C;
end if;
when D => --when in D: MajRd red, MinRd red/amber, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0100";
HEX0(7 downto 0) <= "10100001"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '1'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= E;
else NS <= D;
end if;
when E => --when in E: MajRd red, MinRd green, 10 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0101";
HEX0(7 downto 0) <= "10000110"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '0'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '1'; --MinGreen
if (timer_q(29) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= F;
else NS <= E;
end if;
when F => --when in F: MajRd red, MinRd amber, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0110";
HEX0(7 downto 0) <= "10001110"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '0'; --MinRed
LEDG(1) <= '1'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= G;
else NS <= F;
end if;
when G => --when in G: MajRd red, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0111";
HEX0(7 downto 0) <= "10010000"; --display state on 7 seg
LEDG(5) <= '1'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= H;
else NS <= G;
end if;
when H => --when in H: MajRd red/amber, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "1000";
HEX0(7 downto 0) <= "10001001"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= I;
else NS <= H;
end if;
--new state allows MajRd to stay green (10 sec) if car at MinRd or not
when I => --when in I: MajRd green, MinRd red, 10 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "1001";
HEX0(7 downto 0) <= "11111001"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(29) = '1') then
--timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= C;
else NS <= A;
end if;
when others => -- the catch-all condition
PS <= A; -- if anything else, return to state A
end case;
end process comb_proc;
end TRAFFICLIGHTS_arch;
Video:
https://www.dropbox.com/s/70tkr67zdjj8pyk/File%2018-03-2015%2017%2057%2054.mov?dl=0
Tried adding intermediate states, here's the code from the case statement for the first few below. Its just starting and jumping straight to state B now and not going anywhere.
case PS is
when A => --when in A: MajRd green, MinRd red, no delay
--show state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0001";
HEX0(7 downto 0) <= "10001000"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '0'; --MajAmber
LEDG(3) <= '1'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (KEY(1) = '0') then
timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= B; --if car present #MinRd, next state is B
else NS <= A_1;
end if;
when A_1 =>
--LEDs and 7 seg same as A
LEDG(9 downto 0) <= "0001001100";
HEX0(7 downto 0) <= "10001000"; --display state on 7 seg
timer_rst <= '0'; -- allow timer to count
NS <= B;
when B => --when in B: MajRd amber, MinRd red, 1 sec delay
--print state vector using 4 bit binary 1-8
LEDG(9 downto 6) <= "0010";
HEX0(7 downto 0) <= "10000011"; --display state on 7 seg
LEDG(5) <= '0'; --MajRed
LEDG(4) <= '1'; --MajAmber
LEDG(3) <= '0'; --MajGreen
LEDG(2) <= '1'; --MinRed
LEDG(1) <= '0'; --MinAmber
LEDG(0) <= '0'; --MinGreen
if (timer_q(26) = '1') then
timer_rst <= '1'; -- reset timer
--timer_rst <= '0'; -- allow timer to count
NS <= B_1;
else NS <= B;
end if;
when B_1 =>
--LEDs and 7 seg same as B
LEDG(9 downto 0) <= "0010010100";
HEX0(7 downto 0) <= "10000011"; --display state on 7 seg
timer_rst <= '0'; -- allow timer to count
NS <= C;
Chris, check "FINITE STATE MACHINES IN HARDWARE...", V. A. Pedroni, MIT Press, page 166.

VHDL. Why doesn't my "rdy" value change to 1? Still confused

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.
addendum
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 ltand eqbut 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 swappingMandNinS3(which has the effect of assigningNtoM, andN` 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.

Resources