我需要在 Veriog 中实现 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 很丑陋,我不知道 vcs 是否会识别那里的 K-map。这是否与 case 语句或连接范式的作业一样有效?

有帮助吗?

解决方案

你拥有的很好。案例陈述也同样有效。这只是您希望如何表达的问题。

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

就合成而言,使用哪一种并不重要。任何像样的综合工具都会产生相同的结果。

其他提示

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

另外,我不会太担心 RTL 代码是否简短。为了清晰起见,我会先拍摄。合成工具比你想象的更聪明......

我的偏好 - 如果它对您的问题有意义 - 是使用枚举或“定义”的 case 语句。任何能让代码审查、维护和验证变得更容易的事情。

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

这个建议也适用于一般情况。让您的代码易于人类理解,并且合成工具也可能更容易理解,这使得它能够更有效地从字面上理解 数千 长达数年的算法研究对您的 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

显然我使用的是一个糟糕的合成工具。:-) 我刚刚综合了两个版本(只是使用基于线延迟扇出的模型的模块),问题中的索引版本给出了比 case 语句更好的时序和面积结果。使用 Synopsys DC Z-2007.03-SP。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top