library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library std; use std.textio.all; -------------------------------------------------------------------------------- -- ROM based Up Table -- -- It's based on behavioral description of full synchronous RAM, so it should be -- mapped into FPGA BRAM. Interface is Wishbone like. Data and address bus width -- is configurable. -- -- Table is initialized from file specified by 'init_file' parameter. This is a -- text file which contains one value per line. Values are typed in binary -- format. Sample file 'sin.lut' together with Matlab generation function -- 'gen_lut_sin.m' is enclosed. -------------------------------------------------------------------------------- entity rom_table is generic ( data_width : integer := 10; addr_width : integer := 9; init_file : string := "reci_tab_a.lut"); port ( ack_o : out std_logic; addr_i : in std_logic_vector (addr_width-1 downto 0); clk_i : in std_logic; data_o : out std_logic_vector (data_width-1 downto 0); stb_i : in std_logic ); end entity rom_table; -------------------------------------------------------------------------------- architecture behavioral of rom_table is constant table_size : integer := 2**addr_width; type rom_table_t is array (0 to table_size-1) of bit_vector (data_width-1 downto 0); impure function init_table_from_file (file_name : string) return rom_table_t is file table_file : text open read_mode is file_name; variable file_line : line; variable table : rom_table_t; begin for i in rom_table_t'range loop loop if (endfile(table_file)) and (i /= 0) then -- Repeat file data when not enough data to fill file_close(table_file); file_open(table_file, file_name, read_mode); end if; readline(table_file, file_line); exit when file_line'length /= 0; end loop; read(file_line, table(i)); end loop; return table; end function init_table_from_file; constant ram : rom_table_t := init_table_from_file(init_file); signal stb_delayed : std_logic; -------------------------------------------------------------------------------- begin mem_context : process (clk_i, addr_i) is variable address : integer; begin address := conv_integer(addr_i); if rising_edge(clk_i) then stb_delayed <= stb_i; if stb_i = '1' then data_o <= to_stdLogicVector(ram(address)); end if; end if; end process; ack_o <= stb_delayed; end architecture behavioral;