Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register File using distributed RAM

Status
Not open for further replies.

cmos babe

Full Member level 4
Full Member level 4
Joined
Jan 15, 2005
Messages
209
Helped
11
Reputation
22
Reaction score
0
Trophy points
1,296
Location
Dubai
Activity points
1,897
attribute ram_style of distributed

Hi , how can I write VHDL code for a register file that contains two read ports and a write port with seperate address port for each one utilizing the distributed RAM in spartan 3....XST inferred my code as block RAM but I want to use the block RAM for something else ..
HELP
 

I would try the dual-port Distributed RAM in the Xilinx CoreGenerator.
I would use one port for write and the other for read. Of course, some extra logic is needed to multiplex between the two read ports that you intend to use.
 

andrepandi said:
I would try the dual-port Distributed RAM in the Xilinx CoreGenerator.
I would use one port for write and the other for read. Of course, some extra logic is needed to multiplex between the two read ports that you intend to use.

I forgot to mention that the design should allow two reads and a write simultaneosly

EDIT:
I made some modifications and XST infers this as distributed RAM but it gives me this warning :
Code:
"WARNING:Xst:1771 - You have explicitly defined initial contents for this RAM, which are currently ignored when the RAM is implemented with LUT resources, leading to incorrect circuit behavior. Changing the RAM description if necessary so that it is read synchronously and setting the appropriate RAM style will allow implementation on block RAM resources for which we provide full initial contents support."
I didn't even define any initial contents!




Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity raminfr is
port (
clk : in std_logic;
we : in std_logic;
wa : in std_logic_vector(2 downto 0);
ra1 : in std_logic_vector(2 downto 0);
ra2 : in std_logic_vector(2 downto 0);
di : in std_logic_vector(7 downto 0);
do1 : out std_logic_vector(7 downto 0);
do2 : out std_logic_vector(7 downto 0));
attribute RAM_STYLE: string;
attribute RAM_STYLE of raminfr: entity is "distributed";
end raminfr;
architecture syn of raminfr is
type ram_type is array (7 downto 0) of std_logic_vector (7 downto 0);
signal RAM : ram_type;
signal read_ra1,read_ra2 : std_logic_vector(2 downto 0);
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (we = '1') then
RAM(conv_integer(wa)) <= di;

end if;
read_ra1 <= ra1 ;
read_ra2 <= ra2  ;
end if;
end process;
do1 <= RAM(conv_integer(ra1));
do2 <= RAM(conv_integer(ra2));
end syn;

Any comments on code/warning ?
 

cmos babe,
Try switching the RAM Style in XST Synthesis properties to Distributed.
Synthesis Properties=>HDL Options=>RAM Style to Distributed
 

    cmos babe

    Points: 2
    Helpful Answer Positive Rating
from xst user guide
Code:
Initializing Block RAM

VHDL

Block RAM initial contents can be specified by initialization of the signal describing the
memory array in your VHDL code as in the following example:
...
type ram_type is array (0 to 63) of std_logic_vector(19 downto 0);
signal RAM : ram_type :=
(
X"0200A", X"00300", X"08101", X"04000", X"08601", X"0233A",
X"00300", X"08602", X"02310", X"0203B", X"08300", X"04002",
X"08201", X"00500", X"04001", X"02500", X"00340", X"00241",
X"04002", X"08300", X"08201", X"00500", X"08101", X"00602",
X"04003", X"0241E", X"00301", X"00102", X"02122", X"02021",
X"00301", X"00102", X"02222", X"04001", X"00342", X"0232B",
X"00900", X"00302", X"00102", X"04002", X"00900", X"08201",
X"02023", X"00303", X"02433", X"00301", X"04004", X"00301",
X"00102", X"02137", X"02036", X"00301", X"00102", X"02237",
X"04004", X"00304", X"04040", X"02500", X"02500", X"02500",
X"0030D", X"02341", X"08201", X"0400D"
);
...
process (clk)
begin
if rising_edge(clk) then
if we = ’1’ then
RAM(conv_integer(a)) <= di;
end if;
ra <= a;
end if;
end process;
...
do <= RAM(conv_integer(ra));
The RAM initial contents can be specified in hexadecimal, as in the previous example, or in
binary as shown in the following example:
...
type ram_type is array (0 to SIZE-1) of std_logic_vector(15 downto 0);
signal RAM : ram_type :=
(
"0111100100000101",
"0000010110111101",
"1100001101010000",
...
"0000100101110011"
);
...
Verilog
XST does not support block RAM initialization in Verilog.

