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: 
Visitor mbutura
Visitor
553 Views
Registered: ‎05-11-2018

Help in latch removal

Jump to solution

This is my first design. This is the spi slave core design with miso data only implemented. The design is meant to update the baasys3 leds from the data sent on the miso line. I believe I have an accidental latch created on signals index and input shift register from the vivado message warnings. I would like to know how to prevent the undefined states for the signals in this context and what I may have overlooked.

 

Lines with the warning from vivado are marked:

--LATCH WARNING HERE

 

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;

-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

--Default working of this SPI slave is in SPI mode 0(CPOL_CPHA='00')
--May not work reliably for other SPI modes
entity spi_slave_simple is
    generic(datawidth: integer:= 16);
    port ( rst_i: in std_logic; --Async reset
           clk_i: in std_logic;
           sck_i: in std_logic;
           ss_i: in std_logic;
           mosi_i: in std_logic;
           data_o: out std_logic_vector(datawidth-1 downto 0);
           ready_o: out std_logic);
end spi_slave_simple;

architecture behavioral of spi_slave_simple is

type state_type is (idle, shift);
signal present_state, next_state : state_type ;

signal input_shift_register : std_logic_vector(datawidth-1 downto 0);
signal index : integer range datawidth-1 downto 0;

signal synced_mosi, synced_sck, synced_ss, sck_rise, sck_fall : std_logic;

component synchronizer is
    generic ( stages : natural := 3 );
    Port ( clk_i : in std_logic;
             i : in std_logic;
             o : out std_logic;
             rise_o: out std_logic;
             fall_o: out std_logic);
end component;

    
begin

ss_sync: synchronizer port map(clk_i => clk_i, i => ss_i, o => synced_ss, rise_o => open, fall_o => open);
sck_sync: synchronizer port map(clk_i => clk_i, i => sck_i, o => open, rise_o => sck_rise, fall_o => sck_fall);
mosi_sync: synchronizer port map(clk_i => clk_i, i => mosi_i, o => synced_mosi, rise_o => open, fall_o => open);

--Realises FFs with asynchronous reset
--Has factors affecting state transition in sensitivity list.
state_sync: process(rst_i, clk_i)
begin
    if(rst_i = '0') then
        present_state <= idle;
        data_o<=(others => '0');
        ready_o <= '0';
    elsif(rising_edge(clk_i)) then
            if(synced_ss = '0') then
                if(sck_rise = '1') then
                    present_state <= next_state;
                    ready_o<='0';
                end if;
            else
                    present_state <= idle;
                    data_o<=input_shift_register; --LATCH WARNING HERE
                    ready_o <= '1';
            end if;
    end if;
end process state_sync;

--Outputs are function of past inputs and outputs, no present input on any data lines
combinatorial : process(present_state)
begin
case present_state is
when idle =>
    input_shift_register <= (others=>'0');
    index <= datawidth-1; --LATCH WARNING HERE
    next_state <= shift;
when shift =>
    if (index /= 0) then
        input_shift_register(index) <= synced_mosi;
        index <= index-1;   
    else
        --Left shift and append to the right
        input_shift_register(datawidth-1 downto 0)<=input_shift_register(datawidth-2 downto 0) & synced_mosi;
    end if;
    next_state <= shift;
--Catch all to avoid latch inferencing by synthesis tools
when others =>
next_state <= idle;

end case;
end process combinatorial;

end behavioral;

 

0 Kudos
1 Solution

Accepted Solutions
Scholar richardhead
Scholar
622 Views
Registered: ‎08-01-2012

Re: Help in latch removal

Jump to solution

latches will occur when an asynchronous signal (ie. one not generated in clocked process) is not assigned a value in all possible cases. So in your case, input_shift_register and index should be assigned a value in all branches of the process (you cannot assign it to itself in any way because this is the definition of a latch).

 

For your code, both the shift register and idex values should be in a synchronous process.

You may want to look into using the single process state machine style, as this is all synchronous and no latches can be formed.

0 Kudos
2 Replies
Scholar richardhead
Scholar
623 Views
Registered: ‎08-01-2012

Re: Help in latch removal

Jump to solution

latches will occur when an asynchronous signal (ie. one not generated in clocked process) is not assigned a value in all possible cases. So in your case, input_shift_register and index should be assigned a value in all branches of the process (you cannot assign it to itself in any way because this is the definition of a latch).

 

For your code, both the shift register and idex values should be in a synchronous process.

You may want to look into using the single process state machine style, as this is all synchronous and no latches can be formed.

0 Kudos
Visitor mbutura
Visitor
467 Views
Registered: ‎05-11-2018

Re: Help in latch removal

Jump to solution
This worked Thank you.
0 Kudos