FPGA从入门到精通(2) - LUT

FPGA从入门到精通(2) - LUT

LUT:(look up table) 查找表

今天我要讲的与FPGA CLB相关的第一节LUT。根据上一节课的课程大纲,讲CLB应该是讲SLICEL(SLICEM)。不过当我打开用户手册,看了一下SLICE的结构时(图一),一眼望去,这是分分钟会劝退入门者的节奏啊。为了让读者能更好的接受以及理解,我打算先讲清楚SLICE里面的每一个基本单元,然后再将他们联系在一起,和读者一步步推导出SLICE的结构。(LUT, 进位链,MUX,寄存器,几乎所有的FPGA器件的SLICE都是这四大件组成,只是组合不太一样而已)

图1​​​​

在讲正式的课程内容前,我先列出学完这节课,你将会收获什么。

1.理解LUT与真值表的关系,明白FPGA是用LUT来替代门电路的,以及这样做的好处。

2.理解FPGA 是如何通过两个相同输入的LUT5和一个MUX组成LUT6的。(以此类推用两个相同输入的LUT6和一个MUX组成LUT7,这是课后作业。)


首先我们看例1的verilog代码,以及它编译后的门级电路 ,全都是与门,较为简单。(门电路的输入没标出,自己和代码自行脑补对应,这也是学习的一部分)

//以下是例1
module top(
    input clk,
    input rst,
    input data0,
    input data1,
    input data2,
    input data3,
    input data4,
    input data5,
    output dout
    );
 
 assign dout = data0&data1&data2&data3&data4&data5;
 
endmodule


例1编译后的门级电路

然后我们再看看例2的verilog代码,以及它编译后的门级电路 ,相对于例1又有与门,又有或门,还有异或,比较复杂。(门电路的输入没标出,自己和代码自行脑补对应,这也是学习的一部分)

//以下是例2
module top(
    input clk,
    input rst,
    input data0,
    input data1,
    input data2,
    input data3,
    input data4,
    input data5,
    output dout
    );
 
 assign dout = ((data0&data1)^data2|data3&data4^data5);

endmodule

例2编译后的门级电路

咦?怎么乍眼一看,除了连入的线的顺序外(例1顺序也可以改成例2的,这影响不大),两张图几乎是一模一样,是不是老哥我在忽悠观众。其实不然,是因为在FPGA中,是用LUT的来替代门电路,只要逻辑表达式是6位以内输入1位输出,无论编译后门电路复杂还是简单,综合后的结果都是一个LUT6。当然因为LUT6的结构的原因,当5位相同输入2位输出时,综合后的结果也是一个LUT6,本章后面会讲解。继续!

