为何这两段SystemVerilog组合逻辑描述不等价?
24小时制转12小时制BCD码的Verilog赋值问题
问题背景
我有两个代表24小时制时钟小时数的4位BCD码信号:h1_24h(高位)和h0_24h(低位),需要通过组合逻辑生成对应的12小时制BCD码信号h1_12h和h0_12h,规则如下:
- 00点 → 12点
- 01~12点 → 保持原数值
- 13~19点 → 减去12(如19点→07点)
- 20~21点 → 减去12(如20点→08点)
- 22~23点 → 减去12(如22点→10点)
初始代码(存在问题)
以下代码在Vivado 2023.1中仿真时,除22、23点外均正常,这两个时刻输出错误为00、01(预期应为10、11),且确认对应if语句已执行,但修改高位赋值无法改变输出:
always_comb begin {h1_12h, h0_12h} = {h1_24h, h0_24h}; // 01 am到12 pm保持一致 if (h1_24h == 0 && h0_24h == 0) {h1_12h, h0_12h} = {4'd1, 4'd2}; // 00 -> 12 if (h1_24h == 1 && h0_24h >= 3) {h1_12h, h0_12h} = {4'd0, h0_24h - 2}; // 13-19 -> 01-07 if (h1_24h == 2 && h0_24h <= 1) {h1_12h, h0_12h} = {4'd0, h0_24h + 8}; // 20-21 -> 08-09 if (h1_24h == 2 && h0_24h >= 2) {h1_12h, h0_12h} = {4'd1, h0_24h - 2}; // 22-23 -> 10-11 end
修正代码(仿真正确)
将拼接赋值改为分信号单独赋值后,仿真结果完全正确:
always_comb begin // identical from 01 am to 12 pm h1_12h = h1_24h; h0_12h = h0_24h; // 00 -> 12 if (h1_24h == 0 && h0_24h == 0) begin h1_12h = 4'd1; h0_12h = 4'd2; end // 13-19 -> 01-07 if (h1_24h == 1 && h0_24h >= 3) begin h1_12h = 4'd0; h0_12h = h0_24h - 2; end // 20-21 -> 08-09 if (h1_24h == 2 && h0_24h <= 1) begin h1_12h = 4'd0; h0_12h = h0_24h + 8; end // 22-23 -> 10-11 if (h1_24h == 2 && h0_24h >= 2) begin h1_12h = 4'b1; h0_12h = h0_24h - 2; end end
原因分析
两段代码看似等价,实际差异源于Vivado工具对拼接赋值的解析逻辑:
- 拼接赋值
{h1_12h, h0_12h} = {4'd1, h0_24h - 2};虽然语法上是8位对8位的赋值,但Vivado 2023.1在处理此类操作时,可能无法正确将右侧拼接值拆分到两个独立的4位目标变量中,导致h1_12h的赋值未生效。 - 分信号赋值直接对每个4位变量单独赋值,逻辑清晰,工具能准确解析每一个变量的驱动逻辑,避免了拼接操作带来的歧义。
优化建议
可以将多个独立if改为if-else if结构(因各条件互斥),减少不必要的条件判断,提升逻辑效率:
always_comb begin // 默认赋值:01~12点直接映射 h1_12h = h1_24h; h0_12h = h0_24h; if (h1_24h == 4'd0 && h0_24h == 4'd0) begin // 00点 -> 12点 h1_12h = 4'd1; h0_12h = 4'd2; end else if (h1_24h == 4'd1 && h0_24h >= 4'd3) begin // 13~19点 -> 01~07点 h1_12h = 4'd0; h0_12h = h0_24h - 4'd2; end else if (h1_24h == 4'd2) begin if (h0_24h <= 4'd1) begin // 20~21点 -> 08~09点 h1_12h = 4'd0; h0_12h = h0_24h + 4'd8; end else begin // 22~23点 -> 10~11点 h1_12h = 4'd1; h0_12h = h0_24h - 4'd2; end end end
内容的提问来源于stack exchange,提问作者Benjamín Panatt
相关产品推荐
相关产品推荐

