为什么此Verilog占用30个宏单元和数百个产品术语?


8

我有一个项目消耗了Xilinx Coolrunner II宏单元中的34个。我注意到我有一个错误,并一直追踪到:

assign rlever = RL[0] ? 3'b000 :
                RL[1] ? 3'b001 :
                RL[2] ? 3'b010 :
                RL[3] ? 3'b011 :
                RL[4] ? 3'b100 :
                RL[5] ? 3'b101 :
                RL[6] ? 3'b110 :
                        3'b111;

assign llever = LL[0] ? 3'b000 :
                LL[1] ? 3'b001 :
                LL[2] ? 3'b010 :
                LL[3] ? 3'b011 :
                LL[4] ? 3'b100 :
                LL[5] ? 3'b101 :
                        3'b110 ;

错误是rlever并且llever宽度为1位,我需要它们为3位宽。傻我 我将代码更改为:

wire [2:0] rlever ...
wire [2:0] llever ...

所以有足够的位。但是,当我重建项目时,此更改使我损失了30多个宏单元和数百个产品条款。谁能解释我做错了什么?

(好消息是它现在可以正确模拟... :-P)

编辑-

我想我很沮丧,因为关于我觉得那时候我开始认识的Verilog和CPLD,有事这说明我很清楚有没有了解。

assign outp[0] = inp[0] | inp[2] | inp[4] | inp[6];
assign outp[1] = inp[1] | inp[2] | inp[5] | inp[6];
assign outp[2] = inp[3] | inp[4] | inp[5] | inp[6];

实现这三行的逻辑发生两次。这意味着,每6行的Verilog的消耗约6个宏蜂窝和32的乘积项的每个

编辑2-根据@ThePhoton关于优化开关的建议,以下是ISE生成的摘要页面中的信息:

Synthesizing Unit <mux1>.
    Related source file is "mux1.v".
    Found 3-bit 1-of-9 priority encoder for signal <code>.
Unit <mux1> synthesized.
(snip!)
# Priority Encoders                                    : 2
 3-bit 1-of-9 priority encoder                         : 2

显然,代码被认为是特殊的东西。但是,该设计仍在消耗大量资源。

编辑3-

我制作了一个新原理图,仅包含@thePhoton建议的多路复用器。综合产生的资源使用量很小。我还综合了@Michael Karas推荐的模块。这也产生了微不足道的用法。因此,有一些理智。

显然,我对杠杆值的使用引起了混乱。更多内容。

最终编辑

设计不再是疯狂的。但是,我不确定发生了什么。为了实现新算法,我进行了很多更改。一个推动因素是111个15位元素的“ ROM”。这消耗了少量的宏单元,但是很多产品条款-几乎所有在xc2c64a上可用的条款。我在寻找,但没有注意到。我相信我的错误被优化隐藏了。我正在谈论的“杠杆”用于从ROM中选择值。我假设当我实现(无效的)1位优先级编码器时,ISE优化了一些ROM。那将是一个绝招,但这是我能想到的唯一解释。这种优化显着减少了资源使用,使我无法期待某个基准。固定优先级编码器(按照此线程)后,我看到了优先级编码器和先前已优化的ROM的开销,并将其专门归因于前者。

毕竟,我在宏单元方面表现不错,但是耗尽了我的产品术语。ROM的一半确实是一种奢侈,因为它只是上半年的2的组合。我删除了负值,并通过简单的计算将其替换为其他值。这使我可以将宏单元用于产品条款。

现在,这东西已经适合xc2c64a了。我分别使用了81%和84%的宏单元和乘积项。当然,现在我必须对其进行测试,以确保它能够满足我的要求。

感谢ThePhoton和Michael Karas的协助。除了他们提供的道德支持以帮助我解决这一问题外,我还从Xilinx发布的ThePhoton文档中了解到了这些信息,并且还实施了Michael建议的优先级编码器。


并不是每个问号都有效地暗示着一个多路复用器,并且在结构上您也将它们级联了吗?您希望它占用多少个宏单元?
vicatcu

我不知道该构造应消耗多少个宏单元。但是,考虑到我的项目目前正在消耗34个宏单元,包括这两个“ 1位”多路复用器,而这些只是该项目的一小部分,因此,我对此结果感到惊讶。
托尼·恩尼斯

您正在使用什么工具?
Photon

Xilinx的ISE ...
Tony Ennis,2012年

在您修改的代码中,我想您想|代替||
Photon

Answers:


7

您显示的代码本质上是优先级编码器。即,它具有许多信号的输入,并且其输出指示设置了那些信号中的哪一个,如果设置了多个,则优先于最左边的设置信号。

但是,在我检查的两个地方,我看到该电路的标准行为的定义存在冲突。

根据Wikipedia的介绍,标准优先级编码器的输入从1开始编号。也就是说,如果设置了最低有效输入位,则输出1,而不是0。如果没有设置输入位,则Wikipedia优先级编码器将输出0。

