Last active
January 11, 2021 12:34
-
-
Save Xiretza/22961f931b95c3a8243e221cce005288 to your computer and use it in GitHub Desktop.
memory init
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# ./run.sh 12 - works | |
# ./run.sh 13 - needs --max-stack-alloc= | |
# ./run.sh 17 - needs ulimit -s | |
# ./run.sh 18 - doesn't work at all at ulimit -s 15000 (maximum) | |
set -eu | |
bits=$1 | |
ghdl analyze --std=08 util_pkg.vhd sdp_ram_symm.vhd | |
ghdl elaborate --std=08 sdp_ram_symm | |
rm -f "init$bits.hex" | |
for i in $(seq $((2 ** "$bits"))); do | |
echo "00000000" >> "init$bits.hex" | |
done | |
ghdl run --std=08 sdp_ram_symm -gADDR_WIDTH="$bits" -gINIT_FILE="init$bits.hex" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- strictly symmetric simple dual port RAM to allow inferrence in yosys | |
library ieee; | |
use ieee.std_logic_1164.all, | |
ieee.numeric_std.all; | |
use work.util_pkg.all; | |
entity sdp_ram_symm is | |
generic ( | |
ADDR_WIDTH : positive := 12; | |
DATA_WIDTH : positive := 32; | |
COL_WIDTH : positive := 8; | |
READ_REGISTER : boolean := true; | |
INIT_FILE : string := "" | |
); | |
port ( | |
clk_read : in std_logic; | |
read : in std_logic; | |
addr_read : in std_logic_vector(ADDR_WIDTH - 1 downto 0); | |
data_read : out std_logic_vector(DATA_WIDTH - 1 downto 0); | |
clk_write : in std_logic; | |
write : in std_logic; | |
byte_en : in std_logic_vector(DATA_WIDTH/COL_WIDTH - 1 downto 0); | |
addr_write : in std_logic_vector(ADDR_WIDTH - 1 downto 0); | |
data_write : in std_logic_vector(DATA_WIDTH - 1 downto 0) | |
); | |
end sdp_ram_symm; | |
architecture behavioral of sdp_ram_symm is | |
constant COLS_PER_PORT : positive := DATA_WIDTH / COL_WIDTH; | |
constant DEPTH : positive := 2 ** ADDR_WIDTH; | |
signal store : slv_mem_t(0 to DEPTH - 1)(DATA_WIDTH - 1 downto 0) := | |
init_memory_from_file(INIT_FILE, DEPTH, DATA_WIDTH); | |
signal read_reg : std_logic_vector(DATA_WIDTH - 1 downto 0); | |
begin | |
assert DATA_WIDTH mod COL_WIDTH = 0 | |
report "DATA_WIDTH must be a multiple of COL_WIDTH" | |
severity failure; | |
process(clk_read) | |
begin | |
if rising_edge(clk_read) then | |
if read then | |
read_reg <= store(to_integer(unsigned(addr_read))); | |
end if; | |
end if; | |
end process; | |
process(clk_write) | |
begin | |
if rising_edge(clk_write) then | |
for i in 0 to COLS_PER_PORT - 1 loop | |
if write and byte_en(i) then | |
store(to_integer(unsigned(addr_write)))((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH) <= | |
data_write((i+1) * COL_WIDTH - 1 downto i * COL_WIDTH); | |
end if; | |
end loop; | |
end if; | |
end process; | |
read_reg_gen: if READ_REGISTER generate | |
process(clk_read) | |
begin | |
if rising_edge(clk_read) then | |
data_read <= read_reg; | |
end if; | |
end process; | |
else generate | |
data_read <= read_reg; | |
end generate; | |
end behavioral; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; | |
use ieee.std_logic_1164.all; | |
use std.textio.all; | |
package util_pkg is | |
type slv_mem_t is array(natural range <>) of std_logic_vector; | |
impure function init_memory_from_file( | |
file_name : string; | |
depth : positive; | |
word_size : positive | |
) return slv_mem_t; | |
end package util_pkg; | |
package body util_pkg is | |
impure function read_memory_file( | |
file_name : string; | |
depth : positive; | |
word_size : positive; | |
skip_first_line : boolean | |
) return slv_mem_t is | |
file file_handle : text open read_mode is file_name; | |
variable current_line : line; | |
variable good : boolean; | |
variable result : slv_mem_t(0 to depth-1)(word_size-1 downto 0) := | |
(others => (others => '0')); | |
begin | |
for i in 0 to depth-1 loop | |
exit when endfile(file_handle); | |
readline(file_handle, current_line); | |
hread(current_line, result(i), good); | |
if not good then | |
report "Not a hex literal in memory file '" & file_name & "': " & current_line.all | |
severity failure; | |
end if; | |
end loop; | |
return result; | |
end read_memory_file; | |
impure function init_memory_from_file( | |
file_name : string; | |
depth : positive; | |
word_size : positive | |
) return slv_mem_t is | |
constant uninitialized : slv_mem_t(0 to depth-1)(word_size-1 downto 0) := | |
(others => (others => 'U')); | |
begin | |
if file_name'length = 0 then | |
return uninitialized; | |
else | |
return read_memory_file(file_name, depth, word_size, true); | |
end if; | |
end init_memory_from_file; | |
end package body util_pkg; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment