基于Xilinx ISE的FPAG/CPLD设计与应用
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第1章 聚焦Xilinx ISE

本章首先介绍了Xilinx公司及其产品的基本情况,并在此基础上描述了CPLD和FPGA的内部结构及基本原理,这将有助于系统设计者深入理解ISE软件的设计过程;其次,本章介绍了VHDL硬件描述语言基础知识;最后,详细地讲解了设计软件ISE的安装过程及其主操作界面。

1.1 Xilinx公司及其产品介绍

总部设在加利福尼亚圣何塞市(San Jose)的Xilinx是全球领先的可编程逻辑解决方案的供应商,图1-1为公司标志。Xilinx公司的业务是研发、制造并销售高级集成电路、软件设计工具以及作为预定义系统级功能的IP(Intellectual Property)核,其相关产品在全球占有大量的份额,客户通过使用Xilinx及其合作伙伴的自动化设计软件和IP核,进行器件编程及设计的工作,最终实现特定的逻辑功能。

图1-1 Xilinx公司标志

1.1.1 Xilinx公司简介

Xilinx公司成立于1984年,它首创了现场可编程逻辑阵列(FPGA)这一创新性的技术,并于1985年首次推出商业化产品。目前Xilinx满足了全世界对FPGA产品一半以上的需求。Xilinx产品线还包括复杂可编程逻辑器件(CPLD)。Xilinx可编程逻辑解决方案缩短了电子设备制造商开发产品的时间并加快了产品面市的速度,从而减小了制造商的风险。与采用传统方法,如固定逻辑门阵列相比,利用Xilinx可编程器件,客户可以更快地设计和验证他们的电路。而且,由于Xilinx器件是只需要进行编程的标准部件,客户不需要像采用固定逻辑芯片时那样等待样品或者付出巨额成本。Xilinx产品已经被广泛应用于从无线电话基站到DVD播放机的数字电子应用技术中。

作为一个可编程逻辑器件的供应商,Xilinx有自己的开发套件,至今已经形成了一个完整的整体。

Xilinx公司提供的开发软件主要有以下几种。

● ISE:Xilinx公司集成开发的工具

● Foundation:Xilinx公司早期的开发工具,逐步被ISE取代

● ISE Webpack:Webpack是Xilinx公司提供的免费开发软件,功能比ISE少一些,可以从Xilinx网站下载

● 嵌入式开发套件(EDK):用于开发集成PowerPC硬核和Micro Blaze软核CPU的工具

● System Generator for DSP:配合Matlab,在FPGA中完成数字信号处理的工具

● Xilinx IP核:Xilinx公司拥有非常完整的IP库

1.1.2 几种CPLD系列芯片的特点

1. XC9500XL系列CPLD

该系列整合了先进的架构和有效的制造工艺,为用户提供了巨大的灵活性、可使系统具有较高性能,同时产品具有开发周期较短,成本较低特优点。图1-2所示为XC9572XL实物图。该系列的主要设计特性体现在以下几点:

图1-2 XC9572XL实物图

● 具有5.0V、3.3V和2.5V I/O接口

● 提供36~288个宏单元密度,并具有多种封装选项和I/O性能,能够很轻松地实现不同密度器件间的移植

● 具有先进的、第二代引脚锁定技术,无需改变板布局即可轻松实现重新设计

● 支持IEEE 1149.1 JTAG的边界扫描技术

● 具有快速的在系统编程能力并且擦除时间极短

● 具有可重配置功能,高编程耐久性

2. XC9500XV系列CPLD

Xilinx公司的XC9500XV 2.5V系列的CPLD采用了先进架构,具有强大的灵活性和低成本特性,可以加快产品上市时间,降低制造与技术支持成本。其主要特点如下:

● 低功耗,具有良好的可靠性

● 能够提供具有良好效益的逻辑解决方案

●提供了与3.3V XC9500XL系列一样的先进架构特性和密度,器件密度有36、72、144个和288个宏单元

● 支持业界最广泛的IEEE1149.1 JTAG和IEEE 1532编程接口标准

● 2.5V XC9500XV器件为在系统编程(ISP)提供了优化的支持

此外,XC9500XV具有总线保持电路,并提供了良好的I/O控制、热插拔功能等,为用户进行系统设计提供较强的灵活性。

3. XC9500系列CPLD

XC9500系列CPLD为用户提供了高可靠性,低成本的可编程逻辑解决方案。在保持高性能的同时,XC9500系列还能为用户提供最大的布线能力和灵活性。XC9500系列CPLD特点包括:

● 具有单个p-term输出,其p-term输出具有丰富的资源

● 具有3个全局时钟

● 具有良好的灵活性,具有较强的适应设计变化的能力

● 具有在系统编程能力,并且操作过程简单

● 每个密度点多提供了12%以上的逻辑资源,而且不需要支付额外的成本

● 采用Flash工艺

4. CoolRunner-Ⅱ系列

CoolRunner-Ⅱ系列采用了业界最先进的CPLD技术、具有较低的待机功耗和动态功耗、具有良好的系统性能,采用了低成本封装。Xilinx CoolRunner-Ⅱ系列特点描述如下:

● 具有28.8 mW的超低功耗

● 典型的16μA待机电流

● 增加了DataGate和先进的I/O技术

● 采用了QF32和QF48小型化低成本的封装解决方案,为业界尺寸最小的封装形式

5. CoolRunner XPLA3系列CPLD

该系列为3.3V CPLD,CoolRunner XPLA3 CPLD系列具有以下性能:

● 提供了4.5ns的性能和17~18μA的待机电流,比其他任何3.3V CPLD产品都具有更加出色的性能/功率组合

● 主要面向便携式、手持式等低功耗产品的应用

● 采用了Fast Zero Power(FZP)设计技术,从而可以在一个可编程逻辑器件中同时实现低功耗和高性能

● 提供了业内首个最有效的PLD构架,包括快速输入寄存器;全PLA和VFM单元

● 具有出色的引脚锁定

1.1.3 CoolRunner系列的高级特性

本小节将描述CoolRunner-Ⅱ的一些高级特性,包括双边沿触发(DET)寄存器,时钟分频器,CoolCLOCK技术,DataGATE功能等,这些特性将有助于用户进行相关的设计,从而提高产品的性能。

1.双边沿(DualEdge)触发寄存器

CoolRunner-Ⅱ双边沿触发寄存器能够大大提高产品的设计性能。双边沿触发(DET)寄存器能够在时钟的上升沿和下降沿完成数据的寄存,从而可以大大地提高系统性能。CoolRunner-Ⅱ DET寄存器可以实现的逻辑功能包括移位寄存器、计数器、比较器和状态机。在使用DET寄存器之前,用户必须对设计时所需要的CPLD逻辑性能进行评估,并可通过采用ABEL、HDL或原理图等不同的设计输入方式,来完成DET寄存器的设计或例化。表1-1列出了可用于创建CoolRunner-Ⅱ DET寄存器的方法。

表1-1 DET寄存器的例化方法

用户可以在HDL设计中完成单边沿触发(SET)寄存器。一个输入时钟上升沿有效单边沿触发寄存器的VHDL或Verilog语法描述如下:

            VHDL:if (clock'event) and (clock = '1') then
            Verilog:always @ (posedge clock)

设计CoolRunner-Ⅱ DET寄存器时,要求寄存器在时钟的上升沿和下降沿上都处于有效状态。

CoolRunner DET寄存器的VHDL范例如下:

            Process (clock)
             begin
              if (clock'event) then
…
             end   if;
            end   process;

CoolRunner-Ⅱ DET寄存器Verilog范例如下:

            always@(negedge clock or posedge clock)

此外,DET寄存器可供CoolRunner-Ⅱ家族所有器件中的所有宏单元使用。

2.时钟分频器

1)时钟分频器的特性DET寄存器附加的同步时钟由CoolRunner-Ⅱ CPLD时钟分频器提供,具有良好的灵活性。CoolRunner-Ⅱ时钟分频器完成对输入时钟的分频,并将分频时钟全局地分配给所有宏单元。

此外,时钟分频器可以通过减少内部时钟网络的翻转率,来实现额外的省电效果。

CoolRunner-Ⅱ时钟分频器可用于全局时钟GCK2,可对输入时钟进行2分频、4分频、6分频、8分频、10分频、12分频、14分频和16分频,时钟分频器可以产生50-50占空比的分频时钟,并且不影响TCO。CPLD在上电时,复位电路将初始化时钟分频器的输出为低电平。

2)时钟分频器的结构及元件CoolRunner-Ⅱ时钟分频器结构如图1-3所示,从图中可以看到,时钟分频器电路包含了一个CDRST(高电平有效的同步复位)输入信号,当CDRST信号输入有效时,时钟分频器在当前周期结束后,停止输出。当CDRST信号无效时,时钟分频器将在GCK2第一个边沿上开始工作。

