七段数码管动态显示模块故障:place总线未随移位寄存器更新
七段数码管动态显示时place未随移位寄存器更新的问题分析
问题背景
该模块需实现:按键按下时显示对应单字母,开关激活时通过移位寄存器动态切换place信号,驱动七段数码管循环显示整词。测试发现:按键输入时place值正常;开关激活后,移位寄存器可正常执行移位操作,但place始终保持移位寄存器初始值不变。
问题根源
1. 开关信号sw_for_fullword未正确生效
从测试用例代码来看,sw变量未初始化(logic sw;默认值为不确定态x),直到测试后期才通过阻塞赋值置1。若仿真中sw_for_fullword未被正确置为高电平,always_comb会执行else分支,place将保持按键输入值;若观察到place保持移位寄存器初始值,说明开关信号可能存在赋值时机偏差或信号连接错误,导致always_comb未进入shift_reg赋值分支。
2. 移位寄存器更新时序与组合逻辑的匹配问题
模块中enable采用组合逻辑直接生成:
logic enable = (cnt[2:0] == '0);
而cnt通过非阻塞赋值更新,这会导致enable的更新滞后于cnt的变化:
- 时钟上升沿触发时,
cnt的更新进入非阻塞赋值队列(NBA阶段),此时enable读取的仍是cnt的旧值 - 移位寄存器的更新条件
else if(enable)使用旧值判断,导致移位操作比预期晚一个时钟周期 - 若
place的采样时机未匹配移位寄存器的实际更新点,易出现视觉上的“未变化”假象
3. 组合逻辑的不确定态风险
always_comb中若sw_for_fullword处于不确定态x,分支判断会出现异常,可能导致place赋值不符合预期。
修复方案
1. 初始化测试用例中的开关信号
在testbench的initial块开头添加开关初始化,避免不确定态影响:
initial begin sw = 1'b0; // 初始化开关为关闭状态 rst <= 1'b1; repeat (2) @ (posedge clk); rst <= 1'b0; // 后续测试代码 end
2. 修正enable的生成逻辑
将enable改为时序逻辑,确保与cnt的更新同步:
logic enable; always_ff@(posedge clk, posedge rst)begin if(rst) enable <= 1'b0; else enable <= (cnt[2:0] == '0); end
此修改保证enable在cnt更新后的时钟边沿生效,移位寄存器的更新时机与预期一致。
3. 添加调试验证
在模块和测试用例中添加打印语句,确认信号状态:
- 模块内调试
place赋值分支:
always_comb begin if(sw_for_fullword) begin place = shift_reg; $display("[%0t] Place assigned to shift_reg: %b", $time, shift_reg); end else begin place = {btn_fir, btn_sec,btn_thi,btn_fou}; $display("[%0t] Place assigned to buttons: %b", $time, {btn_fir, btn_sec,btn_thi,btn_fou}); end end
- 测试用例中验证开关信号:
initial begin // ... 其他代码 x='0; sw = '1; $display("[%0t] Switch activated, sw value: %b", $time, sw); repeat (50) @ (posedge clk); $finish; end
通过以上步骤可快速定位开关信号有效性、移位寄存器更新时序等问题,解决place未随移位寄存器更新的异常。
内容的提问来源于stack exchange,提问作者Shuazo
相关产品推荐
相关产品推荐

