xilinx7系列FPGA主要包括:Spartan®-7/Artix®-7/Kintex®-7/Virtex®-7。其性能/密度/价格也随着系列的不同而提升。其中以Virtex-7有着极高的系统性能和资源。本篇主要介绍其组成的基本单元configurable logic blocks(CLBs)。通常来说,我们不需要关心或参与逻辑综合过程CLBs资源的分配。但是如果遇到了性能/时序挑战的时候,就需要重新审视设计,掌握每一个可利用的资源。比如distributed RAMs和Block RAMs互换(在可替换的前提下)、DSPs与LUT设计等。同时也有助于掌握更深层次的设计,设计出更加合理的HDL代码,和XDC约束文件。
本文主要参考:xilinx官方文档UG474《7 Series FPGAs Configurable Logic Block》和White Paper《Xilinx 7 Series FPGAs:The Logical Advantage》。
CLBs是实现时序逻辑组合逻辑电路的主要逻辑单元。一个CLB由两个slice组成,而每个slice由4个6输入LUT、8个FF、复用器和算术进位单元组成。同时SLICE有区分为二:SLICEL和SLICEM(没有看到缩写L/M全程,个人认为是Logic和Multiple缩写,从下面定义可以看出)。大约2/3的是SLICEL(只能用于logic),剩下的是SLICEM(还可以用于distributed RAMs/SRLs32/SRLs16)。每个CLBs是通过Switch Matrix routing,并不是直接互联。注意到一句话:Four flip-flops per slice (one per LUT) can optionally be configured as latches. In that case, the remaining four flip-flops in that slice must remain unused.每个slice中的4个FF可以做锁存器,但是剩下的4个FF不能够再使用,也就是说有50%的资源浪费。这也就是为什么教科书上说,尽量避免latchs使用,除了时序问题之外,还有资源浪费。从芯片资源手册也可以看出,以kintex-7为例:
Slices = SliceL + SliceM;SliceL / SliceM = 2;Slices / LUTs = 4;FF / Slices = 8。
两个slice分别位于CLB的左列底部和右列顶部。这两个slice不是直接互联,而是以列为单位,通过一个独立的进位链(Cout&&Cin)
接。如下图所示:
通过以上的分析,每个CLBs具体的资源配置如下:
注意:如前面所述,只有SLICEM可以配置成distributed RAMs和SRLs。
通过xilinx vivado提供给implementment,可以看到实际情况(vivado 2017.4 kintex 7为例):
每个CLB包括两个slice(两个SLICEL或者一个SLICEM一个SLICEM·)---8个6输入LUTs(逻辑产生单元),16个FF,以及3个Multiplexer(F7AMUX/F7BMUX/F8MUX)和carry chain组成。
LUT:由6个独立的输入A1-A6和两个独立的输出组成O5、O6。
能够实现:
1. 任意的6输入布尔逻辑:A1-A6作为输入,O6作为输出。
2. 两个5输入或者更少的:A1-A5作为输入,A6高,O5和O6作为输出。
经过LUTs的信号可以:不做操作(直接出来slice)/从O6出来进入XOR专用门/从O5出来进入进位链/接入D触发器输入/从O6进入F7AMUX/F7BMUX。F7AMUX和F7BMUX作用是组合4个LUTs,在一个slice中产生任意的7或者8输入。对于大于8输入的逻辑,则需要多个slice。值得注意的是对于大于8输入的多个slice,没有直接连接在一起。
下面深入理解一下上面文档的含义:
-
always@(posedge sys_clk)
-
begin
-
case(key_in)
-
6 'b000_001: key_edge <= 1'b1;
-
6 'b000_010: key_edge <= 1'b0;
-
6 'b000_100: key_edge <= 1'b1;
-
6 'b001_000: key_edge <= 1'b0;
-
6 'b010_000: key_edge <= 1'b1;
-
6 'b100_000: key_edge <= 1'b0;
-
default:key_edge <= 1 'b1;
-
endcase
-
end