图1-3 CoolRunner-Ⅱ时钟分频器结构

CoolRunner-Ⅱ时钟分频器还具有内置的延迟电路。当延迟电路的延迟功能启用时,时钟分频器的输出将被延迟一个完整的计数周期。使用延迟功能时,时钟分频器在分频器到达终止计数值之前不会输出上升时钟沿。延迟功能可在配置时启用或禁用。设计时所例化的时钟分频器元件的类型将决定是启用还是禁用延迟功能。图1-4描述了启用或禁用延迟功能情况下,CoolRunner-Ⅱ时钟分频器的时序波形。

图1-4 CoolRunner-Ⅱ时钟分频器的时序波形

Xilinx的综合技术(XST)允许直接在HDL源代码中例化时钟分频器元件,也可以采用ABEL、或原理图设计方法完成时钟分频器元件的例化。表1-2列出了可在ABEL、HDL或原理图设计中例化的时钟分频器元件。

表1-2 例化的时钟分频器元件

3)时钟分频器元件声明和例化在VHDL中,如果要使用CoolRunner-Ⅱ时钟分频器,就要进行“元件声明”和“元件例化”的描述。

“元件声明”主要用于定义时钟分频器单元的名称和接口。下面是时钟分频因子为2的CLK_DIV2元件的VHDL元件声明语法。

            component CLK_DIV2 is
              port ( CLKIN : in STD_LOGIC;
                    CLKDV : out STD_LOGIC );
            end  component;

元件例化是将信号与时钟分频器元件的端口进行关联。假设设计需要进行2分频,则必须例化CLK_DIV2元件。下面是例化CLK_DIV2元件的VHDL语法示例,其中将输入的时钟信号clk定义在CLKIN端口上,时钟分频器输出信号clk_div_by_2定义在CLKDV端口上。

            U1:CLK_DIV2
            port  map(
                CLKIN => clk,
                CLKDV => clk_div_by_2 );

4)支持同步复位和延迟功能的时钟分频器元件声明和例化假设采用分频因子为16的时钟分频,并且支持同步复位和延迟功能,则必须声明和例化CLK_DIV16RSD元件。其元件声明的VHDL示例如下:

            component CLK_DIV16RSD is
              port ( CLKIN : in STD_LOGIC;
                    CDRST : in STD_LOGIC;
                    CLKDV : out STD_LOGIC );
              end component;

元件例化功能是分配端口信号。将输入时钟信号clk分配在CLKIN端口上,时钟分频器复位信号clk_div_rst分配在CDRST端口上,时钟分频器输出clk_div_by_16分配在CLKDV端口上,同时根据要求使能CoolRunner-Ⅱ时钟分频器的延迟功能。下面是采用VHDL语言例化CLK_DIV16RSD元件的示例:

            U1:  CLK_DIV16RSD
              port map (
            CLKIN => clk,
                  CDRST => clk_div_rst,
                  CLKDV => clk_div_by_16 );

5)Verilog设计方法下的时钟分频器元件声明和例化 前面介绍的时钟分频器元件声明和例化方法采用了VHDL语言,下面将介绍采用Verilog以及ABEL语言的设计范例。

(1)Verilog设计范例。与VHDL设计输入不同,采用XST的Verilog设计输入时,不需要进行元件声明,只需要进行元件的例化工作。

下面是一个采用Verilog语法,完成CLK_DIV16RSD元件例化的示例。在该示例中,输入时钟信号clk分配到CLKIN端口,时钟分频器复位信号clk_div_rst分配到CDRST端口,时钟分频器输出clk_div_by_16分配到CLKDV端口,具体示例描述如下:

            CLK_DIV16RSD U1 (
                ,CLKIN (clk),
                ,CDRST (clk_div_rst),
                ,CLKDV (clk_div_by_16) );

(2)ABEL设计范例。采用ABEL设计输入进行CoolRunner-Ⅱ时钟分频器设计时,与VHDL设计输入一样都需要元件声明和元件例化,所不同的是,采用ABEL设计输入时,必须声明时钟分频器为外部元件:

            CLK_DIV2R external (CLKIN, CDRST -> CLKDV);

在元件例化过程中,首先要为时钟分频器元件定义一个标识符,这一过程是利用ABEL关键字functional_block来完成的,下面的示例为时钟分频器元件CLK_DIV2R定义了一个标识符U1:

            U1 functional_block CLK_DIV2R;

在完成标识符定义后,就需要实现元件端口的映射。下面的示例将输入时钟clk映射到CLKIN端口,时钟分频器复位信号clk_div_rst映射到CDRST端口,时钟分频器输出信号clk_div_by_2分配给CLKDV输出端口,从而完成端口的映射过程。

            U1, CLKIN = clk;
            U1, CDRST = clk_div_rst;
            clk_div_by_2 = U1, CLKDV;

3.CoolCLOCK技术

CoolRunner-Ⅱ的CoolCLOCK技术是一种组合全局时钟分频器和DET寄存器功能的技术。该技术通过将全局时钟进行2分频,使内部时钟网络上分配更低频率的时钟,然后在各个宏单元上,再将时钟加倍,从而来达到降低功耗的目的。由于时钟分频器和DET寄存器的零插入延迟特性,可获得零时钟偏斜。图1-5为CoolRunner-Ⅱ CoolCLOCK特性。

图1-5 CoolRunner-Ⅱ CoolCLOCK特性

由于GCK2是唯一的可分频时钟网络,因此CoolCLOCK功能只能在GCK2网络上使用。通过定义输入时钟的属性,来设置CoolCLOCK特性,换句话说,CoolCLOCK功能可通过设置输入时钟的属性来实现。通过设置CoolCLOCK属性,可以免除实例化时钟分频器和DET寄存器的需要。表1-3列出了CoolCLOCK属性,设置语法和设置范例。

表1-3 CoolCLOCK属性

注意:CoolCLOCK可在CoolRunner-Ⅱ 128宏单元器件和更大的器件上使用。

4.DataGATE特性

在实际设计过程中,往往需要阻塞特定的输入,通过阻塞输入,转换信号不会驱动内部电容,从而减少总功耗。CoolRunner-Ⅱ提供了DataGATE特性来实现这一功能。在DataGATE有效之前,被阻塞的输入引脚上的最后一个值会被锁存,以供CPLD内部使用。图1-6描述了DataGATE功能的基本原理。

图1-6 DataGATE功能的基本原理

在CoolRunner-Ⅱ中,有两种属性与DataGATE特性相关联。第一种属性定义了输入是否受到DataGATE的影响,第二种属性定义用于指定DataGATE控制信号。

设计人员可以逐个引脚选择DataGATE特性。当输入引脚需要设置具有DataGATE功能时,可以通过定义该输入引脚为DATA_GATE属性来实现。表1-4描述了不同设计输入方法下,对输入信号设置DataGATE功能的语法和范例

表1-4 设置DataGATE功能的语法和范例

通过使用I/O引脚或内部逻辑可以完成对DataGATE的驱动控制。对于每一个CoolRunner-Ⅱ封装,DataGATE的使能信号来自专用的DGE/I/O引脚。

软件识别DataGATE的设计并自动分配I/O引脚给DataGATE以用做使能控制功能信号——DGE。通过BUFG DATA_GATE属性定义和分配I/O引脚,以生成内部DataGATE控制逻辑。表1-5描述了定义和分配DataGATE使能信号的语法和方法。

表1-5 定义和分配DataGATE使能信号的语法和方法

5.施密特触发输入缓冲器和I/O端接模式

CoolRunner-Ⅱ的每个I/O有多个输入缓冲器,这些输入缓冲器可以被用于不同的I/O配置。在这些输入缓冲器中,有一个输入缓冲器可作为施密特触发输入缓冲器,在CPLD配置时,可以启用该类型的缓冲器。设计人员利用施密特触发输入缓冲器,能够在同一器件上灵活地使用CoolRunner-Ⅱ,处理高速信号及缓慢转换信号。传统上,当为CMOS输入时,缓慢转换信号会造成双时钟或低频干扰,从而导致数字系统大为混乱。这一问题可以通过利用施密特触发器输入缓冲器来有效消除,而使用施密特触发器输入缓冲器的代价只是几纳秒延迟。表1-6描述了用于给特定信号进行施密特触发器输入缓冲器分配或定义的语法和范例。

表1-6 分配施密特触发器输入缓冲器

1.1.4 主流FPGA产品

Xilinx作为全球领先的可编程逻辑解决方案的供应商,FPGA产品占据市场一定数量的份额,其主流FPGA产品包括Spartan-3系列,Virtex-Ⅱ系列等,下面进行简单的描述。

1.Spartan-3系列

Spartan-3是新一代FPGA产品,结构与Virtex-Ⅱ类似,主要型号包括Spartan-3/3L,Spartan-3A,Spartan-3E等,其主要特点描述如下:

● Spartan-3/3L:全球第一款90nm工艺FPGA,1.2V内核,于2003年开始陆续推出。成本低廉,总体性能指标不是很优秀,适合低成本应用场合,是Xilinx未来几年在低端FPGA市场上的主要产品,目前市场上中低容量型号很容易购买到,大容量相对少一些

● Spartan-3A:适合于对逻辑密度要求比较高的应用场合,当应用需要有桥接、差分信号和存储器接口等时,该型号是一种理想的选择

● Spartan-3E:为Xilinx最新推出的低成本FPGA,其基本框架是基于Spartan-3/3L的,并在此基础上对性能和成本做了进一步优化,适合于逻辑密度要求比较高的应用场合,如应用于逻辑集成、DSP协处理和嵌入式控制等应用;该款产品成本低廉,适合于低成本应用场合,是Xilinx未来几年在低端FPGA市场上的主要产品

2.Virtex-Ⅱ系列FPGA

Virtex-Ⅱ系列是在2002年推出,采用0.15μm工艺,1.5V内核,适用于大规模高端FPGA产品。Xilinx为利用Virte-Ⅱ FPGA进行高性能系统设计提供了所需的全部工具,提供了世界级的IP核解决方案、验证工具以及开发所需要的信息资源,以确保整个设计开发过程。目前,该系列的FPGA主要包括Virtex-Ⅱ、pro Virtex-4、Virtex-5等型号,下面做一个简单描述:

● Virtex-Ⅱ pro:基于Virtex-Ⅱ的结构,采用0.13μm、1.5V工艺技术制造,整合了嵌入式PowerPC处理器和3.125 Gbps RocketIO串行收发器的FPGA产品,基于系统内可配置的SRAM,具有灵活的逻辑资源;高达88192个内部时钟可控的寄存器、锁存器;支持多路选择和输入功能;高性能的时钟管理电路,高达12个数字时钟管理模块;灵活的频率合成技术;具有XCITE数控阻抗I/O端口等

● Virtex-4:是Xilinx最新一代高端FPGA产品,包含三个子系列:LX、SX、FX, Virtex-4系列于2004年推出,采用1.2V、90nm、三栅极氧化层技术制造而成,提供了业界最高的性能,并极大地降低了功耗。各项指标比上一代Virtex-Ⅱ均有很大提高,获得2005年EDN杂志最佳产品称号,从2005年年底开始批量生产,是未来几年Xilinx在高端FPGA市场中的最重要的产品

● Virtex-5:世界上首款采用1.0V、三栅极氧化层工艺技术制造而成的65nm的最新FPGA系列产品。Virtex-5 FPGA的逻辑单元高达330000个;I/O引脚数量高达1200个;此外还带有低功耗Rocket IO串行收发器、内置式PCI Express端点、以太网MAC模块以及其他增强型IP;提供了丰富的集成系统性能,从而缩短了设计周期,并削减了系统成本。在嵌入式处理方面,该系列的产品利用丰富和完备的开发工具,可支持的软处理器核,从而可以完成构建嵌入式系统或实现复杂的控制功能;Virtex-5提供了众多的软IP核选择,包括32bit MicroBlaze处理器、8bit PicoBlaze控制器、IBM CoreConnect总线以及由Xilinx及其合作伙伴开发的外围部件。在数字信号处理(DSP)方面,Virtex-5使用增强型DSP48E slice可以解决多通道、高性能DSP难题,可用于组建实时视频、成像、无线和加密系统。除此以外,Virtex-5 FPGA还可以广泛地应用在网络、电信、存储、服务器、计算、无线、广播、视频、成像、医疗、工业和军事应用领域,以代替ASIC和ASSP

1.2 FPGA/CPLD基本结构与实现原理

FPGA和CPLD都是可编程ASIC器件,有很多共同特点,但由于FPGA和CPLD结构上的差异,具有各自的特点,为了更好地理解FPGA和CPLD的特点和应用场合,下面将对FPGA和CPLD基本结构与实现原理进行简单的介绍,这部分内容将同样有助于用户进行相关的产品设计。

1.2.1 FPGA基本结构与实现原理

如图1-7所示为FPGA的内部结构图。

图1-7 FPGA的内部结构图

1.FPGA基本结构

从图1-7中可以看出,FPGA内部包括5个主要组成部分。

1)可配置逻辑块(CLB) CLB是FPGA内的基本逻辑单元。实际数量和特性会依器件的不同而不同,但是每个CLB都包含一个由4或6个输入、一些选型电路(多路复用器等)和触发器组成的可配置开关矩阵。开关矩阵是高度灵活的,可以进行配置以便处理组合逻辑、移位寄存器或RAM。相应器件的数据手册中提供了更系统的详情。

2)互连CLB提供了逻辑性能,灵活的互连布线在CLB和I/O之间发送信号。有几种布线方法,从专门实现CLB互连的到快速水平和垂直长线,再到实现时钟与其他全局信号的低歪斜发送的器件。 除非特别规定,设计软件使得互连布线任务从用户眼前消失,这样就极大地降低了设计复杂度。

3)I/O块(IOB)当今的FPGA支持很多I/O标准,这样就为您的系统提供了理想的接口连接。 FPGA内的I/O按组分类,每组都能够独立的支持不同的I/O标准。当今领先的FPGA提供了很多I/O组,这样就实现了I/O支持的灵活性。

排成阵列的逻辑单元由布线通道中的可编程内连线连接起来实现一定的逻辑功能,即分段的金属互连线可以由编程开关以任意方式连接形成逻辑单元之间要求的信号线。

4)存储器 大多数FPGA均提供嵌入式Block RAM存储器,这可以在您的设计中实现片上存储器。Xilinx FPGA在36 kbit块中提供高达10Mbits的片上存储器,可以支持真正的双端口操作。

5)完整的时钟管理 业内大多数FPGA均提供数字时钟管理(Xilinx的全部FPGA均具有这种特性)。Xilinx推出的最先进的FPGA提供数字时钟管理和相位环路锁定。相位环路锁定能够提供精确的时钟综合,且能够降低抖动,并能够实现过滤功能。

2.查找表(Look-Up-Table)的原理与结构

Altera的ACEX、APEX系列,Xilinx的Spartan、Virtex等FPGA系列采用查找表(Look-Up-Table)结构,简称为LUT,其本质上就是一个RAM。

目前FPGA中多使用4输入的LUT,所以每一个LUT可以看成一个有4位地址线的16 × 1的RAM。当用户通过原理图或HDL语言描述了一个逻辑电路以后,CPLD/FPGA开发软件会自动计算逻辑电路的所有可能的结果,并把结果事先写入RAM,这样,每输入一个信号进行逻辑运算就等于输入一个地址进行查表,找出地址对应的内容,然后输出相应得逻辑运算结果。

一个四输入与门的例子,如表1-7所示。

表1-7 四输入与门

下面以图1-8所示的电路为例来说明查找表结构的实现原理。

图1-8 四输入与门结构图

图1-8中的A、B、C、D输入信号通过FPGA芯片的引脚输入后,进入可编程部分,然后作为地址线连到LUT,LUT中已经事先写入了所有可能的逻辑结果,通过地址查找到相应的数据然后输出,这样实现了相应的组合逻辑。图1-8所示的电路中,D触发器是直接利用LUT后面D触发器来实现的。时钟信号CLK由I/O脚输入后进入芯片内部的时钟专用通道,直接连接到触发器的时钟端。触发器的输出与I/O脚相连,把结果输出到芯片引脚。这样就实现了图1-8所示电路的逻辑功能。

提示:以上这些步骤都是由软件自动完成的,不需要人为干预

图1-8所示为一个简单的例子,该示例只需要一个LUT,外加一个触发器就可以完成相应功能。当面临一个复杂的逻辑功能时,单一的LUT无法完成或实现的情况下,需要通过进位逻辑,将多个单元相连,以形成复杂的逻辑。

由于LUT主要适合SRAM工艺生产,所以目前大部分FPGA都是基于SRAM工艺的,而SRAM工艺的芯片在掉电后信息就会丢失,所以一定要外加一片专用配置芯片,在上电时,由这个专用配置芯片把数据加载到FPGA中,然后FPGA就可以正常工作,由于配置时间很短,通常不会影响到系统正常工作。也有少数FPGA采用反熔丝或Flash工艺,对这种FPGA,就不需要外加专用的配置芯片。

1.2.2 CPLD基本结构与实现原理

1.CPLD基本结构

大部分CPLD的内部结构可归结为如图1-9所示。

图1-9 CPLD的内部结构图

从图1-9中可以看出,每个器件是一个由多个逻辑块(Logic Block)、I/O块组成,通过内部互连矩阵完全互连的子系统,I/O块提供器件的I/O缓冲,每个逻辑块提供具有一定数目的输入和输出的可编程逻辑的容量。分别描述如下:

1)逻辑块(Logic Block) 每个逻辑块由独立的宏单元、乘积项阵列和乘积项分配组成。宏单元是PLD的基本结构,由它来实现基本的逻辑功能。每个宏单元能够实现一个组合的或寄存的功能。LB负责信号传递,连接所有的宏单元,也接受全局时钟、输出使能和复位/置位信号,同时还可以产生驱动互连矩阵的输出,这些输出信号和相应的输出使能信号也可以用于完成对I/O块(I/O Block)的驱动

2)互连矩阵(Interconnect) 互连矩阵要将来自I/O的信号和逻辑块的输出布线到器件内任何逻辑块的输入。一般互连矩阵有两种形式:基于阵列的互连和基于多路开关的互连。基于阵列的互连是完全的纵横开关的实现方式,它允许任何输入到互连矩阵中的信号布线到任何逻辑块,是完全可布通的。基于多路开关的互连是对逻辑块的每一个输入有一个多路转换器,输入到互连矩阵的信号被连接到每个逻辑块的大量多路开关的输入端,这些多路转换器的选择端是可编程的,只允许其一个输入通过它进入逻辑块。

3)I/O块(I/O Block) I/O控制块负责I/O的电气特性控制,比如可以设定I/O输出为集电极开路输出、摆率控制输出、三态输出等不同输出形式。

下面简要介绍宏单元的基本结构。宏单元的具体结构如图1-10所示。

图1-10 宏单元结构图

从图1-10中可以看出,左侧是乘积项阵列,实际就是一个与或阵列,每一个交叉点都是一个可编程节点,如果导通就是实现“与”逻辑。后面的乘积项选择矩阵是一个“或”阵列。两者一起完成组合逻辑。图1-10右侧是一个可编程D触发器,它的时钟,清零输入都可以编程选择,可以使用专用的全局清零和全局时钟,也可以使用内部逻辑(乘积项阵列)产生的时钟和清零。如果不需要触发器,也可以将此触发器旁路,信号直接输给PIA或输出到I/O脚。

2.CPLD逻辑实现原理

下面以图1-11所示的电路为例,来描述CPLD是如何利用以上结构来实现相应的逻辑功能的。

图1-11 逻辑电路结构图

假设组合逻辑的输出(AND3的输出)为f,则f=(A+B)*C*(!D)=A*C*!D + B*C*!D

注意:以!D表示D的“非”。

图1-12所示的是上述组合逻辑的实现示意图。

输入信号A、B、C、D通过CPLD的引脚输入,然后进入可编程连线阵列(PIA),在内部会产生A,A反,B,B反,C,C反,D,D反8个输出。图中每一个叉表示相连(可编程熔丝导通),所以得到:f= f1 + f2 = (A*C*!D) + (B*C*!D),这样就可以实现图1-11所要求的组合逻辑。图1-11中,D触发器的实现比较简单,直接利用宏单元中的可编程D触发器来实现。时钟信号CLK由I/O脚输入后进入芯片内部的全局时钟专用通道,直接连接到可编程触发器的时钟端。可编程触发器的输出与I/O脚相连,把结果输出到芯片引脚。这样PLD就完成了图1-11所示电路的功能。

图1-12 组合逻辑方式

上述步骤都是由软件自动完成的,不需要人为干预。

图1-11所示的例子为一个简单的示例,只需要一个宏单元就可以完成。但对于一个复杂的电路,一个宏单元是不能实现的,这时就需要通过并联扩展项和共享扩展项将多个宏单元相连,宏单元的输出也可以连接到可编程连线阵列,再作为另一个宏单元的输入。这样PLD就可以实现更复杂逻辑。

这种基于乘积项的PLD基本都是由EEPROM和Flash工艺制造的,一上电就可以工作,无需其他芯片配合。

1.2.3 FPGA/CPLD性能特点差异

不同的应用场合下,对FPGA /CPLD的选用是不一样的,只有了解FPGA/CPLD的区别,才能在实际应用中,更好地选用相关产品。下面对FPGA/CPLD特点上的差异性进行简单的描述。

● CPLD适合于完成各种算法和组合逻辑,FPGA更适合于完成时序逻辑。换句话说,FPGA更适合于触发器丰富的结构,而CPLD更适合于触发器有限而乘积项丰富的结构

● CPLD的连续式布线结构决定了它的时序延迟是均匀的和可预测的,而FPGA的分段式布线结构决定了其延迟的不可预测性

●在编程上FPGA比CPLD具有更大的灵活性。CPLD通过修改具有固定内连电路的逻辑功能来编程,FPGA主要通过改变内部连线的布线来编程;FPGA可在逻辑门下编程,而CPLD是在逻辑块下编程

● FPGA的集成度比CPLD高,具有更复杂的布线结构和逻辑实现

● CPLD比FPGA使用起来更方便。CPLD的编程采用E2PROM或Fast Flash技术,无需外部存储器芯片,使用简单。而FPGA的编程信息需存放在外部存储器上,使用方法复杂

● CPLD的速度比FPGA快,并且具有较大的时间可预测性。这是由于FPGA是门级编程,并且CLB之间采用分布式互连,而CPLD是逻辑块级编程,并且其逻辑块之间的互连是集总式的

●编程方式上,CPLD主要是基于E2PROM或Flash存储器编程,编程次数可达1万次,优点是系统断电时编程信息也不丢失。CPLD又可分为在编程器上编程和在系统编程两类。FPGA大部分是基于SRAM编程,编程信息在系统断电时丢失,每次上电时,需从器件外部将编程数据重新写入SRAM中。其优点是可以编程任意次,可在工作中快速编程,从而实现板级和系统级的动态配置

● CPLD保密性好,FPGA保密性差

● 一般情况下,CPLD的功耗要比FPGA大,且集成度越高越明显

1.3 系统设计语言——VHDL基本概念与程序结构

每一种程序设计语言都有自己一套约定的规则和结构,掌握了这些将会给你下一步的功能设计打下一个坚实的基础,本节主要介绍VHDL语言的一些概念和程序结构。

1.3.1 概述

VHDL的英文全名是Very-High-Speed Integrated Circuit Hardware Description Language,诞生于1982年。1987年年底,VHDL被IEEE(The Institute of Electrical and Electronics Engineers)和美国国防部确认为标准硬件描述语言。白IEEE公布了VHDL的标准版本(IEEE—1076)之后,各EDA公司相继推出了自己的VHDL设汁环境,或宣布白己的设计工具可以和VHDL接口。此后VHDL在电子设计领域得到了广泛的接受,并逐步取代了原有的非标准硬件描述语言。1993年,IEEE对VHDL进行了修订,从更高的抽象层次和系统描述能力上扩展VHDL的内容,公布了新版本的VHDL,即IEEE标准的1076—1993版本。现在,VHDL和Verilog作为IEEE的工业标准硬件描述语言,又得到众多EDA公司的支持,在电子工程领域,已成为事实上的通用硬件描述语言。有专家认为,在21世纪中, VHDL与Verilog语言将承担起几乎全部的数字系统设计任务。

VHDL之所以被硬件设计者日趋重视,是因为它在进行工程设计时有如下优点:

● VHDL行为描述能力明显强于其他HDL语言,这就使得用VHDL编程时不必考虑具体的器件工艺结构,能比较方便地从逻辑行为这一级别描述和设计电路系统。而对于已完成的设计,不改变其源程序,只需改变某些参量,就能轻易地改变设计的规模和结构。比如设计一个计数器,若要设计8位计数器,可以将其输出引脚定义为“BIT_VECTOR(7 DOWNTO 0);”,而要将该计数器改为16位计数器时,只要将引脚定义中的数据7改为15即可

● VHDL丰富的仿真语句和库函数,使得在任何大系统的设计早期(即尚未完成),就能查验设计系统的功能可行性,随时可对设计进行仿真模拟。即在远离门级的高层次上进行模拟,使设计者对整个工程设计的结构和功能的可行性做出决策。使得设计者在系统的设计早期就可检查设计系统的功能,极大地减少了可能发生的错误,降低了开发成本

● VHDL程序结构(如设计实体、程序包、设计库)决定了它在设计时可利用已有的设计成果,并能方便地将较大规模的设计项目分解为若干部分,从而实现多人多任务的并行工作方式,保证了较大规模系统的设计能被高效、高速地完成

● EDA工具和VHDL综合器的性能日益完善。经过逻辑综合,VHDL语言描述能自动地被转变成某一芯片的门级网表;通过优化能使对应的结构更小、速度更快。同时设计者可根据EDA工具给出的综合和优化后的设计信息对VHDL设计描述进行改良,使之更为完善

● VHDL对设计的描述具有相对独立性,设计者可以不懂硬件的结构,也不必管最终设计实现的目标器件是什么,而进行独立的设计。正因为VHDL的硬件描述与具体的工艺技术和硬件结构无关,VHDL设计程序的硬件实现目标器件有广阔的选择范围,其中包括各系列的CPLD、FPGA及各种门阵列器件

1.3.2 VHDL程序基本结构

一个完整的VHDL程序通常包括五个部分:实体(Entity)、结构体(Architecture)、配置(Configuration)、程序包(Package)、库(Library),如图1-13所示。下面针对图1-13所示基本结构对其进行描述。

图1-13 VHDL程序的基本结构

1.实体(Entity)

实体主要用于说明和描述系统的外部接口信号,主要包含实体说明,端口说明等部分。

实体说明的语法结构如下:

            ENTITY  实体名  IS
            [端口说明]
            END  实体名;

注意:VHDL语言中不分大小写字母

其中:端口说明是对设计实体中输入和输出接口的描述,格式如下:

            PORT(端口名(,端口名): 方向 数据类型名;
                      :
                      :
            端口名 (.端口名): 方向 数据类型名);

端口名是赋予每个端口引脚的名称,一般用几个英文字母组成。端口方向是定义引脚的输入、输出属性,见表1-8。

表1-8 端口方向定义

常用的端口数据类型有两种:BIT和BIT_VECTOR,当端口被说明为BIT时,只能取值“1”或“0”,当端口被说明为BIT_VECTOR时,它可能是一组二进制数。

例如:

            PORT(n0, n1, select : IN BIT;
                  Q : OUT BIT;
                  Bus :: OUT BIT_VECTOR(7 DOWNTO 0));

本例中,n0,n1,select是输入引脚,属于BIT型,q是输出引脚,BIT型,Bus是一组8位二进制总线,属于BIT_VECTOR。

例如:

            LIBRARY IEEE;
            USE IEEE, STD_LOGIC, 1164, ALL;
            ENTITY mm IS
              PORT(n0, n1, select : IN STD_LOGIC;
                  Q        :OUT STD_LOGIC;
                    Bus     :OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
            END mm;

在此例中端口数据类型取自IEEE标准库(该库中有数据类型和函数的说明),其中STD_LOGIC取值为“0”,“1”,“X”和“Z”。

因为使用了库所以在实体说明前要增加库说明语句。

2.结构体(Architecture)

结构体主要用于描述系统内部的结构和行为,结构体是实体的一个重要部分,每一个实体都有一个或一个以上的结构体。

结构体格式如下:

            ARCHITECTURE  结构体名 OF 实体名 IS
            [定义语句] 内部信号, 常数, 数据类型, 函数等的定义
            BEGIN
             [并行处理语句]
            END 结构体名;

下面为一个简单的实例:

            ENTITY nax IS
            PORT(a0,a1  :IN BIT;
                  Sel  :IN BIT;
                  Sh  :OUT BIT);
           END nax;
          ARCHITECTURE  dataflow OF nax IS
           BEGIN
              sh<=(a0 AND sel) OR (NOT sel AND a1);
           END dataflow;

结构体描述设计实体的具体行为,它包含两类语句:

● 并行语句 并行语句总是在进程语句(PROCESS)的外部,该语句的执行与书写顺序无关,总是同时被执行;

● 顺序语句 顺序语句总是在进程语句(PROCESS)的内部,从仿真的角度,该语句是顺序执行的。

一个结构体包含几个类型的子结构描述,这些描述是:

● BLOCK描述(块描述);

● PROCESS描述(进程描述);

● SUNPROGRAMS描述(子程序描述)。

1)BLOCK语句描述 使用BLOCK语句描述的格式如下:

            块标号: BLOCK
                  BEGIN
                    :
                    :
                  END BLOCK  块标号:

例如:二选一电路

            ENTITY mux IS
            PORT (d0, d1, sel : IN BIT;
                  q : OUT BIT);
            END mux;
            ARCHITECTURE  connect OF mux IS
            SIGNAL tmp1, tmp2, tmp3 : BIT;
            BEGIN
             cale:
             BLOCK
                BEGIN
                tmp1<=d0 AND sel;
                tmp2<=d1 AND (NOT sel);
                tmp3<=tmp1 OR tmp2;
                q<=tmp3;
              END BLOCK cale;
            END connect;

在对程序进行仿真时,BLOCK中的语句是并行执行的,与书写顺序无关,这一点和结构体中直接写的语句是一样的。

2)进程(PROCESS)描述 进程描述的格式如下:

            [进程名]:PROCESS(信号1, 信号2, …)
            BEGIN
              :
              :
            END PROCESS 进程名;

一般用于组合电路进程模式:

            __进程标记:
            PROCESS (__信号名, __信号名, __信号名)
                VARIABLE__变量名 :STD_LOGIC;
                VARIABLE__变量名 :STD_LOGIC;
            BEGIN
                --  指定信号
                --  指定变量
                --  过程调用
                --  条件语句
                --  CASE语句
                --  循环语句
            END PROCESS __进程标记;

用于时序电路进程模式:

            __进程标记:
            PROCESS (__信号名, __信号名, __信号名)
                VARIABLE__变量名 :STD_LOGIC;
                VARIABLE__变量名 :STD_LOGIC;
            BEGIN
                WAIT UNTIL__时钟信号 ='1';
                --  指定信号
                --  指定变量
                --  过程调用
                --  条件语句
                --  CASE语句
                --  循环语句
            END PROCESS __进程标记;

例如:

                    ENTITY mux1 IS
                    PORT (d0, d1, sel : IN BIT;
                          q      :OUT BIT);
                    END mux1;
                    ARCHITECTURE  connect OF mux1 IS
                  BEGIN
                  cale:
                   PROCESS(d0, d1, sel)
                   VARIABLE tmp1,tmp2,tmp3   :BIT;                 --在进程中定义的变量
                      BEGIN
                        tmp1:=d0 AND sel;                           --输入端口向变量赋值
                        tmp2 : =d1 AND (NOT sel);
                        tmp3 : =tmp1 OR tmp2;
                        q<=tmp3;
                      END PROCESS cale;
                    END connect;

在PROCESS中的语句是顺序执行的,这一点和BLOCK中的语句是不一样的。当PROCESS所带的信号量发生变化时,PROCESS中的语句就会执行一遍。

3)子程序描述 子程序的概念和其他高级程序中子程序的概念相同,在VHDL中有两种类型:

● 过程(Procedure);

● 函数(Function)。

(1)过程的格式。

            PROCEDURE 过程名(参数1, 参数2, …)IS
            [定义变量语句]
            BEGIN
              [顺序处理语句]
            END 过程名;

例如:

              PROCEDURE vector_to_int
                (z      :IN STD_LOGIC_VECTOR;
                  x_flag : OUT BOOLEAN;
                  q    :IN INTEGER)IS
              BEGIN
                q : =0;
                x_flag : =FALSE;
                FOR i IN z RANGE LOOP
                      q : =q*2;
                        IF(z(i)=1)  THEN
                          q : =q+1;
                          ELSEIF (z(i)/=10) THEN
                            x_flag : =TRUE;
                          END IF;
                    END LOOP;
              END vector_to_int;

在过程中,语句是顺序执行的。

(2)函数的格式。

            FUNCTION 函数名 (参数1, 参数2, …)RETURN 数据类型名 IS
            [定义变量语句]
            BEGIN
              [顺序处理语句]
            RETURN [返回变量名];
            END 函数名;

注意:在VHDL语言中函数的参数都是输入信号

例如:

            FUNCTION  min(x,y:INTEGER)RETURN INTEGER IS
            BEGIN
                IF X<Y THEN
                  RETURN(x);
                ELSE
                  RETURN(y);
                END IF;
            END min;

3.配置(Configuration)

描述层与层之间、实体与结构体之间的连接关系,比如高层设计需要将低层实体作为文件加以利用,这就要用到配置说明。用于在多结构体中的实体中选择结构体,例如,在作为RS触发器的实体中使用了两个构造体,目的是研究各个结构体描述的RS触发器的行为性能如何,但是究竟在仿真中使用哪一个结构体的问题就是配置问题。

配置语句格式:

            CONFIGURATION  配置名  OF 实体名 IS
            [说明语句]
            END  配置名;

例如:最简单的配置

            CONFIGURATION  配置名  OF 实体名 IS
              FOR 被选构造体名
              END FOR;
            END  配置名;

例如:

            ENTITY rs IS
            PORT(set, reset : IN BIT;
                  q, qb : BUFFER BIT);
            END rs;
            ARCHITECTURE rsff1 OF rs IS
                COMPONENT nand2
                  PORT(a, b : IN BIT;
                      c:  OUT BIT);
                END COMPONENT;
            BEGIN
              U1 : nand2 PORT MAP(a=>set, b=>qb, c=>q)
              U2 : nand2 PORT MAP(a=>reset, b=>q, c=>qb)
            END rsff1;
            ARCHITECTURE rsff2 OF rs IS
            BEGIN
              q<=NOT(qb AND set);
              qb<=NOT(q AND reset);
            END rsff2;

4.程序包(Package)

用于把共享的定义放置在其中。具体来讲,就是存放各模块都能共享的数据类型、常数、子程序等。通常在一个实体中对数据类型、常量等进行的说明只可以在一个实体中使用,为使这些说明可以在其他实体中使用,VHDL提供了程序包结构,包中罗列VHDL中用到的信号定义、常数定义、数据类型、元件语句、函数定义和过程定义,它是一个可编译的设计单元,也是库结构中的一个层次,使用包时可以用USE语句说明,例如:

              USE IEEE, STD_LOGIC_1164, ALL

程序包分为包头和包体,包结构的格式如下:

(1)包头格式。

            PACKAGE 包名 IS
              [说明语句]
            END  包名

包头中列出所有项的名称。

(2)包体格式。

            PACKAGE BODY 包名 IS
              [说明语句]
            END 包名;

包体给出各项的具体细节。

例如:包头

            USE STD, STD, LOGIC, ALL
            PACKAGE logic IS
                TYPE three_level_logic IS ('0' , '1' , 'z') ; //数据类型项目
                CONSTANT unknown_value : three_level_logic : ='0' ;//常数项目
                FUNCTION invert (input : three_level_logic)//函数项目
                RETURN three_level_logic;
            END logic;

例如:包体

            PACKAGE BODY logic IS
              FUNCTION invert (input : three_level_logic)//函数项目描述
              BEGIN
              CASE input IS
                  WHEN '0' => RETURN '1' ;
                  WHEN '1' => RETURN '0' ;
                  WHEN 'Z' => RETURN 'Z' ;
              END CASE;
             END invert;
            END logic

该包使用例程:

            USE logic, three_level_logic, logic, invert; --使用数据类型和函数两个项目
            ENTITY  inverter IS
              PORT(x : IN three_level_logic ;
                    y : OUT three_level_logic) ;
            END inverter;
            ARCHITECTURE inverter_body OF inverter IS
            BEGIN
              kk :
              PROCESS
                  BEGIN
                      Y<=invert(x) AFTER 10ns;
                      WAIT ON x;
                END PROCESS;
              END inverter_body;

5.库(Library)

存放已编译的实体、结构体、包集合和配置,可由用户生成或由ASIC芯片制造商提供。

库是经编译后的数据的集合,它存放包定义、实体定义、结构定义和配置定义。在设计单元内的语句可以使用库中的结果,所以,库的好处就是设计者可以共享已经编译的设计结果,在VHDL中有很多库,但它们相互独立。

IEEE库:在IEEE库中有一个STD_LOGIC的包,它是IEEE正式认可的包。

STD库:STD库是VHDL的标准库,在库中有名为STANDARD的包,还有TEXTIO包。若使用STANDARD包中的数据可以不按标准格式说明,但是若使用TEXTIO包,则需要按照如下格式说明:

            LIBRARY STD;
            USE STD, TEXTIO, ALL

另外还有ASIC库、WORK库和用户自定义库等。

在使用库之前,一定要进行库说明和包说明,库和包的说明总是放在设计单元的前面:

            LIBRARY  库名;
            USE LIBRARY name, package, name, ITEM, name

例如:

            LIBRARY IEEE;
            USE IEEE, STD_LOGIC_1164, ALL

该例说明要使用IEEE库中的1164包中所有项目。

库的作用范围从一个实体说明开始到它所属的结构体、配置为止,当有两个实体时,第二个实体前要另加库和包的说明。

1.4 HDL编码风格及规则

1.4.1 编码风格

养成一个好的编码风格不仅有助于自己阅读和修改程序,更有利于别人阅读,因此,本节讲述的编码风格希望读者细心体会。

1.文件头和修订列表

作为好的源代码,其中必须包含所有需要的信息。因此源代码中要包含文件头和修订列表(以获得修改情况)。

1)文件头包含以下内容

● 模块名

● 文件名

● 需要的库

● 模块描述

● 使用的仿真器——运行平台和版本

● 使用的综合工具,其运行平台和版本

● 作者名字和E-mail

2)修订列表包含以下内容

● 修订版本号

● 改动的数据

● 修订者名字和E-mail

● 改动的详细描述

下面是一个例子:

            Example Header
            -------------------------------------------------------------------
            --Module              :MAC(Multiply Accumulate Unit)
            --File                :mac,vhd
            --Library              :ieee
            --Description           :It is a general Purpose MultiplyAccumulate Unit capable of
            --Simulator            :ModelSim 5,2/Windows 95
            --Synthesizer           :Synplify/Windows95
            --Author/Designer      :Harish Y S(harish@opencores,org)
            -------------------------------------------------------------------
            Example Revision List
            -------------------------------------------------------------------
            --Revision Number       :1
            --Date of Change        :20th March 2000
            --Modifier             :Harish Y S(harish@opencores,org)
            --Description           :Initial Design
            -------------------------------------------------------------------
            --Revision Number       :2
            --Date of Change        :dd mm yyyy
            --Modifier             :XYZ(email)
            --Description           :Modified the????,to improve????,,
            -------------------------------------------------------------------
            文件头的标准模式:
            -------------------------------------------------------------------
            --Title                :
            --Project              :
            -------------------------------------------------------------------
            --File                :
            --Author              :name    <email>
            -- Organization :
            --Created              :
            --Last update           :
            --Platform             :
            --Simulators           :
            --Synthesizers          :
            --Targets              :
            --Dependency          :
            -------------------------------------------------------------------
            -- Description :
            -------------------------------------------------------------------
            -- Copyright (c) notice
            -------------------------------------------------------------------
            --Revisions            :
            --Revision Number       :
            --Version              :
            --Date                :
            --Modifier             :name<email>
            --Desccription          :
            -------------------------------------------------------------------

2.联机注释

每一个重要的操作和定义后都要加上注释,描述操作和声明的使用。

3.命名规则

1)实体和结构 其规则如下:

● 实体名要确切描述其功能

● 实体名只能用小写字母,不超过10个字符

推荐:每个实体最好有一个3~4个字母的缩略名,可以将其应用在其内部的构造模块(component )和信号名中。

2)端口 其规则如下:

● 端口名应和信号相对应,以大写字母开头

● 若端口是标准设备,可包含标准名,不超过15个字符

提示:端口声明后要有详细注释。

3)结构体 结构体定义系统行为,可从不同方面对其进行描述,结构体和实体是一致的,其名字要表明系统描述的方法。规则如下:

● 结构体名可用“behavioural”表示行为描述,“structural”表示结构描述,“RTL”表示寄存器描述等

● 由综合出来的结构体要有“_syn”后缀,并且在开始和结束出要注明采用的技术

● 在“ARCHITECTURE”语句前要有一行注释,说明其功能,并说明是否可综合,或仅可仿真

推荐:当一个设计中包含多个文件时,通过加“_arch”后缀来加以区分。

4)元件component元件component在VHDL设计的层次结构中使用。其名称以包或实体的缩略名作开头。

推荐:可取有实际意义的单词,大小写可混用,最好不要超过8个字符。

5)配置 配置是用来说明逻辑模块和其构造体间的关系。配置名中要包含顶层设计名;以大写字母开头,不超过15个字符。

推荐:加“_cfg”后缀区分多个文件。

6)包 规则如下:

● 包中要包含系统所需定义的所有常量,数据类型,模块,过程和函数

● 包名以大写字母开头,不超过15个字符

推荐:加“_pkg”后缀区分多个文件,为包定义一个3~4个字符的缩略名,加在其中的常量,过程和函数名中,用以区分不同包中的内容。

7)函数 规则如下:

● 以大写字母开头,不超过10个字母

● 要体现其功能,用前缀“l_”表示局部变量

● 局部信号应有其特征域

推荐:加入包的缩略名于其中。

8)常量和类属说明 采用大写字母,要明确描述常量的用法。

推荐:加入包的缩略名于其中。

9)枚举(enumeration)、数据类型、记录和数组 定义时可采用大写字母,新数据类型要加后缀“_typ”。

10)信号 规则:

● 第一个符号必须是字母,信号名要描述其功能,不超过15个字符

● 头三个字母要显示说明驱动模块的类型,要把其驱动实体,模块或进程缩略名加在前面:如控制单元—“ctl”,算术逻辑运算单元—“alu”,乘法器—“mac”,数据地址发生器—“dag”

● 如果信号只是在仅有时钟的进程中获得其值的,则加“_q”,若是总线则加“_reg”信号定义语句后要有一行注释描述其功能

● 信号名要表明信号的极性:高电平有效/正逻辑(P),低电平有效/负逻辑(N)

● 全局信号“G”,局部信号“L”;若是三态信号,加“Z”

● 后续字符要说明信号的内容

11)变量 规则:

● 变量名要简单并能描述其功能

● 变量名可包含各种格式的字母、数字和下画线

● 变量名要确切的表示其行为

12)进程进程、块和配置可取有实际意义的单词,大小写可混用,最好不超过8个字符。

规则:

● 所有进程必须有进程名,用以描述其功能

● 注释要包含以下内容:组合、时序进程,组合进程要定义所有敏感信号,时序进程要定义时钟和其边沿(上升沿或下降沿),时序进程还要定义复位信号——如果有的话,其有效与否与时钟有关

13)测试工作台(test bench) 由于测试工作台在设计流程中的重要地位,因此,对其有一些特殊的要求。其基本规则如下:

● 其名称要与实体名一致,且加后缀“_TB”

● 结构体、进程、变量和信号同样遵循上述规则

● 内存组织和仿真生成由过程和函数来实现

● 出错报告要提供下述信息:实体或模块名,信号或变量名,过程或函数名,当前时间点,错误号或错误名,可能的出错原因,出错位置(RTL,structural或behavioral代码)

14)文件和目录结构 由目前的集成开发环境中自动管理。

15)其他说明

● 尽可能使用类属参数说明(Generic)

● 尽量多定义常数,这样可以增加代码的可读性

● 写代码之前,要先画出系统框图,对自己要做的模块有一个清楚的认识,这样可以减少写代码时间,提高效率

1.4.2 HDL编码指导

1.复位

复位使初始状态可预测,防止出现禁用状态。一般情况下建议注意以下几点:

● FPGA和CPLD的复位信号采用异步低电平有效信号,连接到其全局复位输入端,使用专用路径通道,FPGA和CPLD有固定时间延迟线,连接到所有资源上

● 对于目标器件为ASIC的core,异步时钟只能局部使用,在顶层设计上要与时钟同步,这可以防止过长的延时

● 复位时,所有双向端口要处于输入状态

强烈推荐:复位信号必须连接到FPGA和CPLD的全局复位引脚,这是由于这些引脚提供较低的抖动。

2.时钟

在core核中尽可使用小的时钟域。建议注意以下几点:

● 信号穿过时钟的两半个周期时,要在前后分别取样,防止出现半稳定状态

● 不要用时钟或复位信号作数据或使能信号,也不能用数据信号作为时钟或复位信号,HDL综合时会出现时序验证问题

● 不要使用门时钟

强烈推荐:时钟信号必须连接到全局时钟引脚上。

3.总线

在进行总线编码时,建议:

● 总线要从0位开始,有些工具不支持不从0位开始的总线

● 从高位到低位,这样可以避免在不同设计层上产生错误

4.通用规则

设计过程中,应该注意一些通用规则:

● 不要使用内部三态信号,否则增加功耗,这样使后端的调整更困难

● 只使用同步设计,这样可以避免在综合、时序验证和仿真中的出现的一些问题

● 不要使用延时单元

● 所有块的外部I/O必须注册,这样可以避免较长的路径延时

推荐:(1)避免使用锁存器,这样会产生综合和时序验证问题;

(2)避免使用负延触发的双稳态多谐振荡器(flip flop),同样会产生综合和时序验证问题。

(3)块内部I/O要例化,这是设计问题,在大部分情况下推荐使用。

5.Verilog编码指导原则

Verilog一般规则描述如下:

●在时钟驱动的同步进程中不要使用block结构,block结构应用于异步进程中

● Synopsys希望使用这种格式,有确定的仿真响应

● 尽量使用无路径的“include”命令行,HDL应当与环境无关

● 避免使用“ifdef”命令,尽量用一个全局定义文件做所有的定义,否则容易产生版本和编辑问题

好的习惯:(1)尽量在一个文件中只用一个模块,文件名要和模块名相同;(2)尽量在例化中使用名称符号,不要用位置符号,有利于调试和增加代码的易读 性;(3)在不同的层级上使用统一的信号名,容易跟踪信号,网表调试也容易;(4)比较总线时要有相同的宽度,否则其他位的值不可预测。

6.VHDL编码指导原则

VHDL编码一般规则描述如下:

● 外部端口用std_logic类型

● 不要赋未知值“x”或检查验证无效的“-”,这些值在仿真和综合时会产生不可预测的行为

● 不要使用信号和变量的默认值(或初始值),用复位脉冲初始化信号和变量,在仿真和综合时会出现不匹配

好的习惯:

(1)在整个VHDL工程中不要混用编码准则(VHDL 87 and VHDL 93 );

(2)尽量在一个VHDL文件中做一个设计,文件名要和结构名一致;

(3)尽量在模块例化中使用名称符号,不要用位置符号。

示例:

            wb_if : wb
                  PORT MAP (
                  CLK => CLK_i,
                  RST_I => RST_I_i,
                  ACK_O => ACK_O_i,
                  ADR_I => ADR_I_i,
                  CYC_I => CYC_I_i,
                  DAT_I => DAT_I_i,
                  DAT_O => DAT_O_i,
                  RTY_O => RTY_O_i,
                  STB_I => STB_I_i,
            WE_I => WE_I_i) ;

此外,编码时还应该注意:

● 在不同的层级上使用统一的信号名,容易跟踪信号,网表调试也容易

● 尽量用配置(configuration)映射实体、结构体和模块,改变不同的结构体只要简单改动一个文件就可以了,这在仿真上很有用,能从高层上改变低层结构体

● 尽量在分开的库中编译每个块

● 使用常量和类属说明定义缓冲大小、总线宽度和其他单元参数,这可增强可读性和代码复用性,在一个最小化的包中定义模块和常量

● 不要在代码中使用buffer类型的端口读取输出数据,要使用out类型,再增加另外变量或信号,以获取输出值。这是因为buffer类型的端口不能连接到其他类型的端口上,因此buffer类型就会在整个设计的端口中传播下去

示例:

                PROCESS (CLK, RST_n)
                variable out_var : std_logic;
                BEGIN   --PROCESS
                  IF RST_n = '0' THEN
                    Outsignal <= '0';
                    out_var <'0';
                    outsign2 <= '0';
                  ELSIF CLK'event AND CLK = '1' THEN
                    Outsign2<=out_var;  --the same as Outsignal
                    out_var : = input1 and input2;
                    Outsignal <= input1 and input2;
                  END IF;
            END PROCESS;

1.5 ISE基本操作

作为设计可编程逻辑器件的基本工具之一,ISE提供了强大的功能,学习好ISE的基本操作将为以后的程序编写和软件调试打下一个很好的基础。

1.5.1 ISE的获取

ISE有不同的系列,我们常说的ISE是指ISE Foundation系列产品。除此之外,还有ISE WebPACK和ISE Classics。

ISE WebPACK是免费的,用户到Xilinx网站注册后即可免费下载,其功能与ISE Foundation系列基本相同,但是支持的器件比较少。本书所讲解软件即是此款的9.2i版本。

ISE Classics包括早期版本的ISE软件,如早期版本的ISE Foundation和ISE WebPACK。这些工具对于完成、升级或维护现有设计,尤其是对不再为主流ISE软件配置所支持的器件,是非常有用的。

提示:ISE Classics是免费提供的,需要的用户可以联系Xilinx公司索取。

1.5.2 ISE的实现功能

ISE(Integrated Software Environment)是Xilinx设计开发FPGA/CPLD的软件。ISE的使用者范围很广,从初次使用CPLD的初学者到富有经验的ASIC设计者,都可以使用该软件进行学习开发。

ISE提供以下几方面的功能:

1. 设计输入(Design Entry)

ISE提供的设计输入工具包括:

● 用于HDL代码输入和报表查看的ISE文本编辑器(ISE Text Editor)

● 用于原理图编辑的工具ECS(Engineering Capture System)。该编辑器是一个图形用户接口,它允许设计者为设计输入创建、查看和编写原理

●用于生成IP Core的CORE Generator,设计者可以在简单的算法操作(如加法器)或系统级的模块化(如滤波器、各种转换器、存储器等)方面为Xilinx FPGA传送参数化的内核

● 用于状态机设计的StateCAD,它允许设计者以图形化的方式来设定状态和转换关系,创建好的图形文件将会被翻译成HDL文件

● 用于约束文件编辑的Constraint Editor,它允许用户创建和更改大部分常用的时序限制

● 用于引脚和区域编辑的PACE(The Pinout and Area Constraints Editor),它允许设计者查看和编辑I/O引脚、全局时钟和内部区域组织的限制

2. 综合(Synthesis)

ISE的综合工具不但包括Xilinx自身提供的综合工具XST(Xilinx Synthesis Technology),还可以集成Mentor Graphics公司的LeonardoSpectrum和Synplicity公司的Synplify等。

