建模 JK FF 时输出错误:输出为 x
Wrong output while modelling JK FF: output is x
我正在使用 Verilog 对 JK 触发器建模。在所有情况下,我得到的输出 q
为 x
。我对各种 jk 组合使用 case
语句。我几乎没有发现代码有任何问题。
设计
module jk_ff ( input j, input k, input clk, output q);
reg q;
always @ (posedge clk)
case ({j,k})
2'b00 : q <= q;
2'b01 : q <= 1'b0;
2'b10 : q <= 1'b1;
2'b11 : q <= ~q;
endcase
endmodule
测试台
module tb_jk;
reg j;
reg k;
reg clk;
always #5 clk = ~clk;
jk_ff jk0 ( .j(j),
.k(k),
.clk(clk),
.q(q));
initial begin
$dumpfile("test.vcd");
$dumpvars;
j <= 0;
k <= 0;
#5 j <= 0;
k <= 1;
#20 j <= 1;
k <= 0;
#20 j <= 1;
k <= 1;
#20 $finish;
end
initial
$monitor ("j=%0d k=%0d q=%0d", j, k, q);
endmodule
日志
vu2swz@PPDP01:~$ iverilog jk_ff.v
vu2swz@PPDP01:~$ ./a.out
VCD info: dumpfile test.vcd opened for output.
j=0 k=0 q=x
j=0 k=1 q=x
j=1 k=0 q=x
j=1 k=1 q=x
输出仅显示 x
而不是 0 1 和 Q。
当我 运行 你的模拟和观察波形时,我发现 clk
总是未知的 (x
)。您将 clk
声明为 reg
,这意味着它默认为 x
。您的赋值 (clk = ~clk
) 不会更改 clk
的值,因为 ~clk
的计算结果为 ~x
,它仍然是 x
.
您需要将 clk
初始化为测试平台中的已知值。例如,更改:
reg clk;
至:
reg clk = 0;
这表明:
j=0 k=0 q=x
j=0 k=1 q=x
j=0 k=1 q=0
j=1 k=0 q=0
j=1 k=0 q=1
j=1 k=1 q=1
j=1 k=1 q=0
有两种方法可以调试这个问题。正如我提到的,一种方法是查看波形;您已经创建了 VCD 文件。这是最有效的方法。 iverilog
网站称 GTKWave“是 Icarus Verilog 的首选波形查看器”。
另一种方法是将 clk
信号添加到您的 $monitor
语句中:
$monitor ("j=%0d k=%0d q=%0d clk=%b", j, k, q, clk);
那么你会看到:
j=0 k=0 q=x clk=x
j=0 k=1 q=x clk=x
j=1 k=0 q=x clk=x
j=1 k=1 q=x clk=x
我正在使用 Verilog 对 JK 触发器建模。在所有情况下,我得到的输出 q
为 x
。我对各种 jk 组合使用 case
语句。我几乎没有发现代码有任何问题。
设计
module jk_ff ( input j, input k, input clk, output q);
reg q;
always @ (posedge clk)
case ({j,k})
2'b00 : q <= q;
2'b01 : q <= 1'b0;
2'b10 : q <= 1'b1;
2'b11 : q <= ~q;
endcase
endmodule
测试台
module tb_jk;
reg j;
reg k;
reg clk;
always #5 clk = ~clk;
jk_ff jk0 ( .j(j),
.k(k),
.clk(clk),
.q(q));
initial begin
$dumpfile("test.vcd");
$dumpvars;
j <= 0;
k <= 0;
#5 j <= 0;
k <= 1;
#20 j <= 1;
k <= 0;
#20 j <= 1;
k <= 1;
#20 $finish;
end
initial
$monitor ("j=%0d k=%0d q=%0d", j, k, q);
endmodule
日志
vu2swz@PPDP01:~$ iverilog jk_ff.v
vu2swz@PPDP01:~$ ./a.out
VCD info: dumpfile test.vcd opened for output.
j=0 k=0 q=x
j=0 k=1 q=x
j=1 k=0 q=x
j=1 k=1 q=x
输出仅显示 x
而不是 0 1 和 Q。
当我 运行 你的模拟和观察波形时,我发现 clk
总是未知的 (x
)。您将 clk
声明为 reg
,这意味着它默认为 x
。您的赋值 (clk = ~clk
) 不会更改 clk
的值,因为 ~clk
的计算结果为 ~x
,它仍然是 x
.
您需要将 clk
初始化为测试平台中的已知值。例如,更改:
reg clk;
至:
reg clk = 0;
这表明:
j=0 k=0 q=x
j=0 k=1 q=x
j=0 k=1 q=0
j=1 k=0 q=0
j=1 k=0 q=1
j=1 k=1 q=1
j=1 k=1 q=0
有两种方法可以调试这个问题。正如我提到的,一种方法是查看波形;您已经创建了 VCD 文件。这是最有效的方法。 iverilog
网站称 GTKWave“是 Icarus Verilog 的首选波形查看器”。
另一种方法是将 clk
信号添加到您的 $monitor
语句中:
$monitor ("j=%0d k=%0d q=%0d clk=%b", j, k, q, clk);
那么你会看到:
j=0 k=0 q=x clk=x
j=0 k=1 q=x clk=x
j=1 k=0 q=x clk=x
j=1 k=1 q=x clk=x