7系列FPGA是Xilinx新推出的基于28nm工艺的FPGA,其中包含三个系列:Artix、Kintex和Virtex。因项目要使用kintex7为平台做设计,需要对其内部结构做了研究,首先从CLB(Configurable Logic Block)开始:
CLB构成了Kintex7主要逻辑单元,其中包含2个Slice,并且Slice分为2种:SLICEL和SLICEM,SLICEL为普通的Slice逻辑单元,而SLICEM在基本逻辑功能的基础上可以扩展为分布式RAM或者移位寄存器。在所有Slice资源中,有2/3是SLICEL,因此一个CLB可以有2个SLICEL或者1个SLICEL、1个SLICEM组成。
如图1所示为SLICEM的内部结构,其中包含4个6输入LUT(红色圈)、进位链(黄色圈)、多路复用器(蓝色圈)和8个寄存器(绿色圈)。

图1
6-input LUT:此处LUT沿用了Xilinx 6系列FPGA的6输入LUT结构,6-input LUT内部是由2个5-input LUT组成,有两个输出分别对应O6和O5。在设计中,如果综合后有2个5-input LUT需要是使用,如果在ISE将综合选项-lc(LUT Combining)设置成Area,综合器XST会将这2个5-input LUT合并在一个6-input LUT中实现,但是此选项相当于以速度换面积,随之逻辑延时将增大。
寄存器:此处Xilinx区别于Altera器件,其1个LUT对应了2个register,而Altera器件中是一一对应的。从图中可以发现,第2列的register比第1列多了FF/LAT这个选项,这表示第1列的register只能作为Flip-Flop使用,而第2列的register既能作为Flip-Flop也能作为Latch使用。另外还有INIT0、INIT1、SRLO和SRHI 四个选项,其中INIT0和INIT1配对,表示通过GSR全局复位/置位,此复位/置位网络为异步的;而SRLO和SRHI配对,表示高电平有效信号SR驱动的复位/置位,此信号可以配置成异步或者同步,但这8个register共用一个SR信号,因此其方式必须相同,根据此特性,建议写代码时,复位/置位方式选择同步高电平有效。
下面对SLICEM做一下重点说明,其可扩展成移位寄存器,如图2所示,Slice中的每个LUT可配置成32-bit的Shift Register,因此1个Slice最多可扩展成128-bit的Shift Register。其操作模式为1个时钟周期移1为,通过D输入端输入,并且最后1位通过MC31输出,并且可以以A[6:2]作为5位地址选择O6输出32位中的某一位进行输出。

图2
在写代码时,可以按规范写出移位寄存器的形式,如以下代码所示:
always@(posedge clk)
if(clk_en)
srl<={srl[31:0],din};
assign dout0=srl[20];
以上代码综合出的结构如图3所示,综合器只用了1个LUT和1个FF就实现了21-bit的移位寄存器,只需1个Slice。

图3
如按一下代码进行综合后得到结构如图4所示,综合器使用了21个FF实现了这个21-bit移位寄存器,则需要21个Slice。
always@(posedge clk)
if(rst)
srl<=32’d0;
else
if(clk_en)
srl<={srl[31:0],din};
assign dout0=srl[20];

图4
为什么综合器会产生不同的结构?分析一下代码的区别,第二段代码相比于第二段代码多了一个同步复位功能,而根据SLICEM的结构,其中的LUT是没有同步复位控制输入端的,因此综合器无法将代码综合成想要的结构,因此写代码时需要根据相应的结构来编写。
观察图3可以发现,在SRLC32E输出端Q后又接入了一个FF作为同步输出,查手册后发现,此移位寄存器可以配置成两种输出模式:静态地址方式和动态地址方式,这两种模式的不同之处在于静态地址方式是同步输出,图3中结构是静态地址方式;而动态地址方式是异步输出,即没有后接FF直接从SRLC32E的Q端输出,以下代码表示动态地址方式,其中addr是一个变量。
always@(posedge clk)
if(rst)
srl<=32’d0;
else
if(clk_en)
srl<={srl[31:0],din};
assign dout0=srl[addr];
对上面的代码进行综合可以得到如图5所示结构,确定输出为异步输出,因此在设计中要注意此处的变化。

图5
转自:https://blog.youkuaiyun.com/nearcsy/article/details/80418962
https://blog.youkuaiyun.com/xuexiaokkk/article/details/48340719