signal ram: ram_t := (others => (others '0'));


T

Travis

I'm examining the VHDL for block and distributed ram on Xilinx, and a short google search led me to this site:
http://vhdlguru.blogspot.com/2011/01/block-and-distributed-rams-on-xilinx.html

The code I'm looking at is as follows:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity ram_example is
port (Clk : in std_logic;
address : in integer;
we : in std_logic;
data_i : in std_logic_vector(7 downto 0);
data_o : out std_logic_vector(7 downto 0)
);
end ram_example;

architecture Behavioral of ram_example is

--Declaration of type and signal of a 256 element RAM
--with each element being 8 bit wide.
type ram_t is array (0 to 255) of std_logic_vector(7 downto 0);
signal ram : ram_t := (others => (others => '0'));

begin

--process for read and write operation.
PROCESS(Clk)
BEGIN
if(rising_edge(Clk)) then
if(we='1') then
ram(address) <= data_i;
end if;
data_o <= ram(address);
end if;
END PROCESS;

end Behavioral;

But I had a question about this part:
signal ram : ram_t := (others => (others => '0'));

I assume this is necessary because it helps the synthesizer make some optimizations and better infer LUTs or block ram, but I don't quite 'understand' it. I can parrot it in the meantime, but maybe someone out there has a good description?

Thanks all,
-Travis
 
Ad

Advertisements

R

Rob Gaddi

I'm examining the VHDL for block and distributed ram on Xilinx, and a short google search led me to this site:
http://vhdlguru.blogspot.com/2011/01/block-and-distributed-rams-on-xilinx.html

The code I'm looking at is as follows:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity ram_example is
port (Clk : in std_logic;
address : in integer;
we : in std_logic;
data_i : in std_logic_vector(7 downto 0);
data_o : out std_logic_vector(7 downto 0)
);
end ram_example;

architecture Behavioral of ram_example is

--Declaration of type and signal of a 256 element RAM
--with each element being 8 bit wide.
type ram_t is array (0 to 255) of std_logic_vector(7 downto 0);
signal ram : ram_t := (others => (others => '0'));

begin

--process for read and write operation.
PROCESS(Clk)
BEGIN
if(rising_edge(Clk)) then
if(we='1') then
ram(address) <= data_i;
end if;
data_o <= ram(address);
end if;
END PROCESS;

end Behavioral;

But I had a question about this part:
signal ram : ram_t := (others => (others => '0'));

I assume this is necessary because it helps the synthesizer make some optimizations and better infer LUTs or block ram, but I don't quite 'understand' it. I can parrot it in the meantime, but maybe someone out there has a good description?

Thanks all,
-Travis

It's just declaring that the initial contents of the RAM should be all
zeros. You can actually assign the initial values to be whatever you'd
like.
 
G

GaborSzakacs

Rob said:
It's just declaring that the initial contents of the RAM should be all
zeros. You can actually assign the initial values to be whatever you'd
like.

For _most_ Xilinx FPGA famlies, the bitstream initializes all memories
by default. If you don't specify a value to initialize the RAMs, then
it will be all zeroes in the bitstream. This also helps to reduce
bitstream size when using compression. Explicitly choosing all zeroes,
when you really don't care about the initial value has the effect
of making simulation match the hardware.

If instead you wanted to make sure you don't read uninitialized memory
and rely on its value, I've seen something like:

signal ram : ram_t := (others => (others => 'U'));
 
Ad

Advertisements

A

Andy

While the explicit 'U' initialization may be more readable (which is generally an admirable goal), it is not necessary.

Per the LRM and the type definition, ram is initialized to (others => (others => 'U')) unless explicitly initialized otherwise.

Andy
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top