You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何这两段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工具对拼接赋值的解析逻辑:

  1. 拼接赋值{h1_12h, h0_12h} = {4'd1, h0_24h - 2};虽然语法上是8位对8位的赋值,但Vivado 2023.1在处理此类操作时,可能无法正确将右侧拼接值拆分到两个独立的4位目标变量中,导致h1_12h的赋值未生效。
  2. 分信号赋值直接对每个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 23:12:12