![]() |
|
|
|
#1 |
|
I would like to initialize a Xilinx BRAM in a format that is more byte wide
organized and with the bytes going in a left to right, or down the page, manner. Presently, the Xilinx BRAMs are initialized in the generic map with statements like this: INIT_00 => "0000000000000000000000000000000000000000000000000 000000004030201", which, I believe are, 256 bit bit_vectors filled with hex literals. The init as shown goes from right to left and would count 1,2,3,4 in a 9 bit wide read. Very clumsy. Even more difficult to format is the extra parity bit. I will make shorter constant bit_vectors and reverse the order with long concatenate statements if no one can suggest to me an easier way. What I would like to see is an unconstained array of 8 or 9 bit bit_vectors, and some sort of procedure or function that stuffs the BRAM init strings with the needed reversed order, perhaps fills the rest of BRAM with a default value, and passes this info to a wrapper BRAM module, whereby most of the BRAMs workings, and initiaization, can be hidden away. Brad Smallridge ai vision Brad Smallridge |
|
|
|
|
#2 |
|
Posts: n/a
|
Brad Smallridge wrote:
> Presently, the Xilinx BRAMs are initialized in the generic map with > statements like this: > > INIT_00 => > "0000000000000000000000000000000000000000000000000 000000004030201", > > which, I believe are, 256 bit bit_vectors filled with hex literals. The init > as shown goes from right to left and would count 1,2,3,4 in a 9 bit wide > read. Very clumsy. Indeed. I would describe the ROM as a constant array and let synthesis handle the gory details. -- Mike Treseler |
|
|
|
#3 |
|
Posts: n/a
|
I was working on this last night, and reading Ashenden's book as well. How do you pronounce this guy's name a-SHEN-den ? perhaps? or is it ASH-en-den? I have the BRAM generic map call a function passing the data array and the init bit_vector index. The while test in the function will test both indexes for overflow. I think it should be fairly robust(although I have not figured out how to test it completely) and easy to modify for other data types. Here's some of the code .. . . type init_array_type is array(natural range <>) of bit_vector(7 downto 0); constant bram8_data : init_array_type :=( X"00",X"01",X"02",X"03",X"04",X"05",X"06",X"07" , X"08",X"09",X"0A",X"0B",X"0C",X"0D",X"0E",X"0F" , X"00", X"FF" ); function stuff_it ( init_array : init_array_type; init_xx : integer ) return bit_vector is variable result : bit_vector(255 downto 0); variable i : integer ; variable j : integer ; begin result := X"000000000000000000000000000000000000000000000000 0000000000000000"; i := 0 ; j := 32*init_xx ; while( (j < init_array'length) and (i<256) ) loop result( (i+7) downto (i) ) := init_array(j) ; i := i + 8 ; j := j + 1 ; end loop; return result; end function stuff_it; .. . . begin .. . . RAMB16_1 : RAMB16 generic map ( .. . . INIT_00 => stuff_it(bram8_data,16#00#), INIT_01 => stuff_it(bram8_data,16#01#), INIT_02 => stuff_it(bram8_data,16#02#), INIT_03 => stuff_it(bram8_data,16#03#), INIT_04 => stuff_it(bram8_data,16#04#), .. . . |
|
|
|
#4 |
|
Posts: n/a
|
> I would describe the ROM as a constant array
> and let synthesis handle the gory details. Wow. For some reason I thought I had to do this on my own, but the Xilinx tool seems to handle it fine. Nice, hopefully portable, code. Thanks Mike. Here's what I did: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity bram8 is port ( clk : in std_logic; rst : in std_logic; q : out std_logic_vector(7 downto 0)); end bram8; architecture behavioral of bram8 is signal addr : std_logic_vector(11 downto 0); type init_array_type is array(natural range <>) of std_logic_vector(7 downto 0); constant bram8_data : init_array_type :=( X"00",X"01",X"02",X"03",X"04",X"05",X"06",X"07" , X"08",X"09",X"0A",X"0B",X"0C",X"0D",X"0E",X"0F" , X"00",X"01",X"02",X"03",X"04",X"05",X"06",X"07" , X"08",X"09",X"0A",X"0B",X"0C",X"0D",X"0E",X"0F" , X"08",X"09",X"0A",X"0B",X"0C",X"0D",X"0E",X"0F" , X"00",X"01",X"02",X"03",X"04",X"05",X"06",X"07" , X"08",X"09",X"0A",X"0B",X"0C",X"0D",X"0E",X"0F" , X"00", X"FF" ); begin LUT_proc : process(clk) begin if( clk'event and clk='1') then if(rst='1') then q <= (others=>'0'); addr <= (others=>'0'); else q <= bram8_data(CONV_INTEGER(addr)); addr <= addr + 1; end if; end if; end process; end behavioral; |
|
|
|
#5 |
|
Posts: n/a
|
Brad Smallridge wrote:
> Thanks Mike. Here's what I did: > LUT_proc : process(clk) > begin > if( clk'event and clk='1') then > if(rst='1') then > q <= (others=>'0'); > addr <= (others=>'0'); > else > q <= bram8_data(CONV_INTEGER(addr)); > addr <= addr + 1; > end if; > end if; > end process; > > end behavioral; If all you need is a rom, you don't have to include hardware for a loader. See below. -- Mike Treseler http://home.comcast.net/~mike_treseler/sync_rom.vhd http://home.comcast.net/~mike_tresel...c_rom_tech.pdf http://home.comcast.net/~mike_treseler/sync_rom_rtl.pdf |
|