DPRAM in VHDL with different bus width

R

reto.knaak

Hi to everybody!
I'm trying to make a VHDL DPRAM for a xilinx spartan II. It works great
for the same bus width on each side but I don't know how to make
different bus size. I need a 128x1 on one side and 16x8 on the other
side...
I tried this, but it generates an error.... anyone who can help?

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity latch_dpram is
generic (
WIDTH : integer := 16;
DEPTH : integer := 8
);
port (
w_clk : in std_logic;
w_en_in : in std_logic;
w_data_in : in std_logic_vector(WIDTH*(2**DEPTH)-1 downto 0);
r_clk : in std_logic;
r_addr_in : in std_logic_vector(DEPTH-1 downto 0);
r_data_out : out std_logic_vector(WIDTH-1 downto 0)
);
end entity;
----------------------------------------------------------------------------------------------------
architecture xilinx_latch_ram of latch_dpram is
type memory_type is array (natural range <>) of
std_logic_vector(WIDTH-1 downto 0);
signal memory : memory_type(2**DEPTH-1 downto 0);
signal r_addr_int: std_logic_vector(DEPTH-1 downto 0);
begin
write : process(w_clk)
begin
if w_clk'event and w_clk = '1' then
if w_en_in = '1' then
memory <= w_data_in;
end if;
end if;
end process;
read : process(r_clk)
begin
if r_clk'event and r_clk = '1' then
r_addr_int <= r_addr_in;
end if;
end process;
r_data_out <= memory(to_integer(unsigned(r_addr_int)));
end architecture;
 
A

Andy Peters

Hi to everybody!
I'm trying to make a VHDL DPRAM for a xilinx spartan II. It works great
for the same bus width on each side but I don't know how to make
different bus size. I need a 128x1 on one side and 16x8 on the other
side...
I tried this, but it generates an error.... anyone who can help?

What error did it generate?

-a
 
J

jens

memory <= w_data_in;
r_data_out <= memory(to_integer(unsigned(r_addr_int)));

memory is array of SLV, w_data_in and r_data_out are not, which is
probably what's generating the error.
 
A

Andy

A couple of points:

AFAIK, inferring ram from arrays requires same read/write data widths.
If you want to use bram hardware to create different width IO, you have
to instantiate the bram. Otherwise, infer the ram with an array of the
widest data path (read or write) and use muxes (on read path) or
decoders and enables (on write path) to split up that wide path into
narrower chunks, based on lower address bits. Note that this extra
hardware will be in clbs, not part of bram.

It looks like you need w_data_in to be slv(width*depth-1 downto 0)

Andy
 
R

reto.knaak

Thank you for all the comments! This night I came to the same
conslusions and following code compiles now (well, not using
blockrams..Synthesizing Unit <latch_dpram>....
Found 16-bit 8-to-1 multiplexer for signal <r_data_out>.
Found 128-bit register for signal <memory>.
Found 3-bit register for signal <r_addr_int>....
Unit <latch_dpram> synthesized.)

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity latch_dpram is
generic (
WIDTH : integer := 16;
DEPTH : integer := 3 --2^3=8
);
port (
w_clk : in std_logic;
w_en_in : in std_logic;
w_data_in : in std_logic_vector(WIDTH*(2**DEPTH)-1 downto 0);
r_clk : in std_logic;
r_addr_in : in std_logic_vector(DEPTH-1 downto 0);
r_data_out : out std_logic_vector(WIDTH-1 downto 0)
);
end entity;
architecture xilinx_latch_ram of latch_dpram is
type memory_type is array (natural range <>) of
std_logic_vector(WIDTH-1 downto 0);
signal memory : memory_type(2**DEPTH-1 downto 0);
signal r_addr_int: std_logic_vector(DEPTH-1 downto 0);
begin
write : process(w_clk)
begin
if w_clk'event and w_clk = '1' then
if w_en_in = '1' then
memory(0) <= w_data_in(15 downto 0); -- not so pretty but
working
memory(1) <= w_data_in(31 downto 16);
memory(2) <= w_data_in(47 downto 32);
memory(3) <= w_data_in(63 downto 48);
memory(4) <= w_data_in(79 downto 64);
memory(5) <= w_data_in(95 downto 80);
memory(6) <= w_data_in(111 downto 96);
memory(7) <= w_data_in(127 downto 112);
end if;
end if;
end process;
read : process(r_clk)
begin
if r_clk'event and r_clk = '1' then
r_addr_int <= r_addr_in;
end if;
end process;
r_data_out <= memory(to_integer(unsigned(r_addr_int)));
end architecture;
 

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,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top