Dual Port RAM Simulation

Discussion in 'VHDL' started by Scott, Jul 18, 2007.

  1. Scott

    Scott Guest

    Hello,

    I could use a little help resolving a simulation issue. I wrote a
    generic dual port ram that can be used to infer Xilinx BlockRams
    because I got tired of using CoreGen to generate multiple instances
    for different configurations. I synthesized the design using
    Synplicity, and it correctly infers BlockRams with all ports connected
    up as I would expect. However, when I tried to simulate this stand
    alone, the array can not be written. My guess is the two processes
    that write to the memory are causing problems. If there is a ways to
    correct this, I would appreciate it. I am using ModelSim.


    --------------------------------------------------------------------------------------------------------
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity dpram_cc is
    generic
    (
    width : integer:=8;
    depth : integer:=256;
    addr : integer:=8
    );

    port
    (
    clk : in std_logic;

    a_en : in std_logic; -- port a enable
    a_wr : in std_logic; -- port a write
    a_addr : in std_logic_vector(addr-1 downto 0); -- port a
    address
    a_data_in : in std_logic_vector(width-1 downto 0); -- port a
    data in
    a_data_out : out std_logic_vector(width-1 downto 0); -- port a
    data out

    b_en : in std_logic; -- port b
    enable
    b_wr : in std_logic; -- port b
    write
    b_addr : in std_logic_vector(addr-1 downto 0); -- port b
    address
    b_data_in : in std_logic_vector(width-1 downto 0); -- port b
    data in
    b_data_out : out std_logic_vector(width-1 downto 0) -- port b
    data out
    );

    end dpram_cc;

    architecture rtl of dpram_cc is

    type mem is array (0 to depth-1) of std_logic_vector(width-1 downto
    0);

    signal ram : mem;

    -- xilinx synthesis attribute for using block rams
    attribute syn_ramstyle : string;
    attribute syn_ramstyle of ram : signal is "block_ram";

    begin

    --
    *************************************************************************
    -- port a write
    --
    *************************************************************************
    process (clk)
    begin
    if (clk'event and clk='1') then
    if (a_wr = '1') and (a_en = '1') then
    ram(to_integer(unsigned(a_addr))) <= a_data_in;
    end if;
    end if;
    end process;

    --
    *************************************************************************
    -- port a read
    --
    *************************************************************************
    process (clk)
    begin
    if (clk'event and clk='1') then
    if (a_en = '1') then
    a_data_out <= ram(to_integer(unsigned(a_addr)));
    end if;
    end if;
    end process;

    --
    *************************************************************************
    -- port b write
    --
    *************************************************************************
    process (clk)
    begin
    if (clk'event and clk='1') then
    if (b_wr = '1') and (b_en = '1') then
    ram(to_integer(unsigned(b_addr))) <= b_data_in;
    end if;
    end if;
    end process;

    --
    *************************************************************************
    -- port a read
    --
    *************************************************************************
    process (clk)
    begin
    if (clk'event and clk='1') then
    if (b_en = '1') then
    b_data_out <= ram(to_integer(unsigned(b_addr)));
    end if;
    end if;
    end process;

    end rtl;
    Scott, Jul 18, 2007
    #1
    1. Advertising

  2. Scott wrote:

    > My guess is the two processes
    > that write to the memory are causing problems. If there is a ways to
    > correct this, I would appreciate it. I am using ModelSim.


    Can't answer your question exactly but I'm wondering if having the two
    write processes results in multiple drivers - at least when both ports are
    writing to the same address at the same time?

    Have you tried using a single write process? I'd certainly be more
    comfortable with that myself...

    Regards,

    --
    Mark McDougall, Engineer
    Virtual Logic Pty Ltd, <http://www.vl.com.au>
    21-25 King St, Rockdale, 2216
    Ph: +612-9599-3255 Fax: +612-9599-3266
    Mark McDougall, Jul 18, 2007
    #2
    1. Advertising

  3. Scott

    Evan Lavelle Guest

    On Wed, 18 Jul 2007 10:56:34 +1000, Mark McDougall <>
    wrote:

    >Scott wrote:
    >
    >> My guess is the two processes
    >> that write to the memory are causing problems. If there is a ways to
    >> correct this, I would appreciate it. I am using ModelSim.

    >
    >Can't answer your question exactly but I'm wondering if having the two
    >write processes results in multiple drivers - at least when both ports are
    >writing to the same address at the same time?
    >
    >Have you tried using a single write process? I'd certainly be more
    >comfortable with that myself...


    Mark's right - each process creates its own drivers for 'ram'. You're
    using resolved logic (std_logic_vector), so the std_ulogic resolution
    function combines the values on the two drivers, giving incorrect data
    at the ram inputs. See 'vhdl_src/ieee/stdlogic.vhd' in the ModelSim
    distribution for details. Many people prefer to use unresolved logic
    (in this case, std_ulogic_vector) so that multiple drivers are flagged
    as errors (actually, your synthesiser should have told you this).

    You need a single write process, which examines all of a_wr, a_en,
    b_wr, and b_en, and which muxes a/b_addr and a/b_data, just like the
    real RAM. You should be able to find some Xilinx source as a model.

    Evan
    Evan Lavelle, Jul 18, 2007
    #3
  4. Scott wrote:

    > However, when I tried to simulate this stand
    > alone, the array can not be written. My guess is the two processes
    > that write to the memory are causing problems. If there is a ways to
    > correct this, I would appreciate it. I am using ModelSim.


    > architecture rtl of dpram_cc is
    >
    > type mem is array (0 to depth-1) of std_logic_vector(width-1 downto
    > 0);
    >
    > signal ram : mem;


    Both write processes assign to ram, so you have multiple drivers. That's why
    you can't write to the array.

    The most important advice that I can give you when modeling RAM: don't use a
    signal, use a variable. It simulates faster and it will consume less work
    station memory than a signal (in the order of 10X).

    All your processes are clocked processes using the same clock, so they can
    be combined into one process quite easily. Obviously, the variable with the
    ram array needs to be declared in that process.

    The order in which you put the read and write parts is important. It
    determines what happens when you read and write to the same address at the
    same time.

    ram_i: process (clk) is
    type mem is array (0 to depth-1) of std_logic_vector(width-1 downto 0);
    variable ram: mem;
    begin
    if clk'event and clk='1' then

    -- port a read
    if a_en = '1' then
    a_data_out <= ram(to_integer(unsigned(a_addr)));
    end if; end process;

    -- port b read
    if b_en = '1' then
    b_data_out <= ram(to_integer(unsigned(b_addr)));
    end if;

    -- port a write
    if (a_wr = '1') and (a_en = '1') then
    ram(to_integer(unsigned(a_addr))) := a_data_in;
    end if;

    -- port b write
    if (b_wr = '1') and (b_en = '1') then
    ram(to_integer(unsigned(b_addr))) := b_data_in;
    end if;
    end if;
    end process ram_i;


    --
    Paul Uiterlinden
    www.aimvalley.nl
    e-mail addres: remove the not.
    Paul Uiterlinden, Jul 18, 2007
    #4
  5. Evan Lavelle wrote:
    > On Wed, 18 Jul 2007 10:56:34 +1000, Mark McDougall <>
    > wrote:
    >
    >> Scott wrote:
    >>
    >>> My guess is the two processes
    >>> that write to the memory are causing problems. If there is a ways to
    >>> correct this, I would appreciate it. I am using ModelSim.

    >> Can't answer your question exactly but I'm wondering if having the two
    >> write processes results in multiple drivers - at least when both ports are
    >> writing to the same address at the same time?
    >>
    >> Have you tried using a single write process? I'd certainly be more
    >> comfortable with that myself...

    >
    > Mark's right - each process creates its own drivers for 'ram'. You're
    > using resolved logic (std_logic_vector), so the std_ulogic resolution
    > function combines the values on the two drivers, giving incorrect data
    > at the ram inputs. See 'vhdl_src/ieee/stdlogic.vhd' in the ModelSim
    > distribution for details. Many people prefer to use unresolved logic
    > (in this case, std_ulogic_vector) so that multiple drivers are flagged
    > as errors (actually, your synthesiser should have told you this).
    >
    > You need a single write process, which examines all of a_wr, a_en,
    > b_wr, and b_en, and which muxes a/b_addr and a/b_data, just like the
    > real RAM. You should be able to find some Xilinx source as a model.
    >

    I have seen (don't have it to hand) a Xilinx app that uses shared
    variables for the RAM array. Those will allow 2 simultaneous accesses.
    Of course, only on the more recent versions of VHDL.
    David R Brooks, Jul 18, 2007
    #5
  6. Scott

    Guest

    Hi,

    what do you mean with "the array can not be written" ?

    Rgds
    , Jul 19, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. john

    FPGA and Dual Port RAM

    john, Nov 3, 2004, in forum: VHDL
    Replies:
    2
    Views:
    3,582
  2. john

    Dual port RAM

    john, Nov 4, 2004, in forum: VHDL
    Replies:
    1
    Views:
    763
    mike_treseler
    Nov 4, 2004
  3. dwerdna

    Dual port Ram - for beginners

    dwerdna, Apr 3, 2005, in forum: VHDL
    Replies:
    7
    Views:
    23,413
    dwerdna
    Apr 8, 2005
  4. Keith Blankenship

    Dual-Port RAM Simulation in ModelSim

    Keith Blankenship, Jan 4, 2006, in forum: VHDL
    Replies:
    1
    Views:
    1,136
    Mike Treseler
    Jan 4, 2006
  5. Scott

    Dual Port RAM Simulation

    Scott, Jul 18, 2007, in forum: VHDL
    Replies:
    0
    Views:
    496
    Scott
    Jul 18, 2007
Loading...

Share This Page