From: Martin Schoeberl on 24 Nov 2005 12:14 >> >>For Xilinx I only know those RAMB16_S9_S36 components where >>the memory size is part of the component name. Is there a >>a Xilinx block RAM component where I can specify the size? >> > NO, but you can use GENERATE (assuming VHDL) to switch between different bram geometries > Aurelian > Really, that's it? Not very comfortable - a plus for Quartus. Perhaps one in this group has already done this coding effort and can provide the VHDL file? Martin
From: Olaf Petzold on 24 Nov 2005 13:14 Hi, > I'll give up one this vendor independent block RAM project. For > the 32-bit write data, 8-bit read data with registered address, Don't give up ;-) Maybe the code attached from my project will help you. Using configurations you can choose the architecture. Regards, Olaf ---8<--- library unisim; use unisim.vcomponents.all; library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ram_512x80 is generic ( RESET_ACTIVE : std_logic := '1'); port ( clk : in std_logic; reset : in std_logic; en : in std_logic; AB : in std_logic_vector(8 downto 0); DB_I : in std_logic_vector(79 downto 0); DB_O : out std_logic_vector(79 downto 0); we : in std_logic); end entity ram_512x80; ------------------------------------------------------------------------------- architecture banking of ram_512x80 is constant NUM_BLOCKS : positive := 10; -- XC2S100 signal m_clk : std_logic; signal m_reset : std_logic; begin -- reset conversation m_reset <= '1' when (reset = RESET_ACTIVE) else '0'; -- xilinx specific clk_buf : BUFG port map (I => clk, O => m_clk); -- instance block ram bram : for n in NUM_BLOCKS-1 downto 0 generate function lsb (i : integer) return integer is begin return i*8; end; function msb (i : integer) return integer is begin return lsb(i) + 7; end; begin -- D(79:72) D(71:64) D(63:56) D(55:48) D(47:40) D(39:32) D(31:24) D(23:16) D(15:8) D(7:0) ram_i : RAMB4_S8 -- RAMB4_S8: Virtex/E, Spartan-II/IIE 512 x 8 Single-Port RAM -- http://toolbox.xilinx.com/docsan/xilinx7/de/libs/lib/ramb4_sn.pdf generic map ( INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( CLK => m_clk, -- Clock input RST => m_reset, -- Synchronous reset input EN => en, -- RAM enable input ADDR => AB, -- 9-bit address input DO => DB_O(msb(n) downto lsb(n)), -- 8-bit data output DI => DB_I(msb(n) downto lsb(n)), -- 8-bit data input WE => we); -- RAM write enable input end generate; end architecture banking; ------------------------------------------------------------------------------- architecture infering of ram_512x80 is constant BIT_DEPTH : positive := 512; constant BIT_WIDTH : positive := 80; type ram_t is array(BIT_DEPTH-1 downto 0) of std_logic_vector(BIT_WIDTH-1 downto 0); -- infer RAM signal blockram : ram_t; begin -- Note, Spartan-II doesn't have "No Change Mode"; -- Using Block RAM Single Port "Write First Mode" process (clk) begin if rising_edge(clk) then if (en = '1') then if (we = '1') then blockram(to_integer(unsigned(AB))) <= DB_I; DB_O <= DB_I; else DB_O <= blockram(to_integer(unsigned(AB))); end if; end if; end if; end process; end architecture infering;
From: Martin Schoeberl on 24 Nov 2005 14:48 Hi Olaf, >> I'll give up one this vendor independent block RAM project. For >> the 32-bit write data, 8-bit read data with registered address, > > Don't give up ;-) > > Maybe the code attached from my project will help you. Using configurations you can choose the architecture. > Not so bad! The infering architecture generates a block ram for the Spartan-3. However, with Quartus it generates registers. A little step forward ;-) The next step is to generate a memory with different port sizes. The attached code instances a block ram with a MUX in Quartus and distributed memory with the Xilinx tool. -- -- gen_mem.vhd -- -- VHDL memory experiments -- -- address, data in are registered -- data out is unregistered -- -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity jbc is generic (jpc_width : integer := 10); port ( clk : in std_logic; data : in std_logic_vector(31 downto 0); rd_addr : in std_logic_vector(jpc_width-1 downto 0); wr_addr : in std_logic_vector(jpc_width-3 downto 0); wr_en : in std_logic; q : out std_logic_vector(7 downto 0) ); end jbc; -- -- registered wraddress, wren -- registered din -- registered rdaddress -- unregistered dout -- architecture rtl of jbc is constant nwords : integer := 2**(jpc_width-2); type mem is array(0 to nwords-1) of std_logic_vector(31 downto 0); signal ram_block: mem; signal d: std_logic_vector(31 downto 0); signal rda_reg : std_logic_vector(jpc_width-1 downto 0); begin d <= ram_block(to_integer(unsigned(rda_reg(jpc_width-1 downto 2)))); process(clk) begin if rising_edge(clk) then if wr_en='1' then ram_block(to_integer(unsigned(wr_addr))) <= data; end if; rda_reg <= rd_addr; end if; end process; process(rda_reg, d) begin case rda_reg(1 downto 0) is when "11" => q <= d(31 downto 24); when "10" => q <= d(23 downto 16); when "01" => q <= d(15 downto 8); when "00" => q <= d(7 downto 0); when others => null; end case; end process; end rtl;
From: John Adair on 24 Nov 2005 16:54 Martin One good place for information is the libraries guide. A version of it is here http://toolbox.xilinx.com/docsan/xilinx7/books/docs/lib/lib.pdf . The RAMB16 macros are basically the size of a single block ram - 16Kbit (18Kbit with parity). There is also help on ram component instantiation in ISE (I believe this is in Webpack). If you click on the lightbulb icon in the ISE tool you should get to some templates. I don't think you will find any other size as ready built macro for Xilinx RAM. You will have build that up yourself if you don't have Coregen. John Adair Enterpoint Ltd. - Home of Broaddown2. The Ultimate Spartan3 Development Board. http://www.enterpoint.co.uk "Martin Schoeberl" <mschoebe(a)mail.tuwien.ac.at> wrote in message news:4385f45c$0$12126$3b214f66(a)tunews.univie.ac.at... >> The RAMB16 elements are the raw RAM macros. The Sx part of the name >> indicates the port width. You can build up bigger memories in Coregen >> which is a bit like the Altera Megawizard tool or build them up yourself >> using generic statements using the raw macros. > > Can you describe this a little bit more specific, please? Are the > other components available to describe Xilinx block RAMs? > > BTW: With the web edition I don't have Coregen and I also don't > use the Megawizzard in Quartus. Ideal setup is a single generic > parameter with the memory size (in lenght of the address). > >> If you looking at switching between vendors one trick is to hide a RAM >> inside a wrapper file. If you use the wrapper level as the RAM component >> for instantiation then you will only have to change the technology based >> memory element in one place i.e. the the wrapper file. > > That's the way I do it. I switch between technologies with different > files in the project. I also use this different VHDL files in projects > for other customization - primitiv, but efficient. > > >> Some synthesisers are capable of inferring RAM usually using an indexed >> array of something like VHDL's "std_logic_vector". I can't tell you much >> about the results as it isn't my own preferred method but a non-vendor >> synthesiser may do better than one offered by the silicon vendors. > > The Xilinx tool interffered distributed RAM from the VHDL description. > A thing I definitely don't want. Quartus had problems with the > different port sizes, but single port sizes work very well. > > Martin > > >>> >I would like to code the on-chip memory in vendor neutral VHDL. >>>> I got it running for a dual-port memory with single clock and >>>> same port sizes for the read and write port. >>>> >>>> However, I need a memory with a 32-bit write port and an 8-bit >>>> read port. So far I was not able to code it in VHDL in a way >>>> that the Synthesizer inferres the correct block ram without >>>> an extra read MUX. >>>> >>> >>> I'll give up one this vendor independent block RAM project. For >>> the 32-bit write data, 8-bit read data with registered address, >>> in data and unregistered out data RAM coded in VHDL I got: >>> >>> On the Altera Cyclone: generates a 32-bit dual port RAM with an >>> external 4:1 MUX. This MUX hurts fmax (from 94MHz down to 84MHz)! >>> >>> On the Xlinix Spartan-3: The RAM gets implemented as distributed >>> RAM! Uses a lot of LCs and the fmax goes from 65MHz down to >>> 50MHz >>> >>> So I will bite the bullet and use two vendor specific VHDL files. >>> However, there is one open issue: I want the memory size be >>> configurable via a generic. This is possible with Alteras >>> altsyncram. >>> >>> For Xilinx I only know those RAMB16_S9_S36 components where >>> the memory size is part of the component name. Is there a >>> a Xilinx block RAM component where I can specify the size? >>> >>> Thanks, >>> Martin >>> >> >> > >
From: Martin Thompson on 25 Nov 2005 08:44 "Martin Schoeberl" <mschoebe(a)mail.tuwien.ac.at> writes: > So I will bite the bullet and use two vendor specific VHDL files. > However, there is one open issue: I want the memory size be > configurable via a generic. This is possible with Alteras > altsyncram. > > For Xilinx I only know those RAMB16_S9_S36 components where > the memory size is part of the component name. Is there a > a Xilinx block RAM component where I can specify the size? > Nope. I've been beating them up on this for years now - they just can't seem to grasp why I wouldn;t want to use Coregen for all my RAM needs! Grrr! (Another) Martin -- martin.j.thompson(a)trw.com TRW Conekt - Consultancy in Engineering, Knowledge and Technology http://www.trw.com/conekt
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Spartan-3E starter kit Next: Slow FIFO using external SRAM |