UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Newbie a.zeoli3
Newbie
211 Views
Registered: ‎02-08-2019

getting 1-bit Latch warning

Jump to solution

I have these 3 warnings about Latch but i don't know how to solve them, can you please help me?

MY CODE IS:

entity Allarme is
Port ( col : in STD_LOGIC_VECTOR(1 to 3);
row : in STD_LOGIC_VECTOR(1 to 4);
p1, p2, f1, f2 : in STD_LOGIC;
clk, rst : in STD_LOGIC;
sys_mod : out STD_LOGIC_VECTOR(1 downto 0);
sirena : out STD_LOGIC);
end Allarme;

architecture Behavioral of Allarme is
type state is (start, activate, allarm);

-- Segnali di appoggio
signal cstate, nstate : state;
signal timeover10 : std_logic :='0';
signal timeover5 : std_logic :='0';
signal count10, ncount10 : integer range 0 to 9;
signal count5, ncount5 : integer range 0 to 4;
signal modality : std_logic_vector(1 downto 0);

begin

up_state : process(clk)
begin
if rising_edge(clk) then
if(rst='1') then
cstate <= start;
count5 <= 0;
count10 <= 0;
else
cstate <= nstate;
count5 <= ncount5;
count10 <= ncount10;
end if;
end if;
end process;

Finite_State_Machine : process(cstate, col, row, p1, p2, f1, f2, timeover10, timeover5)

variable tmp_out : std_logic_vector(1 downto 0);
variable sirena_tmp : std_logic :='0';

begin
case(cstate) is

when start =>
tmp_out :="00";
sirena_tmp := '0';

if(col = "001" and row = "0001") then
tmp_out := "10";
nstate <= activate;
elsif(col = "010" and row = "0001") then
tmp_out := "11";
nstate <= activate;
else
nstate <= start;
end if;

when activate =>
if tmp_out = "10" then -- Siamo nella Modalita' 1
if p1 = '1' then -- Se la Porta 1 viene aperta
if timeover10 = '1' then
nstate <= allarm;
else
nstate <= activate;
end if;
elsif p1 = '0' then
if (p2 = '1' or f1 = '1' or f2 = '1') then -- Se viene aperta la Porta 2 o la/le Finestra/e
if timeover5 = '1' then
nstate <= allarm;
else
nstate <= activate;
end if;
else
nstate <= activate;
end if;
else
nstate <= activate;
end if;
elsif tmp_out = "11" then
if (p2 = '1' or f1 = '1' or f2 = '1') then -- Siamo nella Modalita' 2
if timeover5 = '1' then
nstate <= allarm;
else
nstate <= activate;
end if;
else
nstate <= activate;
end if;

else -- In qualsiasi altro caso
nstate <= activate;
end if;

when allarm =>
sirena_tmp := '1'; -- Attiva la Sirena
if(col = "010" and row = "1000") then -- Se premo 0 sul tastierino, disattivo il Sistema
nstate <= start;
else
nstate <= allarm;
end if;
end case;

sys_mod(1) <= tmp_out(1);
sys_mod(0) <= tmp_out(0);
modality(1) <= tmp_out(1);
modality(0) <= tmp_out(0);
sirena <= sirena_tmp;
end process;

counter_timer10: process(modality, count10)

begin

if (modality = "10") then
if count10 = 9 then
ncount10 <= 0;
timeover10 <= '1';
else
ncount10 <= count10 + 1;
timeover10 <= '0';
end if;
else
ncount10 <= count10;
timeover10 <= '0';
end if;
end process;

counter_timer5: process(modality, count5)

begin

if (modality = "11" or modality = "10") then
if count5 = 4 then
ncount5 <= 0;
timeover5 <= '1';
else
ncount5 <= count5 + 1;
timeover5 <= '0';
end if;
else
ncount5 <= count5;
timeover5 <= '0';
end if;
end process;

end Behavioral;

THE WARNINGS ARE:

WARNING:Xst:737 - Found 1-bit latch for signal <Finite_State_Machine.tmp_out<1>>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal <Finite_State_Machine.tmp_out<0>>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 1-bit latch for signal <Finite_State_Machine.sirena_tmp>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.

