-- synchronous use of lpm_ram -- this program reads the values in a rom using a counter as an address indicator. The -- data read are used as inputs to a ram. First a value is read from the rom (from -- address specified by the counter) and put in the ram on one rising edge of the system -- clock. Then the value is presented by the next rising edge of the system clock. This -- process of writing into the ram and reading from the ram is repeated until the values -- in the rom file "primes.mif" are read. Notice that "write_enable" controls whether we -- write to the ram or read from the ram. -- Following the process of writing into the ram, we disable "write_enable" and we only -- read from the ram to verify the values. library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all; LIBRARY lpm; -- required for the use of lpm functions USE lpm.lpm_components.ALL; entity ram is generic ( rom_data_width : positive := 3; -- width of data in rom rom_address_width : positive := 4; -- width of address in rom rom_data_size : positive := 10); -- number of values in rom PORT( clock: in std_logic; --system clock ram_out : out std_logic_vector( rom_data_width -1 downto 0)); -- output data end ram; architecture behavior of ram is signal counter : std_logic_vector(rom_address_width -1 downto 0) := "0000"; -- address counter signal rom_data_out : std_logic_vector(rom_data_width -1 downto 0); signal write_enable : std_logic:= '1'; signal read_all_ram : boolean := false; -- true to read the ram values sequentially begin obtain_rom : lpm_rom GENERIC MAP (lpm_widthad => rom_address_width, -- width of address of rom lpm_numwords => 10, -- total number of values lpm_outdata => "UNREGISTERED", lpm_address_control => "UNREGISTERED", lpm_file => "primes.mif", -- file to be read lpm_width => rom_data_width) -- width of data PORT MAP ( address => counter, q => rom_data_out); tiny_ram : lpm_ram_dq GENERIC MAP ( lpm_width => rom_data_width, -- width of input and output data lpm_widthad => rom_address_width, -- width of address lpm_indata => "REGISTERED", -- registered for synchronous use lpm_outdata => "REGISTERED", -- registered for synchronous use lpm_numwords => 16, -- maximum number of data lpm_address_control => "UNREGISTERED") PORT MAP ( --signals on the ports data => rom_data_out, we => write_enable, -- determines write or read address => counter, -- address counter inclock => clock, -- synchronized with system clock outclock => clock, q => ram_out); -- output data read_write : process(clock) is begin if falling_edge(clock) then if not read_all_ram then -- if not read the ram values sequentially yet write_enable <= not write_enable; -- setting write_enable else write_enable <= '0'; -- time to read the ram values sequentially end if; end if; end process; address_count : process(clock) is begin if rising_edge(clock) then if counter = conv_std_logic_vector(rom_data_size -1, rom_address_width) then read_all_ram <= true; -- time to read the ram values sequentially end if; if counter > conv_std_logic_vector(rom_data_size -1, rom_address_width) then counter <= (others => '0'); -- counter wraps at nine elsif write_enable = '0' then counter <= counter + 1; end if; end if; end process; end behavior;