Block RAM Distributed RAM

X

Xin Xiao

I have a 65,535 x 16 bit RAM and my synthesis tool is using Distributed RAM
instead of Block RAM. I am told this is not efficient. I have a smaller RAM
and it is actually synthesized using Block RAM. How can I design in VHDL a
65,535 x 16-bit RAM using Block RAM? Or this is not possible?

Thanks,
 
A

Andy

I have a 65,535 x 16 bit RAM and my synthesis tool is using Distributed RAM
instead of Block RAM. I am told this is not efficient. I have a smaller RAM
and it is actually synthesized using Block RAM. How can I design in VHDL a
65,535 x 16-bit RAM using Block RAM? Or this is not possible?

Thanks,

The read operation on block rams is registered, so you need to
introduce a clock cycle delay (i.e. a register that will get absorbed
into the block ram) either on the read address, or the read data.
Don't reset that register.

Andy
 
X

Xin Xiao

This is the code:


entity SRAM is
Port ( Clk : in STD_LOGIC;
Enable : in STD_LOGIC;
Addr : in std_logic_vector(15 downto 0);
RW : in STD_LOGIC;
Data_in : in std_logic_vector(15 downto 0);
Data_out : out std_logic_vector(15 downto 0));
end SRAM;

<signal declaration>

begin
process (Clk)
begin
if (rising_edge(Clk)) then
if (Enable = '1') then
if (RW = '1') then
memory(conv_integer(Addr)) <= Data_in;
end if;
read_a <= Addr;
end if;
end if;
end process;
Data_out <= memory(conv_integer(read_a));
end Behavioral;

The log says it is a "65536x16-bit dual-port distributed RAM", and it is
taking a very long time to be synthesized... I stopped it after 40 minutes
or so, is it normal for a 64 K-word RAM? I suppose that there should be
another techniques, more efficient ones.
 
D

Duane Clark

Xin said:
This is the code:


entity SRAM is
Port ( Clk : in STD_LOGIC;
Enable : in STD_LOGIC;
Addr : in std_logic_vector(15 downto 0);
RW : in STD_LOGIC;
Data_in : in std_logic_vector(15 downto 0);
Data_out : out std_logic_vector(15 downto 0));
end SRAM;

<signal declaration>

begin
process (Clk)
begin
if (rising_edge(Clk)) then
if (Enable = '1') then
if (RW = '1') then
memory(conv_integer(Addr)) <= Data_in;
end if;
read_a <= Addr;
end if;
end if;
end process;
Data_out <= memory(conv_integer(read_a));
end Behavioral;

Go back and read Andy's post again, and then think carefully about how
you are generating read_a. Ignore everything else; your problem is with
read_a. It will come to you ;)
 
X

Xin Xiao

I dont' see it... I based my code on an example that is in my program
documentation on how to create a Block RAM.

See http://toolbox.xilinx.com/docsan/3_1i/data/fise/xst/chap02/xst02013.htm,
section "Single-Port RAM with Synchronous Read (Read Through)".

Note that my synth tool is saying it will use a dual-port RAM, when it is
clearly a single-port RAM... I suppose it has to do with the large size of
the address input (15 downto 0).

I sum up my question: I simply want to create a 65,535 x 16-bit RAM in the
more efficient possible way.
 
M

Mike Treseler

Xin said:
I dont' see it... I based my code on an example that is in my program
documentation on how to create a Block RAM.

This works ok on quartus.
See if it scales.

-- Mike Treseler

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

entity block_ram is
generic (width : natural := 16;
adr_length : natural := 10 --16*2**10=16384 bits
);

port (clk : in std_logic;
data : in std_logic_vector(width-1 downto 0);
adr : in std_logic_vector(adr_length-1 downto 0);
we : in std_logic;
q : out std_logic_vector(width-1 downto 0)
);
end block_ram;

-- M. Treseler Mon Jan 7 11:18:18 2008
architecture synth of block_ram is
constant mem_size : natural := 2**adr_length;
type mem_type is array (mem_size-1 downto 0) of
std_logic_vector (width-1 downto 0);
begin
ram_read : process (clk) is
variable mem_v : mem_type;
begin -- process
if rising_edge(clk) then
if we = '1' then
adr_wires : mem_v(to_integer(unsigned(adr))) := data;
else
data_reg : q <= mem_v(to_integer(unsigned(adr)));
end if;
end if;
end process;
end architecture synth;
 
B

Brad Smallridge

Xin Xiao said:
begin
process (Clk)
begin
if (rising_edge(Clk)) then
if (Enable = '1') then
if (RW = '1') then
memory(conv_integer(Addr)) <= Data_in;
end if;
-- read_a <= Addr; -- don't need this
-- try data_out here for registered output !!!!
Data_out <= memory(conv_integer(Addr));
end if;
end if;
end process;
--Data_out <= memory(conv_integer(read_a));
end Behavioral;

BRad Smallridge
Ai Vision
 
D

Duane Clark

Duane said:
You wrote:
if (Enable = '1') then
...
read_a <= Addr;
end if;

The example you used shows:
if (we = '1') then
...
end if;
read_a = a;

Hmm... it could be I am wrong about this. Having an enable on the read
address might be allowed.
 

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

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,835
Latest member
KetoRushACVBuy

Latest Threads

Top