Thank you!

0 Kudos
1 Solution

Accepted Solutions
Mentor hgleamon1
Mentor
193 Views
Registered: ‎11-14-2011

Re: getting 1-bit Latch warning

Jump to solution

Your FSM is in a combinatorial process and you do not assign tmp_out in every possible if/else structure you have described in that process. The warning messages give a pretty good idea what the problems you have are.

This type of issue is frequenctly cited as an underlying problem with 2-process state machines. However, this can be avoided if you explicitly code values for tmp_out for every condition you have described.

----------
"That which we must learn to do, we learn by doing." - Aristotle
7 Replies
Mentor hgleamon1
Mentor
194 Views
Registered: ‎11-14-2011

Re: getting 1-bit Latch warning

Jump to solution

Your FSM is in a combinatorial process and you do not assign tmp_out in every possible if/else structure you have described in that process. The warning messages give a pretty good idea what the problems you have are.

This type of issue is frequenctly cited as an underlying problem with 2-process state machines. However, this can be avoided if you explicitly code values for tmp_out for every condition you have described.

----------
"That which we must learn to do, we learn by doing." - Aristotle
Newbie a.zeoli3
Newbie
162 Views
Registered: ‎02-08-2019

Re: getting 1-bit Latch warning

Jump to solution

So i have to code a value for tmp_out for every if and every else that i used in my process only?!

0 Kudos
Mentor hgleamon1
Mentor
158 Views
Registered: ‎11-14-2011

Re: getting 1-bit Latch warning

Jump to solution

Yes - this is because the tmp_out variable is never synchronously assigned (the same for sirena_tmp, as well).

----------
"That which we must learn to do, we learn by doing." - Aristotle
Newbie a.zeoli3
Newbie
138 Views
Registered: ‎02-08-2019

Re: getting 1-bit Latch warning

Jump to solution

It works! Thank you very much.

But now i have 2 more questions:

1) I Have 2 new Warnings:

     a) WARNING:Xst:2170 - Unit Allarme : the following signal(s) form a combinatorial loop:           GND_3_o_GND_3_o_MUX_11_o, sys_mod<1>.
     b) WARNING:Xst:2170 - Unit Allarme : the following signal(s) form a combinatorial loop: sys_mod<0>,       GND_3_o_PWR_3_o_mux_38_OUT<0>.

2) I had a simple testbench and i have that my signal 'sirena' turn into 1 after 10( or 5) clks but when clk = '1' and not when clk ='0'. Why?

If you can solve this you will be definitely my hero!

Thank you so much!

 

THIS IS MY ULTIMATE CODE:

entity Allarme is

Port ( col : in STD_LOGIC_VECTOR(1 to 3);
row : in STD_LOGIC_VECTOR(1 to 4);
p1, p2, f1, f2 : in STD_LOGIC;
clk, rst : in STD_LOGIC;
sys_mod : out STD_LOGIC_VECTOR(1 downto 0);
sirena : out STD_LOGIC);
end Allarme;

architecture Behavioral of Allarme is
type state is (start, activate, allarm);

-- Segnali di appoggio
signal cstate, nstate : state;
signal timeover10 : std_logic :='0';
signal timeover5 : std_logic :='0';
signal count10, ncount10 : integer range 0 to 9;
signal count5, ncount5 : integer range 0 to 4;

begin

up_state : process(clk)
begin
if rising_edge(clk) then
if(rst='1') then
cstate <= start;
count5 <= 0;
count10 <= 0;
else
cstate <= nstate;
count5 <= ncount5;
count10 <= ncount10;
end if;
end if;
end process;

Finite_State_Machine : process(cstate, col, row, p1, p2, f1, f2, timeover10, timeover5)

variable tmp_out : std_logic_vector(1 downto 0);
variable sirena_tmp : std_logic :='0';


begin
case(cstate) is

when start =>
tmp_out :="00";
sirena_tmp := '0';

