library ieee; use ieee.std_logic_1164.all, ieee.numeric_bit.all; architecture preloaded of memory is begin mem_behavior : process is constant high_address : natural := mem_size - 1; type memory_array is array ( natural range <> ) of dlx_word; variable mem : memory_array(0 to high_address / 4) := ( others => X"00000000" ); variable byte_address, word_address : natural; variable write_access : boolean; procedure load is constant program : memory_array := ( X"20020000", -- addi r2, r0, 0 X"ac020018", -- loop: sw counter(r0), r2 X"20420001", -- addi r2, r2, 1 X"6441000a", -- snei r1, r2, 10 X"1420fff0", -- bnez r1, loop X"00000001", -- halt X"00000000" ); -- counter: .word 0 begin assert program'length <= mem'length report "memory too small for program" severity failure; mem(program'range) := program; end load; procedure do_write is begin case width is when dlx_mem_width_word => mem(word_address) := unsigned(to_bitvector(d)); when dlx_mem_width_halfword => if a(1) = '0' then -- ms half word mem(word_address)(31 downto 16) := unsigned(to_bitvector( d(31 downto 16) )); else -- ls half word mem(word_address)(15 downto 0) := unsigned(to_bitvector( d(15 downto 0) )); end if; when dlx_mem_width_byte => case a(1 downto 0) is when b"00" => mem(word_address)(31 downto 24) := unsigned(to_bitvector( d(31 downto 24) )); when b"01" => mem(word_address)(23 downto 16) := unsigned(to_bitvector( d(23 downto 16) )); when b"10" => mem(word_address)(15 downto 8) := unsigned(to_bitvector( d(15 downto 8) )); when b"11" => mem(word_address)(7 downto 0) := unsigned(to_bitvector( d(7 downto 0) )); end case; when others => report "illegal width indicator in write" severity error; end case; end do_write; procedure do_read is begin d <= To_X01( bit_vector(mem(word_address)) ); end do_read; begin load; -- initialize outputs d <= disabled_dlx_word; ready <= '0'; -- process memory cycles loop -- wait for a command, valid on leading edge of clk wait on clk until rising_edge(clk) and mem_enable = '1'; -- decode address and perform command if selected byte_address := to_integer(a); write_access := write_enable = '1'; if byte_address <= high_address then word_address := byte_address / 4; if write_access then -- write cycle do_write; wait for Tac_first; -- write access time, 1st cycle else -- read cycle wait for Tac_first; -- read access time, 1st cycle do_read; end if; -- ready synchronous with clk wait until rising_edge(clk); ready <= '1' after Tpd_clk_out; wait until rising_edge(clk); ready <= '0' after Tpd_clk_out; -- do subsequent cycles in burst while burst = '1' loop word_address := (word_address + 1) mod (mem_size / 4); wait until rising_edge(clk); if write_access then -- write cycle do_write; wait for Tac_burst; -- write access time, burst cycle else -- read cycle wait for Tac_burst; -- read access time, burst cycle do_read; end if; -- ready synchronous with clk wait until rising_edge(clk); ready <= '1' after Tpd_clk_out; wait until rising_edge(clk); ready <= '0' after Tpd_clk_out; end loop; if not write_access then -- was read d <= disabled_dlx_word after Tpd_clk_out; end if; end if; end loop; end process mem_behavior; end architecture preloaded;