我的 JK 触发器的模拟输出没有任何变化
the simulation output of my JK Flip-Flop just get nothing changed
以下是带预置和清零的jk触发器
编译后没有问题。但是经过仿真,我发现我的输出(QA,QB,QC,QD)一直都是0,没有变化。
我的案例陈述有什么问题吗?
还是我用错了 negedge?
module one(inputA, inputB, R01, R02, R91, R92, QA, QB, QC, QD);
input inputA, inputB, R01, R02, R91, R92;
output QA, QB, QC, QD;
reg qa = 1'b0, qb = 1'b0, qc = 1'b0, qd = 1'b0;
reg r0, r9, pre1, clr1, clr2, clr3, pre4, clr4, j2, j4, k4;
//your code~~
initial begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
end
always @(negedge inputA) begin
pre1 = r0;
clr1 = r9;
case({pre1, clr1})
2'b01 : qa = 1'b1;
2'b10 : qa = 1'b0;
2'b11 : qa = ~qa;//toggle is the original result of jk
endcase//jk1
end
always @(negedge inputB) begin
j2 = ~qd;
clr2 = ~(r0 | r9);
if (j2 == 0 && clr2 == 0) qb = 0;//clr=0 means must clear it
if (j2 == 1 && clr2 == 0) qb = 0;//clr=0 means must clear it
if (j2 == 1 && clr2 == 1) qb = ~qb;//toggle
//jk2
end
always @(negedge qb) begin
qc = ~qc;
clr3 = ~(r0 | r9);
if (clr3 == 0) qc = 0;//clr=0 means must clear it
else qc = ~qc;
//jk3
end
always @(negedge inputB) begin
j4 = qb & qc;
case({j4, k4, pre4, clr4})
4'b0011 : qd = qd; //HOLD
4'b0001 : qd = 1'b1; //PRESET
4'b0010 : qd = 1'b0; //CLEAR
4'b1011 : qd = 1'b1; //SET
4'b1001 : qd = 1'b1; //PRESET
4'b1010 : qd = 1'b0; //CLEAR
4'b0111 : qd = 1'b0; //RESET
4'b0101 : qd = 1'b1; //PRESET
4'b0110 : qd = 1'b0; //CLEAR
4'b1111 : qd = ~qd; //TOGGLE
4'b1101 : qd = 1'b1; //PRESET
4'b1110 : qd = 1'b0; //CLEAR
endcase
//jk4
end
begin
assign QA = qa;
assign QB = qb;
assign QC = qc;
assign QD = qd;
end
endmodule
下面是测试平台
module one_tb;
reg clk, r0, r9;
wire [3:0] Q;
one test (.inputA(clk), .inputB(Q[0]), .R01(r0), .R02(r0), .R91(r9), .R92(r9), .QA(Q[0]), .QB(Q[1]), .QC(Q[2]), .QD(Q[3]));
always
#5 clk=~clk;
initial
begin
clk=1'b0;
//0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,0,1,2,3,9,0,1,2,3,4,5,6,7,8
r0 = 1'b1; r9 = 1'b0; #3 ;r0 = 1'b0; r9 = 1'b0; #157;
r0 = 1'b1; r9 = 1'b0; #3 ;r0 = 1'b0; r9 = 1'b0; #37;
r0 = 1'b0; r9 = 1'b1; #3; r0 = 1'b0; r9 = 1'b0; #97;
$stop;
end
endmodule
r0
和 r9
在模拟中总是未知的 (X
),因为您只在时间 0 为它们赋值一次。
你可能打算在每次 "R" 信号改变时改变它们。
变化:
initial begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
end
至:
always @* begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
end
这样做可以解析 X 并允许 QA
输出切换。
现在我知道为什么我的 QB、QC、QD 仍然是 0。
preset和clear的功能是依赖于r0,r9,而不是我输入的inputA,inputB。
在我将代码更改为以下内容后,结果看起来不错:
module one(inputA, inputB, R01, R02, R91, R92, QA, QB, QC, QD);
input inputA, inputB, R01, R02, R91, R92;
output QA, QB, QC, QD;
reg qa = 1'b0, qb = 1'b0, qc = 1'b0, qd = 1'b0;
reg r0, r9, pre1, clr1, clr2, clr3, j2, j4, k4;
always@(*) begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
clr2 = r0 | r9;
clr3 = r0 | r9;
end
always @(negedge inputA) begin
qa = ~qa;
//jk1
end
always @(negedge inputB) begin
j2 = ~qd;
if (j2 == 0 ) qb = 0;
if (j2 == 1 ) qb = ~qb;
//jk2
end
always @(negedge qb) begin
qc = ~qc;
//jk3
end
always @(negedge inputB) begin
j4 = qb & qc;
k4 = qd;
case({j4, k4})
2'b01 : qd = 1'b0;//reset
2'b10 : qd = 1'b1;//set
2'b00 : qd = qd;//hold
2'b11 : qd = ~qd;//toggle
endcase
//jk4
end
always @(negedge r9)begin
qa = 1'b1;
//preset of jk1
end
always @(negedge r0)begin
qa = 1'b0;
//clear of jk1
end
always @(negedge clr2)begin
qa = 1'b0;
//clear of jk2
end
always @(negedge clr3)begin
qa = 1'b0;
//clear of jk3
end
always @(negedge r9)begin
qa = 1'b1;
//preset of jk4
end
always @(negedge r0)begin
qa = 1'b0;
//clear of jk4
end
begin
assign QA = qa;
assign QB = qb;
assign QC = qc;
assign QD = qd;
end
endmodule
我将 JK-FF 更改为模块实例化,现在它可以正常工作了:
module jk_ff_example (/*AUTOARG*/
// Outputs
QA, QB, QC, QD,
// Inputs
inputA, inputB, R01, R02, R91, R92
);
//..ports
input inputA, inputB, R01, R02, R91, R92;
output QA, QB, QC, QD;
//..regs and wires declaration
wire qa, qna, qb, qnb, qc, qnc, qd, qnd;
wire r0, r9;
//..r0 and r9 inputs comb logic
assign r0 = ~(R01 & R02);
assign r9 = ~(R91 & R92);
//..qa jk-ff logic
jk_ff qa_ff (
.preset_i (r9),
.clear_i (r0),
.clk_i (inputA),
.j_i (1'b1),
.k_i (1'b1),
.q_o (qa),
.qn_o (qna)
);
//..qb jk-ff logic
jk_ff qb_ff (
.preset_i (1'b1),
.clear_i (r0 | r9),
.clk_i (inputB),
.j_i (qnd),
.k_i (1'b1),
.q_o (qb),
.qn_o (qnb)
);
//..qc jk-ff logic
jk_ff qc_ff (
.preset_i (1'b1),
.clear_i (r0 | r9),
.clk_i (qb),
.j_i (1'b1),
.k_i (1'b1),
.q_o (qc),
.qn_o (qnc)
);
//..qd jk-ff logic
jk_ff qd_ff (
.preset_i (r9),
.clear_i (r0),
.clk_i (inputB),
.j_i (qb & qc),
.k_i (qd),
.q_o (qd),
.qn_o (qnd)
);
assign QA = qa;
assign QB = qb;
assign QC = qc;
assign QD = qd;
endmodule // jk_ff_example
这是带有预设和清除低电平有效输入的 JK-FF 代码:
/*
* JK-Flip Flop with Preset and Clear inputs Truth Table
* Preset, Clear and CLK with active-low logic
*
* -------------------------------------------------------------
* | Preset | Clear | CLK | J | K | Output | Qo | ~Qo |
* -------------------------------------------------------------
* | 0 | 0 | x | x | x | Invalid | 1* | 0* |
* | 0 | 1 | x | x | x | Preset | 1 | 0 |
* | 1 | 0 | x | x | x | Clear | 0 | 1 |
* | 1 | 1 | x | x | x | No change | Qo | ~Qo |
* | 1 | 1 | NEG | 0 | 0 | No change | Qo | ~Qo |
* | 1 | 1 | NEG | 0 | 1 | Reset | 0 | 1 |
* | 1 | 1 | NEG | 1 | 0 | Set | 1 | 0 |
* | 1 | 1 | NEG | 1 | 1 | Toggle | ~Qo | Qo |
* -------------------------------------------------------------
*/
module jk_ff (/*AUTOARG*/
// Outputs
q_o, qn_o,
// Inputs
preset_i, clear_i, clk_i, j_i, k_i
);
//..ports
input preset_i, clear_i, clk_i, j_i, k_i;
output q_o, qn_o;
//..regs and wires
reg q = 0;
//..jk ff w/ preset and clear logic
always @ (negedge preset_i, negedge clear_i, negedge clk_i) begin
case({preset_i, clear_i})
2'b00: q <= 0; //..invalid
2'b01: q <= 1; //..preset
2'b10: q <= 0; //..clear
2'b11: begin
if(clk_i) //..no change
q <= q;
else begin
case({j_i, k_i})
2'b00: q <= q; //..no change
2'b01: q <= 0; //..reset
2'b10: q <= 1; //..set
2'b11: q <= ~q; //..toggle
endcase
end
end
endcase
end
//..output assignment
assign q_o = q;
assign qn_o = ~q;
endmodule // jk_ff
模拟的输出是这样的:
[Cycle: 0] [Q value: 0]
[Cycle: 10] [Q value: 1]
[Cycle: 20] [Q value: 2]
[Cycle: 30] [Q value: 3]
[Cycle: 40] [Q value: 4]
[Cycle: 50] [Q value: 5]
[Cycle: 60] [Q value: 6]
[Cycle: 70] [Q value: 7]
[Cycle: 80] [Q value: 8]
[Cycle: 90] [Q value: 9]
[Cycle: 100] [Q value: 0]
[Cycle: 110] [Q value: 1]
[Cycle: 120] [Q value: 2]
[Cycle: 130] [Q value: 3]
[Cycle: 140] [Q value: 4]
[Cycle: 150] [Q value: 5]
[Cycle: 160] [Q value: 6]
[Cycle: 170] [Q value: 7]
[Cycle: 180] [Q value: 8]
[Cycle: 190] [Q value: 9]
[Cycle: 200] [Q value: 9]
[Cycle: 210] [Q value: 0]
[Cycle: 220] [Q value: 1]
[Cycle: 230] [Q value: 2]
[Cycle: 240] [Q value: 3]
[Cycle: 250] [Q value: 4]
[Cycle: 260] [Q value: 5]
[Cycle: 270] [Q value: 6]
[Cycle: 280] [Q value: 7]
[Cycle: 290] [Q value: 8]
End simulation
[Cycle: 300] [Q value: 9]
我在这个repository中上传了这个作为示例,我已经包含了一个Makefile以便于模拟和FPGA综合,请随意使用它。
以下是带预置和清零的jk触发器 编译后没有问题。但是经过仿真,我发现我的输出(QA,QB,QC,QD)一直都是0,没有变化。
我的案例陈述有什么问题吗? 还是我用错了 negedge?
module one(inputA, inputB, R01, R02, R91, R92, QA, QB, QC, QD);
input inputA, inputB, R01, R02, R91, R92;
output QA, QB, QC, QD;
reg qa = 1'b0, qb = 1'b0, qc = 1'b0, qd = 1'b0;
reg r0, r9, pre1, clr1, clr2, clr3, pre4, clr4, j2, j4, k4;
//your code~~
initial begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
end
always @(negedge inputA) begin
pre1 = r0;
clr1 = r9;
case({pre1, clr1})
2'b01 : qa = 1'b1;
2'b10 : qa = 1'b0;
2'b11 : qa = ~qa;//toggle is the original result of jk
endcase//jk1
end
always @(negedge inputB) begin
j2 = ~qd;
clr2 = ~(r0 | r9);
if (j2 == 0 && clr2 == 0) qb = 0;//clr=0 means must clear it
if (j2 == 1 && clr2 == 0) qb = 0;//clr=0 means must clear it
if (j2 == 1 && clr2 == 1) qb = ~qb;//toggle
//jk2
end
always @(negedge qb) begin
qc = ~qc;
clr3 = ~(r0 | r9);
if (clr3 == 0) qc = 0;//clr=0 means must clear it
else qc = ~qc;
//jk3
end
always @(negedge inputB) begin
j4 = qb & qc;
case({j4, k4, pre4, clr4})
4'b0011 : qd = qd; //HOLD
4'b0001 : qd = 1'b1; //PRESET
4'b0010 : qd = 1'b0; //CLEAR
4'b1011 : qd = 1'b1; //SET
4'b1001 : qd = 1'b1; //PRESET
4'b1010 : qd = 1'b0; //CLEAR
4'b0111 : qd = 1'b0; //RESET
4'b0101 : qd = 1'b1; //PRESET
4'b0110 : qd = 1'b0; //CLEAR
4'b1111 : qd = ~qd; //TOGGLE
4'b1101 : qd = 1'b1; //PRESET
4'b1110 : qd = 1'b0; //CLEAR
endcase
//jk4
end
begin
assign QA = qa;
assign QB = qb;
assign QC = qc;
assign QD = qd;
end
endmodule
下面是测试平台
module one_tb;
reg clk, r0, r9;
wire [3:0] Q;
one test (.inputA(clk), .inputB(Q[0]), .R01(r0), .R02(r0), .R91(r9), .R92(r9), .QA(Q[0]), .QB(Q[1]), .QC(Q[2]), .QD(Q[3]));
always
#5 clk=~clk;
initial
begin
clk=1'b0;
//0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,0,1,2,3,9,0,1,2,3,4,5,6,7,8
r0 = 1'b1; r9 = 1'b0; #3 ;r0 = 1'b0; r9 = 1'b0; #157;
r0 = 1'b1; r9 = 1'b0; #3 ;r0 = 1'b0; r9 = 1'b0; #37;
r0 = 1'b0; r9 = 1'b1; #3; r0 = 1'b0; r9 = 1'b0; #97;
$stop;
end
endmodule
r0
和 r9
在模拟中总是未知的 (X
),因为您只在时间 0 为它们赋值一次。
你可能打算在每次 "R" 信号改变时改变它们。
变化:
initial begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
end
至:
always @* begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
end
这样做可以解析 X 并允许 QA
输出切换。
现在我知道为什么我的 QB、QC、QD 仍然是 0。
preset和clear的功能是依赖于r0,r9,而不是我输入的inputA,inputB。
在我将代码更改为以下内容后,结果看起来不错:
module one(inputA, inputB, R01, R02, R91, R92, QA, QB, QC, QD);
input inputA, inputB, R01, R02, R91, R92;
output QA, QB, QC, QD;
reg qa = 1'b0, qb = 1'b0, qc = 1'b0, qd = 1'b0;
reg r0, r9, pre1, clr1, clr2, clr3, j2, j4, k4;
always@(*) begin
r0 = ~(R01 & R02);
r9 = ~(R91 & R92);
clr2 = r0 | r9;
clr3 = r0 | r9;
end
always @(negedge inputA) begin
qa = ~qa;
//jk1
end
always @(negedge inputB) begin
j2 = ~qd;
if (j2 == 0 ) qb = 0;
if (j2 == 1 ) qb = ~qb;
//jk2
end
always @(negedge qb) begin
qc = ~qc;
//jk3
end
always @(negedge inputB) begin
j4 = qb & qc;
k4 = qd;
case({j4, k4})
2'b01 : qd = 1'b0;//reset
2'b10 : qd = 1'b1;//set
2'b00 : qd = qd;//hold
2'b11 : qd = ~qd;//toggle
endcase
//jk4
end
always @(negedge r9)begin
qa = 1'b1;
//preset of jk1
end
always @(negedge r0)begin
qa = 1'b0;
//clear of jk1
end
always @(negedge clr2)begin
qa = 1'b0;
//clear of jk2
end
always @(negedge clr3)begin
qa = 1'b0;
//clear of jk3
end
always @(negedge r9)begin
qa = 1'b1;
//preset of jk4
end
always @(negedge r0)begin
qa = 1'b0;
//clear of jk4
end
begin
assign QA = qa;
assign QB = qb;
assign QC = qc;
assign QD = qd;
end
endmodule
我将 JK-FF 更改为模块实例化,现在它可以正常工作了:
module jk_ff_example (/*AUTOARG*/
// Outputs
QA, QB, QC, QD,
// Inputs
inputA, inputB, R01, R02, R91, R92
);
//..ports
input inputA, inputB, R01, R02, R91, R92;
output QA, QB, QC, QD;
//..regs and wires declaration
wire qa, qna, qb, qnb, qc, qnc, qd, qnd;
wire r0, r9;
//..r0 and r9 inputs comb logic
assign r0 = ~(R01 & R02);
assign r9 = ~(R91 & R92);
//..qa jk-ff logic
jk_ff qa_ff (
.preset_i (r9),
.clear_i (r0),
.clk_i (inputA),
.j_i (1'b1),
.k_i (1'b1),
.q_o (qa),
.qn_o (qna)
);
//..qb jk-ff logic
jk_ff qb_ff (
.preset_i (1'b1),
.clear_i (r0 | r9),
.clk_i (inputB),
.j_i (qnd),
.k_i (1'b1),
.q_o (qb),
.qn_o (qnb)
);
//..qc jk-ff logic
jk_ff qc_ff (
.preset_i (1'b1),
.clear_i (r0 | r9),
.clk_i (qb),
.j_i (1'b1),
.k_i (1'b1),
.q_o (qc),
.qn_o (qnc)
);
//..qd jk-ff logic
jk_ff qd_ff (
.preset_i (r9),
.clear_i (r0),
.clk_i (inputB),
.j_i (qb & qc),
.k_i (qd),
.q_o (qd),
.qn_o (qnd)
);
assign QA = qa;
assign QB = qb;
assign QC = qc;
assign QD = qd;
endmodule // jk_ff_example
这是带有预设和清除低电平有效输入的 JK-FF 代码:
/*
* JK-Flip Flop with Preset and Clear inputs Truth Table
* Preset, Clear and CLK with active-low logic
*
* -------------------------------------------------------------
* | Preset | Clear | CLK | J | K | Output | Qo | ~Qo |
* -------------------------------------------------------------
* | 0 | 0 | x | x | x | Invalid | 1* | 0* |
* | 0 | 1 | x | x | x | Preset | 1 | 0 |
* | 1 | 0 | x | x | x | Clear | 0 | 1 |
* | 1 | 1 | x | x | x | No change | Qo | ~Qo |
* | 1 | 1 | NEG | 0 | 0 | No change | Qo | ~Qo |
* | 1 | 1 | NEG | 0 | 1 | Reset | 0 | 1 |
* | 1 | 1 | NEG | 1 | 0 | Set | 1 | 0 |
* | 1 | 1 | NEG | 1 | 1 | Toggle | ~Qo | Qo |
* -------------------------------------------------------------
*/
module jk_ff (/*AUTOARG*/
// Outputs
q_o, qn_o,
// Inputs
preset_i, clear_i, clk_i, j_i, k_i
);
//..ports
input preset_i, clear_i, clk_i, j_i, k_i;
output q_o, qn_o;
//..regs and wires
reg q = 0;
//..jk ff w/ preset and clear logic
always @ (negedge preset_i, negedge clear_i, negedge clk_i) begin
case({preset_i, clear_i})
2'b00: q <= 0; //..invalid
2'b01: q <= 1; //..preset
2'b10: q <= 0; //..clear
2'b11: begin
if(clk_i) //..no change
q <= q;
else begin
case({j_i, k_i})
2'b00: q <= q; //..no change
2'b01: q <= 0; //..reset
2'b10: q <= 1; //..set
2'b11: q <= ~q; //..toggle
endcase
end
end
endcase
end
//..output assignment
assign q_o = q;
assign qn_o = ~q;
endmodule // jk_ff
模拟的输出是这样的:
[Cycle: 0] [Q value: 0]
[Cycle: 10] [Q value: 1]
[Cycle: 20] [Q value: 2]
[Cycle: 30] [Q value: 3]
[Cycle: 40] [Q value: 4]
[Cycle: 50] [Q value: 5]
[Cycle: 60] [Q value: 6]
[Cycle: 70] [Q value: 7]
[Cycle: 80] [Q value: 8]
[Cycle: 90] [Q value: 9]
[Cycle: 100] [Q value: 0]
[Cycle: 110] [Q value: 1]
[Cycle: 120] [Q value: 2]
[Cycle: 130] [Q value: 3]
[Cycle: 140] [Q value: 4]
[Cycle: 150] [Q value: 5]
[Cycle: 160] [Q value: 6]
[Cycle: 170] [Q value: 7]
[Cycle: 180] [Q value: 8]
[Cycle: 190] [Q value: 9]
[Cycle: 200] [Q value: 9]
[Cycle: 210] [Q value: 0]
[Cycle: 220] [Q value: 1]
[Cycle: 230] [Q value: 2]
[Cycle: 240] [Q value: 3]
[Cycle: 250] [Q value: 4]
[Cycle: 260] [Q value: 5]
[Cycle: 270] [Q value: 6]
[Cycle: 280] [Q value: 7]
[Cycle: 290] [Q value: 8]
End simulation
[Cycle: 300] [Q value: 9]
我在这个repository中上传了这个作为示例,我已经包含了一个Makefile以便于模拟和FPGA综合,请随意使用它。