但是,Xilinx的XST用户指南(第80页)定义了一个优先级编码器,该编码器与您的编码更接近。输入从0开始编号,因此当设置输入的lsb时,它将给出0输出。但是,当所有输入位都清零时,Xilinx定义不提供输出规范(您的代码将输出3'd7)。

当然,Xilinx用户指南将确定Xilinx综合软件的期望。要点是,(*priority_extract ="force"*)XST需要一个特殊的指令才能识别此结构并生成最佳的合成结果。

这是Xilinx推荐的8至3优先级编码器形式:

(* priority_extract="force" *)
module v_priority_encoder_1 (sel, code);
input [7:0] sel;
output [2:0] code;
reg [2:0] code;
always @(sel)
begin
    if (sel[0]) code = 3b000;
    else if (sel[1]) code = 3b001;
    else if (sel[2]) code = 3b010;
    else if (sel[3]) code = 3b011;
    else if (sel[4]) code = 3b100;
    else if (sel[5]) code = 3b101;
    else if (sel[6]) code = 3b110;
    else if (sel[7]) code = 3b111;
    else code = 3bxxx;
end
endmodule

如果您可以重新排列周围的逻辑以使用Xilinx推荐的编码样式,那可能是获得更好结果的最佳方法。

我想可以通过实例化Xilinx编码器模块来实现

v_priority_encoder_1 pe_inst (.sel({~|{RL[6:0]}, RL[6:0]}), .code(rlever));

我也没有将的所有位加在一起RL[6:0]以获得第8个输入位,当所有RL位都为低时,它将触发3'b111输出。

对于llever逻辑,您可以按照Xilinx模板制作经过修改的编码器模块,但只需要7个输入位(您的6位LL加上另外一位在其他6位都为低时变为高)。

使用此模板假定您拥有的ISE版本正在使用XST综合引擎。似乎他们在ISE的每个主要版本上都更改了综合工具,因此请检查我链接的文档是否确实与您的ISE版本相对应。如果不是,请查看文档中推荐的样式,以查看工具的期望。


谢谢,这将需要一些时间来消化。我的ISE使用的是XST,但我不知道哪个版本。
托尼·恩尼斯

关键在于,(* priority_extract="force" *)即使您涵盖了所有可能的输入,也要具有并可能显式包括无关紧要的输出。(如果没有它,XST可能试图生成一个完整的查找表,这就是为什么这么多产品术语的原因)请尝试首先添加“不在乎”选项。如果不起作用,请尝试完全使用Xilinx样板。
Photon

我实现了上面代码的完整片段,但没有得到改进的结果。ISE摘要页面表明已识别出MUX,尽管识别能力不如其他构造强。我将在几分钟后发布相关信息。
托尼·恩尼斯

编辑-忽略上面关于“强力识别”的评论-在那里,我昨晚错过了;我重做了工作,现实工作正常。
托尼·恩尼斯

6

ThePhoton的答案是一个很好的答案。我想在这里添加一些其他信息供您考虑。这是由于这样的事实,即使我们拥有使用HDL和综合工具的先进的FPGA和CPLD器件,仔细研究几年前设计的内容还是很有帮助的。待在我最后解决我的建议时,和我在一起。

有分立的逻辑部分执行优先级编码功能。当必须将晶体管的数量减少到最低限度时,这些部件实现的逻辑已经存在了很长时间。您可以在网上搜索具有通用零件编号的逻辑零件,例如74HC148或MC14532B,以查找包含这些零件等效逻辑图的数据表。下图是摘自TI数据手册中74HC148器件的一个示例。

在此处输入图片说明

此逻辑实现以下真值表(取自同一数据表):

在此处输入图片说明

请注意,上述系列产品使用低有效输入信号。安森美半导体MC14532B零件的另一数据表显示了使用高电平有效输入信号的编码器功能真值表,类似于您的Verilog示例。

在此处输入图片说明

同一数据表显示了MC14532B的逻辑方程式,如下所示:

在此处输入图片说明

您可能需要考虑将类似的方程式直接编码到您的Verilog代码中,以了解其与当前示例的比较。这很有可能导致更有利的结果。


谢谢,我会的。这个问题使我丧命。我相信以前它的合成效率更高。然后我改变了一些东西。/ selfbonk
Tony Ennis,

谢谢,我已经实现了。不幸的是,它没有实质性的改变。
托尼·恩尼斯

好答案。让我们来看看托尼只是多少产品方面应该需要实现这个逻辑。Tony,如果您使用Xilinx的样板程序或Michael的方程式,并且仍在生成数百个乘积项,那么您需要在代码中的其他地方寻找可能导致问题的细微变化;否则请非常仔细地查看综合日志文件,以查看是否发生了意外的事情。
Photon

我完全同意@ThePhoton。我已经用软管扎了东西。我可以肯定的是它曾经有用-我什至没有注意到它的消耗如此之小。哦,这是开始理解更多“摘要”信息的好借口。
托尼·恩尼斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.