if(col = "001" and row = "0001") then
tmp_out := "10";
sirena_tmp := '0';
nstate <= activate;
elsif(col = "010" and row = "0001") then
tmp_out := "11";
sirena_tmp := '0';
nstate <= activate;
else
tmp_out := "00";
sirena_tmp := '0';
nstate <= start;
end if;

when activate =>
if tmp_out = "10" then -- Siamo nella Modalita' 1
if p1 = '1' then -- Se la Porta 1 viene aperta
tmp_out := "10";
sirena_tmp := '0';
if timeover10 = '1' then
tmp_out := "10";
sirena_tmp := '0';
nstate <= allarm;
else
tmp_out := "10";
sirena_tmp := '0';
nstate <= activate;
end if;
elsif p1 = '0' then
tmp_out := "10";
sirena_tmp := '0';
if (p2 = '1' or f1 = '1' or f2 = '1') then -- Se viene aperta la Porta 2 o la/le Finestra/e
tmp_out := "10";
sirena_tmp := '0';
if timeover5 = '1' then
tmp_out := "10";
sirena_tmp := '0';
nstate <= allarm;
else
tmp_out := "10";
sirena_tmp := '0';
nstate <= activate;
end if;
else
if tmp_out = "10" then
tmp_out := "10";
sirena_tmp := '0';
nstate <= activate;
elsif tmp_out = "11" then
tmp_out := "11";
sirena_tmp := '0';
nstate <= activate;
end if;
end if;
else
tmp_out := "10";
sirena_tmp := '0';
nstate <= activate;
end if;
elsif tmp_out = "11" then
tmp_out := "11";
sirena_tmp := '0';
if (p2 = '1' or f1 = '1' or f2 = '1') then -- Siamo nella Modalita' 2
tmp_out := "11";
sirena_tmp := '0';
if timeover5 = '1' then
tmp_out := "11";
sirena_tmp := '0';
nstate <= allarm;
else
tmp_out := "11";
sirena_tmp := '0';
nstate <= activate;
end if;
else
tmp_out := "11";
sirena_tmp := '0';
nstate <= activate;
end if;

else -- In qualsiasi altro caso
tmp_out := "00";
sirena_tmp := '0';
nstate <= start;
end if;

when allarm =>
if tmp_out = "10" then
tmp_out := "10";
sirena_tmp := '1'; -- Attiva la Sirena
if(col = "010" and row = "1000") then -- Se premo 0 sul tastierino, disattivo il Sistema
tmp_out := "00";
sirena_tmp := '0';
nstate <= start;
else
tmp_out := "10";
sirena_tmp := '1';
nstate <= allarm;
end if;
elsif tmp_out = "11" then
tmp_out := "11";
sirena_tmp := '1'; -- Attiva la Sirena
if(col = "010" and row = "1000") then -- Se premo 0 sul tastierino, disattivo il Sistema
tmp_out := "00";
sirena_tmp := '0';
nstate <= start;
else
tmp_out := "11";
sirena_tmp := '1';
nstate <= allarm;
end if;
else
tmp_out := "00";
sirena_tmp := '0';
nstate <= start;
end if;
end case;

sys_mod(1) <= tmp_out(1);
sys_mod(0) <= tmp_out(0);
sirena <= sirena_tmp;
end process;

counter_timer10: process(p1, count10)

begin

if (p1 = '1') then
if count10 = 9 then
ncount10 <= 0;
timeover10 <= '1';
else
ncount10 <= count10 + 1;
timeover10 <= '0';
end if;
else
ncount10 <= count10;
timeover10 <= '0';
end if;
end process;

counter_timer5: process(p2,f1,f2, count5)

begin

if (p2 = '1') then
if count5 = 4 then
ncount5 <= 0;
timeover5 <= '1';
else
ncount5 <= count5 + 1;
timeover5 <= '0';
end if;

elsif (f1 = '1') then
if count5 = 4 then
ncount5 <= 0;
timeover5 <= '1';
else
ncount5 <= count5 + 1;
timeover5 <= '0';
end if;

