mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 06:07:52 -04:00
[sim] xbus_memory: add HEX file init option
no VHDL2008 required
This commit is contained in:
parent
3ebe1169b4
commit
0827fe731d
1 changed files with 65 additions and 18 deletions
|
@ -11,14 +11,16 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
library neorv32;
|
||||
use neorv32.neorv32_package.all;
|
||||
|
||||
entity xbus_memory is
|
||||
generic (
|
||||
MEM_SIZE : natural := 1024; -- memory size in bytes; should be a power of two
|
||||
MEM_LATE : natural := 1 -- number of latency cycles (min 1)
|
||||
MEM_SIZE : natural := 4; -- memory size in bytes; min 4; should be a power of two
|
||||
MEM_LATE : natural := 1; -- number of latency cycles (min 1)
|
||||
MEM_FILE : string := "" -- memory initialization file (plain HEX), no initialization if empty
|
||||
);
|
||||
port (
|
||||
clk_i : in std_ulogic;
|
||||
|
@ -30,11 +32,49 @@ end xbus_memory;
|
|||
|
||||
architecture xbus_memory_rtl of xbus_memory is
|
||||
|
||||
-- address width --
|
||||
constant addr_bits_c : natural := index_size_f(MEM_SIZE/4);
|
||||
|
||||
-- memory type --
|
||||
type mem8_bv_t is array (natural range <>) of bit_vector(7 downto 0); -- bit_vector type for optimized system storage
|
||||
type ram8bv_t is array (natural range <>) of bit_vector(7 downto 0); -- bit_vector type for optimized system storage
|
||||
|
||||
-- initialize ram8bv_t array from ASCII HEX file (no VHDL08 required) --
|
||||
impure function init_mem8bv_from_hexfile_f(file_name : string; num_words : natural; byte_sel : natural) return ram8bv_t is
|
||||
file hex_file : text;
|
||||
variable hex_line_v : line;
|
||||
variable hex_char_v : character;
|
||||
variable tmp_v : natural;
|
||||
variable word_v : bit_vector(31 downto 0);
|
||||
variable mem_v : ram8bv_t(0 to num_words-1);
|
||||
variable index_v : natural;
|
||||
begin
|
||||
mem_v := (others => (others => '0'));
|
||||
if (file_name /= "") then
|
||||
file_open(hex_file, file_name, read_mode);
|
||||
index_v := 0;
|
||||
while (endfile(hex_file) = false) and (index_v < num_words) loop -- not end of file / end of memory
|
||||
readline(hex_file, hex_line_v); -- read one line from file
|
||||
for i in 7 downto 0 loop -- get full 32-bit word
|
||||
read(hex_line_v, hex_char_v);
|
||||
if (hex_char_v >= '0') and (hex_char_v <= '9') then
|
||||
tmp_v := 0 + (character'pos(hex_char_v) - character'pos('0'));
|
||||
elsif (hex_char_v >= 'a') and (hex_char_v <= 'f') then
|
||||
tmp_v := 10 + (character'pos(hex_char_v) - character'pos('a'));
|
||||
elsif (hex_char_v >= 'A') and (hex_char_v <= 'F') then
|
||||
tmp_v := 10 + (character'pos(hex_char_v) - character'pos('A'));
|
||||
else -- invalid character
|
||||
tmp_v := 0;
|
||||
end if;
|
||||
word_v(i*4+3 downto i*4+0) := to_bitvector(std_ulogic_vector((to_unsigned(tmp_v, 4))));
|
||||
end loop;
|
||||
mem_v(index_v) := word_v(byte_sel*8+7 downto byte_sel*8+0); -- extract desired byte
|
||||
index_v := index_v + 1;
|
||||
end loop;
|
||||
end if;
|
||||
return mem_v;
|
||||
end function init_mem8bv_from_hexfile_f;
|
||||
|
||||
-- memory access --
|
||||
signal addr : integer range 0 to (MEM_SIZE/4)-1;
|
||||
signal rdata : std_ulogic_vector(31 downto 0);
|
||||
signal ack : std_ulogic;
|
||||
|
||||
|
@ -45,29 +85,36 @@ architecture xbus_memory_rtl of xbus_memory is
|
|||
|
||||
begin
|
||||
|
||||
-- word-aligned read/write address --
|
||||
addr <= to_integer(unsigned(xbus_req_i.addr(index_size_f(MEM_SIZE/4)+1 downto 2)));
|
||||
|
||||
|
||||
-- Non-Initialized Memory Core ------------------------------------------------------------
|
||||
-- Pre-Initialized Memory (all-zero or HEX image if specified) ----------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
memory_core: process(clk_i)
|
||||
variable mem8_bv_b0_v, mem8_bv_b1_v, mem8_bv_b2_v, mem8_bv_b3_v : mem8_bv_t(0 to (MEM_SIZE/4)-1);
|
||||
variable mem8bv_b0_v : ram8bv_t(0 to (MEM_SIZE/4)-1) := init_mem8bv_from_hexfile_f(MEM_FILE, MEM_SIZE/4, 0);
|
||||
variable mem8bv_b1_v : ram8bv_t(0 to (MEM_SIZE/4)-1) := init_mem8bv_from_hexfile_f(MEM_FILE, MEM_SIZE/4, 1);
|
||||
variable mem8bv_b2_v : ram8bv_t(0 to (MEM_SIZE/4)-1) := init_mem8bv_from_hexfile_f(MEM_FILE, MEM_SIZE/4, 2);
|
||||
variable mem8bv_b3_v : ram8bv_t(0 to (MEM_SIZE/4)-1) := init_mem8bv_from_hexfile_f(MEM_FILE, MEM_SIZE/4, 3);
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
ack <= '0';
|
||||
if (xbus_req_i.cyc = '1') and (xbus_req_i.stb = '1') then
|
||||
ack <= '1';
|
||||
if (xbus_req_i.we = '1') then
|
||||
if (xbus_req_i.sel(0) = '1') then mem8_bv_b0_v(addr) := to_bitvector(xbus_req_i.data(07 downto 00)); end if;
|
||||
if (xbus_req_i.sel(1) = '1') then mem8_bv_b1_v(addr) := to_bitvector(xbus_req_i.data(15 downto 08)); end if;
|
||||
if (xbus_req_i.sel(2) = '1') then mem8_bv_b2_v(addr) := to_bitvector(xbus_req_i.data(23 downto 16)); end if;
|
||||
if (xbus_req_i.sel(3) = '1') then mem8_bv_b3_v(addr) := to_bitvector(xbus_req_i.data(31 downto 24)); end if;
|
||||
if (xbus_req_i.sel(0) = '1') then
|
||||
mem8bv_b0_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))) := to_bitvector(xbus_req_i.data(07 downto 00));
|
||||
end if;
|
||||
if (xbus_req_i.sel(1) = '1') then
|
||||
mem8bv_b1_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))) := to_bitvector(xbus_req_i.data(15 downto 08));
|
||||
end if;
|
||||
if (xbus_req_i.sel(2) = '1') then
|
||||
mem8bv_b2_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))) := to_bitvector(xbus_req_i.data(23 downto 16));
|
||||
end if;
|
||||
if (xbus_req_i.sel(3) = '1') then
|
||||
mem8bv_b3_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))) := to_bitvector(xbus_req_i.data(31 downto 24));
|
||||
end if;
|
||||
else
|
||||
rdata(07 downto 00) <= to_stdulogicvector(mem8_bv_b0_v(addr));
|
||||
rdata(15 downto 08) <= to_stdulogicvector(mem8_bv_b1_v(addr));
|
||||
rdata(23 downto 16) <= to_stdulogicvector(mem8_bv_b2_v(addr));
|
||||
rdata(31 downto 24) <= to_stdulogicvector(mem8_bv_b3_v(addr));
|
||||
rdata(07 downto 00) <= to_stdulogicvector(mem8bv_b0_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))));
|
||||
rdata(15 downto 08) <= to_stdulogicvector(mem8bv_b1_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))));
|
||||
rdata(23 downto 16) <= to_stdulogicvector(mem8bv_b2_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))));
|
||||
rdata(31 downto 24) <= to_stdulogicvector(mem8bv_b3_v(to_integer(unsigned(xbus_req_i.addr(addr_bits_c+1 downto 2)))));
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue