Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
17 years ago

Dual port RAM in Quartus II 7.2, different behavior on ModelSim than Quartus simulato

I'm using the Quartus II template for a true Dual port RAM with single clock, when I simulate it in Quartus simulator the behavior is ok, and synthsised correctly to the memory bits in a Cyclone III device.

However, when I simulate the same code using ModelSim RTL simulation the behavior is different. The problem arises when I try to write to both ports at the same time at two different addresses, where the data is written as 'X'!!. Note that: the whole memory is initially zeros.

I use the same code of the template directly from Quartus, which is attached below. Any explanation??!!

library ieee;

use ieee.std_logic_1164.all;

entity true_dual_port_ram_single_clock is

generic

(

DATA_WIDTH : natural := 8;

ADDR_WIDTH : natural := 6

);

port

(

clk : in std_logic;

addr_a : in natural range 0 to 2**ADDR_WIDTH - 1;

addr_b : in natural range 0 to 2**ADDR_WIDTH - 1;

data_a : in std_logic_vector((DATA_WIDTH-1) downto 0);

data_b : in std_logic_vector((DATA_WIDTH-1) downto 0);

we_a : in std_logic := '1';

we_b : in std_logic := '1';

q_a : out std_logic_vector((DATA_WIDTH -1) downto 0);

q_b : out std_logic_vector((DATA_WIDTH -1) downto 0)

);

end true_dual_port_ram_single_clock;

architecture rtl of true_dual_port_ram_single_clock is

-- Build a 2-D array type for the RAM

subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);

type memory_t is array(addr_a'high downto 0) of word_t;

-- Declare the RAM signal.

signal ram : memory_t;

begin

-- Port A

process(clk)

begin

if(rising_edge(clk)) then

if(we_a = '1') then

ram(addr_a) <= data_a;

-- Read-during-write on the same port returns NEW data

q_a <= data_a;

else

-- Read-during-write on the mixed port returns OLD data

q_a <= ram(addr_a);

end if;

end if;

end process;

-- Port B

process(clk)

begin

if(rising_edge(clk)) then

if(we_b = '1') then

ram(addr_b) <= data_b;

-- Read-during-write on the same port returns NEW data

q_b <= data_b;

else

-- Read-during-write on the mixed port returns OLD data

q_b <= ram(addr_b);

end if;

end if;

end process;

end rtl;

22 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Using the template would be fine if it weren't broken for simulation. Using the Verilog version requires me to have both a Verilog and VHDL simulation license for ModelSim, doesn't it?

    Moreover, instantiating the primitive causes simulations to run significantly slower. I'd prefer to use a configuration switch in the top level on a generic dual port RAM in VHDL than do mixed-mode HDL.

    In the end, the template should be changed to allow proper simulation in either language.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    In the end, the template should be changed to allow proper simulation in either language.

    --- Quote End ---

    I suggest that you file a mySupport service request asking for this enhancement. (I'm calling it an enhancement rather than a bug fix because the templates might not have been intended necessarily to work in third-party tools, and ModelSim-Altera Edition is really just Mentor's ModelSim as far as this is concerned.)