【问题标题】:Verilog: tristates for synthesis, and difference between conditional and case?Verilog:综合的三态,以及条件和案例之间的区别?
【发布时间】:2024-01-29 19:00:01
【问题描述】:

如何将三态总线转换为两态逻辑以进行综合?

我做了一个小测试

module test1( inout tristate, output flattened);
    assign flattened = tristate ? 1 : 0;
endmodule

module test2( inout tristate, output reg flattened);
    always @(tristate) begin
        case(tristate)
            0:          flattened = 0;
            default: flattened = 1;
        endcase
    end
endmodule

`timescale 1ns / 1ps

module test_tb;
    reg tristateEnable;
    reg tristateValue;
    wire tristate = tristateEnable ? tristateValue : 1'bz;
    wire flattened1, flattened2;

    test1 uut1(tristate, flattened1);
    test2 uut2(tristate, flattened2);

    initial begin
        tristateValue = 1'b0;
        tristateEnable = 1;
        #10 tristateValue = 1'b1;
        #10 tristateEnable = 1'b0;
    end

endmodule

模拟它我得到了模块test1将flattened设置为X,模块test2将它设置为1,后者是我想要的,但我还没有合成它。有没有更好/标准的方法来做到这一点?

【问题讨论】:

  • 我使用 VCS 模拟了您的测试,结果模拟结果对于 test1 和 test2 是相同的。你能详细说明你的意图吗?我认为 test1 可能更可取,只是一个猜测。

标签: verilog synthesis tri-state-logic


【解决方案1】:

您已经问了两个问题:(1) 条件运算符和 case 语句有什么区别,以及 (2) 如何处理三态值。

关于语言问题:

简而言之,Verilog 有 4 种状态的数据类型,运算符对这 4 种状态的处理方式不同。

  1. case 语句执行“4 状态测试”,也称为“大小写相等”。将 case 表达式(在您的示例中为 tristate)与 01xz 进行比较。当它是z 时,采用默认分支,所以flattened1,如您所见。
  2. 条件(“三元”)运算符也执行 4 状态测试,并将 tristate 查找为 z。它现在不知道该做什么,因此它将您提供的两个值(01)组合成一个结果x,这就是您所看到的。基本上,它试图变得聪明。见 2005 年 LRM 表 5-21。 请注意,if 语句执行 4 状态测试。

三态:你很困惑,因为你的控制信号(tristate)转到zdata 信号 (flattened) 应该发送到 z。 您不会为了综合而“压平”三态;您通常对上拉或下拉进行建模。这将特定于您的技术,但您可能只需要实例化一个上拉或下拉组件。如果您有类似的代码,您的合成器可能会也可能不会自动为您执行此操作

assign sig_o = (ena == 1'b1)? sig_i : 1'bz;

您需要阅读合成器文档才能确定。请注意,如果 ena 保证为 2 状态 (0/1),您应该只使用这样的条件运算符。

【讨论】:

  • 就我而言,我使用 32 位双向通信线路连接到外部 USB 控制器。我的简化连接方案是:module communications(inout data_bus, input out_stream, output in_stream, ..) .... assign data_bus = (en_data_bus) ? out_stream :1'bz; assign in_stream = databus; ... endmodule 它模拟没有问题,但 in_stream 在综合中得到优化。由于我无法在 fpga 内部使用三态,因此我试图将 in_stream 强制为 2 态。
  • 如果它正在被优化,它与三态无关 - 这是因为你没有使用它,所以没有必要。看起来您的进/出方向可能有些混乱,可能还有您的模块连接。
  • 是的,我知道这一点。在我的代码中,它正在积极使用它,因此它可能是一个链式优化的东西。反正原问题已经回答了,谢谢!
  • @eml 表示第 1 点,我们可以使用 casez 忽略所有 z 设计吗?
  • 在设计中使用casez 忽略所有z:你可以,但这不是一个好主意。请参见 www.sunburst-design.com/papers/CummingsSNUG1999SJ_SynthMismatch.pdf,第 4.4 节。无论如何,你不能在你的设计中留下浮动节点,所以只要确保一切都被拉上或拉下。对于输入或 I/O,请确保实例化具有上拉或下拉的单元格。