Inferring block ram in Spartan II with non standard bus sizes

Hello. Im relatively new to VHDL and im doing a small project in which i've to store the co-efficients of the FIR filter into the block ram at system startup which are supposed to be used later by the filter block for implementing the MAC operation needed for the filter. I am using spartan II by xilinx. First of all, what i'd like to know is that, what does the phrase 'infer from the code' imply in the context of memory instantiation in vhdl or any HD. I used to think that there are dedicated hardware memory blocks on the FPGA and we need to address the port pins as in done in microcontroller programming environments and the like. After reading for a while and coming accross many codes for that, I now understand it as the synthesis tool 'realises' such a block in the FPGA. The only restriction we have is that we should write code keeping in mind the actual hardware capabilities of the board and/or the target device. Like incase of the XC2S50 device we can instantiate 8 blocks of 4K bits each and so on. Is my thinking correct in this regard or is there something which i am overlooking and/on misinterpreting?

Now heres the second question: The block ram in the spartan II FPGA is arranged as 4K blocks and the blocks can have variable address and data bus widths depending on the width of the data bus. My data is 10 bits wide and I actually need 9 (actually 8.6) bits to address that data. So when I write the code for that, can I declare an input port which is 10 bits wide (std_logic_vector(9 downto 0) ) or do I have to specify it using a signal which is 16 bits wide. The xilinx user manual says that the block ram can have data widths of 1,2,4,8, and 16. So if I declare my signal as 10 bits wide does the tool infer the code and create a 4K block with a data bus which is 16 bits wide.

Heres a sample code which I've adapted from my synthesis tool vendor's reference guide:

LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; USE ieee.std_logic_unsigned.all;

ENTITY syncram_sndsmple IS generic ( data_width : natural := 10; addr_width : natural := 4);

port ( clk : in std_logic; we : in std_logic; addr : in std_logic_vector(addr_width - 1 downto 0); data_in : in std_logic_vector(data_width - 1 downto 0); data_out : out std_logic_vector(data_width - 1 downto 0));

END ENTITY syncram_sndsmple ;

-- ARCHITECTURE rtl OF syncram_sndsmple IS

type mem_type is array (2**addr_width downto 0) of std_logic_vector(data_width - 1 downto 0); signal mem : mem_type; signal addr_reg : std_logic_vector(addr_width - 1 downto 0); attribute block_ram : boolean; attribute block_ram of mem : signal is true; begin singleport_sndsmple : process(clk) begin if clk'event and clk = '1' then if we = '1' then mem(conv_integer(addr))

Reply to
aijazbaig1
Loading thread data ...

That looks correct, as does your other conclusions that followed (which I've cut). The only other thing that may need a comment is:

[...]

I assume you mean parallel them. The answer is yes.

Have fun,

Marc

Reply to
Marc Randolph

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.