3. 仿真(Simulation)

ISE自带了一个具有图形化波形编辑功能的仿真工具HDL Bencher,还提供了使用Model Technology公司的ModelSim进行仿真的接口。

4. 实现(Implementation)

此功能包括翻译(Translate)、映射(Map)和布局布线(Place and Route)、定时分析(Timing Analyzer)、配置(Fit,只适用于CPLD)、芯片浏览(ChipViewer)等。

● 翻译:翻译过程会运行NGDBuild来把所有输入网表文件和设计约束信息合并到一个Xilinx数据库文件当中

● 映射:映射程序会将逻辑设计映射到具体的Xilinx器件中

● 布局和布线:PAR程序接收已经映射好的设计,将其布局布线到Xilinx器件中,为比特流生成器产生输出

● 定时分析:定时分析器为CPLD和FPGA设计提供静态定时分析方式,在对FPGA器件进行了映射、布局和布线、对CPLD器件进行了配置和布线后可立即进行定时分析

● 配置:CPLD的配置过程会将网表文件映射到指定的设备中并且创建JEDEC可编程文件

● 芯片浏览:此工具会提供给设计者I/O、宏单元详细信息、引脚分配等方面的图形化描述,便于清晰的看到器件内部的实际状况

5. 下载(Download)

下载功能包括两部分:

● 一是BitGen,它用于将布局布线后的设计文件转换为位流文件(Bitstream)供给器件进行配置

● 另一个是iMPACT,它的主要功能是产生各种各样的可编程文件格式,进行设备配置和通信,以及烧写FPGA芯片

1.5.3 ISE软件运行硬件环境及安装

ISE的硬件运行环境要求并不高,可以运行在Windows XP® Professional 32-bit/64-bit、Windows 2000 、Windows Vista™ Business 32-bit等操作系统上,还可以运行在Red Hat® Enterprise WS 3.032-bit/64-bit、Red Hat Enterprise WS 4.032-bit/64-bit、Red Hat Enterprise WS 5.032-bit/64-bit等Linux操作系统上,同样还可以运行在Solaris 9等UNIX操作系统上。下面给出该软件的详细安装过程。

(1)解压下载的WebPACK_SFD_9.2i软件包,双击其下的setup.exe图标,开始安装过程。此时系统弹出如图1-14所示【Welcome】窗口,单击按钮。

图1-14 【Welcome】窗口

(2)此时系统会弹出如图1-15所示的【Accept Software License】窗口,选中“I accept the terms of this software license”,单击按钮。此后的两步操作与此相同。

图1-15 【Accept Software License】窗口

(3)单击按钮后,系统会弹出如图1-16所示的【Select Destiantion Directory】对话框。在该对话框中,需要用户选择安装目录和命名在开始菜单中显示的该程序的名字。设置好后的结果如图1-16所示。

图1-16 【Select Destiantion Directory】对话框

(4)单击按钮后,系统会弹出如图1-17所示的【Select Installation Options】对话框,在该对话框中,用户需要选择要安装的组件,为了全面的开发考虑,选择所有的组件。

图1-17 【Select Installation Options】对话框

(5)单击按钮后,系统弹出如图1-18所示的另一个【Select Installation Options】对话框,该对话框选择是否用软件提供的环境变量来更新相应的值,全部选中,这样就不用自己重新设定。

图1-18 【Select Installation Options】对话框

(6)单击按钮后,系统会弹出如图1-19所示的又一个【Select Installation Options】对话框,该对话框用来选择是否安装在其官方网站上搜寻更新版本的更新软件,这里选中。

图1-19 【Select Installation Options】对话框

(7)单击按钮后,系统弹出如图1-20所示的【Begin Installation】窗口,该窗口中列出了之前的所有需要的操作。单击按钮后即开始安装软件。

图1-20 【Begin Installation】窗口

(8)安装中的画面如图1-21所示。

图1-21 安装中的画面

安装完毕软件后,有如下两种方式启动ISE。

(1)双击桌面上的快捷方式图标,如图1-22所示。

图1-22 快捷方式图标

(2)通过执行菜单命令【开始】/【所有程序】/【Xilinx ISE 9.2i】/【Project Navigator】,如图1-23所示。

图1-23 菜单命令

1.5.4 ISE运行及主界面简介

运行ISE软件后,在之前没有进行任何操作的情况下,首次打开的主界面如图1-24所示。

图1-24 ISE 主界面

1. 菜单栏

菜单栏如图1-25所示。主要包括文件、编辑、视图、工程、资源、操作、窗口、帮助等菜单。

图1-25 菜单栏

2. 工具栏

工具栏如图1-26所示。主要包括新建文件、打开文件、保存文件、放大、缩小等一些操作。

图1-26 工具栏

提示:设计者还可以通过视图菜单来决定哪些工具可以在工具栏中显示。

下面通过一个实例介绍其余的窗口。单击【File】菜单,选择【Open Example…】,如图1-27所示,此时系统会打开如图1-28所示的对话框,选择其中的v2_fifo_vhd_258,单击按钮打开实例。打开后的主界面如图1-29所示。

图1-27 菜单命令

图1-28 【Open Example】对话框

图1-29 主界面

3. 【Sources】窗口

1)【Sources】选项卡 该窗口显示了设计者所创建的和加载到工程中的源文件,如图1-30所示。从图中可以看出该工程中有两个文件。【Sources for】后的下拉菜单如图1-31所示。选择不同的项将列出对应操作下的文件。

图1-30 【Sources】选项卡

图1-31 【Sources for】下拉菜单

2)【Snapshots】选项卡 也可称为“快照”,可以是其所表示的数据的一个副本,也可以是数据的一个复制品,主要用于支持快速数据恢复的可扩展、高性能且具有空间效率的副本。当用户选择工程进行快照后,所设计的工程文件、源文件、工作目录的副本等将会被保存在这个选项卡下,它只是个只读文件,以备将来的参考和使用。通过单击【Project】/【Take snapshot】,如图1-32所示,可对当前工程文件进行快照处理。【Snapshots】选项卡如图1-33所示。

图1-32 【Project】/【Take snapshot】菜单命令

图1-33 【Snapshots】选项卡

4. 【Processes】窗口

如图1-34所示。该窗口列出了对源文件的一系列操作,还包括增加已有源文件和创建新的源文件两项。相关操作主要是设计工具、用户约束、综合、设计实现、产生可编程文件。各项操作如何进行将在以后的章节中陆续介绍。

图1-34 【Processes】窗口

5. 【Transcript】窗口

如图1-35所示。该窗口中显示的是操作进行中或进行完后的相关信息。其中【Console】选项卡下的窗口显示正在执行操作时的相关信息,这些信息默认是以滚动的形式显示的,但也可以手动显示,组合键会继续滚动显示;【Error】显示处理过程中遇到的错误信息,必须将错误处解决,否则无法继续进行;【Warning】显示遇到的警告信息,但是处理过程仍然能够完成并产生相关的文件输出。

图1-35 【Transcript】窗口

6. 【Workspace】窗口

当设计者打开工程文件、打开语言模板或运行某些报告、日志时,相关的文件或报告就会出现在这个窗口中,一次可以打开多个文件或视图,窗口底部的选项卡上显示了当前窗口中都有哪些文件已打开,单击就可以把它选为当前工作文档。

1.6 本章小结

本章从实用的角度,简要介绍了FPGA/CPLD的基本结构和CLB、IO Block等核心组成部分,使读者对FPGA/CPLD知识有了一个初步的认识,有了这些知识,读者在使用ISE的时候就会明白相关的操作是什么道理,理解起来就会轻松得多。

Xilinx公司提供了各式各样的FPGA/CPLD产品,每一款产品都有自己的特点,设计者在设计前要充分考虑所进行的设计侧重于哪些方面,进而选用最优的产品,确定了所选用的器件后,就可以到Xilinx官方网站下载该款器件的各种技术手册,对其有一个充分得了解。

进行产品开发时,其过程往往是复杂、反复不断进行的,本章介绍的ISE的实现功能是一个基本操作流程,是最基本的。在实际的设计时往往交叉使用,因此过程也会变得相对繁琐一些,但其本质还是没有变的,都是围绕本章的基本操作流程。好的开发流程可以加快进度、节省时间,随着学习的深入和设计经验的增长,读者会慢慢接触一些新的流程。

1.7 思考与练习

1. 概念题

(1)常用的FPGA/CPLD芯片有哪几款?各自的性能特点是什么?

(2)FPGA/CPLD的基本结构包括哪几部分?

(3)一个完整的VHDL程序通常都包括哪几部分?各部分的结构是怎么安排的?

2. 操作题

按照书中的讲解,自己下载并安装上一个版本的ISE开发工具。