Verilog 코드는 FPGA에서 예측 된대로 실행되지 않지만 실행되지 않습니다.
문제
코드의 행동 시뮬레이션을 수행했는데 완벽하게 작동합니다. 결과는 예상대로됩니다. 코드를 종합하고 스파르타 3E FPGA에 업로드하고 Chipscope를 사용하여 분석하려고하면 결과가 예상했던 것과 가깝지 않습니다. 내가 무엇을 잘못 했습니까?http://pastebin.com/xwmekl7r
해결책
귀하의 문제는 13-16 행입니다. 여기서 상태 레지스터의 초기 값을 설정합니다.
reg [OUTPUT_WIDTH-1:0] previousstate = 0;
reg [OUTPUT_WIDTH-1:0] presentstate = 1;
reg [6:0] fib_number_cnt = 1;
reg [OUTPUT_WIDTH-1:0] nextstate = 1;
이것은 합성 할 수없는 이러한 값을 할당하는 "초기"명령문을 작성하는 것과 같습니다. 하드웨어의 기본값은 없습니다. 디자인을 FPGA 내부에 넣으면 이러한 레지스터는 모두 임의의 값을 취합니다.
대신, 재설정이 높을 때 항상 블록 내부 에이 카운터/상태를 초기화해야합니다.
always @(posedge clk or posedge reset)
if (reset) begin
previousstate <= 0;
presentstate <= 1;
... etc ...
end
후속 질문에 대한 답변 :
이와 같은 코드를 초기화하면 하드웨어에서 전혀 아무런 일이 발생하지 않습니다. 마치 $ 디스플레이 명령문을 넣은 것처럼 완전히 무시됩니다. 합성 도구는 모든 시뮬레이션 전용 구성을 건너 뜁니다. 일반적으로 이에 대한 경고를 제공합니다 (실제로 도구에 따라 다름).
이제 블로킹 및 비 블로킹 질문에는 매우 긴 답변이 필요합니다 :) SNUG-2000 에서이 논문으로 안내 할 것입니다. 그것은 당신의 질문뿐만 아니라 주제에 대한 많은 다른 질문에 대답합니다. 그 후, 순차적 논리에서 차단 문을 사용하는 것이 나쁜 관행으로 간주되는 이유와 어쨌든 차단 문에서 코드가 잘 작동하는 이유를 이해할 것입니다.
http://cs.haifa.ac.il/courses/verilog/cummings-nonblocking-snug99.pdf
더 많은 답변 :
당신과 같은 논리를 만드는 일반적인 "패턴"은 항상 두 개의 블록, 하나는 논리를 정의하고 플롭을 정의하는 것입니다. 전자에서는 차단 문을 사용하여 논리를 구현하고 후자에서 생성 된 값을 래치 (또는 재설정)합니다. 그래서 다음과 같은 것 :
wire some_input;
// Main logic (use blocking statements)
reg state, next_state;
always @*
if (reset) next_state = 1'b0;
else begin
// your state logic
if (state) next_state = some_input;
else next_state = 1'b0;
end
// Flops (use non-blocking)
always @(posedge clock)
if (reset) state <= 1'b0;
else state <= next_state;
동기 재설정을 사용하고 있지만 필요한 경우 비동기를 사용할 수 있습니다.
다른 팁
13-16 행이 정확합니다. "Reg [6 : 0] fib_number_cnt = 1;" "초기"명령문을 사용하는 것과 동일하지 않습니다. 레지스터를 초기화하는 방법에 대한 자세한 설명은 Xilinx Synthesis Guide를 읽으십시오.