VHDL coding tips and tricks: VHDL: Does Process Sensitivity List Matter In Simulation or Synthesis?

Tuesday, April 13, 2010

VHDL: Does Process Sensitivity List Matter In Simulation or Synthesis?

    You might have encountered this error while trying to synthesis your VHDL code: One or more signals are missing in the process sensitivity list (or)  signal 'xxx' is read in the process but is not in the sensitivity list. In this article I want explain if there is any relation between the process sensitivity list and synthesis results.

Let us look at an example:

library ieee;
use ieee.std_logic_1164.all;

entity test1 is
port(clk : in std_logic;
    rst : in std_logic;
    a,b : in std_logic;
    c,d : out std_logic
);
end test1;

architecture Behavioral of test1 is

begin

--Synchronous process(some flipflop's are used for implementation)
process(clk,rst)
begin
    if(rst = '1') then
        c <= '0';
    elsif(rising_edge(clk)) then
        c <= a;
    end if;
end process;

--combinational process(some LUT's are used for implementation)
process(a,b)
begin
    d <= a and b;
end process;

end Behavioral;

The code has one synchronous process, which assigns the input a to output c. It also has a combinatorial process which does an and operation on inputs a and b and assigns the result to d.

The following testbench code was used for testing the functionality of the above code:

library ieee;
use ieee.std_logic_1164.all;

entity testbench is
end testbench;

architecture Behavioral of testbench is
    --inputs
    signal a,b : std_logic := '0';
    signal clk : std_logic := '0';
    signal rst : std_logic := '0';
        --outputs
    signal c,d : std_logic := '0';
    -- clock period definitions
    constant clk_period : time := 10 ns;
begin

    -- instantiate the unit under test (uut)
    uut: entity work.test1 port map (
        clk => clk,
        rst => rst,
        a => a,
        b => b,
        c => c,
        d => d);

   -- clock process definitions
    clk_process :process
    begin
        wait for clk_period/2;
        clk <= not clk;  --keep toggling the clock once half of the clock period is over
    end process;

    -- stimulus process
    stim_proc: process
    begin  
        a <= '1';   b <= '1';     
        wait for clk_period;
        --try reset
        wait for clk_period/4;
        rst<='1';
        wait for clk_period;
        rst<='0';
        b <= '0';
        wait;
    end process;

end;

The simulation waveform is shared few scrolls down and verifies that the code is working as its supposed to. 

Let's also synthesis the code. I used Xilinx Vivado 2023.2 for this. The schematic generated by Vivado is shared below. It confirms that the logic we wrote behavioral code for, is correctly implemented in hardware. 

schematic in xilinx vivado. sensitivity list


Now, in order to check the effect of process sensitivity on simulation or synthesis, we will make the following changes in the code:
  1. Use process(rst)  instead of process(clk,rst).
  2. Use process(b) instead of process(a,b).
Simulate the design once more using the same testbench code. Let me share both the simulation waveforms in one image, so that you can easily compare them.

simulation waveform in modelsim for process sensitivity list



    What do you notice? The simulation waveform seems to be affected by the minor changes we have made to the process sensitivity list. 
  • The change in rst doesnt cause a change in output c right away. The synchronous process, as if, waits until the change in clk happens to get activated again.
  • As for the second combinatorial process, the change in b doesnt cause any change in output d. This is because b is not in the process sensitivity list. 
So, clearly, for simulation to work well, you need to add all the read signals to the process sensitivity list. 

Now, lets synthesis the design. The synthesis is successfully  completed without any errors and it even generated the exact schematic shared previously in this article. This means that the second code will work in the same way as the first one. But I do get the following two warnings:
[Synth 8-614] signal 'rst' is read in the process but is not in the sensitivity list
[Synth 8-614] signal 'b' is read in the process but is not in the sensitivity list 

So what about the warning? After going through some online forums I found the following reasons for this warning:

  • Usually the behavior in the equations inside a process is what is intended, the sensitivity list is just a bookkeeping chore. It doesnt have anything to do with synthesis.
  • Technically what XST(Xilinx synthesis tool) have implemented is not what your VHDL code says to do as per the VHDL language definition. They are taking somewhat of a guess about what you really intended to do. By violating the language specification they implement it the way they think you 'really' want it and kick out a warning to let you know that the actual implementation will operate differently than your simulation shows.
           (Thanks KJ for your answer)

    One more thing to note is that, if the signals are synchronous(meaning inside the rising_edge(clk) statement), then they dont need to be in the sensitivity list. You might have noticed that even when the signal a is read in the first process, it wasnt included in the sensitivity list.

Conclusion :- Sensitivity list has nothing to do with synthesis. But without the proper sensitivity list, the process will not work in simulation. So as a good practice include all the signals which are read inside the process, in the sensitivity list. The results may be varied if you are using some other tool. I have used Xilinx Vivado 2023.2 version for this analysis.

5 comments:

  1. A small note :- In spite of the fact that it does not give any errors it is not advisable to follow this practice.Mentioning signals in the process sensitivity list will ensure that the logic is clearly defined for the process.Also this will increase the readability of the program.

    ReplyDelete
  2. Do we need to include 'a 'in the sensitive list like this: process(clk,r,a)? Becasue the value of a is assigned to b

    if(rising_edge(clk)) then
    b<=a;

    ReplyDelete
  3. @zhensofa : no, no need to include.if you are getting any warnings in this case then you can ignore them.

    ReplyDelete
  4. Also remember that for a clocked process you may need not include the signals in the process sensitivity list, which are read at the clock edge.

    ReplyDelete
  5. This synthesis behavior stands in contradiction to the book "Top-Down Digital VLSI Design" by Hubert Kaeslin. He says that omitting a signal in the sensitivity list implies memory and therefore sequential behavior in synthesis. Since all non-sensitive signals needs to be captured in a past state. Maybe this is synthesizer dependent?

    ReplyDelete