2017-10-22 10 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'になります。今すぐ同じクロックで組み合わせブロックが起動され、case文が実行されます。従ってFMuxからX-> 1へ直接になる。その結果方程式 "のFib < =のFib +カウント" 常に利回り 'X' 以来のFibは決してゼロに初期化されなかっました。

をテストベンチからゼロにリセットしないようにしてください。したがって、FSM状態は決して変化しません。

モジュールでは、リセットを順次ブロックで使用します。リセットの取り扱いについて

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

関連する問題