VHDL - Симуляция тестового стенда ModelSim зависает при отправке "run"
У меня проблема с тестовым стендом, который я разрабатываю для аппаратного алгоритма бабочки для вычисления преобразования Фурье.
Я пытаюсь прочитать серию файлов входных данных (32-битных векторов) и записать выходные данные в некоторые другие выходные файлы.
Входными файлами являются Ar.txt, Ai.txt, Br.txt, Bi.txt, Wr.txt и Wi.txt.
Выходные файлы: Ar_OUT_TB.txt, Ai_OUT_TB.txt, Br_OUT_TB.txt, Bi_OUT_TB.txt.
Но когда я пытаюсь смоделировать с ModelSim, программа просто зависает: я все еще могу делать что-то, например, открывать другой проект / файл и т. Д., Но сигнал не отображается, а также отсутствует командная строка. Я также пытался смоделировать мой старый проект VHDL, и он действительно имитировал, так что я думаю, проблема в этом коде.
Это основные процессы (РЕДАКТИРОВАТЬ: я также добавляю остальную часть кода, для понимания):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE STD.TEXTIO.ALL;
ENTITY BUTTERFLY_TESTBENCH IS
END BUTTERFLY_TESTBENCH;
ARCHITECTURE DEVICE OF BUTTERFLY_TESTBENCH IS
COMPONENT progetto_butterfly
GENERIC(N_IN, N_OUT: INTEGER := 32;
N_BUSES: INTEGER := 63);
PORT(START, CLK, MAIN_RST_N: IN STD_LOGIC;
DATA_IN, Wr_IN, Wi_IN: IN SIGNED(N_IN-1 DOWNTO 0);
DATA_OUT: OUT SIGNED(N_IN-1 DOWNTO 0);
DONE: OUT STD_LOGIC);
END COMPONENT;
CONSTANT N_IN: INTEGER := 32;
CONSTANT N_OUT: INTEGER := 32;
SIGNAL TEST_DATA_IN, TEST_Wr_IN, TEST_Wi_IN: SIGNED(N_IN-1 DOWNTO 0);
SIGNAL TEST_OUTPUT: SIGNED(N_OUT-1 DOWNTO 0);
SIGNAL CLK: STD_LOGIC;
SIGNAL TEST_START, TEST_RST, TEST_DONE: STD_LOGIC;
FILE Ar_IN_FILE: TEXT OPEN READ_MODE IS "Ar.txt";
FILE Ai_IN_FILE: TEXT OPEN READ_MODE IS "Ai.txt";
FILE Br_IN_FILE: TEXT OPEN READ_MODE IS "Br.txt";
FILE Bi_IN_FILE: TEXT OPEN READ_MODE IS "Bi.txt";
FILE WR_FILE: TEXT OPEN READ_MODE IS "Wr.txt";
FILE WI_FILE: TEXT OPEN READ_MODE IS "Wi.txt";
FILE Ar_OUT: TEXT OPEN WRITE_MODE IS "Ar_OUT_TB.txt";
FILE Ai_OUT: TEXT OPEN WRITE_MODE IS "Ai_OUT_TB.txt";
FILE Br_OUT: TEXT OPEN WRITE_MODE IS "Br_OUT_TB.txt";
FILE Bi_OUT: TEXT OPEN WRITE_MODE IS "Bi_OUT_TB.txt";
BEGIN
BUTTERFLY_TEST_COMPONENT: progetto_butterfly PORT MAP(START => TEST_START, CLK => CLK, MAIN_RST_N => TEST_RST,
DATA_IN => TEST_DATA_IN, Wr_IN => TEST_Wr_IN, Wi_IN => TEST_Wi_IN,
DATA_OUT => TEST_OUTPUT, DONE => TEST_DONE);``
DATA_IN_PROCESS: PROCESS
VARIABLE DATA_BUFFER: LINE;
VARIABLE DATA_STIMULUS: BIT_VECTOR(N_IN-1 DOWNTO 0);
BEGIN
IF NOT (ENDFILE(Br_IN_FILE)) THEN
IF(TEST_START = '1' AND TEST_RST = '1') THEN
READLINE(Br_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT UNTIL CLK'EVENT AND CLK = '1';
READLINE(Bi_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT UNTIL RISING_EDGE(CLK);
READLINE(Ar_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT UNTIL RISING_EDGE(CLK);
READLINE(Ai_IN_FILE,DATA_BUFFER);
READ(DATA_BUFFER,DATA_STIMULUS);
TEST_DATA_IN <= SIGNED(TO_STDLOGICVECTOR(DATA_STIMULUS));
WAIT FOR 12 ns;
ELSE
TEST_DATA_IN <= (OTHERS => '0');
END IF;
END IF;
END PROCESS;
WR_PROCESS: PROCESS
VARIABLE wr_buf: LINE;
VARIABLE WR_STIMULUS: BIT_VECTOR(N_IN-1 DOWNTO 0);
BEGIN
WHILE NOT (ENDFILE(WR_FILE)) LOOP
IF(TEST_START = '1' AND TEST_RST = '1') THEN
READLINE(WR_FILE,wr_buf);
READ(wr_buf,WR_STIMULUS);
TEST_Wr_IN <= SIGNED(TO_STDLOGICVECTOR(WR_STIMULUS));
WAIT FOR 20 ns;
END IF;
END LOOP;
END PROCESS;
WRITING_PROCESS: PROCESS
VARIABLE STRING_LINE: STRING(N_OUT DOWNTO 1);
VARIABLE OUT_LINE: LINE;
VARIABLE I: INTEGER;
BEGIN
WAIT FOR 12 ns;
WHILE (TEST_START = '1' AND TEST_RST = '1') LOOP
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Br_OUT,OUT_LINE);
WAIT UNTIL RISING_EDGE(CLK);
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Bi_OUT,OUT_LINE);
WAIT UNTIL RISING_EDGE(CLK);
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Ar_OUT,OUT_LINE);
WAIT UNTIL RISING_EDGE(CLK);
FOR I IN N_OUT-1 DOWNTO 0 LOOP
IF(TEST_OUTPUT(I) = '0') THEN
STRING_LINE(I+1) := '0';
ELSE
STRING_LINE(I+1) := '1';
END IF;
END LOOP;
WRITE(OUT_LINE,STRING_LINE);
WRITELINE(Ai_OUT,OUT_LINE);
END LOOP;
END PROCESS;
CLK_PROCESS: PROCESS
BEGIN
CLK <= '1';
WAIT FOR 2 ns;
CLK <= '0';
WAIT FOR 2 ns;
END PROCESS;
TEST_RST <= '0', '1' AFTER 2 ns;
TEST_START <= '0', '1' AFTER 3 ns;
END ARCHITECTURE;
Что-то сделано не так? Я не вижу, что мне не хватает.
3 ответа
Ваш DATA_IN_PROCESS
Процесс представляет собой бесконечный цикл. Пока условие TEST_START = '1' AND TEST_RST = '1'
не выполнено, процесс продолжает выполняться без увеличения времени моделирования. Это съедает время симулятора и время симуляции не увеличивается.
Решите это, добавив WAIT UNTIL RISING_EDGE(CLK);
в else
пункт.
Другие проблемы с вашим кодом перечислены здесь: http://www.sigasi.com/vhdl-code-check?ID=27869561
Вашим процессам нужен либо список чувствительности, либо WAIT
заявление.
После сборки MVCe из вашего примера я обнаружил, что кажется, что входной файл, который вы читаете, слишком короткий, что выявляет ошибки в двух ваших процессах (data_in_process и wr_process).
library ieee;
use std.textio.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sometb is
end entity;
architecture foo of sometb is
constant n_in: integer := 8;
signal test_start: std_logic := '1';
signal test_rst: std_logic := '1';
file br_in_file: text open READ_MODE is "Br.txt";
signal test_data_in: signed(n_in - 1 downto 0);
signal clk: std_logic := '0';
file bi_in_file: text open READ_MODE is "Bi.txt";
file ar_in_file: text open READ_MODE is "Ar.txt";
file ai_in_file: text open READ_MODE is "Ai.txt";
file wr_file: text open READ_MODE is "Wr.txt";
signal test_wr_in: signed(n_in - 1 downto 0);
constant n_out: integer:= 8;
signal test_output: std_logic_vector(n_out - 1 downto 0);
file br_out: text open WRITE_MODE is "Br_OUT_TB.txt";
file bi_out: text open WRITE_MODE is "Bi_OUT_TB.txt";
file ar_out: text open WRITE_MODE is "Ar_OUT_TB.txt";
file ai_out: text open WRITE_MODE is "Bi_OUT_TB.txt";
begin
CLOCK:
process
begin
wait for 6 ns;
clk <= not clk;
end process;
data_in_process:
process
variable data_buffer: line;
variable data_stimulus: bit_vector(n_in-1 downto 0);
begin
if not endfile(br_in_file) then
if test_start = '1' and test_rst = '1' then
readline(br_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait until clk'event and clk = '1';
readline(bi_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait until rising_edge(clk);
readline(ar_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait until rising_edge(clk);
readline(ai_in_file,data_buffer);
read(data_buffer,data_stimulus);
test_data_in <= signed(to_stdlogicvector(data_stimulus));
wait for 12 ns;
else
test_data_in <= (others => '0');
end if;
end if;
wait until rising_edge(clk); -- added for endfile
end process;
wr_process:
process
variable wr_buf: line;
variable wr_stimulus: bit_vector(n_in-1 downto 0);
begin
while not endfile(wr_file) loop
if test_start = '1' and test_rst = '1' then
readline(wr_file,wr_buf);
read(wr_buf,wr_stimulus);
test_wr_in <= signed(to_stdlogicvector(wr_stimulus));
wait for 20 ns;
end if;
end loop;
wait for 20 ns; -- added for when endfile(wr_file) is TRUE.
end process;
writing_process:
process
variable string_line: string(n_out downto 1);
variable out_line: line;
-- variable i: integer; -- the following are not my i
begin
wait for 12 ns;
while test_start = '1' and test_rst = '1' loop
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i + 1) := '0';
else
string_line(i + 1) := '1';
end if;
end loop;
write(out_line, string_line);
writeline(br_out, out_line);
wait until rising_edge(clk);
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i + 1) := '0';
else
string_line(i + 1) := '1';
end if;
end loop;
write(out_line,string_line);
writeline(bi_out,out_line);
wait until rising_edge(clk);
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i+1) := '0';
else
string_line(i+1) := '1';
end if;
end loop;
write(out_line,string_line);
writeline(ar_out,out_line);
wait until rising_edge(clk);
for i in test_output'range loop -- n_out-1 downto 0 loop
if test_output(i) = '0' then
string_line(i+1) := '0';
else
string_line(i+1) := '1';
end if;
end loop;
write(out_line,string_line);
writeline(ai_out,out_line);
end loop;
end process;
end architecture;
я добавил
wait until rising_edge(clk); -- added for endfile
до конца процесса в data_in_process, иначе он будет зацикливаться без приостановки, если END_FILE(br_in_file) равен TRUE. (И у вас действительно должен быть тест или тест, который охватывает все ваши входные данные).
я добавил
wait for 20 ns; -- added for when endfile(wr_file) is TRUE.
wr_process по той же причине.
Изменения в writing_process были использованы для определения рабочего диапазона для сигнала test_output. Обратите внимание, что декларативный элемент процесса для переменной i может быть удален, он не используется. (I - это не i в константах цикла).
Я обнаружил проблемы с входными файлами в среде UNIX (OS X), касающейся входных файлов, которые создают их с нулевой длиной (после страховки мой имитатор VHDL будет жаловаться, если они не существуют).