2024年3月18日发(作者:吉韦曲)
Xilinx公司原语的使用方法2
3.4.7 RAM/ROM组件
RAM/ROM组件可用于例化FIFO、分布式RAM、分布式RAM、块ROM以
及块ROM,具体包括12个组件,如表3-16所示。
表3-16 RAM/ROM原语列表
下面主要介绍FIFO、分布式双口RAM以及块双口RAM原语的使用,单口
RAM和ROM原语的用法类似,限于篇幅,就不再介绍。
1.RAM16X1S
RAM16X1S是深度为16比特,位宽为1的同步RAM。当写使能信号WE
为低时,写端口的数据操作无效,RAM内部的数据不会改变;当WE为高
时,可以在任意地址中写入比特。为了保证数据的稳定性,地址和数据应该
在WCLK的上升沿前保持稳定。输出信号O为RAM中由读地址信号所确
定的地址中所存数据的值。此外,还可通过属性指定RAM的初始值。
RAM16X1S原语的例化代码模版如下所示:
// RAM16X1S: 16比特1深度同步RAM(16 x 1 posedge write distributed (LUT)
RAM)
// 适用芯片:所有芯片
// Xilinx HDL库向导版本,ISE 9.1
RAM16X1S #(
.INIT(16'h0000)
//对RAM的内容进行初始化,这里初始化为全1
) RAM16X1S_inst (
.O(O), // RAM output
.A0(A0), // RAM address[0] input
.A1(A1), // RAM address[1] input
.A2(A2), // RAM address[2] input
.A3(A3), // RAM address[3] input
.D(D), // RAM data input
.WCLK(WCLK), // Write clock input
.WE(WE) // Write enable input
);
// 结束RAM16X1S模块的例化过程
需要注意的是,RAM16X1S原语是Xilinx独有的一类结构,在小数据量存
储方面非常节省资源。在综合结果分析时,RAM16X1S原语的RTL结构如
图3-45所示。
图3-45 原语RAM16X1S的RTL结构图
2.RAMB16
RAMB16是FPGA芯片中内嵌的双口块RAM,数据位宽可配置成1、2、4、
9、18以及36比特,每个块RAM的大小为18 1024比特,所以位宽越大,
深度越小。块RAM在FPGA中按照矩阵的方式排列,其数量完全取决于芯
片容量的大小。在使用中,可以添加坐标来约束块RAM的位置。例如:
LOC = RAMB16_X#Y#;
同样,也可以对块RAM完成初始化。块RAM是以硬核的方式内嵌到FPGA
芯片中,不占用芯片的逻辑资源,是FPGA芯片内部非常宝贵的一种资源。
在工作时,要尽量使用芯片的块RAM资源,不仅能保证较高的工作频率,
还具有很低的动态功耗。
RAMB16的Verilog例化代码如下所示。
// RAMB16: 块RAM(Virtex-4 16k+2k Parity Paramatizable BlockRAM
// 适用芯片:Virtex-4芯片
// Xilinx HDL库向导版本,ISE 9.1
RAMB16 #(
.DOA_REG(0),
// A端口可选的输出寄存器,可设置为0或1,分别表示输出不寄存/寄存
.DOB_REG(0),
// B端口可选的输出寄存器,可设置为0或1,分别表示输出不寄存/寄存
.INIT_A(36'h000000000),
// 初始化A端口的输出初始值
.INIT_B(36'h000000000),
// 初始化A端口的输出初始值
.INVERT_CLK_DOA_REG("FALSE"),
// 反转A端口寄存器的时钟,可设置为"TRUE"或 "FALSE",分别表示不反
转/反转
.INVERT_CLK_DOB_REG("FALSE"),
// 反转B端口寄存器的时钟,可设置为"TRUE"或 "FALSE",分别表示不反
转/反转
.RAM_EXTENSION_A("NONE"),
// RAM的A端口扩展选项,可设置为"UPPER"、"LOWER"或 "NONE",分
别表示作为// 高字节、低字节级联,或者不扩展
.RAM_EXTENSION_B("NONE"),
// RAM的B端口扩展选项.READ_WIDTH_A(0),同A端口
.READ_WIDTH_A(0),
// A端口的数据读取宽度,有效值为1, 2, 4, 9, 18, 或36
.READ_WIDTH_B(0),
// B端口的数据读取宽度,有效值为1, 2, 4, 9, 18, 或36
.SIM_COLLISION_CHECK("ALL"),
// 碰撞检测使能信号,可设置为"ALL"、"WARNING_ONLY"、
"GENERATE_X_ONLY" // 或者"NONE"
.SRVAL_A(36'h000000000),
// 复位后A端口的输出值
.SRVAL_B(36'h000000000),
//复位后A端口的输出值
.WRITE_MODE_A("WRITE_FIRST"),
// A端口的写模式,可设置为"WRITE_FIRST", "READ_FIRST", 或
"NO_CHANGE"
.WRITE_MODE_B("WRITE_FIRST"),
// B端口的写模式,可设置为"WRITE_FIRST", "READ_FIRST", 或
"NO_CHANGE"
.WRITE_WIDTH_A(2),
// A端口的数据写入宽度,有效值为1, 2, 4, 9, 18, 或36
.WRITE_WIDTH_B(0),
// B端口的数据写入宽度,有效值为1, 2, 4, 9, 18, 或36
// 下列INIT_xx 声明用于指定RAM的初始化内容
.INIT_00(256'h0000
),
.INIT_01(256'h0000
),
.INIT_02(256'h0000
),
.INIT_03(256'h0000
),
.INIT_04(256'h0000
),
.INIT_05(256'h0000
),
.INIT_06(256'h0000
),
.INIT_07(256'h0000
),
.INIT_08(256'h0000
),
.INIT_09(256'h0000
),
.INIT_0A(256'h0000
),
.INIT_0B(256'h0000
),
.INIT_0C(256'h0000
),
.INIT_0D(256'h0000
),
.INIT_0E(256'h0000
),
.INIT_0F(256'h0000
),
.INIT_10(256'h0000
),
.INIT_11(256'h0000
),
.INIT_12(256'h0000
),
.INIT_13(256'h0000
),
.INIT_14(256'h0000
),
.INIT_15(256'h0000
),
.INIT_16(256'h0000
),
.INIT_17(256'h0000
),
.INIT_18(256'h0000
),
.INIT_19(256'h0000
),
.INIT_1A(256'h0000
),
.INIT_1B(256'h0000
),
.INIT_1C(256'h0000
),
.INIT_1D(256'h0000
),
.INIT_1E(256'h0000
),
.INIT_1F(256'h0000
),
.INIT_20(256'h0000
),
.INIT_21(256'h0000
),
.INIT_22(256'h0000
),
.INIT_23(256'h0000
),
.INIT_24(256'h0000
),
.INIT_25(256'h0000
),
.INIT_26(256'h0000
),
.INIT_27(256'h0000
),
.INIT_28(256'h0000
),
.INIT_29(256'h0000
),
.INIT_2A(256'h0000
),
.INIT_2B(256'h0000
),
.INIT_2C(256'h0000
),
.INIT_2D(256'h0000
),
.INIT_2E(256'h0000
),
.INIT_2F(256'h0000
),
.INIT_30(256'h0000
),
.INIT_31(256'h0000
),
.INIT_32(256'h0000
),
.INIT_33(256'h0000
),
.INIT_34(256'h0000
),
.INIT_35(256'h0000
),
.INIT_36(256'h0000
),
.INIT_37(256'h0000
),
.INIT_38(256'h0000
),
.INIT_39(256'h0000
),
.INIT_3A(256'h0000
),
.INIT_3B(256'h0000
),
.INIT_3C(256'h0000
),
.INIT_3D(256'h0000
),
.INIT_3E(256'h0000
),
.INIT_3F(256'h0000
),
// 下面的INITP_xx 用于初始化校验比特
.INITP_00(256'h000
0),
.INITP_01(256'h000
0),
.INITP_02(256'h000
0),
.INITP_03(256'h000
0),
.INITP_04(256'h000
0),
.INITP_05(256'h000
0),
.INITP_06(256'h000
0),
.INITP_07(256'h000
0)
) RAMB16_inst (
.CASCADEOUTA(CASCADEOUTA), // A端口的1比特级联输出
.CASCADEOUTB(CASCADEOUTB), // B端口的1比特级联输出
.DOA(DOA), // A端口的32比特数据输出
.DOB(DOB), // B端口的32比特数据输出
.DOPA(DOPA), // A端口4比特校验数据输出
.DOPB(DOPB), // B端口4比特校验数据输出
.ADDRA(ADDRA), // A端口15比特地址输入
.ADDRB(ADDRB), // B端口15比特地址输入
.CASCADEINA(CASCADEINA), // A端口1比特级联地址输入
.CASCADEINB(CASCADEINB), // B端口1比特级联地址输入
.CLKA(CLKA), //A端口的工作时钟输入
.CLKB(CLKB), // B端口的工作时钟输入
.DIA(DIA), // A端口的32比特写数据
.DIB(DIB), // A端口的32比特写数据
.DIPA(DIPA), //A端口4比特校验输入数据
.DIPB(DIPB), //B端口4比特校验输入数据
.ENA(ENA), //A端口的1比特使能信号
.ENB(ENB), //B端口的1比特使能信号
.REGCEA(REGCEA), //A端口1比特寄存器使能信号
.REGCEB(REGCEB), //B端口1比特寄存器使能信号
.SSRA(SSRA), // A端口1比特复位输入信号
.SSRB(SSRB), // B端口1比特复位输入信号
.WEA(WEA), // A端口4比特写使能输入信号
.WEB(WEB) // B端口4比特写使能输入信号
);
// 结束RAMB16模块的例化过程
在综合结果分析时,RAMB16的RTL结构如图3-46所示。
图3-46 RAMB16的RTL结构示意图
3.4.8 寄存器和锁存器
寄存器和锁存器是时序电路中常用的基本元件,其原语在表3-17中给出。
表3-17 寄存器和锁存器原语列表
下面只介绍FDCPE原语的使用,其余两个原语的使用方法类似。
1.FDCPE原语
FDCPE指带单数据输入信号D、单输出O、时钟使能信号CE、异步复位PRE
和异步清空信号CLR的D触发器。当PRE信号为高时,输出端O为高;当
CLR为高时,输出端O为低;当PRE和CLR都为低、CE信号为高时,输
入信号D在时钟上升沿被加载到触发器中,并被送到输出端;当PRE和CLR
都为低、CE信号为低时,输出端保持不变。FDCPE的真值表如表3-18所列。
表3-18 FDCPE原语的真值表
FDCPE原语的Verilog实例化代码如下所示:
// FDCPE: D触发器(Single Data Rate D Flip-Flop )
// 适用芯片:所有FPGA芯片
// Xilinx HDL库向导版本,ISE 9.1
FDCPE #(
.INIT(1'b0)
//初始化寄存器的值,可设置为1'b0或1'b1
) FDCPE_inst (
.Q(Q), // 数据输出端口
.C(C), // 时钟输入端口
.CE(CE), // 时钟使能输入信号
.CLR(CLR), // 异步清空输入信号
.D(D), // 数据输入信号
.PRE(PRE) // 异步复位输入信号
);
// 结束FDCPE模块的例化过程
在综合结果分析时,FDCPE原语的RTL结构如图3-47所示。
图3-47 FDCPE的RTL结构
3.4.9 移位寄存器组件
移位寄存器组件为Xilinx芯片所独有,由于属性的不同,具体有8个,如表
3-19所列。
表3-19移位寄存器组件列表
各个移位寄存器原语都是在SRL16的基础上发展起来的,因此,本节主要
介绍基本的SRL16原语。
1.SRL16原语
SRL16是基于查找表(LUT)的移位寄存器,在实际应用中既能节省资源,
还能保证时序。其输入信号A3、A2、A1以及A0选择移位寄存器的读取地
址,当写使能信号高有效时,输入信号将被加载到移位寄存器中。单个移位
寄存器的深度可以是固定的,也可以动态调整,最大不能超过16。需要更
大深度的移位寄存器时,则需要将多个SRL16拼接起来。单个SRL16的地
址信号线与输出的真值表如表3-20所示。
表3-20 SRL16的功能说明表
SRL16本质上是一种基于查找表(LUT)的移位寄存器,因此其位宽(B)
和深度(D)需要满足查找表的结构特点,所占用Slice资源M的计算公式
为:
其中,R[]函数的意义是取整。从上式可以看出,深度为1的移位寄存器和
深度为16的移位寄存器所占用的Slice资源是一样的。和触发器相比,SRL16
最大的特点就是占用Slice资源特别少。
只要固定A3~A0的信号电平,即可获得一个固定长度的移位寄存器,其长
度范围从1~16,可由公式(M)计算得到。当A3~A0全为0时,其寄存深
度为1;当A3~A0全为1时,其寄存深度为16。
Length = (8 x A3) +(4 x A2) + (2 x A1) + A0 +1 (M)
SRL16原语的Verilog实例化代码如下所示:
// SRL16: 16位查找表移位寄存器(16-bit shift register LUT operating on
posedge of clock)
// 适用芯片:所有FPGA芯片
// Xilinx HDL库向导版本,ISE 9.1
SRL16 #(
.INIT(16'h0000)
// 初始化移位寄存器的值,可以为16比特任意整数
) SRL16_inst (
.Q(Q), // SRL16的数据输出信号
.A0(A0), // 选择[0]输入
.A1(A1), // 选择[1]输入
.A2(A2), // 选择[2]输入
.A3(A3), // 选择[3]输入
.CLK(CLK), // 时钟输入信号
.D(D) // SRL16的数据输入信号
);
// 结束SRL16模块的例化过程
在综合结果分析时,SRL16原语的RTL级结构如图3-48所示。
图3-48 SRL16的RTL级结构示意图
3.4.10 Slice/CLB组件
Slice/CLB组件涵盖了Xilinx FPGA中所有的逻辑单元,包括各种查找表、
复用器以及逻辑操作等21个原语,如表3-21所列。
表3-21 Slice/CLB组件列表
本节主要介绍基本的单输出1比特查找表原语和通用输出2到1复用器原语
的使用方法。
1.LUT1原语
FPGA内部的组合逻辑都可以通过LUT结构实现,常用的LUT结构有LUT1、
LUT2、LUT3以及LUT4,其区别在于查找表输入比特宽度的不同。LUT1
是其中最简单的一种,常用于实现缓冲器和反相器,是带通用输出的1比特
查找表。
LUT1原语的Verilog实例化代码如下所示:
// LUT1: 1比特输入的通用查找表(1-input Look-Up Table with general
output)
// 适用芯片:所有FPGA芯片
// Xilinx HDL库向导版本,ISE 9.1
LUT1 #(
.INIT(2'b00)
// 指定LUT的初始化内容
) LUT1_inst (
.O(O), // LUT的通用输出
.I0(I0) // LUT输入信号
);
// 结束LUT1模块的例化过程
在综合结构分析时,LUT1原语的RTL级结构如图3-49所示。
图3-49 LUT1的RTL级结构示意图
2.MUXF7原语
MUXF7是带通用输出的2到1查找表复用器,其控制信号S可以是任何内
部信号,当其为低电平时,选择I0;当其为高电平时选择I1。MUXF7需要
占用一个完整的CLB资源,和其相关的查找表可组成7功能的查找表和16
到1的选择器,可将MUXF6的输出连接到MUXF7的输入端。MUXF7的
真值表如表3-22所示。
表3-22 MUXF7的真值表
MUXF7原语的实例化代码如下所示:
// MUXF7: 2到1LUT复用器(CLB MUX to tie two MUXF6's together with
general output)
// 适用芯片:Virtex-II/II-Pro 以及Spartan-3/3E
// Xilinx HDL库向导版本,ISE 9.1
MUXF7 MUXF7_inst (
.O(O), // MUX的通用输出信号
.I0(I0),
.I1(I1), // 复用器的输入信号,连接到MUXF6 LO
.S(S) // 复用器的输入选择信号
);
// End of MUXF7_inst instantiation
在综合结构分析时,MUXF7原语的RTL级结构如图3-50所示。
图3-50 MUXF7的RTL及结构示意图
本节给出了典型的Xilinx原语的使用,但更多的原语需要读者在实践中大量
应用才能熟练掌握。只有全面掌握了原语,才能对Xilinx FPGA的资源有一
个理性认识,从而将工程设计提升到艺术雕刻的高度,这是每一个FPGA开
发人员的目标。详细的原语资料可在ISE安装目录下的“docusenglish
booksdocs”文件夹中找到,其中Virtex4系列芯片的原语资料文件“”
位于“v4ldl”文件中,Virtex5系列芯片的原语资料文件“”位于“v5ldl”
文件中,Spartan 3A系列芯片的原语资料文件“”位于“s3adl”文件中,
Spartan 3E系列芯片的原语资料文件“”位于“s3edl”文件中。
3.5 本章小结
本章主要介绍基于Xilinx芯片的Verilog开发技术。首先介绍了典型的硬件
设计思维;然后讨论了优秀的通用代码风格和Xilinx专用的代码风格,无论
哪种风格都是稳定性、速度以及硬件资源三者优化,只不过前者从FPGA器
件共有的特性出发,后者则面向Xilinx公司的FPGA芯片特点;最后,介绍
了Xilinx公司FPGA器件的硬件原语,以及典型原语的使用方法。特别需要
强调的一点是:对原语的全面掌握是Xilinx FPGA开发人员的基本要求。
2024年3月18日发(作者:吉韦曲)
Xilinx公司原语的使用方法2
3.4.7 RAM/ROM组件
RAM/ROM组件可用于例化FIFO、分布式RAM、分布式RAM、块ROM以
及块ROM,具体包括12个组件,如表3-16所示。
表3-16 RAM/ROM原语列表
下面主要介绍FIFO、分布式双口RAM以及块双口RAM原语的使用,单口
RAM和ROM原语的用法类似,限于篇幅,就不再介绍。
1.RAM16X1S
RAM16X1S是深度为16比特,位宽为1的同步RAM。当写使能信号WE
为低时,写端口的数据操作无效,RAM内部的数据不会改变;当WE为高
时,可以在任意地址中写入比特。为了保证数据的稳定性,地址和数据应该
在WCLK的上升沿前保持稳定。输出信号O为RAM中由读地址信号所确
定的地址中所存数据的值。此外,还可通过属性指定RAM的初始值。
RAM16X1S原语的例化代码模版如下所示:
// RAM16X1S: 16比特1深度同步RAM(16 x 1 posedge write distributed (LUT)
RAM)
// 适用芯片:所有芯片
// Xilinx HDL库向导版本,ISE 9.1
RAM16X1S #(
.INIT(16'h0000)
//对RAM的内容进行初始化,这里初始化为全1
) RAM16X1S_inst (
.O(O), // RAM output
.A0(A0), // RAM address[0] input
.A1(A1), // RAM address[1] input
.A2(A2), // RAM address[2] input
.A3(A3), // RAM address[3] input
.D(D), // RAM data input
.WCLK(WCLK), // Write clock input
.WE(WE) // Write enable input
);
// 结束RAM16X1S模块的例化过程
需要注意的是,RAM16X1S原语是Xilinx独有的一类结构,在小数据量存
储方面非常节省资源。在综合结果分析时,RAM16X1S原语的RTL结构如
图3-45所示。
图3-45 原语RAM16X1S的RTL结构图
2.RAMB16
RAMB16是FPGA芯片中内嵌的双口块RAM,数据位宽可配置成1、2、4、
9、18以及36比特,每个块RAM的大小为18 1024比特,所以位宽越大,
深度越小。块RAM在FPGA中按照矩阵的方式排列,其数量完全取决于芯
片容量的大小。在使用中,可以添加坐标来约束块RAM的位置。例如:
LOC = RAMB16_X#Y#;
同样,也可以对块RAM完成初始化。块RAM是以硬核的方式内嵌到FPGA
芯片中,不占用芯片的逻辑资源,是FPGA芯片内部非常宝贵的一种资源。
在工作时,要尽量使用芯片的块RAM资源,不仅能保证较高的工作频率,
还具有很低的动态功耗。
RAMB16的Verilog例化代码如下所示。
// RAMB16: 块RAM(Virtex-4 16k+2k Parity Paramatizable BlockRAM
// 适用芯片:Virtex-4芯片
// Xilinx HDL库向导版本,ISE 9.1
RAMB16 #(
.DOA_REG(0),
// A端口可选的输出寄存器,可设置为0或1,分别表示输出不寄存/寄存
.DOB_REG(0),
// B端口可选的输出寄存器,可设置为0或1,分别表示输出不寄存/寄存
.INIT_A(36'h000000000),
// 初始化A端口的输出初始值
.INIT_B(36'h000000000),
// 初始化A端口的输出初始值
.INVERT_CLK_DOA_REG("FALSE"),
// 反转A端口寄存器的时钟,可设置为"TRUE"或 "FALSE",分别表示不反
转/反转
.INVERT_CLK_DOB_REG("FALSE"),
// 反转B端口寄存器的时钟,可设置为"TRUE"或 "FALSE",分别表示不反
转/反转
.RAM_EXTENSION_A("NONE"),
// RAM的A端口扩展选项,可设置为"UPPER"、"LOWER"或 "NONE",分
别表示作为// 高字节、低字节级联,或者不扩展
.RAM_EXTENSION_B("NONE"),
// RAM的B端口扩展选项.READ_WIDTH_A(0),同A端口
.READ_WIDTH_A(0),
// A端口的数据读取宽度,有效值为1, 2, 4, 9, 18, 或36
.READ_WIDTH_B(0),
// B端口的数据读取宽度,有效值为1, 2, 4, 9, 18, 或36
.SIM_COLLISION_CHECK("ALL"),
// 碰撞检测使能信号,可设置为"ALL"、"WARNING_ONLY"、
"GENERATE_X_ONLY" // 或者"NONE"
.SRVAL_A(36'h000000000),
// 复位后A端口的输出值
.SRVAL_B(36'h000000000),
//复位后A端口的输出值
.WRITE_MODE_A("WRITE_FIRST"),
// A端口的写模式,可设置为"WRITE_FIRST", "READ_FIRST", 或
"NO_CHANGE"
.WRITE_MODE_B("WRITE_FIRST"),
// B端口的写模式,可设置为"WRITE_FIRST", "READ_FIRST", 或
"NO_CHANGE"
.WRITE_WIDTH_A(2),
// A端口的数据写入宽度,有效值为1, 2, 4, 9, 18, 或36
.WRITE_WIDTH_B(0),
// B端口的数据写入宽度,有效值为1, 2, 4, 9, 18, 或36
// 下列INIT_xx 声明用于指定RAM的初始化内容
.INIT_00(256'h0000
),
.INIT_01(256'h0000
),
.INIT_02(256'h0000
),
.INIT_03(256'h0000
),
.INIT_04(256'h0000
),
.INIT_05(256'h0000
),
.INIT_06(256'h0000
),
.INIT_07(256'h0000
),
.INIT_08(256'h0000
),
.INIT_09(256'h0000
),
.INIT_0A(256'h0000
),
.INIT_0B(256'h0000
),
.INIT_0C(256'h0000
),
.INIT_0D(256'h0000
),
.INIT_0E(256'h0000
),
.INIT_0F(256'h0000
),
.INIT_10(256'h0000
),
.INIT_11(256'h0000
),
.INIT_12(256'h0000
),
.INIT_13(256'h0000
),
.INIT_14(256'h0000
),
.INIT_15(256'h0000
),
.INIT_16(256'h0000
),
.INIT_17(256'h0000
),
.INIT_18(256'h0000
),
.INIT_19(256'h0000
),
.INIT_1A(256'h0000
),
.INIT_1B(256'h0000
),
.INIT_1C(256'h0000
),
.INIT_1D(256'h0000
),
.INIT_1E(256'h0000
),
.INIT_1F(256'h0000
),
.INIT_20(256'h0000
),
.INIT_21(256'h0000
),
.INIT_22(256'h0000
),
.INIT_23(256'h0000
),
.INIT_24(256'h0000
),
.INIT_25(256'h0000
),
.INIT_26(256'h0000
),
.INIT_27(256'h0000
),
.INIT_28(256'h0000
),
.INIT_29(256'h0000
),
.INIT_2A(256'h0000
),
.INIT_2B(256'h0000
),
.INIT_2C(256'h0000
),
.INIT_2D(256'h0000
),
.INIT_2E(256'h0000
),
.INIT_2F(256'h0000
),
.INIT_30(256'h0000
),
.INIT_31(256'h0000
),
.INIT_32(256'h0000
),
.INIT_33(256'h0000
),
.INIT_34(256'h0000
),
.INIT_35(256'h0000
),
.INIT_36(256'h0000
),
.INIT_37(256'h0000
),
.INIT_38(256'h0000
),
.INIT_39(256'h0000
),
.INIT_3A(256'h0000
),
.INIT_3B(256'h0000
),
.INIT_3C(256'h0000
),
.INIT_3D(256'h0000
),
.INIT_3E(256'h0000
),
.INIT_3F(256'h0000
),
// 下面的INITP_xx 用于初始化校验比特
.INITP_00(256'h000
0),
.INITP_01(256'h000
0),
.INITP_02(256'h000
0),
.INITP_03(256'h000
0),
.INITP_04(256'h000
0),
.INITP_05(256'h000
0),
.INITP_06(256'h000
0),
.INITP_07(256'h000
0)
) RAMB16_inst (
.CASCADEOUTA(CASCADEOUTA), // A端口的1比特级联输出
.CASCADEOUTB(CASCADEOUTB), // B端口的1比特级联输出
.DOA(DOA), // A端口的32比特数据输出
.DOB(DOB), // B端口的32比特数据输出
.DOPA(DOPA), // A端口4比特校验数据输出
.DOPB(DOPB), // B端口4比特校验数据输出
.ADDRA(ADDRA), // A端口15比特地址输入
.ADDRB(ADDRB), // B端口15比特地址输入
.CASCADEINA(CASCADEINA), // A端口1比特级联地址输入
.CASCADEINB(CASCADEINB), // B端口1比特级联地址输入
.CLKA(CLKA), //A端口的工作时钟输入
.CLKB(CLKB), // B端口的工作时钟输入
.DIA(DIA), // A端口的32比特写数据
.DIB(DIB), // A端口的32比特写数据
.DIPA(DIPA), //A端口4比特校验输入数据
.DIPB(DIPB), //B端口4比特校验输入数据
.ENA(ENA), //A端口的1比特使能信号
.ENB(ENB), //B端口的1比特使能信号
.REGCEA(REGCEA), //A端口1比特寄存器使能信号
.REGCEB(REGCEB), //B端口1比特寄存器使能信号
.SSRA(SSRA), // A端口1比特复位输入信号
.SSRB(SSRB), // B端口1比特复位输入信号
.WEA(WEA), // A端口4比特写使能输入信号
.WEB(WEB) // B端口4比特写使能输入信号
);
// 结束RAMB16模块的例化过程
在综合结果分析时,RAMB16的RTL结构如图3-46所示。
图3-46 RAMB16的RTL结构示意图
3.4.8 寄存器和锁存器
寄存器和锁存器是时序电路中常用的基本元件,其原语在表3-17中给出。
表3-17 寄存器和锁存器原语列表
下面只介绍FDCPE原语的使用,其余两个原语的使用方法类似。
1.FDCPE原语
FDCPE指带单数据输入信号D、单输出O、时钟使能信号CE、异步复位PRE
和异步清空信号CLR的D触发器。当PRE信号为高时,输出端O为高;当
CLR为高时,输出端O为低;当PRE和CLR都为低、CE信号为高时,输
入信号D在时钟上升沿被加载到触发器中,并被送到输出端;当PRE和CLR
都为低、CE信号为低时,输出端保持不变。FDCPE的真值表如表3-18所列。
表3-18 FDCPE原语的真值表
FDCPE原语的Verilog实例化代码如下所示:
// FDCPE: D触发器(Single Data Rate D Flip-Flop )
// 适用芯片:所有FPGA芯片
// Xilinx HDL库向导版本,ISE 9.1
FDCPE #(
.INIT(1'b0)
//初始化寄存器的值,可设置为1'b0或1'b1
) FDCPE_inst (
.Q(Q), // 数据输出端口
.C(C), // 时钟输入端口
.CE(CE), // 时钟使能输入信号
.CLR(CLR), // 异步清空输入信号
.D(D), // 数据输入信号
.PRE(PRE) // 异步复位输入信号
);
// 结束FDCPE模块的例化过程
在综合结果分析时,FDCPE原语的RTL结构如图3-47所示。
图3-47 FDCPE的RTL结构
3.4.9 移位寄存器组件
移位寄存器组件为Xilinx芯片所独有,由于属性的不同,具体有8个,如表
3-19所列。
表3-19移位寄存器组件列表
各个移位寄存器原语都是在SRL16的基础上发展起来的,因此,本节主要
介绍基本的SRL16原语。
1.SRL16原语
SRL16是基于查找表(LUT)的移位寄存器,在实际应用中既能节省资源,
还能保证时序。其输入信号A3、A2、A1以及A0选择移位寄存器的读取地
址,当写使能信号高有效时,输入信号将被加载到移位寄存器中。单个移位
寄存器的深度可以是固定的,也可以动态调整,最大不能超过16。需要更
大深度的移位寄存器时,则需要将多个SRL16拼接起来。单个SRL16的地
址信号线与输出的真值表如表3-20所示。
表3-20 SRL16的功能说明表
SRL16本质上是一种基于查找表(LUT)的移位寄存器,因此其位宽(B)
和深度(D)需要满足查找表的结构特点,所占用Slice资源M的计算公式
为:
其中,R[]函数的意义是取整。从上式可以看出,深度为1的移位寄存器和
深度为16的移位寄存器所占用的Slice资源是一样的。和触发器相比,SRL16
最大的特点就是占用Slice资源特别少。
只要固定A3~A0的信号电平,即可获得一个固定长度的移位寄存器,其长
度范围从1~16,可由公式(M)计算得到。当A3~A0全为0时,其寄存深
度为1;当A3~A0全为1时,其寄存深度为16。
Length = (8 x A3) +(4 x A2) + (2 x A1) + A0 +1 (M)
SRL16原语的Verilog实例化代码如下所示:
// SRL16: 16位查找表移位寄存器(16-bit shift register LUT operating on
posedge of clock)
// 适用芯片:所有FPGA芯片
// Xilinx HDL库向导版本,ISE 9.1
SRL16 #(
.INIT(16'h0000)
// 初始化移位寄存器的值,可以为16比特任意整数
) SRL16_inst (
.Q(Q), // SRL16的数据输出信号
.A0(A0), // 选择[0]输入
.A1(A1), // 选择[1]输入
.A2(A2), // 选择[2]输入
.A3(A3), // 选择[3]输入
.CLK(CLK), // 时钟输入信号
.D(D) // SRL16的数据输入信号
);
// 结束SRL16模块的例化过程
在综合结果分析时,SRL16原语的RTL级结构如图3-48所示。
图3-48 SRL16的RTL级结构示意图
3.4.10 Slice/CLB组件
Slice/CLB组件涵盖了Xilinx FPGA中所有的逻辑单元,包括各种查找表、
复用器以及逻辑操作等21个原语,如表3-21所列。
表3-21 Slice/CLB组件列表
本节主要介绍基本的单输出1比特查找表原语和通用输出2到1复用器原语
的使用方法。
1.LUT1原语
FPGA内部的组合逻辑都可以通过LUT结构实现,常用的LUT结构有LUT1、
LUT2、LUT3以及LUT4,其区别在于查找表输入比特宽度的不同。LUT1
是其中最简单的一种,常用于实现缓冲器和反相器,是带通用输出的1比特
查找表。
LUT1原语的Verilog实例化代码如下所示:
// LUT1: 1比特输入的通用查找表(1-input Look-Up Table with general
output)
// 适用芯片:所有FPGA芯片
// Xilinx HDL库向导版本,ISE 9.1
LUT1 #(
.INIT(2'b00)
// 指定LUT的初始化内容
) LUT1_inst (
.O(O), // LUT的通用输出
.I0(I0) // LUT输入信号
);
// 结束LUT1模块的例化过程
在综合结构分析时,LUT1原语的RTL级结构如图3-49所示。
图3-49 LUT1的RTL级结构示意图
2.MUXF7原语
MUXF7是带通用输出的2到1查找表复用器,其控制信号S可以是任何内
部信号,当其为低电平时,选择I0;当其为高电平时选择I1。MUXF7需要
占用一个完整的CLB资源,和其相关的查找表可组成7功能的查找表和16
到1的选择器,可将MUXF6的输出连接到MUXF7的输入端。MUXF7的
真值表如表3-22所示。
表3-22 MUXF7的真值表
MUXF7原语的实例化代码如下所示:
// MUXF7: 2到1LUT复用器(CLB MUX to tie two MUXF6's together with
general output)
// 适用芯片:Virtex-II/II-Pro 以及Spartan-3/3E
// Xilinx HDL库向导版本,ISE 9.1
MUXF7 MUXF7_inst (
.O(O), // MUX的通用输出信号
.I0(I0),
.I1(I1), // 复用器的输入信号,连接到MUXF6 LO
.S(S) // 复用器的输入选择信号
);
// End of MUXF7_inst instantiation
在综合结构分析时,MUXF7原语的RTL级结构如图3-50所示。
图3-50 MUXF7的RTL及结构示意图
本节给出了典型的Xilinx原语的使用,但更多的原语需要读者在实践中大量
应用才能熟练掌握。只有全面掌握了原语,才能对Xilinx FPGA的资源有一
个理性认识,从而将工程设计提升到艺术雕刻的高度,这是每一个FPGA开
发人员的目标。详细的原语资料可在ISE安装目录下的“docusenglish
booksdocs”文件夹中找到,其中Virtex4系列芯片的原语资料文件“”
位于“v4ldl”文件中,Virtex5系列芯片的原语资料文件“”位于“v5ldl”
文件中,Spartan 3A系列芯片的原语资料文件“”位于“s3adl”文件中,
Spartan 3E系列芯片的原语资料文件“”位于“s3edl”文件中。
3.5 本章小结
本章主要介绍基于Xilinx芯片的Verilog开发技术。首先介绍了典型的硬件
设计思维;然后讨论了优秀的通用代码风格和Xilinx专用的代码风格,无论
哪种风格都是稳定性、速度以及硬件资源三者优化,只不过前者从FPGA器
件共有的特性出发,后者则面向Xilinx公司的FPGA芯片特点;最后,介绍
了Xilinx公司FPGA器件的硬件原语,以及典型原语的使用方法。特别需要
强调的一点是:对原语的全面掌握是Xilinx FPGA开发人员的基本要求。