- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hallo everyone,
i need a true dual port asynchronous ram for my selfmade soft-core project. to be hardware independent i try to infer the ram-block from vhdl-code. this is my code:--
-- Dual-Port Block RAM with Two Write Ports
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity TDPR is
generic( width : natural := 16;
depth : natural := 6);
port ( clka : in std_logic;
clkb : in std_logic;
ena : in std_logic;
enb : in std_logic;
wea : in std_logic;
web : in std_logic;
rsta : in std_logic;
rstb : in std_logic;
addra : in std_logic_vector(depth-1 downto 0);
addrb : in std_logic_vector(depth-1 downto 0);
dia : in std_logic_vector(width-1 downto 0);
dib : in std_logic_vector(width-1 downto 0);
doa : out std_logic_vector(width-1 downto 0);
dob : out std_logic_vector(width-1 downto 0));
end TDPR;
architecture syn of TDPR is
type ram_type is array ((2**depth)-1 downto 0) of std_logic_vector(width-1 downto 0);
shared variable RAM : ram_type;
begin
process(CLKA)
begin
if CLKA'event and CLKA = '1' then
if ENA = '1' then
if WEA = '1' then
RAM(conv_integer(ADDRA)) := DIA;
end if;
if rsta = '1' then -- optional reset
doa <= (others => '0');
else
doa <= ram(conv_integer(addra)) ;
end if;
end if;
end if;
end process;
process (CLKB)
begin
if CLKB'event and CLKB = '1' then
if ENB = '1' then
if WEB = '1' then
RAM(conv_integer(ADDRB)) := DIB;
end if;
if rstb = '1' then -- optional reset
dob <= (others => '0');
else
dob <= ram(conv_integer(addrb)) ;
end if;
end if;
end if;
end process;
end syn;
xilinx ise infers the correct block structure. but quartus gives an error message: Info: Found 1 instances of uninferred RAM logic Info: RAM logic "TDPR:inst|RAM" is uninferred due to asynchronous read logic Error: Cannot synthesize dual-port RAM logic "TDPR:inst|RAM" is there any possibility to use an true dual port asynchronous ram in vhdl code. (i'm using quartus 9.0sp2) with best regards erik_dl
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You should consider the hardware differences to understand the different behaviour.
Xilinx actually has asynchronous (unregistered) RAM with all FPGA series as far as I'm aware of, Altera hasn't. Furthermore, inference of asynchronous RAM seems not to work even with those Altera Stratix devices, that have the option in hardware. You can review the Quartus VHDL templates to see which RAM constructs are supported for inference.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for your fast answer.
the quartus megafunctions supports asynchronous dual port ram. and the synthesis seems to be correct (although i have not tested it on my cyclone II board), so i thought that should be possible in vhdl too.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Asynchronous RAM is not available for Cyclone series, see the hardware handbook for details, but Stratix III and Stratix IV have it. Inference from HDL code seems not to work for those devices, though.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- hallo everyone, i need a true dual port asynchronous ram for my selfmade soft-core project. to be hardware independent i try to infer the ram-block from vhdl-code. this is my code:
--
-- Dual-Port Block RAM with Two Write Ports
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity TDPR is
generic( width : natural := 16;
depth : natural := 6);
port ( clka : in std_logic;
clkb : in std_logic;
ena : in std_logic;
enb : in std_logic;
wea : in std_logic;
web : in std_logic;
rsta : in std_logic;
rstb : in std_logic;
addra : in std_logic_vector(depth-1 downto 0);
addrb : in std_logic_vector(depth-1 downto 0);
dia : in std_logic_vector(width-1 downto 0);
dib : in std_logic_vector(width-1 downto 0);
doa : out std_logic_vector(width-1 downto 0);
dob : out std_logic_vector(width-1 downto 0));
end TDPR;
architecture syn of TDPR is
type ram_type is array ((2**depth)-1 downto 0) of std_logic_vector(width-1 downto 0);
shared variable RAM : ram_type;
begin
process(CLKA)
begin
if CLKA'event and CLKA = '1' then
if ENA = '1' then
if WEA = '1' then
RAM(conv_integer(ADDRA)) := DIA;
end if;
if rsta = '1' then -- optional reset
doa <= (others => '0');
else
doa <= ram(conv_integer(addra)) ;
end if;
end if;
end if;
end process;
process (CLKB)
begin
if CLKB'event and CLKB = '1' then
if ENB = '1' then
if WEB = '1' then
RAM(conv_integer(ADDRB)) := DIB;
end if;
if rstb = '1' then -- optional reset
dob <= (others => '0');
else
dob <= ram(conv_integer(addrb)) ;
end if;
end if;
end if;
end process;
end syn;
xilinx ise infers the correct block structure. but quartus gives an error message: Info: Found 1 instances of uninferred RAM logic Info: RAM logic "TDPR:inst|RAM" is uninferred due to asynchronous read logic Error: Cannot synthesize dual-port RAM logic "TDPR:inst|RAM" is there any possibility to use an true dual port asynchronous ram in vhdl code. (i'm using quartus 9.0sp2) with best regards erik_dl --- Quote End --- Hi, your reset and enable functions could not implemented with Altera Rams. This causes that the RAM is not inferred. The info is a little bit misleading. That means that Quartus could not use the internal RAM for implementation. The only way now for Quartus to implement a RAM are register, which don't have a dual input. That's why you get the error message. If you remove the reset and enable the RAM should be inferred, but that is not what you want ??? Kind regards GPK
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I seem to recall a discussion on comp.lang.VHDL a while ago about this very issue.
IIRC, the conclusion was that Xilinx devices changed read-during-write behaviour when you swapped RAM between a signal and a shared variable. For Altera, when it did compile (I cant remember whether reset and enable inputs were included) there was no difference between the shared variable and signal versions. This meant that to modify the behaviour you had to use the altsyncram megafunction. I think I found the discussion: http://groups.google.com/group/comp.lang.vhdl/browse_frm/thread/b4b6147c98e6af5a/81d7b4efdc6ce246?lnk=gst&q=dual+port+ram#81d7b4efdc6ce246- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ok...its not the best way...but now i am using the megafunctions in my vhdl description.
but at synthesis appeared an other problem. configuration of my altsyncram: - two read/write ports (true dual-port mode) - 256 words (word = 16 bits) -> 256x16 - dual clock: use seperate clocks for A and B ports - create one clock enable signal for each clock signal so the total used memory bits should be 256*16 = 4096 bits but the synthesis uses 8192 bits (2 M4Ks). is this the correct behaviour? i have not find any application note to this topic. i am using a cyclone II device edit: i have tested the megafunction with Input/Output and Single Clock mode. in both cases the synthesis uses 1 M4K cell.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think, it's a Cyclone II problem. Quartus has special code to handle a silicon bug with internal RAM of some Cyclone II devices, resulting in doubled resource usage with true dual port RAM, If your devices aren't affected by the problem, you can disable this setting. Details can be found in the Cyclone II erata sheets.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks to all, that helps a lot to understand the compilation result.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ah, that's right, you should have gotten a warning that tells you to read the errata.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page