Logic Verilog中4:1函数的高效综合

Logic Verilog中4:1函数的高效综合,logic,verilog,synthesis,version-control,Logic,Verilog,Synthesis,Version Control,我需要在Verilog中实现一个4对1的函数。输入为4位,一个0-15之间的数字。输出为单位,0或1。每个输入提供不同的输出,输入到输出的映射是已知的,但输入和输出本身不是。我希望vcs能够成功地优化代码,并使其尽可能简短/整洁。到目前为止,我的解决方案是: wire [3:0] a; wire b; wire [15:0] c; assign c = 16'b0100110010111010; //for example but could be any constant assign b

我需要在Verilog中实现一个4对1的函数。输入为4位,一个0-15之间的数字。输出为单位,0或1。每个输入提供不同的输出,输入到输出的映射是已知的,但输入和输出本身不是。我希望vcs能够成功地优化代码,并使其尽可能简短/整洁。到目前为止,我的解决方案是:

wire [3:0] a;
wire b;
wire [15:0] c;

assign c = 16'b0100110010111010; //for example but could be any constant
assign b = c[a];

必须声明c是丑陋的,我不知道风投公司是否会识别那里的K图。这和case语句或合取范式赋值一样有效吗?

如果对您的问题有意义的话,我更喜欢使用enum或` defines的case语句。使代码审查、维护和验证更容易的任何东西。

我完全同意达拉斯的观点。使用案例陈述-它使你的意图更清晰。合成工具将它构建为一个查找表(如果它是并行的),并将尽可能优化它


另外,我也不会太担心RTL代码的简短。我会先拍清楚。合成工具比你想象的更聪明…

你拥有的一切都很好。案例陈述也同样有效。这只是一个你希望表达的程度的问题

如果select编码没有任何特殊意义(例如内存地址选择器),那么您的解决方案索引工作正常。如果select编码对设计者来说确实有一些特殊的语义意义(并且没有太多),那么使用case语句和枚举


就合成而言,你用哪一个都不重要。任何像样的合成工具都会产生同样的结果。

对于这样的事情,RTL清晰性在很大程度上胜过一切。SystemVerilog具有特殊的always block指令,以明确块何时应合成为组合逻辑、锁存或触发器(如果您编写的RTL与此冲突,则合成工具应抛出错误(例如,always block的灵敏度列表中不包括所有信号)。还要注意的是,该工具可能会用最具硬件效率的编码(使总体设计面积最小化的编码)替换您的任何编码,除非编码本身传播到顶级模块的引脚

这条建议也适用于一般情况。使您的代码易于人类理解,并且合成工具也可能更容易理解,这使得它能够更有效地将数千人年的算法研究应用到您的RTL中

如果您愿意,也可以使用三元运算符对其进行编码,但我更喜欢这样:

always_comb //or "always @*" if you don't have an SV-enabled tool flow
begin 
  case(a)
  begin
    4'b0000: b = 1'b0;
    4'b0001: b = 1'b1;
    ...
    4'b1111: b = 1'b0;
    //If you don't specify a "default" clause, your synthesis tool
    //Should scream at you if you didn't specify all cases,
    //Which is a good thing (tm)
  endcase //a
end //always

显然,我使用的是一个糟糕的综合工具。:-)我刚刚综合了两个版本(只是模块使用了一个基于线延迟扇出的模型),问题的索引版本比案例陈述提供了更好的时间和面积结果。使用Synopsys DC Z-2007.03-SP