Search code examples
vhdlfpga

how to use sensitivity list in multiple processes that are dependent


I'm writing a code for a simple arithmetic equation d=1+(k*o). I have three processes in my code.the third process is dependent on second and second is dependent on first.I'm unable to keep the sensitivity list correct. The output goes undefined.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity dcalc is
    Port ( k : in  STD_LOGIC_VECTOR (7 downto 0);
           o : in  STD_LOGIC_VECTOR (7 downto 0);
           e : in  STD_LOGIC_VECTOR (7 downto 0);
           d : out  STD_LOGIC_VECTOR (7 downto 0);
              clk: in  STD_LOGIC);
end dcalc;

architecture Behavioral of dcalc is
COMPONENT divd
    PORT(
         d1 : IN  std_logic_vector(7 downto 0);
         e : IN  std_logic_vector(7 downto 0);
         remi : OUT  std_logic_vector(7 downto 0);
         clk : IN  std_logic
        );
    END COMPONENT;
signal  endp1,d2,k1,o1,e1,d3: unsigned (7 downto 0);
--signal d3:std_logic_vector(7 downto 0);
begin

--process 1
process(k,o,e)
begin
if(clk'event and clk='1') then
k1<=unsigned(k);
o1<=unsigned(o);
e1<=unsigned(e);
endp1<=x"01";
end if;
end process; 

--process 2
process(endp1)
begin
if(clk'event and clk='1') then
d2<=1+(k1*o1);
end if;
end process;

--process 3
process(d2)
begin
if(clk'event and clk='1') then
d<=std_logic_vector(d2);
end if;
end process;

end Behavioral;

In the first process, conversion is done. When process 1 is done then the d2 should be calculated in process 2. when d2 is calculated in process 2, d should be updated in the process 3. here is my testbench code:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY ccalctb IS
END ccalctb;

ARCHITECTURE behavior OF ccalctb IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT dcalc
    PORT(
         k : IN  std_logic_vector(7 downto 0);
         o : IN  std_logic_vector(7 downto 0);
         e : IN  std_logic_vector(7 downto 0);
         d : OUT  std_logic_vector(7 downto 0);
         clk : IN  std_logic
        );
    END COMPONENT;


   --Inputs
   signal k : std_logic_vector(7 downto 0) := (others => '0');
   signal o : std_logic_vector(7 downto 0) := (others => '0');
   signal e : std_logic_vector(7 downto 0) := (others => '0');
   signal clk : std_logic := '0';

    --Outputs
   signal d : std_logic_vector(7 downto 0);

   -- Clock period definitions
   constant clk_period : time := 10 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: dcalc PORT MAP (
          k => k,
          o => o,
          e => e,
          d => d,
          clk => clk
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 100 ns;  
k<=x"07";
o<=x"08";
e<=x"07";
      wait for clk_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;

Please help. Here is the simulation result after changing all the process sensitivity list to only clk:

enter image description here


Solution

  • In a synchronous (clocked) process, the sensitivity list is required to be only the clock (and possibly asynchronous reset):

    process(clk)
    begin
      if RISING_EDGE(clk) then
        k1<=unsigned(k);
        o1<=unsigned(o);
        e1<=unsigned(e);
        endp1<=x"01";
      end if;
    end process;
    

    With your original sensitivity list, changes on the D flip-flop (or register which is a vector of D flip-flops) inputs triggered process execution, but as we know the output doesn't change immediately, it waits for the clock edge. And then when the clock edge came, clk wasn't in the sensitivity list, so the simulation ignored it. As a result, your outputs never update in simulation.

    (In contrast, synthesis tends to ignore your sensitivity list and just place a logic element configured as a genuine D flip-flop, which will update properly on the clock edge)