2016-10-03 6 views
0

DE0 Nano Altera FPGA 보드에 간단한 bruteforce 컨볼 루션 프로세서를 설정하려고합니다. 충동 (impulse_length-1-I)의 인덱스 루프의 연속 동안 감소하지 않지만, audio_buffer (I)의 인덱스는 않습니다 : 내 문제가VHDL : for 루프에서 인덱스 연산이 작동하지 않습니다.

LIBRARY ieee; 
USE ieee.std_logic_1164.all; 
use ieee.numeric_bit.all; 

ENTITY Convolution IS 
    PORT( clock : IN std_logic; 
      audio_in : IN unsigned(15 downto 0); 
      audio_out : OUT unsigned(31 downto 0));  
END Convolution; 

ARCHITECTURE Convolution_Core OF Convolution IS 

    constant impulse_length : integer := 10; 

    type array16 is array(0 to impulse_length-1) of unsigned(15 downto 0); 
    type array32 is array(0 to impulse_length-1) of unsigned(31 downto 0); 

    constant impulse : array16 := (x"FFFF", x"FFFE", x"FFFD", x"FFFC", 
               x"FFFB", x"FFFA", x"FFF9", x"FFF8", 
               x"FFF7", x"FFF6"); 

    signal audio_buffer : array16 := (others=> (others=>'0')); 

    signal seq_buffer : unsigned(31 downto 0); 

BEGIN 
    process(clock) 
    begin 
     if rising_edge(clock) then 
      -- buffer the audio input in audio_buffer 
      for i in 0 to (impulse_length-2) loop 
       audio_buffer(i) <= audio_buffer(i+1); 
      end loop; 
      audio_buffer(impulse_length-1) <= audio_in; 

      for i in 0 to (impulse_length-1) loop 
       if i = 0 then 
        seq_buffer <= audio_buffer(i) * impulse(impulse_length-1-i); 
       else 
        seq_buffer <= seq_buffer + audio_buffer(i) * impulse(impulse_length-1-i); 
       end if; 
      end loop; 
     end if; 
    end process; 

    audio_out <= seq_buffer; 

END Convolution_Core; 

: 여기처럼 내 코드가 어떻게 표시되는지를 보여줍니다. 그게 내가 코드를 시뮬레이션하고 내 결과가 왜 틀린 지 알아내는 것을 좋아합니다.

ModelSim에서 볼 수있는 신호에 (impulse_length-1-i) 넣으려고했는데 최대/최소 32 비트 부호있는 범위 (+/- 2 147 483 647)에서 시작하고 다음 사이클이 0으로 점프하고 0으로 유지됩니다.

또한 프로세스 초기에 0에서 시작하여 i 대신 배열에 대한 인덱스로 사용할 수 있도록 변수 j를 프로세스 내부에서 사용하려고 시도했습니다. 하지만 그로 인해 ModelSim이 치명적인 오류를보고하게 만들었지 만 그 이유는 알 수 없습니다.

누군가 내가 잘못한 것을 설명 할 수 있습니까?

고지.

+0

도 참조 http://stackoverflow.com/questions/13954193/is-process-in-vhdl-reentrant/13956532#13956532 –

답변

2

주요 문제는 소프트웨어를 작성하는 대신 하드웨어를 설명 할 때 신호 및 for 루프가 작동하는 방식을 이해하지 못하는 것입니다.

두 번째 for 루프를 반복 할 때마다 동일한 신호에 값이 할당됩니다. 프로세스 내에서 명명 된 신호에 대한 마지막 신호 할당 만 중요하며 신호의 모든 읽기는 프로세스 시작 전에 보유한 값을 사용합니다. 즉, 두 번째 for 루프의 반복은 (impulse_length-1)뿐입니다.

나는 신호 변수이 당신에게 좀 더 세부 사항을 제공 할 수 있습니다 이는 VHDL 프로세스 내에서 작동하는 방법에 대해 몇 년 전에 대답을 썼다 : https://stackoverflow.com/a/19234859/1360002

당신이 이러한 모든 10 추가/곱셈 연산 것을 작성하는 경우 동일한 사이클에서 (예 : seq_buffer 신호에 할당 한 값을 계산하기 위해 seq_buffer 대신 변수를 사용하는 경우), 로직 경로가 매우 길어서 클록 속도가 적당히 높습니다. 이것은 귀하의 경우에 문제가되지 않을 수도 있습니다.

또한 곱셈 연산자에서 나오는 결과 너비에 문제가있을 수 있지만, 곱셈 단위를 의미하지는 않으므로 확신 할 수 없으므로 관련 연산자 함수의 세부 사항에 익숙하지 않습니다.

0

고맙습니다.

그래서 올바르게 이해하면 프로세스 내에서 변수가있는 for 루프를 사용하면 "생성"문을 사용하는 것과 같은 종류의 로직 구현이 가능합니다. 어쩌면 그 이유는 내가 컴파일 할 때 비슷한 걸 시도했을 때 컴파일 할 나이가 걸렸습니다.)

Java 또는 C에서 for 루프와 비슷한 작업을 수행하는 유일한 방법은 "수동으로"각 반복을 클록하는 것입니다. 입력 신호를 전환하고 성공적인 결과를 버퍼링하십시오.

그러나 그렇다면 왜 내가 쓴 "오디오 버퍼링"프로세스가 타이밍 시뮬레이션과 함께 올바르게 작동하는지 이해할 수 없다고해야합니다 ...

안부

+0

루프가있을 때 때문에 루프의 "오디오 버퍼링이"작동 언 롤링 될 때마다 각 반복은 신호의 다른 인덱스에 값을 지정합니다. 이는 모두 충돌없이 병렬로 작동 할 수 있음을 의미합니다. For 루프는 실제로 신호에서 순차적으로 작동하지 않습니다. Generate 문은 루프처럼 작동하지만 최종 할당 문제 만 수행하는 대신 구현 중에 여러 드라이버 오류가 발생합니다. – QuantumRipple

+0

진정한 순차 논리를 수행하는 유일한 방법은 입력 블록을 mux 입력하는 일종의 상태 머신을 사용하는 것이지만 10 개의 값 모두를 조합하여 모든 사이클마다 새로운 출력을 얻으려면, 변수를 사용하여 수학을 10 배 곱하거나 파이프 라인하여 긴 타이밍 경로를 작성해야합니다 (이는 자원을 저장하지 않지만 논리 경로가 더 짧아집니다). – QuantumRipple

+0

컴파일 시간은 일반적으로 디자인의 타이밍 효율성 또는 자원 효율성이 의미있는 것은 아닙니다. 이것은 얼마나 많은 리소스가 전체적으로 사용되는지와 타겟 FPGA에 얼마나 많은 리소스가 사용되는지와 상관되지만 구현하려고하는 기능에 실제로 필요한 수 (효율성)와 비교할 때 얼마나 많은 리소스가 사용되는 것과 관련이 있습니다. – QuantumRipple