2015-01-09 4 views
1

테스트 벤치 관련 문제가 있습니다. 푸리에 변환을 계산하기위한 하드웨어 버터 플라이 알고리즘을 개발 중입니다.VHDL - "run"을 보낼 때 ModelSim 테스트 벤치가 멈춤

내가 시도하려는 것은 일련의 입력 데이터 파일 (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; 

뭔가 잘못 수행되어

다음은 주요 공정은? 내가 빠진 것을 나는 볼 수 없다.

+0

은 VHDL의 오류 무료 시뮬레이션을 중지 두 가지가 있습니다. 모든 운전자가 예상 한 출력 파형에서 예정된 이벤트를 모두 소비하고 시뮬레이션 시간을 올리거나 지금과 비교해 높입니다 (시간이 좀 걸릴 수 있습니다). Modelsim의 실행 명령은 짧은 시간 동안 실행되도록 실행 시간과 함께 제공 될 수 있습니다. 전체 모델, 특히 선언을 표시하지 않습니다. 그것은 [최소, 완전하고 검증 가능한 예제]가 아닙니다 (http://stackoverflow.com/help/mcve). – user1155120

+0

나머지 코드를 추가했습니다. "now'high"에 관해서는, 당신은 나에게 무엇을 의미하는지 설명 할 수 있습니까? – Jacob

답변

0

DATA_IN_PROCESS 프로세스는 무한 루프입니다. TEST_START = '1' AND TEST_RST = '1' 조건이 충족되지 않는 한 프로세스는 시뮬레이션 된 시간을 증가시키지 않고 계속 실행됩니다. 그것은 시뮬레이터 시간과 simuated를 먹는다 시간은 증가하지 않는다.

else 절에 WAIT UNTIL RISING_EDGE(CLK);을 추가하여이를 해결하십시오.코드와

다른 문제는 다음과 같습니다 : http://www.sigasi.com/vhdl-code-check?ID=27869561

+0

네, 그게 다예요. WHILE 문과 IF 문을 모두 제거했습니다. 이제 실행됩니다! 고마워요! – Jacob

0

프로세스에는 감도 목록 또는 WAIT 문이 필요합니다.

+0

필자는 테스트 벤치에서 sentivity 목록이 필요 없다고 생각했습니다. WAIT 문에 관해서는 무엇을 기다려야합니까? 시계? 그 과정의 어느 시점에? 맨 처음에? – Jacob

+0

감도 목록 및/또는 wait 문이없는 프로세스는 시간이 지나도 내부 문을 반복해서 실행해야합니다. 이것은 귀하의 시뮬레이터가 귀하의 요청에 따라 기본적으로 시도하는 것입니다. – mfro

+0

모든 프로세스에는 'wait' 문이 있습니다. 그러나 그들은 각각의 branch에 'wait'문을 가져야한다. – Philippe

0

예제에서 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; 

난, data_in_process의 처리의 종료 전에
 wait until rising_edge(clk); -- added for endfile 

추가 그렇지 않은 것 END_FILE (br_in_file)이 TRUE 인 경우 현탁없이 루프. (그리고 실제로 모든 테스트를 수행해야합니다.)

나는 같은 이유로 wr_process하는
 wait for 20 ns; -- added for when endfile(wr_file) is TRUE. 

을 추가했다.

writing_process의 변경 사항은 test_output 신호의 작동 범위를 찾는 데 사용되었습니다. 변수 i에 대한 프로세스 선언 항목은 제거 될 수 있으므로 사용되지 않습니다. (나는 루프 상수에 i가 없다).

UNIX 환경 (OS X)에서 길이가 0 인 입력 파일을 터치하여 입력 파일에 문제가 있음을 확인했습니다 (VHDL 시뮬레이터가 존재하지 않는 경우이를 확인한 후).

+0

break 옵션을 선택하면 modelsim에서 시뮬레이션이 WI_PROCESS의 endfile 루프의 끝인 줄 102에서 중단되었음을 보여줍니다. 루프 종료 직후에 WAIT 문 (그냥 WAIT)을 추가했습니다. 입력 파일의 길이에 대해 제안한 것과 상관 관계가 있습니까? 그래도 여전히 이상하게 보입니다. 디버깅을 위해 모든 파일에 입력 데이터 (Ar에 대해 1 줄, Ai에 1 줄 등)를 나타내는 1 줄만 넣었습니다. 그게 어떻게 가능해? – Jacob