I am trying to set up a problem for state machines in lab and I keep receiving errors when trying to compile in Quartus
I have tried using commas, else statements and nothing seems to work
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.All;
ENTITY SM_VHDL IS -- Do not modify this entity statement!
PORT(X : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
RESETN,
CLOCK : IN STD_LOGIC;
Z : OUT STD_LOGIC;
Q : OUT STD_LOGIC_VECTOR(1 DOWNTO 0) );
END SM_VHDL; -- Do not modify this entity statement!
ARCHITECTURE behavior of SM_VHDL IS
TYPE STATE_TYPE IS (A, B, C);
SIGNAL state : STATE_TYPE;
BEGIN
PROCESS(CLOCK, RESETN)
BEGIN
IF RESETN = '0' THEN
state <= A;
ELSIF CLOCK'EVENT AND CLOCK = '1' THEN
CASE state IS
WHEN A =>
CASE X IS
WHEN "00" =>
state <= B;
WHEN "11" =>
state <= C;
WHEN OTHERS =>
state <= A;
END CASE;
WHEN B =>
CASE X IS
WHEN "10" =>
state <= A;
WHEN "11" =>
state <= C;
WHEN OTHERS =>
state <= B;
END CASE;
WHEN C =>
CASE X IS
WHEN "00" =>
state <= B;
WHEN "01" =>
state <= A;
WHEN OTHERS =>
state <= C;
END CASE;
END CASE;
END IF;
END PROCESS;
Z <= '1' WHEN C;
'0' WHEN A;
'0' WHEN B;
Q <= "00" WHEN A;
"01" WHEN B;
"10" WHEN C;
"11" WHEN "-";
END behavior;
I need it to compile
WHEN can only be used with boolean conditions. A/B/C are all literals of STATE_TYPE. You need to create a boolean result by creating a comparison on the state signal:
Z <= '1' when STATE = C
else '0' when STATE = A -- This state not actually needed as a single ELSE would cover it
else '0';
Ill let you work out the statement for Q
The syntax for assigning to Z and Q is wrong for multiple issues:
Missing WITH state SELECT ... before assign
Uses ";" between when parts, use , instead
Cant use "-" (don't care) after last when, use OTHERS instead
So updated code:
WITH state SELECT Z <=
'1' WHEN C,
'0' WHEN A,
'0' WHEN B;
WITH state SELECT Q <=
"00" WHEN A,
"01" WHEN B,
"10" WHEN C,
"11" WHEN OTHERS;
Btw. consider using ModelSim Starter Edition as compiler/simulator before moving to Quartus, since the compile time is faster and messages often better.
Related
Please take a look at this example code of a simple state machine:
entity Top is
Port ( Clock : in STD_LOGIC;
Reset : in STD_LOGIC;
TREADY : out STD_LOGIC
);
end Top;
architecture Behavioral of Top is
type STATE_t is (S0, S1, S2);
signal CurrentState : STATE_t := S0;
signal TREADY_Int : STD_LOGIC := '0';
begin
-- Transit network
process(Clock, Reset, CurrentState)
variable NextState : STATE_t;
begin
if(rising_edge(Clock)) then
case CurrentState is
when S0 =>
if(Reset = '1') then
NextState := S0;
else
NextState := S1;
end if;
when S1 =>
NextState := S2;
when S2 =>
NextState := S1;
end case;
end if;
CurrentState <= NextState;
end process;
-- Output network
process(CurrentState)
begin
if(CurrentState = S0) then
TREADY_Int <= '0';
elsif(CurrentState = S1) then
TREADY_Int <= '1';
elsif(CurrentState = S2) then
TREADY_Int <= '0';
end if;
end process;
TREADY <= TREADY_Int;
end Behavioral;
The synthesis shows me the following warning:
[Synth 8-327] inferring latch for variable 'TREADY_Int_reg'
The warning disappears when I change the last condition of the output network to
else
TREADY_Int <= '0';
end if;
and also the latch is gone
So why does the last condition of the output state machine in the first version result in a latch? Why is else something other than elsif()? In my opinion, the two expressions are equal, because the state machine has only three states, so else and elsif(<ThirdState>) should be the same when all other states are handled. But it seems that my understanding is wrong here.
It's usually best not to assume that a synthesiser is as clever as you are. Using else is safer as you have discovered.
Here's another example. This is better:
process (A, B)
begin
if (A < B)
F <= ...
else
F <= ...
end if;
end process;
than this:
process (A, B)
begin
if (A < B)
F <= ...
end if;
if (A >= B)
F <= ...
end if;
end process;
I need your help. I have a VHDL with nested condition and I would like to redraw it into a schematic. I think I should use one 2bit mux and 4bit mux. Is there anyone who can help me please? I tried google it but I didn't find anything that can help me.
process (a,b,c,d) begin
y <= '0';
z <= b;
if d='1' then
y <= b;
if a = '0' then
y <= c;
end if;
z <= '1';
else
y <= '1';
z <= d;
end if;
end process;
a,b,c,d are std_logic in
z, y are std_logic out
This a code for a 4-bit mux you can easily modify to make 2 bit
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY mux_4_1 IS
PORT (
a : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
s : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
b : OUT STD_LOGIC);
END ENTITY;
ARCHITECTURE behavioural OF mux_4_1 IS
BEGIN
PROCESS (a, s)
BEGIN
IF s = "00" THEN
b <= a(0);
ELSIF s = "01" THEN
b <= a(1);
ELSIF s = "10" THEN
b <= a(2);
ELSE
b <= a(3);
END IF;
END PROCESS;
END ARCHITECTURE;
Right now i'm working on a project concerning the use of D Flip Flop on Falling Edge, with x and y being the inputs and z being the output.
The Circuit will only give z ='1' only if x and y are both 0 and also if they were both 0 in a previous clock cycle, and the transitions only occurring in the clock's falling edge.
Variables a and b will represent states Q0(a) and Q1(b).
The Mealy machine is of two states : Q0 and Q1, and the transations are as follow:
Q0
x y z
0 0 1
0 1 x
1 0 0 --> goes to next state (Q1)
1 1 x
Q1
x y z
0 0 0 --> goes to next state (Q0) only this time z='0'
0 1 x
1 0 x
1 1 0 --> stays in current state (Q1)
The problem is that when the transition from Q1 to Q0 happens, z is still '1' instead of '0'.
Is there any advice on how could i manage to get around that fast transition?
Here is the code so far:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Mealys is
Port (
inicio: in std_logic;
clk: in std_logic;
x: in std_logic;
y: in std_logic;
z: out std_logic;
a: out std_logic;
b: out std_logic
);
end Mealys;
architecture behavior of Mealys is
type nombres_estados is (Q0, Q1);
signal estado: nombres_estados;
signal entrada_aux: std_logic_vector (1 downto 0);
begin
entrada_aux <= x & y;
FF_D: process (clk)
begin
if (inicio = '1') then
estado <= Q0;
elsif falling_edge(clk) then
case estado is
when Q0 =>
case entrada_aux is
when "00" => estado<=Q0;
when "10" => estado<=Q1;
when others => estado<=Q0;
end case;
when Q1 =>
case entrada_aux is
when "00" => estado<=Q0;
when "11" => estado<=Q1;
when others => estado<=Q1;
end case;
when others => estado<=Q0;
end case;
end if;
end process;
next_decode: process(estado, entrada_aux)
begin
case (estado) is
when Q0 =>
a <= '1';
b <= '0';
if entrada_aux <= "00" then
z<='1';
elsif entrada_aux <= "10" then
z<='0';
end if;
when Q1 =>
a <= '0';
b <= '1';
if entrada_aux <= "00" then
z<='0';
elsif entrada_aux <= "11" then
z<='0';
end if;
end case;
end process;
end behavior;
And here is the state diagram
Thank you for you time.
I assume that you are learning VHDL, that you are starting with the VHDL subset for synthesis and that the final goal is to synthesize your design.
Your design comprises two processes: a synchronous one and a combinatorial one. Both are bogus for synthesis.
Your synchronous process does not correctly handle the reset. If your reset is asynchronous (that is, is taken into account immediately when asserted), it should be in the sensitivity list:
process(clk, inicio)
begin
if inicio = '1' then
<initialize things>
elsif falling_edge(clk) then
<do things>
end if;
end process;
And if it is synchronous (that is taken into account only on the clock falling edge), it should not be in the sensitivity list but the reset part of your process should be under the scope of the clock edge test:
process(clk)
begin
if falling_edge(clk) then
if inicio = '1' then
<initialize things>
else
<do things>
end if;
end if;
end process;
Your combinatorial process has 3 outputs: a, band z. They must all be assigned a value during any execution of the process. This is what combinatorial means: each time an input changes, the signals propagate and all outputs finally get a new value. The new value can be the same as the previous one but this must be by accident, not because the output has not been assigned. Else, it would mean to a synthesizer: "keep the previous value", which usually leads to the inference of latches to store the previous value... Not what you want in a true combinatorial process. In your process, when estado or entrada_aux change, a and b are assigned but not always z (I let you understand why).
There is another problem in this process: the equality test operator is =, not <= which is the less or equal test operator. Note that your code should not even compile as it is.
It is not easy to propose a fixed version of this process because your specification is not 100% clear. What do these x mean in the transition table? For instance, what happens to z if we are in state Q0 and xy is 01 or 11? If the answer is "z does not change", then its computation must involve a memory element and you must describe this in your synchronous process. Else, if it means "z takes any value" (we don't care), then you must decide yourself before coding and add this to your combinatorial process (for instance with an else statement).
I will assume that it means "z does not change". So, you need a memory element (a D-flip-flop) to store the previous value. Add another signal (previous_z) and assign it in your synchronous process:
signal previous_z: std_logic:
...
process(clk, inicio)
begin
if inicio = '1' then
previous_z <= '0';
<initialize other things>
elsif falling_edge(clk) then
previous_z <= z;
<do other things>
end if;
end process;
There is a potential problem here because we are reading the value of z which is an output port of your entity. In VHDL versions previous 2008 this was forbidden. If you are using a pre-2008 version of VHDL you must declare another internal signal (local_z) that you can read and assign, use it everywhere, and assign it to the output z, for instance in a concurrent signal assignment (outside any process):
signal previous_z: std_logic:
signal local_z: std_logic:
...
process(clk, inicio)
begin
if inicio = '1' then
previous_z <= '0';
<initialize other things>
elsif falling_edge(clk) then
previous_z <= local_z;
<do other things>
end if;
end process;
z <= local_z;
Now, you can use this previous_z signal in your combinatorial process to compute local_z (or z in VHDL 2008):
next_decode: process(estado, entrada_aux, previous_z)
begin
case estado is
when Q0 =>
a <= '1';
b <= '0';
if entrada_aux = "00" then
local_z <= '1';
elsif entrada_aux = "10" then
local_z <= '0';
else
local_z <= previous_z;
end if;
when Q1 =>
a <= '0';
b <= '1';
if entrada_aux = "00" then
local_z <= '0';
elsif entrada_aux = "11" then
local_z <= '0';
else
local_z <= previous_z;
end if;
end case;
end process;
Note that previous_z must be added to the sensitivity list. Do you see now how the local_z output of the process will always be assigned?
There is an even better option which consists in assigning a default value to each output, unconditionally, at the beginning of the process and change this if and only if needed:
next_decode: process(estado, entrada_aux, previous_z)
begin
a <= '0':
b <= '0';
local_z <= previous_z;
case estado is
when Q0 =>
a <= '1';
if entrada_aux = "00" then
local_z <= '1';
elsif entrada_aux = "10" then
local_z <= '0';
end if;
when Q1 =>
b <= '1';
if entrada_aux = "00" then
local_z <= '0';
elsif entrada_aux = "11" then
local_z <= '0';
end if;
end case;
end process;
This works because, in a combinatorial process, when a signal is assigned several times, it is the last assignment that wins. And this coding style has a good property: you cannot forget to assign an output.
There is another good option: concurrent signal assignments (outside any process):
a <= '1' when estado = Q0 else '0';
b <= '1' when estado = Q1 else '0';
local_z <= '1' when estado = Q0 and entrada_aux = "00" else
'0' when estado = Q0 and entrada_aux = "10" else
'0' when estado = Q1 and entrada_aux = "00" else
'0' when estado = Q1 and entrada_aux = "11" else
previous_z;
Concurrent signal assignments, when the logic is simple enough, are maybe even better than the two other options because there is no need to worry about sensitivity lists and always assigning the outputs. Probably very good points, at least for beginners.
One last remark: you use the std_logic resolved type without any good reason. This is unfortunate and error prone. You should use std_ulogic, its unresolved parent type instead (u for Unresolved). But this is out of scope your question.
I'm trying to implement a finite state machine identifier with xilinix 10.1
I've seen those errors in previous questions but the answers didn't include my question.. I'm not searching for an answer but rather a meaning for the FFd1 part
The following error is generated
WARNING:Xst:1293 - FF/Latch <machine1/current_state_FFd1> has a constant value of 0 in block <Main>. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1293 - FF/Latch <machine1/current_state_FFd2> has a constant value of 0 in block <Main>. This FF/Latch will be trimmed during the optimization process.
this is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity M_1 is
Port ( x : in STD_LOGIC;
clk : in STD_LOGIC;
state : out integer range 0 to 5 := 0;
z : out STD_LOGIC );
end M_1;
architecture Behavioral of M_1 is
type state_type is (A, B, C, D);
signal next_state, current_state: state_type := A;
begin
process(clk) is
begin
if (clk = '1' and clk'event) then
current_state <= next_state;
end if;
end process;
process(x,current_state)
begin
case current_state is
when A =>
if(x='0') then
next_state <= B;
z <='0';
elsif(x='1') then
next_state <= C;
z <='1';
end if;
when B =>
if(x='0') then
next_state <= C;
z <='1';
elsif(x='1') then
next_state <= D;
z <='0';
end if;
when C =>
if(x='0') then
next_state <= A;
z <='0';
elsif(x='1') then
next_state <= D;
z <='1';
end if;
when D =>
if(x='0') then
next_state <= B;
z <='0';
elsif(x='1') then
next_state <= C;
z <='0';
end if;
end case;
end process;
process (current_State) is
begin
case current_state is
when A =>
state <=0;
when B =>
state <=1;
when C =>
state <=2;
when D =>
state <=3;
end case;
end process;
end Behavioral;
can anyone tell me
What does current_state_FFd1 and what's the difference between it and current_State_1 ?
how can i solve this error ?
Thanks inadvance
The "current_state" signal is mapped onto a 2-bit flip-flop primitive by the CAD tools. The flip-flop will look something like the FD16CE primitive, shown here.
The flip-flop will take 2 data inputs (current_state_FFd1 and current_state_FFd2) and a clock, and produce two data outputs (current_state_FFq1 and current_state_FFq2). The inputs determine the value of the current_state signal sampled at the next clock edge, and the outputs reflect the current state.
The message you're seeing suggests that the CAD tools can prove that "current_state" never changes from the "00" encoding ("A" in your enumerated type), and so the flip-flop can be optimized away with a hard-wired output of "00".
The VHDL you posted looks reasonable -- changes on the 'x' input should cause a change in current_state. I'll bet the 'x' input is somehow hard-wired to 0 in higher-level VHDL (or in your testbench.)
Is it possible to implement a mux with multiple control signals? For example, I want to do something like this:
with (sig1 & sig2) select
output <= A when "00",
B when "01",
C when "10",
D when "11",
'0' when others;
I know I could just assign them to a new signal and use that, but that's something I want to avoid if possible.
You need to enable VHDL2008 mode on your compiler to have it work.
An alternative (also 2008):
muxing: process (sig1, sig2) is
begin -- process muxing
case sig1 & sig2 is
when "00" => output <= '1';
when "01" => output <= '0';
when "10" => output <= '0';
when "11" => output <= '1';
when others => output <= '0';
end case;
end process muxing;
If you have no VHDL-2008 mode on your compiler it will fail with complaints of
Array type case expression must be of a locally static subtype.
or similar.
If your compiler can't be made to be VHDL-2008 compliant, you have to work around this by creating a type that you can use to surround the sig1 & sig2 to explicitly tell the compiler what's going on:
subtype twobits is bit_vector(0 to 1);
Then:
with twobits'(sig1 & sig2) select
output <= '1' when "00",
-- etc.
or:
case twobits'(sig1 & sig2) is
when "00" => -- etc.
See this, maybe it helps you
entity MUX is
port ( a, i0, i1 : in bit;
o : out bit );
end MUX;
architecture behave of MUX is
begin
process ( a, i0, i1 ) begin
if a = '1' then
o <= i1;
else
o <= i0;
end if;
end process;
end behave;