J.Doe
J.Doe

Reputation: 127

Why does this attempt of creating a synchronous reset in VHDL "not hold its value under NOT(clock-edge) condition"

Good Day, i have written the following entity:

library ieee; 
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all; 


entity ADCinterface is    
generic (
    adc_id : std_logic_vector(1 downto 0):="00";            -- Holds the ID of the ADC its assigned to; for data reference
    word_size : natural := 32;                              -- Size of the transmission word in bit (overeall)
    crc_length : natural :=8                                -- Size/Length of the crc
);
port(   
    --internal Ports
    clkin:      in   std_logic;                             -- Module main Clock
    n_reset:    in   std_logic;                             -- Module reset
    adc_clkin:  in   std_logic;                             -- ADC sample clock input
    spi_clkin:  in   std_logic;                             -- SPI master clock input
    ack_buffer: in   std_logic;                             -- Signals that the buffer has been copied and can be overwritten
    paket_ID:   out  std_logic_vector(5 downto 0);          -- write the paket ID, a consecutive number 
    spi_data:   out  std_logic_vector(word_size-1 downto 0);-- Holds the data received from the adc
    data_buffer:out  std_logic_vector(word_size-1 downto 0);-- holds the data for the paket manager
    word_valid: out  std_logic;                             -- Signals data available to the internal paket manager

    --External ports 
    data_in:    in   std_logic;                             -- SPI data input
    ndrdy:      in   std_logic;                             -- Frame Sync pin (alias nDRDY) input from the ADC
    data_out:   out  std_logic;                             -- SPI data output
    start_adc:  out  std_logic;                             -- Enables the ADC
    adc_clk:    out  std_logic;                             -- ADC sampling clk out
    spi_clkout: out  std_logic                              -- SPI master clock out     
); 
end ADCinterface;

architecture ADCinterface_arch of ADCinterface is

    signal receive_word         : bit := '0';       --enables the receive process
    signal adc_data_ready       : std_logic := '0';     --holds the captured falling edge on ndrdy

begin
    adc_data_ready <= ndrdy;

    ADCinterface : process (clkin)

    begin

    if (rising_edge(clkin) and n_reset='0') then
        receive_word        <= '0';             --stop any active transmission

    elsif (rising_edge(clkin) and adc_data_ready='1') then
        receive_word <= '1';    --start / enable the data transmission
    end if;

    end process ADCinterface;
end ADCinterface_arch; 

which fails to sythesize with the error:

ERROR - line(65): statement is not synthesizable since it does not hold its value under NOT(clock-edge) condition. VHDL-1242

line 65 correspond to the last "end if;" statement.

When i now change

if (rising_edge(clkin) and n_reset='0') then

to

if (n_reset='0') then

it finishes the synthesis without error. I use Lattice Diamond V 3.11.2.446 with LSE for synthesis.

I can't see how that change changes anything thou, can someone help me out understand what's going on here? I would expect the produced logic to be able to hold its value under a non clock-edge condition in both cases...

Thanks in advance

Upvotes: 0

Views: 306

Answers (2)

pink-o
pink-o

Reputation: 31

The problem is that you are using the rising_edge two times and the synthesis tool doesn't know what to do because is not synthesizable

if (rising_edge(clkin) and n_reset='0') then
    receive_word        <= '0';             --stop any active transmission

elsif (rising_edge(clkin) and adc_data_ready='1') then
    receive_word <= '1';    --start / enable the data transmission
end if;

Try to change in:

if (rising_edge(clkin))
    if (n_reset='0') then
        receive_word        <= '0';             --stop any active transmission
    elsif (adc_data_ready='1') then
        receive_word <= '1';    --start / enable the data transmission
    end if;
end if;

Upvotes: 3

mfro
mfro

Reputation: 3335

Synthesis tools look for certain code patterns to find out what kind of logic to infer. Thus, even there is no obvious (logical) difference between

if rising_edge(clk) and n_reset = '0' then

and

if rising_edge(clk) then
    if n_reset = '0' then

your synthesis tool might only recognise the latter. There should be a section (probably named "recommended HDL coding style" or similar) in your manual that explains what VHDL syntax is required to infer the desired implementation.

Upvotes: 2

Related Questions