HDLBits题目DFFs and Gates自定义D触发器方案问题排查
D触发器输出延迟一个时钟周期的问题分析
问题场景
在完成HDLBits中DFFs and Gates题目时,自定义D触发器实现的代码输出始终比正确结果延迟一个时钟周期,尝试切换阻塞赋值q = d与非阻塞赋值q <= d后问题依旧。
自定义实现代码
module top_module ( input clk, input x, output z ); wire d_xor, d_and, d_or; wire z2, z3; wire fb_xor, fb_and, fb_or; assign d_xor = x ^ fb_xor; assign d_and = x && fb_and; assign d_or = x || fb_or; d_ff(.d(d_xor), .clk(clk), .q(fb_xor)); d_ff(.d(d_and), .clk(clk), .q(z2), .nq(fb_and)); d_ff(.d(d_or), .clk(clk), .q(z3), .nq(fb_or)); assign z = ~|{fb_xor, z2, z3}; endmodule module d_ff ( input wire d, input wire clk, output reg q = 1'b0, output reg nq = 1'b1 ); always @(posedge clk) begin q = d; nq = ~d; end endmodule
问题原因
反馈路径逻辑错误
题目要求的三个触发器逻辑为:- 第一个触发器:
D = x ^ Q1(你的实现是正确的) - 第二个触发器:
D = x & Q2 - 第三个触发器:
D = x | Q3
但你的代码中,第二个触发器的反馈信号用了nq(即~z2),第三个触发器用了nq(即~z3),导致输入到D端的逻辑变成: d_and = x & ~z2(与要求相反)d_or = x | ~z3(与要求相反)
这种反向反馈会导致触发器的更新逻辑偏离预期,直接引发输出延迟一个时钟周期的问题。
- 第一个触发器:
初始状态不符合要求
自定义D触发器的nq初始值为1'b1,导致第二个触发器的初始反馈信号fb_and=1,第一个时钟沿时z2被更新为x & 1 = x,而题目要求初始状态下触发器输出为0,第一个时钟沿应更新为x & 0 = 0,初始状态的偏差进一步放大了周期延迟问题。
修正方案
- 调整反馈路径,使用触发器的正向输出作为反馈信号,而非反向输出
nq - 移除不必要的
nq输出,简化D触发器模块,同时推荐用非阻塞赋值描述时序逻辑
修正后的核心代码片段:
module top_module ( input clk, input x, output z ); wire d_xor, d_and, d_or; wire q1, q2, q3; assign d_xor = x ^ q1; assign d_and = x && q2; assign d_or = x || q3; d_ff(.d(d_xor), .clk(clk), .q(q1)); d_ff(.d(d_and), .clk(clk), .q(q2)); d_ff(.d(d_or), .clk(clk), .q(q3)); assign z = ~|{q1, q2, q3}; endmodule module d_ff ( input wire d, input wire clk, output reg q = 1'b0 ); always @(posedge clk) begin q <= d; end endmodule
内容的提问来源于stack exchange,提问作者CodeStacker42
相关产品推荐
相关产品推荐

