2017-10-22 1 views
1

다음 시퀀스를 생성하는 하드웨어를 설계하려고합니다. F = 첫 번째 N 정수의 합, 즉 1 + 2 ... + N입니다. (예 : N = 3 인 경우 F = 1 + 2 + 3 = 6). 나는 입력 N이 변할 때마다 최신 N 클럭 사이클 후에 F를 생성하는 모듈을 구현 중이다. N은 4 비트 숫자가됩니다 (F는 7 비트 길이 여야 함). 새로운 F가 계산되는 동안 N은 변경되지 않습니다.Verilog에서 최대 N의 정수를 구현하십시오.

module Fib (clock, reset, N, Fib); 

input clock, reset; input [3:0] N; 
output [6:0] Fib; 

reg [6:0] Fib; 
// local vars 
reg [2:0] Nprev; 
reg [2:0] count; 
reg state, next_state; 

// control lines 
reg [1:0] Fmux, Cmux; 

//status line 
wire zero, equal; 

parameter wait4newN=1'b0, 
    wait4Zero=1'b1; 

// Datapath 
[email protected](posedge clock) 
    case(Fmux) 
    2'h0 : Fib <= N; 
    2'h1 : Fib <= Fib + count; 
    endcase 

[email protected](posedge clock) 
case (Cmux) 
    2'h0 : count <= N-1; 
    2'h1 : count <= count - 1; 
    endcase 

assign zero = (count == 0); 
assign equal = (Nprev==N); 

// Controller 
[email protected](posedge clock) 
    Nprev <= N; 

[email protected](posedge clock) 
    if (reset) state <= wait4newN; 
    else 
     state <= next_state; 

[email protected](*) 
    begin 
    Fmux = 0; Cmux = 0; 
    case (state) // synopsys full_case parallel_case 
     wait4newN : 
      if (!equal) 
      begin 
       Fmux = 0; Cmux = 0; 
       next_state=wait4newN; 
      end 
      else 
       begin 
       Fmux = 1; Cmux = 1; 
       next_state=wait4Zero; 
       end 
     wait4Zero : 
      if(!zero) 
       begin 
        Fmux = 1; Cmux = 1; 
        next_state = wait4Zero; 
       end 
      else 
      begin 
       Fmux = 0; Cmux =0; 
       next_state =wait4newN; 
      end 
     default: 
     $display("why am I here?"); 
     endcase 
    end 
endmodule 

내 테스트 픽스처가

// Testbench 
module test; 

reg clk, reset; 
reg [3:0] N; 
reg [6:0] Fib; 

    // Instantiate device under test 
Fib fibInstance(.clock(clk),.reset(reset), .N(N), .Fib(Fib)); 

    initial begin 
    // Dump waves 
    $dumpfile("dump.vcd"); 
    $dumpvars(1, test); 

    clk = 0; 
    reset = 1; 
    N = 5; 
    $display("wait4newN N: %0h, Fib: %0h", 
     N, Fib); 

    toggle_clk; 
    $display("wait4Zero N: %0h, Fib: %0h", 
     N, Fib); 

    toggle_clk; 
    $display("wait4Zero N: %0h, Fib: %0h", 
     N, Fib); 

    toggle_clk; 
    $display("wait4Zero N: %0h, Fib: %0h", 
     N, Fib); 

    toggle_clk; 
    $display("wait4Zero N: %0h, Fib: %0h", 
     N, Fib); 

    toggle_clk; 
    $display("wait4Zero N: %0h, Fib: %0h", 
     N, Fib); 

    toggle_clk; 
    $display("wait4newN N: %0h, Fib: %0h", 
     N, Fib); 
    end 

    task toggle_clk; 
    begin 
     #5 clk = ~clk; 
     #5 clk = ~clk; 
    end 
    endtask 

endmodule 

입니다 시뮬레이션의 결과는 내가 잘못하고있는 중이 야 무엇 F.

[2017-10-21 20:17:23 EDT] iverilog '-Wall' '-g2012' design.sv testbench.sv && unbuffer vvp a.out 
VCD info: dumpfile dump.vcd opened for output. 
wait4newN N: 5, Fib: xx 
wait4Zero N: 5, Fib: xx 
wait4Zero N: 5, Fib: xx 
wait4Zero N: 5, Fib: xx 
wait4Zero N: 5, Fib: xx 
wait4Zero N: 5, Fib: xx 
wait4newN N: 5, Fib: xx 
Done 

에 대한 XX하십시오입니다 : 여기 내 시도는 무엇입니까?

미리 감사드립니다.

+0

한가지는 테스트 벤치에서'reset' 신호를 지우는 것을 잊었 기 때문에 * wat4newN *과 * wait4Zero * 사이를 토글합니다. 또한 리셋 신호 동작으로 인해 * Fmux *와 * clock * 사이에 경쟁이 생겨서 posedge에서 '0'으로 보이게됩니다. – Serge

답변

2

으로 인해 문제가 발생한 것 같습니다. 여기에 일반 무슨 일이 일어나고 있는지에 대한 설명입니다 : 당신 에 변수를 초기화하지 않는, 당신의 FIB 모듈에서

를 재설정합니다. 재설정이 적용되면 상태는 'X'에서 'wait4newN'으로 변경됩니다. 이제 같은 시간에 combinational 블록이 트리거되고 case 문이 실행됩니다. 따라서 FMux에서 X-> 1로 직접이됩니다. 그 결과 방정식 "FIB < = FIB +는 계산"항상 수익률 'X'이후 FIB 결코 제로으로 초기화하지 했다.

이외에도 을 테스트 벤치에서 0으로 재설정하지 않습니다. 그래서 FSM 국가는 결코 바뀌지 않습니다.

Fib 모듈에서는 순차적 블록으로 재설정을 사용하십시오. 리셋 처리에 대한

always @(posedge clk) begin // Assuming synchronous reset 
    if(reset) begin 
    // Reset variables 
    end else begin 
    // other logic 
    end 
end 

자세한 내용은 this siteCummings Reset related Paper에서 확인할 수있다.

+0

완벽합니다. 설명과 링크를 주셔서 대단히 감사합니다! – chikitin

관련 문제