[英]Faulty outputs for JK flip flop state diagram implementation
I am trying to implement a simple FSM of JK flip flop in verilog. 我正在尝试在verilog中实现JK触发器的简单FSM。 However I see that the outputs 'q' and 'q_not' are wrong for multiple time instants. 但是,我看到输出“ q”和“ q_not”在多个时间点都是错误的。 I am presenting the code and the output below. 我在下面介绍代码和输出。 Could some one please let me know what's wrong with the code. 可以让我知道代码有什么问题吗? Especially I would like to know what's wrong with this implementation even though there are other ways to implement JK flip flops. 尤其是我想知道这种实现有什么问题,即使还有其他方法可以实现JK触发器。
modules of JK flip flop and testbench JK触发器和测试台模块
`timescale 1ns/100ps
module jk_ff(j, k, clk, reset, q, q_not);
input j, k, clk, reset;
output reg q, q_not;
reg present_state, next_state;
parameter state_a = 1'b0;
parameter state_b = 1'b1;
always @ (present_state or j or k)
begin:comb_logic
next_state = state_a;
//next_state = 0;
case(present_state)
state_a: begin
if (j == 1'b0 && k == 1'b0) begin
next_state = state_a;
end
else if (j == 1'b0 && k == 1'b1) begin
next_state = state_a;
end
else if (j == 1'b1 && k == 1'b0) begin
next_state = state_b;
end
else if (j == 1'b1 && k == 1'b1) begin
next_state = state_b;
end
end
state_b: begin
if (j == 1'b0 && k == 1'b0) begin
next_state = state_b;
end
else if (j == 1'b0 && k == 1'b1) begin
next_state = state_a;
end
else if (j == 1'b1 && k == 1'b0) begin
next_state = state_b;
end
else if (j == 1'b1 && k == 1'b1) begin
next_state = state_a;
end
end
default: next_state = state_a;
endcase
end
always @ (posedge clk or reset)
begin: seq_logic
if (reset) begin
q <= 1'b0;
q_not <= 1'b1;
present_state <= state_a;
end
else begin
present_state <= next_state;
case(present_state)
state_a: begin
q <= 1'b0;
q_not <= 1'b1;
end
state_b: begin
q <= 1'b1;
q_not <= 1'b0;
end
default: present_state <= state_a;
endcase
end
end
endmodule
//testbench
module jk_ff_tb;
reg j, k, clk, reset;
wire q, q_not;
jk_ff DUT(.j(j), .k(k), .clk(clk), .reset(reset), .q(q), .q_not(q_not));
initial begin
clk =0;
forever #5 clk = !clk;
end
initial begin
$monitor("j = %b, k = %b, q = %b, q_not = %b", j, k, q, q_not);
$dumpfile("jk_ff_wave.vcd");
$dumpvars;
reset = 1;
j=1'b0;
k=1'b1;
#10 reset = 0;
#15 j=1'b1;
#15 k=1'b0;
#15 j=1'b0;
#15 k=1'b1;
#15 j=1'b1;
#15 k=1'b1;
#10 $finish;
end
endmodule
output of the test bench simulation showing values of inputs and primary outputs 测试台模拟的输出,显示输入和主要输出的值
j = 0, k = 1, reset = 1, q = 0, q_not = 1 j = 0, k = 1, reset = 0, q = 0, q_not = 1 j = 1, k = 1, reset = 0, q = 0, q_not = 1 j = 1, k = 1, reset = 0, q = 1, q_not = 0 j = 1, k = 0, reset = 0, q = 1, q_not = 0 j = 1, k = 0, reset = 0, q = 0, q_not = 1 j = 0, k = 0, reset = 0, q = 1, q_not = 0 j = 0, k = 1, reset = 0, q = 1, q_not = 0 j = 1, k = 1, reset = 0, q = 0, q_not = 1 j = 1, k = 1, reset = 0, q = 1, q_not = 0 j = 1, k = 1, reset = 0, q = 0, q_not = 1
enter code here
Thank you! 谢谢!
You've got all sorts of problems here: 您这里遇到各种各样的问题:
seq_logic
, you assign present_state
with a blocking assignment, and the next statement is case(present_state)
. 在seq_logic
,分配present_state
与阻塞分配和下面的语句是case(present_state)
This tests the old value of present_state
, which isn't what you want 这测试了present_state
的旧值,这不是您想要的 present_state
, but your seq_logic
process changes present_state
on rising clock edges. 你“comb_logic”的过程是敏感present_state
,但你的seq_logic
过程改变present_state
在时钟的上升沿。 At first sight, that seems the right thing to do, but it's not - draw it out. 乍一看,这似乎是正确的做法,但事实并非如此-将其绘制出来。 The way you've written this, comb_logic
should be sensitive to only J
and K
您编写此comb_logic
的方式, comb_logic
应该仅对J
和K
敏感 Those two are enough to get the right result, but this is far too complicated for a JK - start again, put everything in one clocked process, dump the next logic process, just use the behaviour of a JK - load, set, or toggle. 这两个足以获得正确的结果,但这对于JK来说太复杂了-重新启动,将所有内容放入一个时钟进程中,转储下一个逻辑进程,仅使用JK的行为-加载,设置或切换。 You should also add the current time to your $monitor
. 您还应该将当前时间添加到$monitor
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.