+++ /dev/null
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-library std;
-use std.textio.all;
-
-
-entity sim_memory is
- generic (
- FILENAME: string := ""
- );
- port (
- we: in std_logic;
- address: in std_logic_vector(15 downto 0);
- data: inout std_logic_vector(7 downto 0)
- );
-end sim_memory;
-
-
-architecture behavioral of sim_memory is
-
- function str_endswith(str: string; suffix: string) return boolean is
- begin
- if str'length < suffix'length then
- return false;
- else
- return str(str'right - (suffix'length - 1) to str'right) = suffix;
- end if;
- end function;
-
-
- -----------------------------------------------------------------
- -- Linked-list implementation of sparsely populated list of bytes
-
- subtype byte_t is std_logic_vector(7 downto 0);
- type byte_array_t is array(natural range <>) of byte_t;
- type p_byte_array_t is access byte_array_t;
- type item_t;
- type p_item_t is access item_t;
-
- type sparse_t is record
- default: byte_t;
- page_size: natural;
- first: p_item_t;
- end record;
-
- type item_t is record
- base: integer;
- data: p_byte_array_t;
- next_item: p_item_t;
- end record;
-
-
- ----------------------------
- -- Create a new sparse array
- function sparse_new(default: byte_t := (others => 'U'); page_size: natural := 4096) return sparse_t is
- begin
- return (
- default => default,
- page_size => page_size,
- first => null
- );
- end function;
-
-
- ----------------------------------
- -- Get a value from a sparse array
- function sparse_get(sparse: sparse_t; idx: natural) return byte_t is
- variable base: natural;
- variable this: p_item_t;
- begin
- -- Find a page that contains idx
- base := idx - (idx mod sparse.page_size);
- this := sparse.first;
- while this /= null loop
- if this.base = base then
- -- Retrieve the value and exit
- return this.data(idx mod sparse.page_size);
- end if;
- this := this.next_item;
- end loop;
-
- -- No page containing idx, return the default value
- return sparse.default;
- end function;
-
-
- ------------------------------------
- -- Set a value within a sparse array
- procedure sparse_set(sparse: inout sparse_t; idx: natural; val: byte_t) is
- variable base: natural;
- variable this: p_item_t;
- variable new_item: p_item_t;
- begin
- -- Find a page that contains idx
- base := idx - (idx mod sparse.page_size);
- this := sparse.first;
- while this /= null loop
- if this.base = base then
- -- Write the value and exit
- this.data(idx mod sparse.page_size) := val;
- return;
- end if;
- this := this.next_item;
- end loop;
-
- -- No page found containing idx, create one and add it
- new_item := new item_t;
-
- new_item.base := base;
- new_item.data := new byte_array_t(sparse.page_size-1 downto 0);--'(others => sparse.default);
- new_item.next_item := sparse.first;
-
- sparse.first := new_item;
-
- for i in 0 to sparse.page_size-1 loop
- new_item.data(i) := sparse.default;
- end loop;
- new_item.data(idx mod sparse.page_size) := val;
- end procedure;
-
-begin
-
- p_reset: process
- type char_file_t is file of character;
- subtype ibyte_t is natural range 0 to 255;
-
- file f: char_file_t;
- variable fstatus: FILE_OPEN_STATUS;
-
- variable i: natural;
- variable c: character;
- variable b: ibyte_t;
- variable v: byte_t;
-
- variable mem: sparse_t;
- begin
- mem := sparse_new;
-
- -- Load data from file
- if str_endswith(FILENAME, ".bin") then
- -- Raw binary file
-
- file_open(fstatus, f, FILENAME, READ_MODE);
- assert fstatus = OPEN_OK report "Failed to open file '" & FILENAME & "'" severity failure;
-
- i := 0;
- while not endfile(f) loop
- read(f, c);
- b := character'pos(c);
- v := std_logic_vector(to_unsigned(b, 8));
- sparse_set(mem, i, v);
- report "char " & natural'image(i) & " = " & natural'image(b) & "";
- i := i + 1;
- end loop;
-
- file_close(f);
-
- elsif str_endswith(FILENAME, ".hex") then
- -- Intel HEX format
- assert false report "Intel HEX format not yet supported" severity failure;
- else
- assert false report "Filename suffix not recognized: '" & FILENAME & "'" severity failure;
- end if;
- file_close(f);
-
- report integer'image(to_integer(unsigned(sparse_get(mem, 6))));
- wait;
- end process;
-
-end behavioral;