-->

VHDL Process Confusion with Sensitivity Lists

2019-08-30 02:23发布

问题:

I am learning VHDL by reading books online (Free Range VHDL), and imlementing the examples on my Nexsys2 via Xilinx ISE Webpack 14.7. I am re-reading the Free Range VHDL text and am currently in the chapter discussing processes. I have a solid understanding of what a process is, and how it works, but I implemented an example and I do not understand the results.

I implemented an 8 to 1 mux using the following code.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity mux81 is
    port( d_in : in std_logic_vector(7 downto 0);
            sel : in std_logic_vector(2 downto 0);
            ce : in std_logic;
            F : out std_logic);
end mux81;

architecture my_mux81 of mux81 is
begin
mux_proc: process(d_in, sel, ce)
    begin
        if (ce = '1') then
            if (sel = "111") then
                F <= d_in(7);
            elsif (sel = "110") then
                F <= d_in(6);
            elsif (sel = "101") then
                F <= d_in(5);
            elsif (sel = "100") then
                F <= d_in(4);
            elsif (sel = "011") then
                F <= d_in(3);
            elsif (sel = "010") then
                F <= d_in(2);
            elsif (sel = "001") then
                F <= d_in(1);
            elsif (sel = "000") then
                F <= d_in(0);
            else
                F <= '0';   
            end if;
        else
            F <= '0';
        end if;
    end process mux_proc;
end my_mux81;

which performs the mux operation only if the 'ce' signal is '1'. All worked as expected. I then tried an experiment by removing the 'ce' signal from the sensitivity list. Based on my understanding of the process statement, it should only execute if a signal in the sensitivity list changes. By removing the 'ce' signal, the circuit should not respond to 'ce' changes alone. Here is the modified circuit:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity mux81 is
    port( d_in : in std_logic_vector(7 downto 0);
            sel : in std_logic_vector(2 downto 0);
            ce : in std_logic;
            F : out std_logic);
end mux81;

architecture my_mux81 of mux81 is
begin
mux_proc: process(d_in, sel)
    begin
        if (ce = '1') then
            if (sel = "111") then
                F <= d_in(7);
            elsif (sel = "110") then
                F <= d_in(6);
            elsif (sel = "101") then
                F <= d_in(5);
            elsif (sel = "100") then
                F <= d_in(4);
            elsif (sel = "011") then
                F <= d_in(3);
            elsif (sel = "010") then
                F <= d_in(2);
            elsif (sel = "001") then
                F <= d_in(1);
            elsif (sel = "000") then
                F <= d_in(0);
            else
                F <= '0';   
            end if;
        else
            F <= '0';
        end if;
    end process mux_proc;
end my_mux81;

As you can see, the only change is that 'ce' is removed from the sensitivity list. However, when I implement this circuit, it operates exactly like the version that had 'ce' in the sensitivity list. In other words, keeping signals "d_in" and "sel" constant, but modifying 'ce' caused the process statement to execute and change the output signal as if 'ce' were still in the sensitivity list. I did not get any warnings when I ran the synthesis. It is like the program made an assumption that 'ce' should also be monitored, but I thought that should also generate a warning...

Thanks for the help!

回答1:

Sensitivity lists are ignored by many synthesis tools. Check the warnings from your synthesis tool, and you will probably find that it warns about the missing CE signal.

Incomplete sensitivity lists are a notorious cause of problems, because the simulation and post-synthesis behavior are not the same!

Usually, you don't want to use level sensitive latches. They cause all sorts of trouble and they are harder to verify than plain old synchronous logic.

If you really want to create an level sensitive latch, you should either instantiate one that is provided by your FPGA vendor, or figure out which coding style to use to make your synthesis tool infer a latch.