シミュレーションを少なくとも(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
は、あなたが使用しているテストベンチを示してもらえますか? – Qiu