I am aware that inferred latches occur when not every possible path is defined, but I have made considerations to avoid this in my process:
The signal is:
signal BothButtons : std_logic_vector (1 downto 0) ;
The process is:
Signaling : process(button0, button1)
begin
if (button0= '0') AND (button1 = '0') then
BothButtons <= "00";
elsif (button0= '0') AND (button1 = '1') then
BothButtons <= "01";
elsif (button0= '1') AND (button1 = '0') then
BothButtons <= "10";
elsif (button0= '1') AND (button1 = '1') then
BothButtons <= "11";
end if;
end process;
This is driving me crazy, any help is appreciated, maybe I lack an understanding of something really simple!
The error is:
Warning (10631): VHDL Process Statement warning at swDisplay.vhd(28): inferring latch(es) for signal or variable "BothButtons", which holds its previous value in one or more paths through the process
As far as I am aware I am not assigning to the signal two values at the same time, rather it is in receiving values in different situations?
this time I am using that previous signal to drive the output of another process but another latch is appearing within it, this time I did take into account any other value and place an "else" statement to take care of that but no luck:
Counting : process(BothButtons)
variable count0 : integer range 0 to 9; -- to hold the counter value
begin
if BothButtons = "00" then
count0 := 0;
elsif BothButtons = "01" then
count0 := count0 + 1;
elsif BothButtons = "10" then
count0 := count0;
elsif BothButtons = "11" then
count0 := count0;
else
count0 := 0;
end if;
For those of you who are wondering, yes this is part of an academic exercise!
What happens if button0 is neither '0' nor '1'? There's your latch. (ditto button1) Even 'H' and 'L' will confuse it, even though these have a clear meaning to you or me...
Now what do you need that BothButtons <= button0 & button1; doesn't do? (I may have misunderstood the problem you are having)
You have latches because you have a process with memory without a clock.
In the first example you give you just need an else in the end of the if-case. Otherwise it is forced to use a previous value, which requires that it has some memory of this previous value. Memory requires latches or flip-flops - and without a clock it is forced to use latches.
In the second example the lines count0 := count0 + 1; and count0 := count0; uses the value from a previous iteration of the process. This requires memory. And memory without a clock gives you latches.
Related
This is a branch off of a separate question I asked. I am going to explain more in depth on what I am trying to do and what it is not liking. This is a school project and doesn't need to follow standards.
I am attempting to make the SIMON game. Right now, what I am trying to do is use a switch case for levels and each level is supposed to be faster (hence different frequency dividers). The first level is supposed to be the first frequency and a pattern of LEDs is supposed to light up and disappear. Before I put in a switch case, the first level was by itself (no second level stuff) and it lit up and disappeared like it should. I also used compare = 0 in order to compare in output to an input. (The user is supposed to flip up the switches in the light pattern they saw). This worked when the first level was by itself but now that it is in a switch case, it doesn't like compare. I'm not sure how to get around that in order to compare an output to an input.
The errors I am getting are similar to before:
Error (10821): HDL error at FP.vhd(75): can't infer register for "compare" because its behavior does not match any supported register model
Error (10821): HDL error at FP.vhd(75): can't infer register for "count[0]" because its behavior does not match any supported register model
Error (10821): HDL error at FP.vhd(75): can't infer register for "count[1]" because its behavior does not match any supported register model
Error (10821): HDL error at FP.vhd(75): can't infer register for "count[2]" because its behavior does not match any supported register model
Error (10822): HDL error at FP.vhd(80): couldn't implement registers for assignments on this clock edge
Error (10822): HDL error at FP.vhd(102): couldn't implement registers for assignments on this clock edge
Error (12153): Can't elaborate top-level user hierarchy
I also understand that it doesn't like the rising_edge(toggle) but I need that in order to make the LED pattern light up and disappear.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity FP is
port(
clk, reset : in std_logic;
QF : out std_logic_vector (3 downto 0);
checkbtn : in std_logic;
Switch : in std_logic_vector(3 downto 0);
sel : in std_logic_vector (1 downto 0);
score : out std_logic_vector (6 downto 0)
);
end FP;
architecture behavior of FP is
signal time_count: integer:=0;
signal toggle : std_logic;
signal toggle1 : std_logic;
signal count : std_logic_vector (2 downto 0);
signal seg : std_logic_vector (3 downto 0);
signal compare : integer range 0 to 1:=0;
type STATE_TYPE is (level1, level2);
signal level : STATE_TYPE;
--signal input : std_logic_vector (3 downto 0);
--signal sev : std_logic_vector (6 downto 0);
begin
process (clk, reset, sel)
begin
if (reset = '0') then
time_count <= 0;
toggle <= '0';
elsif rising_edge (clk) then
case sel is
when "00" =>
if (time_count = 1249999) then
toggle <= not toggle;
time_count <= 0;
else
time_count <= time_count+1;
end if;
when "01" =>
if (time_count = 2499999) then
toggle1 <= not toggle1;
time_count <= 0;
else
time_count <= time_count+1;
end if;
when "10" =>
if (time_count = 4999999) then
toggle <= not toggle;
time_count <= 0;
else
time_count <= time_count+1;
end if;
when "11" =>
if (time_count = 12499999) then
toggle <= not toggle;
time_count <= 0;
else
time_count <= time_count+1;
end if;
end case;
end if;
end process;
Process (toggle, compare, switch)
begin
case level is
when level1 =>
if sel = "00" then
count <= "001";
seg <= "1000";
elsif (rising_edge (toggle)) then
count <= "001";
compare <= 0;
if (count = "001") then
count <= "000";
else
count <= "000";
end if;
end if;
if (switch = "1000") and (compare = 0) and (checkbtn <= '0') then
score <= "1111001";
level <= level2;
else
score <= "1000000";
level <= level1;
end if;
when level2 =>
if sel = "01" then
count <= "010";
seg <= "0100";
elsif (rising_edge (toggle1)) then
count <= "010";
compare <= 1;
if (count = "010") then
count <= "000";
else
count <= "000";
end if;
end if;
if (switch = "0100") and (compare = 1) and (checkbtn <= '0') then
score <= "0100100";
else
score <= "1000000";
level <= level1;
end if;
end case;
case count is
when "000"=>seg<="0000";
when "001"=>seg<="1000";
when "010"=>seg<="0100";
when "011"=>seg<="0110";
when "100"=>seg<="0011";
when others=>seg<="0000";
end case;
end process;
QF <= seg;
end behavior;
Thanks again in advance!
Well... it is hard to tell what is wrong, because this state machine is written in wrong way. You should look for references about proper modeling of FSM in VHDL. One good example is here.
If you use Quartus, you could also look for Altera's description on how to model FSM specifically for their compiler.
I will now give you just two advices. First is that you shouldn't (or mabye even you can't) use is two
if rising_edge (clk)
checks in one process. If your process is supposed to be sensitive on clock edge, write it once at the beginning.
Second thing is that if you want to model FSM with one process with synchronous reset, then put just clk on sensitivity list.
EDIT after question and code edit:
Ok, much better now. But another few things:
Your FSM is still not like it should. Look again at the example in the source I gave you above and edit it to be like there, or make it one process FSM like in example in this link.
Intends! Very important. I couldn't spot some of obvious errors, before I made proper intendation in your code. This leads me to...
Look at the places, there you assign values to count, in particular the if statements. No mater what, you assign the same value of "000".
Similar story with another signal - seg. You assign to it some value in the process, and then at the end of this process there is case statement in which you assign to it some other value, making this previous assignments irrelevant.
Use rising_edge only once in the process, only to clock, and only at the very beginning of the process, or in the way you did in the first process, that has asynchronous reset. In second process you did all this three things.
In sequential process with rising_edge, like the first one, you don't have to put to sensitivity list anything more than clock, and reset if it is asynchronous, like in your case.
Sensitivity list in second process. It is parallel process, so you should put there signals, that you check in a process, and can change outside of it. It is not the case for compare. But there should be signals: level, sel and toggle1.
As I'm still not sure what are you trying to achieve, I will not tell you what exactly to do. Fix your code according to points above, then maybe it will just work.
I have this code:
architecture Behavioral of BlockName is
signal t: std_logic;
signal c : std_logic_vector (1 downto 0);
begin
process (reset, clk) begin
if (reset = '1') then
t <= '0';
c <= (others=>'0');
elsif clk'event and clk='l' then
if (c = din) then
t <= NOT(t);
c <= (others=>'0');
else
c <= c + 1;
end if;
end if;
end process;
dout <= t;
end Behavioral;
This code's role is to divide the frequency when it gets input (clock + value) and outputs a divided frequency.
Now my questions:
What does this c <= (others=>'0'); mean ?
What value does t get here t <= NOT(t); ? the last t value? does the <= work as = ?
c <= (others=>'0'); is equivalent to c <= "00";
t <= not(t); assigns to t the opposite of the current value in t.
= is an equality comparison in VHDL.
<= is signal assignment in VHDL.
since 'C' is taken as a vector and to store every bit of it with zero 'c <= (others=>'0');' was used and the concept of blocking and non blocking signals is not present in VHDL. here '=' is used to compare and '<=' is used to assign the signal.
In the your code 't' is declared as a signal and a signal will be updated at the end of the every iteration of the process block. so in the statement 't <= NOT(t);' the value of the t is still the old value and will be updated at the end of the current simulation tick.
if(rising_edge(clk)) then
count := count + 1;
if count = 3 then
enable <= 1;
elsif count = 6 then
enable <= 0;
count := 0;
end if;
end if;
if enable = 0 then
a0i <= a_0;
boi <= b_0;
end if;
if enable = 1 then
a0i <= a_1;
boi <= b_1;
end if;
All are signals except the count. Value of a0i and boi should response as soon as enable becomes either 0 or 1. I tried using the variable. but it can not allow me to use out side the process.
I am getting the o/p as this. How ever I want to change the input as soon as enable signal change.
Put the last two if conditions in another process
Process(enable, a_0, b_0, a_1, b_1)
begin
If(enable = '0')THEN
a0i <= ...
....
ELSE
.....
END IF;
END PROCESS;
This process is sensitive to the enable signal so anytime there is a change in enable, independent of the clock, the statements will take effect immediately (asynchronously)
Solution 1: use 2 processes as blueprint mentioned.
Solution 2: use an internal variable.
process(clk)
variable count : natural range of 0 to 6 := 0;
variable enable_i : std_logic := '0';
begin
if(rising_edge(clk)) then
count := count + 1;
if count = 3 then
enable_i := '1';
elsif count = 6 then
enable_i := '0';
count := 0;
end if;
end if;
if enable = '0' then
a0i <= a_0;
boi <= b_0;
else
a0i <= a_1;
boi <= b_1;
end if;
enable <= enable_i;
end process;
Some hints:
Maybee, the type boolean is more suitable for your signal/variable enable_i
If enable_i is only used inside the process, then you can remove the conversion to enable
including the data path and multiplexers in a state machine (I assume this is a part of it) is not a good design choice.
You could also take these two equation below out from your process.
process(...)
[...]
if enable = 0 then
a0i <= a_0;
boi <= b_0;
end if;
if enable = 1 then
a0i <= a_1;
boi <= b_1;
end if;
end process
Then you cannot use the IF statement anymore, but you can use the WHEN statement :
a0i <= a_0 when enable = '0' else a_1;
boi <= b_0 when enable = '0' else b_1;
Note that in this case, the multiplexer will be after the latch. This could be important if you have timing issues on these signals.
From your simulation waveform, it looks to me like you failed to include enable, a_0, b_0, a_1, and b_1 in your sensitivity list, but I can't be sure because you didn't post the complete example. Because you test the values of the 5 mentioned signals outside of the if rising_edge(clk), they need to be included. The values are only updated on the falling edge of clk because, presuming that clk is the only thing in your sensitivity list, that is the next time the process is evaluated.
It should be otherwise functional as written, although you could use an else instead of a separate test for enable = 0 for a slight readability improvement. Synthesis usually ignores the sensitivity list (it just makes simulation more efficient) so it should already work if you were to synthesize.
So I've been using VHDL to make a register, where it loads in the input X if LOAD is '1' , and outputs the data in serial fashion , basically a parallel in serial out register. The input X is a 4 bit ( 3 downto 0 ) input , what I want to make the program do is constantly output 0 when the register has successfully output all the btis in the input.
It works when "count" is defined as a signal , however , when count is defined as a variable , the output is a constant 0 , regardless of whether load is '1' or not. My code is as shown:
entity qn14 is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
LOAD : in STD_LOGIC;
X : in STD_LOGIC_VECTOR (3 downto 0);
output : out STD_LOGIC);
end qn14;
architecture qn14_beh of qn14 is
type states is ( IDLE , SHIFT );
signal state : states;
signal count: STD_LOGIC_VECTOR(1 downto 0);
begin
process(clk , reset)
variable temp: STD_LOGIC;
variable data: STD_LOGIC_VECTOR(3 downto 0);
begin
if reset = '1' then
state <= IDLE;
count <= "00";
output <= '0';
elsif clk'event and clk = '1' then
case state is
when IDLE =>
if LOAD = '1' then
data := X;
output <= '0';
state <= SHIFT;
elsif LOAD = '0' then
output <= '0';
end if;
when SHIFT =>
if LOAD ='1' then
output <= '0';
elsif LOAD = '0' then
output <= data( conv_integer(count) );
count <= count + 1;
if (count >= 3) then
state <= IDLE ;
end if;
end if;
end case;
end if;
end process;
end qn14_beh;
Hoping to seek clarification on this.
Thank you.
This may not fully answer your question, but I will cover several issues that I see.
The elsif LOAD = '0' then could just be else unless you're trying to cover the other states (X,U...) but you would still want an else to cover those.
count = 3 is clearer than count >= 3. count is a 2-bit vector, so it can never be greater than 3.
Although you output 0 when LOAD is asserted while in the SHIFT state, you don't actually load a new value. Did you intend to?
Changing count to a variable without changing the position of the assignments will cause your first X -> output sequence to abort a cycle early (you increment count before you test it against 3). It will cause subsequent X -> output sequences to go "X(3), X(0), X(1), X(2)"
The variable temp is never used. The variable data would work just as well as a signal. You do not need the properties of variables for this use. This also brings up the question of why you tried count as variable; unless you need the instant assignments of variables, it is typically better to use a signal because signals are easier to view in (most) simulators and harder to make mistakes with. I hope that you aren't trying to end up with count as a variable, but just have an academic curiosity why it doesn't work.
Have you looked at this in a simulator? Are you changing states properly? Are all the bits of all your inputs strongly driven to a defined value ('1' or '0')?
I don't see anything that would cause the failure you described merely from changing count to a variable from a signal, but the change would cause the undesired behavior described above. My best guess is that your symptom arises from an issue with how you drive your inputs.
I have VHDL code that uses havily the fallowing syntax:
signal_1 <= (others => '0') when cau_state = st_idle else
signal_2 - signal_3 when cau_state = st_cycle_1 else
signal_4 when cau_state = st_cycle_2 else
signal_5 when cau_state = st_cycle_3 else
signal_6 when cau_state = st_cycle_4 else
signal_1;
Where cau_state is a signal that holds the current state. This syntax worked in simulation on Model-Sim and everything worked fine. But when I wanted to burn the code to an FPGA, the code didn't synthesize on Altera Quartus II 32-bit ver. 12.1 And I got the fallowing error messages:
Warning (13012): Latch CAU:uut|cross_3_sig[0][31] has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal CAU:uut|cau_state.st_cycle_2
Warning (13012): Latch CAU:uut|cross_3_sig[0][30] has unsafe behavior
Warning (13013): Ports D and ENA on the latch are fed by the same signal CAU:uut|cau_state.st_cycle_2
I get these messages for many signals, but NOT for all the signals that are using this syntax. And for a signal that get this message I get it for all its bits: cross_3_sig[0][31] to cross_3_sig[0][0]. The syntax for the signal cross_3_sig(0) is:
constant WIDTH : integer := 32;
...
subtype scalar is std_logic_vector((WIDTH-1) downto 0);
type vector_nd is array (natural range <>) of scalar;
subtype vector_3d is vector_nd(2 downto 0);
...
signal cross_3_sig : vector_3d;
...
cross_3_sig(0) <= sum_mults_out_sig when cau_state = st_cycle_2 else
mult1_out_sig - mult2_out_sig when cau_state = st_cycle_9 else
cross_3_sig(0);
And there are some places where I assign cross_3_sig(0) into other signals, i.e.:
numer_sig <= C_ZERO - cross_3_sig(0) & (16 downto 0 => '0');
mult1_in2_sig <= (others => '0') when cau_state = st_idle else
...
cross_3_sig(0) when cau_state = st_cycle_11 else
...
What is the problem, and how can I fix it?
The problem is that this form of expression creates a latch (which is sensitive to glitches on its control signal) and furthermore it is a latch with multiple control signals, for which there is no direct equivalent in real hardware.
signal_1 <= (others => '0') when cau_state = st_idle else
...
signal_6 when cau_state = st_cycle_4 else
signal_1;
Any time you see (outside a clocked process) something like
signal_1 <= ... else signal_1;
you know you have a problem. This is a signal feeding itself directly, an attempt to use a simple wire as a memory.
The correct use for this pattern is as a multiplexer, not as memory,
output_1 <= input_1 when ... else
input_2 when ... else
input_n;
The correct way to remember the old value of signal1 is a clocked process, e.g.
process (clk)
begin
if rising_edge(clk) then
if cau_state = st_idle then signal_1 <= (others => '0')
...
elsif cau_state = st_cycle_4 then signal_1 <= signal_6;
end if;
end if;
end process;
With no assignment, signal_1 will maintain its current value.
Or a better alternative : use a case statement in the process:
process (clk)
begin
if rising_edge(clk) then
case cau_state is
when st_idle => signal_1 <= (others => '0')
...
when st_cycle_4 => signal_1 <= signal_6;
-- when others => some default action
end case;
end if;
end process;
This does change the semantics to a clocked design, but unclocked designs are troublesome in FPGA, to say the least!