Я бы поддержал комментарий Брайана, в цикле for всего 3 оператора. Похоже, у вас проблема с файлом stddata. Как отмечает Патрик Леманн, вы можете проверить EOF (ENDFILE), что позволит вам отметить, если ваш файл будет коротким. inst_mem — это массив (от 0 до 32), 33 записи, как отмечает Мортен Зилмер.
Я создал экземпляр вашей модели (с изменениями для поддержки VHDL-инструмента, совместимого с -1993, и переключением с conv_integer на to_integer в пакете numeric_std вы можете игнорировать дополнительные элементы в области деклараций архитектуры):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
-- USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;
entity inst_mem is
port(
load: in std_logic;
address: in std_logic_vector (5 downto 0);
dataout: out std_logic_vector (10 downto 0)
);
end entity;
architecture arch_inst_mem of inst_mem is
TYPE inst_mem is array (0 to 32) of std_logic_vector(10 downto 0);
type MVL9plus is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-', ERROR);
type MVL9_indexed_by_char is array (character) of STD_ULOGIC;
type MVL9plus_indexed_by_char is array (character) of MVL9plus;
constant char_to_MVL9: MVL9_indexed_by_char :=
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => 'U');
constant char_to_MVL9plus: MVL9plus_indexed_by_char :=
('U' => 'U', 'X' => 'X', '0' => '0', '1' => '1', 'Z' => 'Z',
'W' => 'W', 'L' => 'L', 'H' => 'H', '-' => '-', others => ERROR);
procedure READ(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is
variable m: STD_ULOGIC;
variable c: character;
variable s: string(1 to value'length-1);
variable mv: STD_LOGIC_VECTOR(0 to value'length-1);
constant allU: STD_LOGIC_VECTOR(0 to value'length-1)
:= (others => 'U');
variable GOOD: boolean;
begin
loop -- skip white space
read(l,c);
exit when ((c /= ' ') and (c /= CR) and (c /= HT));
end loop;
if (char_to_MVL9plus(c) = ERROR) then
value := allU;
good := FALSE;
return;
end if;
read(l, s);
for i in integer range 1 to value'length-1 loop
if (char_to_MVL9plus(s(i)) = ERROR) then
value := allU;
good := FALSE;
return;
end if;
end loop;
mv(0) := char_to_MVL9(c);
for i in integer range 1 to value'length-1 loop
mv(i) := char_to_MVL9(s(i));
end loop;
value := mv;
good := TRUE;
end READ;
procedure init_mem(variable memory : out inst_mem;
constant datafile : string) is
file stddata: text;
variable l: line;
variable data: std_logic_vector (10 downto 0);
begin
file_open (stddata, datafile, READ_MODE);
for i in memory'range(1) loop
readline (stddata, l);
read (l, data);
memory(i):= data;
end LOOP;
end procedure;
begin
process (load , address)
variable memory: inst_mem;
begin
if (load = '1') then
init_mem (memory, "inst_mem.txt");
dataout <= memory (to_integer(unsigned(address))); -- (conv_integer(address));
end if;
end process;
end arch_inst_mem;
И генерируется файл inst_mem.txt с 33 записями:
00000000000
00000000001
00000000010
00000000011
00000000100
00000000101
00000000110
00000000111
00000001000
00000001001
00000001010
00000001011
00000001100
00000001101
00000001110
00000001111
00000010000
00000010001
00000010010
00000010011
00000010100
00000010101
00000010110
00000010111
00000011000
00000011001
00000011010
00000011011
00000011100
00000011101
00000011110
00000011111
00000100000
И модель успешно работала под управлением ghdl (0.31, совместимость с -1993).
Сделав очень уродливые вещи в ghdl (который не поддерживает отображение переменных в осциллограммах), я могу продемонстрировать, что память inst_mem инициализируется последовательным вызовом процедуры init_mem:
(кликабельно )
Что более чем вероятно говорит о том, что у вас неправильное количество записей в inst_mem.txt, что приводит к ошибке, потому что ENDFILE не используется для обнаружения EOF:
ghdl -r inst_mem --wave=inst_mem.ghw
../../../src/std/textio_body.v93:558:5:@1ns:(сбой подтверждения): ошибка чтения символа
. /inst_mem:error: ошибка утверждения
./inst_mem:error: ошибка моделирования
ghdl: ошибка компиляции
Всего за 32 записи.
(И вы заметили, что ghdl не выполняет обратную трассировку в спецификации проекта.)
Если бы была недопустимая запись, вы бы получили кучу un-defines в определенном месте памяти.
Итак, похоже, вы должны были либо определить:
TYPE inst_mem is array (0 to 31) of std_logic_vector(10 downto 0);
введите inst_mem как массив из 32 элементов, или убедитесь, что ваш файл inst_mem.txt имеет нужное количество элементов, или использовали тест ENDFILE и просто не инициализировали оставшиеся элементы массива.
И добавление теста ENDFILE:
procedure init_mem(signal memory : out inst_mem;
constant datafile : string) is
file stddata: text;
variable l: line;
variable data: std_logic_vector (10 downto 0);
begin
file_open (stddata, datafile, READ_MODE);
for i in memory'range(1) loop
if not ENDFILE(stddata) then
readline (stddata, l);
read (l, data);
memory(i) <= data;
end if;
end LOOP;
FILE_CLOSE(stddata);
end procedure;
устраняет указанную выше ошибку. У него также есть побочный эффект, заключающийся в том, что оставшиеся элементы массива остаются неинициализированными.
Вы также заметите, что я добавил процедуру FILE_CLOSE, которую рекомендует Мортен, в соответствии с теорией, что вы можете повторно инициализировать массив памяти в любое время, когда у вас есть событие либо при загрузке, либо по адресу и load = '1'.
И это также говорит вам о том, что вы должны обнаруживать высокую нагрузку, а не уровень:
process (load , address)
variable memory: inst_mem;
begin
if load'event and load = '1' then
init_mem (memory, "inst_mem.txt");
dataout <= memory (conv_integer(address));
end if;
end process;
Предполагая, что это находится на испытательном стенде или не является целью синтеза.
Если вы намеревались предоставить файл инициализации для встраивания в битовый поток FPGA, вы должны придерживаться процесса поставщика для этого.
Вы пытаетесь использовать тот же процесс, потому что объявили память как переменную. Это может быть общая переменная. и у вас может быть два отдельных процесса: один для инициализации, другой для чтения.
Реализация памяти в качестве сигнала немного проще и в этом случае не приведет к снижению производительности.
(Меня интересуют вопросы текстио.)
person
Community
schedule
20.01.2015
file_close
в конце процедурыinit_memory
, чтобы соответствоватьfile_open
. Убедитесь, что в файле inst_mem.txt указано правильное количество записей, поскольку нечетно, что портaddress
имеет 6 бит, что дает 64 (2 ** 6) записей, в то время как считываются 33 записи (от 0 до 32). Кроме того, рассмотрите возможность использования только пакетаieee.numeric_std
, так какIEEE.STD_LOGIC_UNSIGNED
иieee.std_logic_arith
не являются стандартными и могут быть заменены пакетомieee.numeric_std
. - person Morten Zilmer   schedule 20.01.2015