library bv_utilities; use bv_utilities.bv_arithmetic.bv_to_natural, bv_utilities.bv_arithmetic.natural_to_bv; architecture preloaded of memory is begin mem_behavior : process is constant high_address : natural := mem_size - 1; type memory_array is array (natural range 0 to high_address / 4) of dlx_bv_word; variable mem : 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"44000000", -- trap 0 X"00000000", -- counter: .word 0 others => X"00000000" ); variable byte_address, word_address : natural; variable write_access : boolean; procedure do_write is subtype ls_2_bits is bit_vector(1 downto 0); begin case width is when dlx_mem_width_word => mem(word_address) := to_bitvector(d); when dlx_mem_width_halfword => if To_bit(a(1)) = '0' then -- ms half word mem(word_address)(0 to 15) := to_bitvector( d(0 to 15) ); else -- ls half word mem(word_address)(16 to 31) := to_bitvector( d(16 to 31) ); end if; when dlx_mem_width_byte => case ls_2_bits'(To_bitvector(a(1 downto 0))) is when b"00" => mem(word_address)(0 to 7) := to_bitvector( d(0 to 7) ); when b"01" => mem(word_address)(8 to 15) := to_bitvector( d(8 to 15) ); when b"10" => mem(word_address)(16 to 23) := to_bitvector( d(16 to 23) ); when b"11" => mem(word_address)(24 to 31) := to_bitvector( d(24 to 31) ); 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( mem(word_address) ); end do_read; begin -- initialize outputs d <= disabled_dlx_word; ready <= '0'; -- process memory cycles loop -- wait for a command, valid on leading edge of phi2 wait on phi2 until rising_edge(phi2) and To_bit(mem_enable) = '1'; -- decode address and perform command if selected byte_address := bv_to_natural(To_bitvector(a)); write_access := To_bit(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 phi2 wait until rising_edge(phi2); ready <= '1' after Tpd_clk_out; wait until falling_edge(phi2); ready <= '0' after Tpd_clk_out; -- do subsequent cycles in burst while To_bit(burst) = '1' loop word_address := (word_address + 1) mod (mem_size / 4); wait until rising_edge(phi2); 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 phi2 wait until rising_edge(phi2); ready <= '1' after Tpd_clk_out; wait until falling_edge(phi2); 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;