FPGA的设计艺术(29)FPGA中的逻辑综合资源讨论

李锐博恩 2021-05-23 23:50:14 5029

前言

有了上一篇博文:https://www.ebaina.com/articles/140000012562的铺垫,我们就清晰地了解了触发器的异步与同步之分。

上篇博文的最后,我们提到了要进去逻辑综合这一步去看看FPGA更真实的资源去实现我们想要的逻辑功能,但这还不是最终的FPGA实现,最能说明FPGA实际情况的阶段还是实现(implementation)这一步。本篇博客,我们暂时不深入去implementation,仅综合这一步,其实也就能看出FPGA的资源使用情况了。

本文针对特定FPGA的综合库,来讨论设计中考虑什么能够让我们的设计更加的合理,同时认识到,我们的设计是如何对应到综合资源上的,对实际设计有一定的参考意义。

逻辑综合资源讨论

简单的逻辑在赛灵思FPGA中使用查找表(LUT)和逻辑 "Slice "内的触发器来实现,这些 "slice "包含在可配置逻辑块(CLB)中。即使像XC3S50这样的小型器件也有1500多个LUT和触发器对。然而,当涉及到在实际设计中使用这些对时,有句话说得太对了,那就是照顾好一分钱,英镑就会照顾好自己。

如下图所示4输入的lut:

LUT4

LUT可以实现四个输入的任何功能,不管需要多少个门来描述它。LUT的输出直接进入触发器的D输入。这样组合起来的设计将是小型和高性能的。

下面的RTL描述的逻辑可以使用上面的设计来实现:

VHDL描述:

process (clk)
begin
if clk’event and clk=’1’ then
data_out <= a and b and c and d;
end if; 
end process;

Verilog描述


always @(posedge clk) begin
data_out <= a & b & c & d;
end

如果有更多的输入呢?

只要一个函数有四个以上的输入,综合工具就别无选择,只能以某种方式在两个或多个LUT之间分割逻辑。图2显示了一个六输入的AND门最可能的实现方式,不管是什么语言或综合工具。

两级逻辑
注意这个函数的成本是单级逻辑的两倍。只要函数不能装入一个LUT,就必须使用两个LUT。我们还可以看到对性能的重大影响。通过额外的LUT会产生延迟,连接函数的 "线 "同时增加了更多的延迟,这对建立时间的整体影响可能是很大的。当然,这也是时间规格和布局布线(PAR)工具在保持网络延迟在限制范围内发挥的作用;然而,避免这种情况显然会使设计更快、更小。

下面尝试添加复位端口:

当在设计中添加控制时,设计者经常包括一个全局复位。这种复位在仿真中特别受欢迎。然而,由于Xilinx FPGA在配置(Configuration)后已经在一个已知的状态下启动,全局复位确实没有必要。下面的VHDL和V erilog例子显示了如何实现全局复位。
VHDL描述:

process (clk, reset)
begin
if reset=‘1’ then
data_out <= ‘0’;
elsif clk’event and clk=’1’ then
data_out <= a and b and c and d;
end if; 
end process;

Verilog描述:

always @(posedge clk or posedge reset) begin
if (reset) begin
data_out <= 1’b0;
end
else begin
data_out <= a & b & c & d;
end

每个触发器都有一组专用控制输入,以支持置位、复位和时钟使能控制。显然,综合工具应该足够明智,在可以使用这些输入时,意味着LUT被保留给我们试图控制的实际功能。如下图所示,触发器的异步清零(CLR)输入已被使用,这意味着仍有一个最佳的单级逻辑。

综合工具使用了触发器的异步复位端,就可以使得LUT的输入恰好是4输入的,对于最大只有4输入的FPGA来说,可以在一个lut中就实现这个4输入的电路,不用浪费更多的资源。

异步复位

我们尝试添加更多的控制。

下面展示了一些类似于实际设计中必须包含的额外控制。下面的代码具有相同的四输入功能,但触发器需要复位、置位和时钟使能的控制。

VHDL描述:

process (clk,reset)
begin
if reset=’1’ then
data_out <= ’0’; 
elsif clk’event and clk=’1’ then
if enable=’1’ then 
if force_high=’1’ then 
data_out <= ’1’;
else
data_out <= a and b and c and d;
end if; 
end if;
end if;
end process;

Verilog描述:

    always@(posedge clk or posedge reset) begin
        if(reset) begin
            data_out    <= 0;
        end
        else if(enable) begin
            if(force_high) begin
                data_out    <= 1;
            end
            else begin
                data_out    <= a&b&c&d;
            end
        end
        else begin
            data_out    <= data_out;
        end
    end

看看赛灵思合成工具(XST)是如何处理这段代码的。为什么它没有直接在触发器上使用控制,从而使我们的单级逻辑变成了双级逻辑,而且成本和性能都降低了?

综合工具的处理方式

综合工具已经尽其所能。问题的原因是代码,它所描述的东西在逻辑片中直接实现是不自然的。代码可能描述了设计者希望它做的事情,但综合工具被迫使用它的可用资源来模拟该功能。这就像用刀刃来拧紧一个松动的螺丝:它可能会完成工作,但螺丝和刀会被损坏,而且执行这个操作的人也会有一定的危险!

触发器可以支持异步和同步的复位和置位控制。但是,它们不能在同一个触发器上支持异步和同步控制的混合。因此,综合工具必须在具有SET和RST控制的同步触发器或具有PRE和CLR控制的异步触发器之间进行选择。异步复位总是优先考虑并强制选择。

触发器

异步复位让我们回到了全局复位的问题上。很多时候,全局复位被定义为异步的。看看你的代码,验证它是否是异步的。前面的例子同时使用了置位和复位控制,这可能不是很常见;然而,也有这样的情况:同一个触发器有两个复位条件。一个是全局复位,在编码方式中你默认有全局复位,第二个是出于操作目的所需的局部复位(即一个BCD计数器,在9之后必须翻转到0)。如果全局复位是异步的,那么局部同步复位必须用LUT来模拟,有可能以两倍的成本和较低的性能强制执行两级逻辑。

如果你仍然坚持要有一个全局复位(除非上面反对的理由说服了你),那就试试同样的例子,用一个同步复位来看看是否能让事情变得更好。

VHDL描述

process (clk)
begin
if clk’event and clk=’1’ then
if reset=’1’ then
data_out <= ’0’; 
else
if enable=’1’ then 
if force_high=’1’ then 
data_out <= ’1’;
else
data_out <= a and b and c and d;
end if; 
end if;
end if;
end if;
end process;

Verilog描述:

    always@(posedge clk) begin
        if(reset) begin
            data_out    <=   0;
        end
        else if(enable) begin
            if(force_high) begin
                data_out    <= 1;
            end
            else begin
                data_out    <= a&b&c&d;
            end
        end
        else begin
            data_out    <=  data_out;
        end
    end

下图显示了XST对同步代码的处理情况。同样,看起来工具浪费了触发器上的专用SET控制,并在逻辑中实现了这个控制。结果又是两级逻辑,成本增加了一倍,性能降低了

同步控制

同样,XST已经做了它可能做的最好的事情。代码要求综合工具实现一些不自然的东西,而XST被迫模仿描述的东西。

成功实现的关键是了解触发器的工作方式。尽管FPGA作为一个整体是可编程的,但每个低级特征实际上是固定的。可编程性来自于决定是否使用该特性的能力。想象一下,你要使用一个离散的器件。在使用它之前,你必须研究数据表,看看连接和控制是如何工作的。研究一下表1吧。不管这个器件是什么,它的输入和输出都与一个触发器一致。

触发器真值表

表1显示,具有最高优先级的R输入,将在C的上升沿复位Q输出,只有当R输入为低电平时,才能发生其他事情。请注意,S的优先级次之,迫使Q输出为高电平。最后,CE输入必须是高电平,Q输出才会跟随D输入。这并不是什么火箭科学,但下面的信息可能会让人有点吃惊。

表1取自在线Libraries Guide,该指南与ISE™软件工具一起提供,来自描述被称为FDRSE的触发器的页面。这个名字从左到右读起来更有意义。

触发器命名

FPGA内部的所有触发器都有这些相同的控制,尽管异步触发器被称为FDCPE以反映异步清零和预置控制。当使用一个以上的控制时,每个控制都遵循它被分配的优先级。在 "同步设计 "中的VHDL代码例子中,enable的优先级高于set,这不符合专用控制所支持的顺序。综合工具通过使用顺序正确的专用控件和一些LUT逻辑的组合来解决这个问题,以模拟正在描述的触发器的其余部分。

当我们连接外部元件时,我们都非常清楚控制和它们的优先级。原理图设计者也非常清楚FPGA内部触发器的控制优先级,仅仅是因为他们从库中手动选择触发器,然后必须遵循优先级规则,使元件在电路中工作。在编写更高抽象水平的HDL代码时,这些方面很容易被忽略。幸运的是,由于所有的触发器组件都是一样的,一旦我们知道了它们的简单规则,就可以比较容易地编写出与它们的工作方式相适应的通用代码,如以下代码所示。

VHDL描述:

process (clk)
begin
if clk’event and clk=’1’ then
if reset=’1’ then
data_out <= ’0’; 
else
if force_high=’1’ then 
data_out <= ’1’;
else
if  enable=’1’ then 
data_out <= a and b and c and d;
end if; 
end if;
end if;
end if;
end process;

Verilog描述:

    always@(posedge clk ) begin
        if(reset) begin
            data_out    <= 0;
        end
        else if(force_high) begin
            data_out    <= 1;
        end
        else if(enable) begin
            data_out    <= a&b&c&d;
        end
        else begin
            data_out    <= data_out;
        end
    end

单级逻辑

结论

看看你为最近的设计所写的HDL代码,观察你的优先级是否正确。有多少次你有一个异步复位,阻止任何后续的同步复位或置位直接在触发器上实现?有多少次你看到一个优先级高于同步复位的使能?并非所有这些问题都会迫使另一层逻辑的出现,但潜力肯定存在。如果你的设计是有效的,就不要改变它! 记住这句话,如果它没有坏,就不要修。对于你的下一个设计,只要想想你是如何写代码的,你就会发现有很多方法既能减少尺寸又能加快你的设计速度。

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 92 3 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
李锐博恩
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区