Jump to content
  • 0

Why VHDL RAM only can write but not read with test bench


TJ

Question

Hello,

Please see my RAM VHDL code and RAM test bench.   Does anyone have any idea why I can only write but not read from RAM?   Please see below:

 

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
 
entity RAM is
    Generic (
        DATA_WIDTH        : integer := 8;
        ADDRESS_WIDTH    : integer := 8
    );
    Port ( 
        Clock     : in  STD_LOGIC;
      Reset     : in  STD_LOGIC;
        DataIn     : in  STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
        Address    : in  STD_LOGIC_VECTOR (ADDRESS_WIDTH - 1 downto 0);
        WriteEn    : in  STD_LOGIC;
        Enable     : in  STD_LOGIC;
        DataOut     : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0)
    );
end RAM;
 
architecture Behavioral of RAM is
    type Memory_Array is array ((2 ** ADDRESS_WIDTH) - 1 downto 0) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
    signal Memory : Memory_Array;
begin
 
    -- Read process
    process (Clock)
    begin
        if rising_edge(Clock) then
            if Reset = '1' then
                -- Clear DataOut on Reset
                DataOut <= (others => '0');
            elsif Enable = '1' then
                if WriteEn = '1' then
                    -- If WriteEn then pass through DIn
                    DataOut <= DataIn;
                else
                    -- Otherwise Read Memory
                    DataOut <= Memory(to_integer(unsigned(Address)));
                end if;
            end if;
        end if;
    end process;
 
    -- Write process
    process (Clock)
    begin
        if rising_edge(Clock) then
            if Reset = '1' then
                -- Clear Memory on Reset
                for i in Memory'Range loop
                    Memory(i) <= (others => '0');
                end loop;
            elsif Enable = '1' then
                if WriteEn = '1' then
                    -- Store DataIn to Current Memory Address
                    Memory(to_integer(unsigned(Address))) <= DataIn;
                end if;
            end if;
        end if;
    end process;
 
end Behavioral;

  

-- beginning of test bench

 

 

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.NUMERIC_STD.ALL;
 
ENTITY TB_RAM IS
END TB_RAM;
 
ARCHITECTURE behavior OF TB_RAM IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT RAM
       GENERIC (
        DIN_WIDTH  : integer := 8;
        ADDR_WIDTH : integer := 5;
        ADDR_COUNT : integer := 32
          );
      PORT(
         CLK    : IN  std_logic;
         RST    : IN  std_logic;
         Din    : IN  std_logic_vector(7 downto 0);
         Addr    : IN  std_logic_vector(4 downto 0);
         Wr_En : IN  std_logic;
         En     : IN  std_logic;
         DOut    : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
    
 
   --Inputs
   signal CLK   : std_logic := '0';
   signal RST   : std_logic := '1';
   signal Din     : std_logic_vector(7 downto 0) := (others => '0');
   signal Addr     : std_logic_vector(4 downto 0) := (others => '0');
   signal Wr_En : std_logic := '0';
   signal En    : std_logic := '0';
 
     --Outputs
   signal DOut  : std_logic_vector(7 downto 0);
 
   -- Clock period definitions
   constant CLK_period : time := 10 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
    uut : RAM
        PORT MAP (
            CLK => CLK,
            RST => RST,
            Din => Din,
            Addr => Addr,
            Wr_En => Wr_En,
            En => En,
            DOut => DOut
        );
 
   -- Clock process definitions
   CLK_process : process
   begin
        CLK <= '0';
        wait for CLK_period/2;
        CLK <= '1';
        wait for CLK_period/2;
   end process;
 
    -- Stimulate Control process
    stim_main : process
    begin
        wait for CLK_period * 10;    
        
        RST <= '0';
        
      wait for CLK_period * 10;
        
        En <= '1';
        
        wait for CLK_period * 112;
 
        En <= '0';
        
        wait for CLK_period * 16;
        
        RST <= '1';
        
        wait for CLK_period * 16;
        
        RST <= '0';
        
        En <= '1';
        
        wait;
 
    end process;
 
   -- Stimulate Write process
   stim_write : process
   begin        
      wait for CLK_period * 20;    
        
      for i in 0 to 31 loop
            Wr_En <= '1';
            
            Din  <= Din + 3;
            
            wait for CLK_period * 1;
            
            Wr_En <= '0';
            
            wait for clk_period * 2;
        end loop;
 
      wait;
   end process;
    
    -- Stimulate Read process
    stim_read : process
   begin        
      --wait for CLK_period * 1000;    
      wait for CLK_period * 20;
      --Wr_En <= '0';
      
      loop
            Addr <= Addr + 7;
            
            wait for clk_period * 1;
        end loop;
 
      wait;
   end process;
 
end;

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

I am confused about your read process. Why does it do something when WriteEn is '1'? It seems to me that it should only do a READ when WriteEn is '0'.

Test bench:

In your code, the RAM enable is named "Enable", but in the test bench it is named "En". These two need to be connected in your test bench. You have the same problem with "WriteEn" and "WR_en".

READ: WR_en should be '0'! BTW your read LOOP will run forever!

WRITE: Although you change Din, you don't change the address!

Link to comment
Share on other sites

Davep238,

Thank you so much and great catches!   You are correct I only read when write enable is 0.   I need to make proper connections in test bench.  I agree.  I need to initialize addresses to zerp before looping.  I need to remove my infinite loop.  

Thanks again,

TJ

   

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...