Search code examples
vhdl

VHDL signal assignment delay and simulation confusion


New to VHDL and trying to implement a small cache.

Part of my cache.vhd

entity cache is   

      Port (  clock  : in  STD_LOGIC;
              rw_sel  : in  STD_LOGIC;  --'1' to read from cache ,
                                                --'0' to write to cache
              ad_sel: in STD_LOGIC;     --'0' to send address,     '1' to send data
              data_in :in STD_LOGIC_VECTOR (7 downto 0);    
                                         --send data or address controled by ad_sel
                     ...      
        end cache;

        architecture Behavioral of cache is 
        ....
        signal block_addr_n : integer range 0 to 15;  
                            -- cache block address
        signal block_cell_addr_n: integer range 0 to 1;
                            -- byte-in-cache address
    begin 
    process(clock, init)
    begin
    case init is
        when '0' =>
            for i in 0 to 15 loop
                cache_memory(i)<="1111111111111111";
                tag_memory(i)<="11";
            end loop;
        when others =>null;
    end case;
    case ad_sel is
        when '0' => 
            address<=data_in(6 downto 0);
        when '1' => data_cpu_wr<=data_in;
        when others =>null;
    end case;
    block_addr_n  <= conv_integer(unsigned(address(4 downto 1)));
    block_cell_addr_n<=conv_integer(address(0));
    case rw_sel is
            ....

part of my testbench file :

 ....
      --Inputs
   signal clock : std_logic := '0';
   signal rw_sel : std_logic := '1';
   signal ad_sel : std_logic := '0';
   signal init: std_logic:='1';
   signal data_in : std_logic_vector(7 downto 0) := (others => '0');
  ....
 stim_proc: process
   begin    
         -- initialize  
        init<='0';         
        wait for 100 ns;   
        -- read address "0101111"(MSB cut), expecting miss
        cache_mem_data<="1100110011001100";
        ad_sel<='0';
        rw_sel<='1';
        data_in<="00101111";
        clock <= not clock;
        wait for 100 ns;
        -- write to address "0101111" but written in "0000000" which is default
        data_in<="10101010";
        ad_sel<='1';
        rw_sel<='0';
        clock<=not clock;
        wait for 100 ns;
        data_in<="00101111";
        ad_sel<='0';
        rw_sel<='1';
        clock<=not clock;
      wait;
   end process;

END;

And what I got in the ISim window is enter image description here

Why doesn't the block_addr_n and block_cell_addr_n be assigned in the second 100 ns since the signal address be assigned at that time directly? I think this is the reason that causes my program into unexpected results, since the cache block 0 is written while I just set address 0 as default but pass in the address "0101111" after the first 100 ns.

Any ideas?


Solution

  • The sensitivity list does not contain all the signals that are used in the process, since the address is a signal (assigned in the same process, but that does not matter) but the signal is not in the sensitivity list of the process. So the process is not reexecuted by the simulator when the value of address changes. Process parts:

    process(clock, init)
    begin
        ...
        address<=data_in(6 downto 0);
        ...
        block_addr_n  <= conv_integer(unsigned(address(4 downto 1)));
        block_cell_addr_n<=conv_integer(address(0));
    

    If you are using VHDL-2008, then you can make the sensitivity list automatically with process (all), but I don't think Xilinx has implemented VHDL-2008 yet, so you must probably make the sensitivity list yourself by manually including all used signals in the sensitivity list.

    Btw, consider making the processes either purely combinatorial (gates), or clocked (flip-flops or RAMs), so that combinatorial process should not have for example clock in the sensitivity list.