Limitations
- Initialization is only valid for block RAM resources. If you attempt to initialize
distributed RAM, XST ignores the initialization, and issues a warning message.
- Initialization is only valid for single-port RAM. If you attempt to initialize multipleport
RAM, XST ignores the initialization, and issues a warning message.
- Initialization of inferred RAMs from RTL code is not supported via INIT constraints.
Use of INIT constraints is only supported if RAM primitives are directly instantiated
from the UNISIM library.


try explicitly instantiating "RAM16X8D" and

Specifying Initial Contents of a RAM
You can use the INIT attribute to specify an initial value directly on the symbol if the
RAM is 1 bit wide and 16, 32, 64, or 128 bits deep. The value must be a hexadecimal
number, for example, INIT=ABAC. If the INIT attribute is not specified, the RAM is
initialized with zero.
For Virtex, Virtex-E, Spartan-II, and Spartan-IIE, lower INIT values get mapped to the
G function generator and upper INIT values get mapped to the F function generator.
See the "INIT" section of the Constraints Guide for more information on the INIT
attribute.
For Spartan-3, Virtex-II, Virtex-II Pro, and Virtex-II Pro X, wide RAMs (2, 4, and 8-bit
wide single port synchronous RAMs with a WCLK) can also be initialized. These
RAMs, however, require INIT_xx attributes. See “Specifying Initial Contents of a
Spartan-3, Virtex-II, Virtex-II Pro, and Virtex-II Pro X Wide RAM” in the RAM16X2S
section for more information on initializing Virtex-II wide RAM.

Specifying Initial Contents of a Spartan-3, Virtex-II, Virtex-II Pro, and
Virtex-II Pro X Wide RAM
You can use the INIT_xx properties to specify the initial contents of a Spartan-3,
Virtex-II, Virtex-II Pro, and Virtex-II Pro X wide RAM. INIT_00 initializes the RAM
cells corresponding to the O0 output, INIT_01 initializes the cells corresponding to the
O1 output, etc. For example, a RAM16X2S instance is initialized by INIT_00 and
INIT_01 containing 4 hex characters each. A RAM16X8S instance is initialized by
eight properties INIT_00 through INIT_07 containing 4 hex characters each. A
RAM64x2S instance is completely initialized by two properties INIT_00 and INIT_01
containing 16 hex characters each. See the INIT_xx section of the Constraints Guide for
more information on the INIT_xx attribute.

my code is almost similar but i'm not initializing the regfile:
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;

-- async read and sync write.............
entity regfile is
   port(
      aadr : in std_logic_vector(3 downto 0);
      badr : in std_logic_vector(3 downto 0);
      ad : in std_logic_vector(15 downto 0);
      adwe : in std_logic;
      clk : in std_logic;
      aq : out std_logic_vector(15 downto 0);
      bq : out std_logic_vector(15 downto 0)
   );
end regfile;

architecture Behavioral of regfile is       
   type ramtype is array(0 to 15) of std_logic_vector(15 downto 0);
   signal ram : ramtype;
begin
   process(clk)
   begin
      if rising_edge(clk) then
         if adwe = '1' then
            ram(conv_integer(aadr)) <= ad;   
         end if;
      end if;
   end process;
   aq <= ram(conv_integer(aadr));
   bq <= ram(conv_integer(badr));
end Behavioral;
 

    cmos babe

    Points: 2
    Helpful Answer Positive Rating
Are you willing to initialize the RAM content at all?
If not, I guess, you can just ignore that warning. Of course you have to treat the initial content as "xx..x", which makes no problem if you only read from an address where to you have already written something.
 

    cmos babe

    Points: 2
    Helpful Answer Positive Rating
Hi CMOS babe,
The best way to get a distributed RAM inferred instead of Block RAM is to add a reset signal signal to the RAM code and initialize the RAM variable to '0' with others=>'0' clause. This will cause distributed RAM to be inferred as Block RAM does not support reset. Try this and tell if it was ok.

Best Regards,
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top