SRAM testbench

From Hamsterworks Wiki!

Jump to: navigation, search

Here is a simple SRAM test bench that simulates the first 32 words of the 10ns SRAM on the Papilio Plus.

It will write errors to the console if

  • the write enable pulse is too short
  • the data setup times for a write is too short
  • the address bus changes when write enable is active

The data bus will be 'X's during the access time, allowing you to see if you are capturing the data too early

Source

----------------------------------------------------------------
-- tb_sram.vhd  - A simple SRAM test bench module that acts like
--           a 32 word x 16 bit SRAM, with byte enable signals
--
-- Author: Mike Field (hamster@snap.net.nz)
--
----------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity tb_sram is
    Port ( mem_nCE : in  STD_LOGIC;
           mem_nWE : in  STD_LOGIC;
           mem_nOE : in  STD_LOGIC;
           mem_addr : in  STD_LOGIC_VECTOR (17 downto 0);
           mem_data : inout  STD_LOGIC_VECTOR (15 downto 0);
           mem_nUB : in  STD_LOGIC;
           mem_nLB : in  STD_LOGIC
    );
end tb_sram;

architecture Simulation of tb_sram is
   constant t_access     : time := 10 ns;
   constant t_we_min     : time := 8  ns;
   constant t_data_setup : time := 5  ns;

   signal data_bus   : STD_LOGIC_VECTOR (15 downto 0);
   signal address    : integer;
   signal data       : STD_LOGIC_VECTOR (32*16 downto 0) := (others => '0');
   signal read_value : STD_LOGIC_VECTOR (15 downto 0);
      
   shared variable start_write_cycle: time := 0 ns;
   shared variable address_change   : time := 0 ns;
   shared variable data_high_change : time := 0 ns;
   shared variable data_low_change  : time := 0 ns;
begin

   -- Convert the value on the address bus to a number
   process(mem_addr)
   begin
      address <= conv_integer(mem_addr(4 downto 0));
      address_change := now;
   end process;

   process(mem_data(7 downto 0))
   begin
      data_low_change := now;
   end process;
   
   process(mem_data(15 downto 8))
   begin
      data_high_change := now;
   end process;
   
   -- If the address changes, look up the value
   process(address)
   begin
      read_value <= data(address*16+15 downto address*16);
   end process;
   
   -- Perform the delayed output of the value (after the 10ns access time)
   process(address,read_value)
   begin
      data_bus <= "----------------";
      data_bus <= read_value after t_access;
   end process;
   
   -- Update the stored values
   process(mem_nWE)
   begin
      if rising_edge(mem_nWE)  then
         assert now - start_write_cycle > t_we_min
            report "SRAM: Write pulse too short"
            severity Error;         

         if mem_nUB = '0' and mem_nCE = '0' then
            -- verify address and data haven't changed during the cycle
            assert address_change <= start_write_cycle
               report "SRAM: Address changed during write cycle"
               severity Error;
            assert now - data_high_change >= t_data_setup
               report "SRAM: Data hold time violated"
               severity Error;             
            data(address*16+15 downto address*16+8) <= mem_data(15 downto 8);
         end if;

         if mem_nLB = '0' and mem_nCE = '0' then
            assert address_change <= start_write_cycle
               report "SRAM: Address changed during write cycle"
               severity Error;
            assert now - data_low_change >= t_data_setup
               report "SRAM: Data hold time violated"
               severity Error;
            data(address*16+7 downto address*16) <= mem_data(7 downto 0);
         end if;
      elsif falling_edge(mem_nWE) then
         start_write_cycle := now;
      end if;
   end process;
   
   -- Control the values on the external data bus
   mem_data(15 downto 8) <= data_bus when mem_nCE = '0' and mem_nWE = '1' and mem_nOE = '0' and mem_nUB = '0'
                else "ZZZZZZZZ";
   mem_data( 7 downto 0) <= data_bus when mem_nCE = '0' and mem_nWE = '1' and mem_nOE = '0' and mem_nLB = '0'
                else "ZZZZZZZZ";
end Simulation;

Personal tools