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.
Now, in order to check the effect of process sensitivity on simulation or synthesis, we will make the following changes in the code:
- Use process(rst) instead of process(clk,rst).
- Use process(b) instead of process(a,b).
- 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.
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.
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.
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.
ReplyDeleteDo we need to include 'a 'in the sensitive list like this: process(clk,r,a)? Becasue the value of a is assigned to b
ReplyDeleteif(rising_edge(clk)) then
b<=a;
@zhensofa : no, no need to include.if you are getting any warnings in this case then you can ignore them.
ReplyDeleteAlso 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.
ReplyDeleteThis 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