Как сообщает @Tricky, я упустил из виду, что вы используете quartus . Насколько мы оба знаем, Quartus не поддерживает чтение файлов в функциях инициализатора. Весь пакет textio
для файлового ввода-вывода не поддерживается / игнорируется. Вам необходимо использовать примитивы мега-функции Altera из библиотеки VHDL altera_mf
с именем altsyncram
для представления ОЗУ или ПЗУ. В PoC-библиотеке есть реализация.
altsyncram
пример для однопортовой оперативной памяти:
library altera_mf;
use altera_mf.all;
mem : altsyncram
generic map (
address_aclr_a => "NONE",
indata_aclr_a => "NONE",
init_file => INIT_FILE,
intended_device_family => getAlteraDeviceName(DEVICE),
lpm_hint => "ENABLE_RUNTIME_MOD = NO",
lpm_type => "altsyncram",
numwords_a => DEPTH,
operation_mode => "SINGLE_PORT",
outdata_aclr_a => "NONE",
outdata_reg_a => "UNREGISTERED",
power_up_uninitialized => "FALSE",
widthad_a => A_BITS,
width_a => D_BITS,
width_byteena_a => 1,
wrcontrol_aclr_a => "NONE"
)
port map (
clocken0 => ce,
wren_a => we,
clock0 => clk,
address_a => a_sl,
data_a => d,
q_a => q
);
Источник: https://github.com/VLSI-EDA/PoC/blob/master/src/mem/ocram/altera/ocram_sp_altera.vhdl?ts=2
Оригинальный ответ:
Вам нужно поместить код инициализации вашей RAM в функцию, которая возвращает начальные значения для вашей RAM. В функции вы читаете внешний файл и конвертируете каждую строку в значение памяти.
Вот несколько фрагментов, которые помогут вам выбрать правильный путь:
architecture a of e is
type ram_type is array(natural range <>) of std_logic_vector(31 downto 0);
function initialize(
constant file_name : string;
constant size : positive
) return ram_type is
file mem_file : text;
variable result : ram_type(0 to size - 1);
begin
file_open(mem_file, file_name, READ_MODE);
while not endfile(mem_file) loop
-- ... read and convert content
end loop;
file_close(mem_file);
return result;
end function;
signal mem : ram_type := initialize("memfile.dat", 64);
begin
process(a)
begin
rd <= mem(to_integer(unsigned(a(7 downto 2))));
end process;
Дополнительные подсказки:
- Обычно чтение памяти команд (BlockRAM) является синхронизированным процессом. В настоящее время вы читаете асинхронно при каждом изменении адреса.
- Оператор
wait on
эквивалентен процессу со списком чувствительности.
- Вы должны закрыть открытые файлы.
- Не используйте пакет
STD_LOGIC_arith
, используйте numeric_std
.