Initializing 2 block rams

S

Shannon

Guest
I have a generic RAM entity:

entity ram is

generic
(
DATA_WIDTH : natural := 10;
ADDR_WIDTH : natural := 10
);

port
(
clk : in std_logic;
addr : in natural range 0 to 2**ADDR_WIDTH - 1;
data : in std_logic_vector((DATA_WIDTH-1) downto 0);
we : in std_logic := '1';
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);

end entity;

architecture rtl of ram is

subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH - 1 downto 0) of word_t;

signal ram : memory_t;

signal addr_reg : natural range 0 to 2**ADDR_WIDTH - 1;

begin

process(clk)
begin
if(rising_edge(clk)) then
if(we = '1') then
ram(addr) <= data;
end if;

addr_reg <= addr;
end if;
end process;

q <= ram(addr_reg);

end rtl;

In my top level I create two instances of this ram with different data
widths and addr width.
So far so good.

Now I want to initialize these two rams when I program them in-
circuit. For a single ram, Quartus wants you to add to the
architecture:

attribute ram_init_file : string;
attribute ram_init_file of ram : signal is "ram.mif";

Where "ram.mif" is the initialization file. My problem is that this
must go in the architecture declaration section or the ram entity. Is
there a way to do this at the top level so that I don't have to create
two separate ram entities?

It looks like I'm going to add a third and possibly fourth ram. I
would really like to only have one generic ram entity yet have the
four instances all initialized with separate data files.

I hope my question is clear.

Shannon
 
Shannon wrote:

I would really like to only have one generic ram entity yet have the
four instances all initialized with separate data files.
Block RAM initialization is fussy
and device specific, but it many not be needed.

If I am using a block RAM, it means that some process
can write to this RAM. I would have this
write process do whatever initialization is needed.

If I am using a block RAM, and I realized that
there is no such write process, I would switch
to a block ROM template for these constants.

These are safe and vendor-independent ways
to cover this problem.

-- Mike Treseler
 
On Sep 21, 11:42 am, Mike Treseler <mike_trese...@comcast.net> wrote:
Shannon wrote:
I would really like to only have one generic ram entity yet have the
four instances all initialized with separate data files.

Block RAM initialization is fussy
and device specific, but it many not be needed.

If I am using a block RAM, it means that some process
can write to this RAM. I would have this
write process do whatever initialization is needed.

If I am using a block RAM, and I realized that
there is no such write process, I would switch
to a block ROM template for these constants.

These are safe and vendor-independent ways
to cover this problem.

-- Mike Treseler
I guess I never really thought about a logical difference between ram
and rom in this context. Initializing the ram/rom contents from
within a process is not gonna happen in the near term. In the long
term the microcontroller programmers will catch up. Right now I just
need a way to initialize the data and test things out in hardware.

That aside. With regards to initialization from a data file, how
would rom be different from ram? I recognize that this stuff is very
device specific but I have a specific device in mind! Could you point
me in the direction of a vendor-independent way of dealing with this?

Shannon
 
"Shannon" <sgomes@sbcglobal.net> wrote in message
news:1190397719.306187.166310@e34g2000pro.googlegroups.com...
I have a generic RAM entity:

entity ram is

generic
(
DATA_WIDTH : natural := 10;
ADDR_WIDTH : natural := 10
);

port
(
clk : in std_logic;
addr : in natural range 0 to 2**ADDR_WIDTH - 1;
data : in std_logic_vector((DATA_WIDTH-1) downto 0);
we : in std_logic := '1';
q : out std_logic_vector((DATA_WIDTH -1) downto 0)
);

end entity;

architecture rtl of ram is

subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
type memory_t is array(2**ADDR_WIDTH - 1 downto 0) of word_t;

signal ram : memory_t;

signal addr_reg : natural range 0 to 2**ADDR_WIDTH - 1;

begin

process(clk)
begin
if(rising_edge(clk)) then
if(we = '1') then
ram(addr) <= data;
end if;

addr_reg <= addr;
end if;
end process;

q <= ram(addr_reg);

end rtl;

In my top level I create two instances of this ram with different data
widths and addr width.
So far so good.

Now I want to initialize these two rams when I program them in-
circuit. For a single ram, Quartus wants you to add to the
architecture:

attribute ram_init_file : string;
attribute ram_init_file of ram : signal is "ram.mif";

Where "ram.mif" is the initialization file. My problem is that this
must go in the architecture declaration section or the ram entity. Is
there a way to do this at the top level so that I don't have to create
two separate ram entities?

It looks like I'm going to add a third and possibly fourth ram. I
would really like to only have one generic ram entity yet have the
four instances all initialized with separate data files.
I did something like that in Verilog.
Did you try GENERIC / GENERIC MAP ?
 
Shannon wrote:

I guess I never really thought about a logical difference between ram
and rom in this context. Initializing the ram/rom contents from
within a process is not gonna happen in the near term. In the long
term the microcontroller programmers will catch up. Right now I just
need a way to initialize the data and test things out in hardware.
I would use a rom template for that.
Something like
http://home.comcast.net/~mike_treseler/sync_rom.vhd

That aside. With regards to initialization from a data file, how
would rom be different from ram?
A rom description contains data.
Synthesis will do the dirty work of converting
that data into whatever format the device requires.

A ram description is an empty array with
read and write procedures:
http://home.comcast.net/~mike_treseler/sync_rom.vhd

I recognize that this stuff is very
device specific but I have a specific device in mind!
Fair enough, but you asked about how
to simplify the process.

Could you point
me in the direction of a vendor-independent way of dealing with this?
The examples above.

-- Mike Treseler
 
Mike Treseler wrote:

A ram description is an empty array with
read and write procedures:
http://home.comcast.net/~mike_treseler/sync_rom.vhd
make that:
http://home.comcast.net/~mike_treseler/block_ram.vhd
-- Mike Treseler
 
Thanks Mike. (as always!)

Two things:
1) I really should think three times before posting. (I already think
twice but it isn't enough) The answer that 'devices' gave above was
correct. All I had to do was map the name of the init file to the
instance. Not too hard.
2) In your rom example Mike, I assume someone could initialize the rom
with a file like I've been talking about, rather than actually typing
all those mappings you had.

Shannon
 

Welcome to EDABoard.com

Sponsor

Back
Top