那么在这个LUT6里面又蕴含着什么玄机呢?我们不妨导出它的网表来看一看。

 //以下是例1网表中的LUT6
  LUT6 #(
    .INIT(64'h8000000000000000)) 
    dout_OBUF_inst_i_1
       (.I0(data5_IBUF),
        .I1(data0_IBUF),
        .I2(data2_IBUF),
        .I3(data1_IBUF),
        .I4(data4_IBUF),
        .I5(data3_IBUF),
        .O(dout_OBUF)); 


//以下是例2网表中的LUT6
LUT6 #(
    .INIT(64'h78FFFFFFFF787878)) 
    dout_OBUF_inst_i_1
       (.I0(data0_IBUF),
        .I1(data1_IBUF),
        .I2(data2_IBUF),
        .I3(data3_IBUF),
        .I4(data4_IBUF),
        .I5(data5_IBUF),
        .O(dout_OBUF));

​很显然,这两个LUT6中最大的不同,就是.INIT的值。那么,这个INIT的值又代表着是什么呢?下面我列出了例1和例2中的逻辑表达式所对应的真值表供各位看官参考,由于真值表太大了,我就只拿最高的8位与所导出的网表进行比对。不信的小伙伴可以留言跟我要画真值表的python的源文件以及所导出的真值表文件(●ˇ∀ˇ●)。

例1与例2导出的真值表结果图

网表文件中,例1(O=I0&I1&I2&I3&I4&I5)LUT的.INIT高八位为8'h80=8'b1000_0000,与图中相符。例2(O=(I0&I1)^I2|I3&I4^I5)LUT的.INIT高八位为8'h78=8'b0111_1000,也与图中相符。

由上面的结果我们可以得出,LUT6中INIT存放的结果初始值就是我们逻辑表达式真值表的结果,这就是LUT与真值表之间的关系啦,同时这也是FPGA最为“灵性”的地方,它用LUT来实现各式各样的门电路功能。只要是6位以内输入,1位输出的门电路,无论它多么的复杂,只需要我们修改LUT6的INIT值,都可以将其与门电路一一映射。

如果FPGA里面不是LUT而是各式各样的门电路,那么即便我们在器件做了很多门,却有可能,导致最终的利用率十分的低下。因为在实际应用情况不确定的情况下,我们根本不可能知道用与门,或门,非门还是别的门单元,也不可能不知道会有多少位的输入,多少位的输出。最终将导致器件规模巨大,不具有灵活性。但是使用LUT就恰恰相反,LUT可以用来替代各种门,以及它们的结合,因此用LUT作为FPGA的基本单元可以确保更多的LUT可以用上,来达到提高利用率的目的。

相信很多人都听说过LUT6本质上是64x1(深度为64,位宽为1)的ROM,因为当我们把它的输入I5~I0看作ROM的6根地址线,那么O就是当前输入地址所输出的结果。


之前我们提到,XILINX的LUT6除了可以做到6位输入1位输出,还可以做到5位相同的输入2位输出,那么它是怎么实现的呢?从下图中,我们可以看到XILINX的LUT6是有两个输出的,那这两个输出是怎么来的呢?不急,继续往下看!

XILINX中LUT6的结构

​​ 好吧,不卖关子,直接开奖,LUT6是由两个LUT5组成的,具体结构如下图(自己画的略丑,请见谅)。

1.当LUT6作为两个5位相同输入2位输出时,I5被强行写为1,MUX选择下面的LUT5的输出结果到O6,至于上面的那个LUT5输出结果,它是可以直接输出到O5的。所以可以有两个LUT5输出(O5,O6)。

2.当LUT6作为6位输入,1位输出时。上面的LUT5存放I5为0时的输出结果,下面的LUT5存放I5为1时的输出结果 ,将I5接入MUX的数据选择端口,那么两个LUT5和一个MUX就可以组成一个LUT6,此时O6为LUT6的输出,O5为上面的LUT5的输出(O5这个输出我们一般没怎么用到,容易被忽视)。

由两个LUT5与1个MUX构成LUT6

​下面,我简单的举个例子(例3)来验证5位相同输入2位输出的情况

//以下是例3
module top(
    input clk,
    input rst,
    input data0,
    input data1,
    input data2,
    input data3,
    input data4,
    output dout0,
    output dout1
    );
 
 assign dout0 = data0&data1&data2&data3&data4;
 assign dout1 = data0&data1|data2^data3&data4;
 
endmodule

例三综合后的原理图如下,从资源占用报告中可以看出,即便原理图是两个LUT5,但最终资源依旧和之前的例1,例2一样,只占用了1个LUT6。

例3综合后的原理图

​ 好的,说了那么多6输入1输出,5输入2输出的。但在实际的应用中,输入输出的数量会根据应用所需进行修改。那么应该如何修改呢?

1.当输出是1位,输入比6位少,那么我们只关注有效输入位真值表的结果。举个例子,我只用了两个输入(低2位),将它作为异或门。无论高4位(I5~I2)是啥,我们只需要将I1=0,I0=1或者I1=1,I0=0的真值表输出设为1,然后再把真值表64个输出结果写入LUT6的原语中的.INIT就好。

2.当输出是1位,输入比6位多。或者输出大于1位的情况,我们只需要使用多个LUT6并行处理就好。并行LUT6越多,也就意味着一个完整的多位输入得分为多个路径才能到输出,但实际情况中,路径的延迟很难保持一致,从而导致输出结果错误。所以我们通常需要使用到寄存器来同步后再将结果输出,以确保输出结果正确。同等条件下,如何让FPGA在以高频率运作的同时,输出结果尽可能保持正确,这就是让广大与FPGA相关工作者掉发的原因,-__-!!!!。好吧,今天就说到这。



再哔哔两句:

如今,某国对我国进行出口限制,其中就包括限制某国的FPGA,然而我们国产FPGA的老大哥紫光同创也只能达到X家、A家十年前的水平。这也意味着将来有可能很快会有那么一天,我们现在所用的国外那些高端的FPGA越来越少,越来越贵。到了那时,我们很有可能不得不用国产,用国产会有许许多多的限制,其中很重要的一点限制就是资源数(还有EDA IP 生态等等)。我们不能苛求国产厂家明天就研发出个7nm ,几百K资源的FPGA,但是我们能做到的就是在已有的条件下进一步优(ya)化(zha)FPGA上的资源,这是为什么我一开头会花那么多口水去讲FPGA的片上资源而不是上来就叫你怎么去用IP的原因。

不急不躁,打好基本功,不断的往上爬,终究有一天你会发现原来自己已经爬到那么高的地方了。

发布于 05-28

文章被以下专栏收录