0

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

我做了一个小测试

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,后者是我想要的,但我还没有合成它。有没有更好/标准的方法来做到这一点?

4

1 回答 1

1

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

关于语言问题:

简而言之,Verilog 有一个 4 状态的数据类型,并且操作符对这 4 种状态的处理方式不同。

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

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

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

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

于 2015-12-22T13:50:32.353 回答