elsif (f2 = '1') then
if count5 = 4 then
ncount5 <= 0;
timeover5 <= '1';
else
ncount5 <= count5 + 1;
timeover5 <= '0';
end if;
else
ncount5 <= count5;
timeover5 <= '0';
end if;
end process;

end Behavioral;

 

 

AND THIS IS MY TB (In this case when f1 <= '1', after 5clks(when clk <= '0') sirena <= '1' but in my case, after 5clks sirena <='1' (but when clk <= '1' ):

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_arith.all;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;

ENTITY TB_Allarme IS
END TB_Allarme;

ARCHITECTURE behavior OF TB_Allarme IS

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT Allarme
PORT(
col : IN std_logic_vector(1 to 3);
row : IN std_logic_vector(1 to 4);
p1 : IN std_logic;
p2 : IN std_logic;
f1 : IN std_logic;
f2 : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
sys_mod : OUT std_logic_vector(1 downto 0);
sirena : OUT std_logic
);
END COMPONENT;

--Inputs
signal col : std_logic_vector(1 to 3) := (others => '0');
signal row : std_logic_vector(1 to 4) := (others => '0');
signal p1 : std_logic := '0';
signal p2 : std_logic := '0';
signal f1 : std_logic := '0';
signal f2 : std_logic := '0';
signal clk : std_logic := '0';
signal rst : std_logic := '0';
--Outputs
signal sys_mod : std_logic_vector(1 downto 0);
signal sirena : std_logic;

-- Clock period definitions
constant clk_period : time := 10 ns;

BEGIN

-- Instantiate the Unit Under Test (UUT)
uut: Allarme PORT MAP (
col => col,
row => row,
p1 => p1,
p2 => p2,
f1 => f1,
f2 => f2,
clk => clk,
rst => rst,
sys_mod => sys_mod,
sirena => sirena
);

-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;

-- Stimulus process
stim_proc: process
begin
-- Sequenza di reset
rst <= '1';
wait for clk_period;
rst <= '0';
wait for clk_period;

col <= "001";
row <= "0001";
wait for clk_period;
f1 <= '1';
wait for 15*clk_period;
col <= "010";
row <= "1000";
wait;
end process;

END;

 

0 Kudos
Mentor hgleamon1
Mentor
95 Views
Registered: ‎11-14-2011

Re: getting 1-bit Latch warning

Jump to solution

You seem to be a little unsure about the logic that you are describing. There is a mix of synchronous and combinatorial logic in your source code (nothing wrong with that, per se - very common) but your expectations of what you want your logic to do are a little skewed.

I took your code and simulated it. To take you queries one by one:

 

1. Do you understand that sys_mod(1) is exactly the same signal as tmp_out(1)? It is asynchornously assigned in your combinatorial FSM process. Now, within that process, you are also testing for the condition of tmp_out and making subsequent assignments to the signal as a result of the test. In the activate state you firstly test if tmp_out = "10", then later test if tmp_out = "11" or otherwise assign tmp_out <= "00". So if tmp_out = "01", it will combinatorially become "00". This is a combinatorial loop.

2. Essentially the same as above.

 

I don't really understand why tmp_out is a variable. Why not make it a signal and register it in your synchronous process, then test for the condition of the synchronous signal? This is, as I understand it, the point of a two-process state machine.

 

I haven't investigated too closely but I suspect that sirena <= '1' on this rising edge of the clock because your state machine is sensitive to the synchronous version of the state (cstate). In the simulation cstate <= allarm on the rising edge of the clock and only then are all of the simulation conditions met to affect the sirena output.

----------
"That which we must learn to do, we learn by doing." - Aristotle
Newbie a.zeoli3
Newbie
88 Views
Registered: ‎02-08-2019

Re: getting 1-bit Latch warning

Jump to solution

All clear, thanks a lot!

0 Kudos
Moderator
Moderator
67 Views
Registered: ‎03-16-2017

Re: getting 1-bit Latch warning

Jump to solution

Hi @a.zeoli3,

 

Please close the thread if your issue has been resolved, by marking it as accepted solution.

Regards,
hemangd

Don't forget to give kudos and mark it as accepted solution if your issue gets resolved.