如何将三态总线转换为二态逻辑进行合成?
我做了一个小小的测试
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,后者是我想要的,但我还没有合成它。有更好/标准的方法吗?
您已经问了两个问题:(1)条件运算符和case语句之间的区别是什么,以及(2)如何处理三态值。
关于语言问题:
简而言之,Verilog有一个4状态的数据类型,操作员处理这4种状态的方式不同。
- case语句执行"4状态测试",也称为"case相等"。将事例表达式(示例中的
tristate
)与0
、1
、x
和z
进行比较。如果是z
,则采用默认分支,因此flattened
就是1
,正如您所发现的 - 条件('ternary')运算符还执行4状态测试,并将
tristate
查找为z
。它不知道现在该做什么,所以它将您提供的两个值(0
和1
)组合成一个结果x
,这就是您所看到的。基本上,它试图变得聪明。参见2005 LRM中的表5-21。请注意,if
语句执行而不是执行4状态测试
三态:您感到困惑,因为您的控制信号(tristate
)进入z
;应该去往z
的是数据信号(flattened
)。你不会为了合成而"压平"三态;你通常模拟上拉或下拉。这将特定于您的技术,但您可能只需要实例化一个上拉或下拉组件。如果你有这样的代码,你的合成器可能会自动为你做这件事,也可能不会
assign sig_o = (ena == 1'b1)? sig_i : 1'bz;
你需要阅读你的合成器文档来确定。请注意,只有当ena
被保证为2-状态(0
/1
)时,才应该使用这样的条件运算符。