Block RAM Distributed RAM

Xin Xiao wrote:

Your code works well, but when the RAM is 64 K word, there's no
resources available to implement it.
As I didn't find any solution, I finally made the RAM smaller.
I'd call that a solution.
You can't infer ram that's not there ;)

-- Mike Treseler
 
The problem was that I need a larger device if I want a 64K x 16 bit RAM
implemented with blocks, not LUTs.

Your code works well, but when the RAM is 64 K word, there's no resources
available to implement it.

As I didn't find any solution, I finally made the RAM smaller.

"Mike Treseler" <mike_treseler@comcast.net> wrote in message
news:5ufd6iF1hgbljU1@mid.individual.net...
Xin Xiao wrote:
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;
 
X

Xin Xiao

Guest
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,
 
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.

"Andy" <jonesandy@comcast.net> wrote in message
news:ed2f93bb-a0e2-431e-91e7-5cf721cdff82@k39g2000hsf.googlegroups.com...
On Jan 7, 9:58 am, "Xin Xiao" <x...@x.com> wrote:
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
 
On Jan 7, 9:58 am, "Xin Xiao" <x...@x.com> wrote:
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
 
Xin Xiao wrote:
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 ;)
 
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.


"Duane Clark" <junkmail@junkmail.com> wrote in message
news:_Ftgj.36956$Pv2.23960@newssvr23.news.prodigy.net...
Xin Xiao wrote:
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 ;)
 
Xin Xiao wrote:
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;
 
Xin Xiao wrote:
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)".
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;
 
"Xin Xiao" <x@x.com> wrote >
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
 
Duane Clark wrote:
Xin Xiao wrote:
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)".


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.
 

Welcome to EDABoard.com

Sponsor

Back
Top