2016-11-07 3 views
0

Sir、Verilogを使用して4ビットcountetrをインクリメントしない

私はVerilogを使用して4ビットアップカウンタを行っています。シミュレーション中は増加していませんでした。カウンタに必要なクロックを供給するために分周回路が使用されています。これを解決するのに役立ちます。コードは次のとおりです

module my_upcount(
    input clk, 
    input clr, 
    output [3:0] y 
    ); 

reg [26:0] temp1; 
wire clk_1; 

always @(posedge clk or posedge clr) 
    begin 
     temp1 <= ((clr) ? 4'b0 : temp1 + 1'b1); 
    end 
assign clk_1 = temp1[26]; 


reg [3:0] temp; 

always @(posedge clk_1 or posedge clr) 
    begin 
     temp <= ((clr) ? 4'b0 : temp + 1'b1); 
    end 
assign y = temp;  
endmodule 
+1

は、あなたが使用しているテストベンチを示してもらえますか? – Qiu

答えて

1

シミュレーションを少なくとも(2^27)/2 + 1回実行しましたか?そうでなければ、あなたのclk_1シグナルは決して1に上がることはなく、あなたのカウンターは増分しません。除数カウンタには4ビットを使用してください。そうすれば、シミュレーションをあまり長く実行する必要はありません。また、除算カウンタが最大値に達すると、clk_1信号がアクティブになり、MSBビットが1ではありません。

それとは別に、あなたのコードと他の問題がいくつかあります:

  • ドライブ単一クロックを持つすべてのレジスタは、 - それは違反として、単一のハードウェアモジュール内の異なるクロックを使用すると、非常に悪い考えです同期設計の原則すべてのレジスタは同じクロック信号で駆動する必要があります。それ以外の場合は、トラブルを探しています。
  • 現在のレジスタ値と次のレジスタ値を分ける - 現在のレジスタ値と次のレジスタ値を分けることをお勧めします。次のレジスタ値は、回路の組み合わせ部分(クロックによって駆動されない)に割り当てられ、次のクロックサイクルの開始時にレジスタに格納されます(例えば以下のチェックコード)。これにより、コードをはっきりと理解しやすくなり、競合状態や不要な推論メモリの確率が最小限に抑えられます。
  • モジュールの先頭にすべての信号を定義します。 - すべての信号は、モジュールの先頭に定義する必要があります。これは、モジュールロジックをできるだけクリーンに保つのに役立ちます。ここで

は私の提案に応じて書き換えます例です:

module my_counter 
(
    input wire clk, clr, 
    output [3:0] y 
); 

    reg [3:0] dvsr_reg, counter_reg; 
    wire [3:0] dvsr_next, counter_next; 
    wire dvsr_tick; 

    always @(posedge clk, posedge clr) 
     if (clr) 
     begin 
      counter_reg <= 4'b0000; 
      dvsr_reg <= 4'b0000; 
     end 
     else 
     begin 
      counter_reg <= counter_next; 
      dvsr_reg <= dvsr_next; 
     end 

    /// Combinational next-state logic 
    assign dvsr_next = dvsr_reg + 4'b0001; 
    assign counter_next = (dvsr_reg == 4'b1111) ? counter_reg + 4'b0001 : counter_reg; 

    /// Set the output signals 
    assign y = counter_reg; 

endmodule 

そしてここでは、その動作を確認するための簡単なテストベンチがあります:

module my_counter_tb; 

    localparam 
     T = 20; 

    reg clk, clr; 
    wire [3:0] y; 

    my_counter uut(.clk(clk), .clr(clr), .y(y)); 

    always 
    begin 

     clk = 1'b1; 
     #(T/2); 
     clk = 1'b0; 
     #(T/2); 

    end 

    initial 
    begin 

     clr = 1'b1; 
     @(negedge clk); 

     clr = 1'b0; 
     repeat(50) @(negedge clk); 

     $stop; 

    end 
endmodule 
+0

ありがとうございます。 – Varun

+1

問題を解決する場合は、回答を受け入れるようにしてください。 – dbajgoric

関連する問題