Block ram simulation

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
I am doing a project for a Virtex2 fpga with the Free ISE WebPACK 5.2i with
all the latest patches. I am writing a piece of behavioral VHDL that will
synthesize as dual ported block ram and a testbench to verify its behavior
by writing three values to it and then read them back. This works all fine
in a behavioral simulation, but when I advance to a post-translate or
post-place & route simulation the last of the three values read ( the first
written) is wrong. Can someone tell me what is wrong? Maybe it is never
written?

I have also tried to instantiate the block ram manualy (RAMB1_s36_s36). This
gives exactly the same problem.

Sincerely Christian.

This is my VHDL

----Memory.vhd------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity memory is
  Port ( clk : in std_logic;
  reset : in std_logic;
  write_addr : in std_logic_vector(8 downto 0);
  write_data : in std_logic_vector(31 downto 0);
  write_en : in std_logic;
  read_addr : in std_logic_vector(8 downto 0);
  read_data : out std_logic_vector(31 downto 0);
  read_en : in std_logic);
end memory;

architecture Behavioral of memory is
  type mem_type is array (511 downto 0) of std_logic_vector(31 downto 0);
  signal data : mem_type := (OTHERS => (OTHERS => '0'));
begin
  process (clk)
  begin
    IF clk'event AND clk = '1' then
      if write_en = '1' then
       data(CONV_INTEGER(UNSIGNED(write_addr))) <= write_data;
     end if;
     IF read_en = '1' THEN
       read_data <= data(CONV_INTEGER(UNSIGNED(read_addr)));
     END IF;
    end if;
  end process;
end Behavioral;
-------------------------



--Testbench----------------------

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

ENTITY testbench IS
END testbench;

ARCHITECTURE behavior OF testbench IS

 COMPONENT memory
 PORT(
  clk : IN std_logic;
  reset : IN std_logic;
  write_addr : IN std_logic_vector(8 downto 0);
  write_data : IN std_logic_vector(31 downto 0);
  write_en : IN std_logic;
  read_addr : IN std_logic_vector(8 downto 0);
  read_data : OUT std_logic_vector(31 downto 0);
  read_en : in std_logic
  );
 END COMPONENT;

 SIGNAL clk :  std_logic;
 SIGNAL reset :  std_logic;
 SIGNAL write_addr :  std_logic_vector(8 downto 0);
 SIGNAL write_data :  std_logic_vector(31 downto 0);
 SIGNAL write_en :  std_logic;
 SIGNAL read_addr :  std_logic_vector(8 downto 0);
 SIGNAL read_data :  std_logic_vector(31 downto 0);
 SIGNAL read_en : std_logic;

BEGIN

 uut: memory PORT MAP(
  clk => clk,
  reset => reset,
  write_addr => write_addr,
  write_data => write_data,
  write_en => write_en,
  read_addr => read_addr,
  read_data => read_data,
  read_en => read_en
 );

  PROCESS
  BEGIN
    clk <= '0';
    wait for 50 ns;
    clk <= '1';
    wait for 50 ns;
  END PROCESS;


reset <= '1', '0' after 7 ns;
read_en <= '1';
read_addr <= "100000000", "000100001" after 107 ns, "001000010" after 207
ns, "000000000" after 307 ns, "000000001" after 407 ns, "000000010" after
507 ns;
write_addr <= "000000010", "000000001" after 107 ns, "000000000" after 207
ns, "010000000" after 307 ns, "000010001" after 407 ns, "000001010" after
507 ns;
write_data <= X"00000003", X"00000002" after 107 ns, X"00000001" after 207
ns;
write_en <= '1', '0' after 307 ns;

END;

-------------------------------------------



Re: Block ram simulation
Quoted text here. Click to load it

Maybe you need to register the address.
http://groups.google.com/groups?q=sync_ram+entity+lpm_ram_dq

  -- Mike Treseler


Re: Block ram simulation
Virtex BlockRAMs always register the address internally, even during a
read access.
(Which is sometimes desirable, sometimes not).
Peter Alfke

Mike Treseler wrote:
Quoted text here. Click to load it

Re: Block ram simulation
The only difference between "your" code and the one posted is the read
scheme. Yours is "write firste" where as the posted is "read firste". The
testbench never writes to and reads from the same address in the same clock
cycle, so the read scheme can't explain why the last read value is
incorrect. I have tried using your code and it has exactly the same problem.

A screenshot of the wave forms for behavioural and post-translate simulation
can be found at.

http://www.student.dtu.dk/~s001467/simulation.jpg


Bo Esbech


Quoted text here. Click to load it
with
will
behavior
fine
first



Re: Block ram simulation
The gate level model includes the gsr signal. Add the gsr signal (inside the
dut) to your waveform! This is asserted for the first 100 ns of simulation
and prevents the BRAMS from operating, hence the first writes you do don't
work.

If you delay your stimulus by, say 150ns, everything will work.

BTW, I would strongly recommend using the following style for your stimulus
generation
process
begin
  read_addr  <= ...
  write_addr <= ...
  write_data <=  ...
  write_en    <= ...
  wait for 7 ns;

  --do something
  wait for 100 ns;

  --do something else
  wait for 100 ns;

  --do something else
  wait for 100 ns;

  --do something else
  wait for 100 ns;
  wait;
end process;

rather than trying to list your stimulii:
read_addr <= "100000000", "000100001" after 107 ns, "001000010" after 207
ns, "000000000" after 307 ns, "000000001" after 407 ns, "000000010" after
507 ns;

which is almost impossible to maintain, read, edit etc!

Ian


Quoted text here. Click to load it
clock
problem.
simulation
never



Site Timeline