FPGA开发教程-基于Xilinx和Verilog 课件全套-第1-15讲-FPGA基础概念 -ADC实验_第1页
FPGA开发教程-基于Xilinx和Verilog 课件全套-第1-15讲-FPGA基础概念 -ADC实验_第2页
FPGA开发教程-基于Xilinx和Verilog 课件全套-第1-15讲-FPGA基础概念 -ADC实验_第3页
FPGA开发教程-基于Xilinx和Verilog 课件全套-第1-15讲-FPGA基础概念 -ADC实验_第4页
FPGA开发教程-基于Xilinx和Verilog 课件全套-第1-15讲-FPGA基础概念 -ADC实验_第5页
已阅读5页,还剩294页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

FPGA开发实用教程——基于Xilinx和VerilogPracticalTutorialforFPGADevelopment——BasedonXilinxandVerilog第1讲FPGA基础概念1什么是FPGAWhatisFPGA“

FPGA(FieldProgrammableGateArray)中文名称为现场可编程门阵列,是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物,是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数量有限的缺点。简而言之,FPGA就是一个可以通过编程来改变内部结构的芯片。1.12FPGA与MCU3读取指令分析指令执行指令程序程序指令MCUFPGA×N程序工作设计图纸外部配置FLASHFLASHSRAM应用场景4通信领域数字信号处理领域视频图像处理领域高速接口设计领域医学成像领域IC验证领域——实现无线通信中的高速数字信号处理、高速通信协议处理

——FIR等重复性数字滤波、高速并行的数字信号处理任务

——处理对图像稳定性、清晰度、亮度和颜色要求较高的图像数据——实现不同的接口逻辑,减少专用接口芯片数量

——超声、核磁共振等成像的高频采样、各种影像算法的处理——把IC的代码移植到FPGA上生成接近真实IC芯片的电路,验证IC设计FGPA基本结构BasicstructureofFGPA“

FPGA的基本结构包括可编程输入输出单元,基本可编程逻辑单元,布线资源,全局时钟资源,嵌入式块RAM,内嵌的底层功能单元,内嵌专用IP单元。1.25基本结构——可编程输入输出单元(IOB)6

可编程输入/输出单元(IOB)是芯片与外界电路的接口部分。为了便于管理和适应多种电器标准,FPGA的IOB被划分为若干个组(Bank),每个Bank的接口标准由其接口电压决定,一个Bank只能有一种VCCX,但不同Bank的VCCX可以不同。目前大多数FPGA的I/O单元被设计为可编程模式,即通过软件的灵活配置,可适应不同的电器标准与I/O物理特性。基本结构——基本可编程逻辑单元(CLB)7

基本可编程逻辑单元主要由查找表和寄存器组成的。其中,查找表完成组合逻辑功能,寄存器可配置为带同步/异步复位和置位、时钟使能的触发器,也可以配置成为锁存器,用于完成时序逻辑功能。一般来说,比较经典的基本可编程单元的配置是一个寄存器加一个查找表,但不同厂商的寄存器和查找表的内部结构有一定的差异,组合模式也各不相同。基本结构——查找表(LUT)8

查找表(Look-Up-Table)简称为LUT,其本质上就是一个RAM。目前FPGA内部中多使用4输入的LUT,每一个LUT可以看成一个有4位地址线的RAM。当通过原理图或硬件描述语言设计了一个逻辑电路以后,FPGA开发软件会自动计算逻辑电路的所有可能结果,并把真值表(即结果)事先写入RAM中。这样,每输入一个信号进行逻辑运算就等于输入一个地址进行查找表操作,通过地址找到对应的RAM中的结果,最后将其输出。基本结构——布线资源9

在FPGA芯片内部有着丰富的布线资源,连通了内部的所有单元,其长度和工艺决定着信号在连线上的驱动能力和传输速度。根据工艺、长度、宽度和分布位置的不同而划分为4类不同的类别:全局布线资源、长线资源、短线资源及分布式的布线资源。基本结构——全局时钟资源10

FPGA器件的时钟信号源一般来自外部,通常使用晶体振荡器(简称晶振)产生时钟信号。全局时钟是FPGA内的一种时钟网络,可以覆盖FPGA中各种资源的时钟输入,为其提供高频、低抖的时钟信号。在Spartan6系列的FPGA芯片中,全局时钟网络连接着由DCM和PLL组成的时钟管理模块,能够实现时钟信号的倍频、分频和相移等功能,进一步提升整个系统的性能。基本结构——嵌入式块RAM(BRAM)11

块RAM是FPGA内部一种SRAM结构的块状存储器,以阵列的方式排布于FPGA的内部,是实现各种存储功能的主要部分,可被配置为ROM、RAM、内容地址存储器(CAM)以及FIFO等常用存储结构。使用BRAM时不会占用额外的逻辑资源,并且读写速度非常快,但是使用时消耗的BRAM资源只能是其块大小的整数倍,就算只存了1bit的数据也要占用一个块RAM的资源。在实际应用中,块RAM的数量也是选择芯片的一个重要因素。基本结构——内嵌专用IP单元12

内嵌专用IP单元指的是由FPGA厂商预先设计好,经过严格测试和优化过的软核IP和硬核IP。如DLL、PLL、DSP、CPU等通用程度较高的软核,以及专用乘法器、浮点运算单元、串并收发器等处理能力强大的专用硬核。这些丰富的内嵌专用IP单元,使得FPGA成为了系统级的设计工具,逐步具备了软硬件联合设计的能力,性能和应用场景得到了进一步的提升。基本结构13电源定义Definitionofpowersupply“

FPGA的电源主要由核电压VCCINT,IO电压VCCIO,辅助电压VCCAUX,blockRAM的供电压VCCBRAM以及高速GTX接口电压(VMGTAVCC,VMGTAVTT,VMGTVCCAUX,VMGTAVTTRCAL等电压组成。这里主要介绍核电压、IO电压和辅助电压。1.314核电压VCCINTVCCINT是FPGA芯片的内核电压是用来给FPGA内部的逻辑门和触发器上的电压。即芯片的晶体管开关是由核心电压提供。当内部逻辑工作时钟速率越高使用逻辑资源越多,则核心电压供电电流会更大,可高达几安,此时芯片必然会发烫,需要散热装置辅助散热。随着FPGA的发展,核心电压可支持的电源输入从5V减小到了现在的1.2V,由核心电压引起的芯片发烫、功耗等也变的越来越低。15IO电压VCCOVCCO用于FPGA驱动IO模块的电压,因为FPGA经常要与多种不同电平接口的芯片通信,所以都会支持非常多的电平标准,为此,VCCO通常以Bank为界,相互之间是独立的,即一个Bank块只能存在一种IO电压,每个Bnak可以与一种电平芯片通信,如VCCO0接3V3的电源,与之对应的Bank0引脚便与3.3V的MCU通信,

VCCO1接2.5V,Bank1的引脚则与2.5V的DDR芯片通信。16辅助电压VCCAUX

从FPGA的基本结构可以看出,FPGA并非一个单纯的数字逻辑芯片,内部也带有一些模拟组件,比如Xilinx的DCM数字时钟管理组件、高档点的FPGA还有高速串并转换器serdes、温度监控器件等这些模拟器件,这些模拟器件对电源噪声要求很高,所以需要一个独立稳定的电源进行供电。VCCAUX就是为这些模拟器件提供电压,另外,VCCAUX还可以给部分IO供电,像JTAG等。17数据存储及配置模式Datastorageandconfigurationmethods“1.418数据存储的载体

在FPGA内部,用来作为数据存储的载体主要有3种,分别是触发器、查找表和块RAM。触发器:可以在非时钟有效沿期间记忆并保持某个状态,主要用于时序逻辑电路中;查找表:也被称为分布式RAM,一般用于保存组合逻辑的真值表,实现组合逻辑的功能;块RAM:FPGA实现各种存储功能的主要部分,可以配置为ROM、RAM、FIFO以及STACK等常用存储结构。如果外部有大量数据交互时,就要通过增加外设来对数据进行暂时性的存储,如SDRAM存储器或者DDR3存储器,暂存在外设中的数据最终也要通过FPGA内部的RAM进行存储与处理。19编程数据的存储

FPGA的编程数据一般存储在块RAM中的SRAM单元里,在运行时,FPGA会将编程信息读出,根据信息配置好硬件资源后,FPGA便开始工作;由于SRAM掉电就会丢失内部数据,因此往往都会外接一个能够掉电保存数据的片外存储器以保存程序。这样一来,上电时FPGA便将外部存储器中的数据读入片内RAM以完成配置,对FPGA编程完成后便进入工作状态;掉电后FPGA内部SRAM中存储的数据丢失,逻辑清零。以这种方式配置FPGA不仅能反复使用,还无需重复的手动配置。完成一次主动配置之后每次上电便会自动的实现FPGA的内部编程。20配置模式

FPGA的配置方式灵活多样,根据芯片是否能够自己主动加载配置数据可分为主模式、从模式以及JTAG模式。主模式:由FPGA内部产生时钟,从片外FLASH中加载配置所需的比特流,读入到SRAM中,实现内部结构映射。从模式:FPGA作为从设备,微处理器控制器或或者其他终端提供配置所需的时序,实现配置数据的下载。JTAG模式:通过JTAG将PC中的比特文件流下载到FPGA中进行调试,断电即丢失。21Spartan6的配置22开发流程Developmentprocess“1.523

FPGA的设计流程就是利用EDA开发软件和编程工具对FPGA芯片进行开发的过程。原理图和HDL(Hardwaredescriptionlanguage,硬件描述语言)是两种最常用的数字硬件电路描述方法。其中,运用HDL设计方法具有更好的移植性、通用性以及利于模块划分的特点,在工作学习中被广泛使用。HDL语言

HDL(HardwareDescripTIonLanguage)语言又称为硬件描述语言,是一种用文本的方式把硬件电路描述出来的语言。目前最主要的硬件描述语言是VHDL和VerilogHDL。VHDL发展的较早,语法严格,而VerilogHDL是在C语言的基础上发展起来的一种硬件描述语言,语法较自由。我们在阅读HDL程序的时候,在脑子里应该能反映出一个完整的硬件电路结构。也就是说,我们在编写HDL语言之前,就要对需要实现的电路有清晰的概念。所以HDL语言只是一个描述我们头脑中具体电路的工具,掌握FPGA的根本不是语言而是逻辑电路的设计。24基于HDL的开发流程

典型FPGA的开发流程一般先通过系统功能设计,然后通过VHDL/VerilogHDL硬件描述语言进行RTL级HDL设计,然后进行RTL级仿真、综合、门级仿真、布局布线和时序仿真等步骤,最后生成下载配置文件,下载到FPGA中进行板级调试。25FPGA开发实用教程——基于Xilinx和VerilogPracticalTutorialforFPGADevelopment——BasedonXilinxandVerilog第2讲-FPGA开发平台和工具26XC6SLX16芯片介绍IntroductiontoXC6SLX16Chip“2.127XC6SLX16芯片

XC6SLX16是赛灵思(Xilinx)Spartan-6系列的一种低成本、低功耗的FPGA芯片,在工业控制、医疗设备等各种领域都有应用。XC6SLX16芯片采用了45nm的CMOS工艺,速度等级为-2,引脚总数为324个,可用I/O数量为232个,内部提供了14579个逻辑单元,136KB的分布式RAM,576KB的内嵌式块RAM,最大工作频率可达1080MHz。28FPGA高级开发系统FPGAAdvancedDevelopmentSystem“2.229FPGA高级开发系统

FPGA高级开发系统上的核心板通过两个连接器将148个可用I/O引出给平台上的外设使用,剩下的用于核心板上的外扩SRAM、用户配置FLASH及JTAG下载等。30系统资源31资源说明资源说明FPGASpartan-6XC6SLX16外扩用户FlashW25Q128,16MB外扩SDRAMH57V2562GTR,256Mbit温湿度传感器采用SHT20芯片独立LED8位DAC1通道,BNC接口独立按键4位ADC1通道,BNC接口七段数码管8位人体生理参数监测系统接口通过USB线与人体生理参数监测系统进行通信(串口通信方式)矩阵键盘4×4独立按键矩阵键盘拨动开关16位OLED分辨率128×64蓝牙串口蓝牙,采用HC-05模块USB转UART1路,通过B型USB线连接计算机Wi-Fi串口Wi-Fi,采用ESP8266模块外扩用户EEPROMAT24C02,2K(256字节)电容触摸屏7寸串口电容触摸屏,分辨率为800×480系统可开展的实验32序号实验名称序号实验名称1分频器实验7串口通信实验2流水灯实验8读写外部EEPROM实验3独立按键去抖实验9读写外部FLASH实验4七段数码管显示实验10SHT20温湿度测量实验5矩阵键盘扫描实验11DAC实验6OLED显示实验12ADC实验软件安装和配置SoftwareInstallationandConfiguration“2.333ISE14.7简介34

集成软件环境(IntergratedSoftwareEnvironment,ISE)是XilinxFPGA/CPLD的综合性集成设计平台,该平台集成了设计输入、仿真、逻辑综合、布局布线与实现、时序分析、芯片下载与配置、功率分析等几乎所有设计流程所需要的工具。Synplify简介35

Synplify/SynplifiyPro是Synplicity公司出品的综合工具,该工具支持大多数半导体厂商的FPGA。在实际应用中,可以使用Synplify/SynplifiyPro对设计进行综合得到EDIF网表文件,再在ISE中引入网表文件进行布局布线就可以实现设计。安装与配置36ISE14.7的安装与配置Synplify的安装与配置Xilinx下载器驱动的安装CH340串口驱动的安装FPGA开发实用教程——基于Xilinx和VerilogPracticalTutorialforFPGADevelopment——BasedonXilinxandVerilog第3讲VerilogHDL语法基础37Verilog模块Verilogmodule“

VerilogHDL是被IEEE认定的国际标准硬件描述语言,模块(module)是VerilogHDL描述数字电路的基本单元,又称建模,它可以表示一个简单的门电路,也可以是功能复杂的电路或系统。每个模块(电路)的描述均以关键词module开始,以endmodule结束(后面不用加分号)3.138模块(module)语法结构module模块名(//端口列表——端口类型-信号类型-位宽-端口名input(输入)

信号类型(wire)

位宽

端口名,

output(输出)信号类型(wire/reg)位宽

端口名,inout(双向)信号类型(wire)

位宽

端口名);//端口定义//内部变量及参数声明;wire,reg,function,task,parameter,define等//功能定义(模块功能实现)数据流描述:assign结构化描述:门级描述或module例化

行为级描述:initial,alwaysendmodule39端口定义举例①moduleled(

inputwireclk_50mhz_i,//时钟输入,50MHz

inputwirerst_n_i,//复位输入,低电平有效

outputwire[3:0]led_o//led输出,共4位);……endmodule②moduleled(clk_50mhz_i,rst_n_i,led_o);

inputwireclk_50mhz_i;//时钟输入,50MHz

inputwirerst_n_i;//复位输入,低电平有效

outputwire[3:0]led_o;//led输出,共4位……endmodule40Verilog模块举例module

EasyDS(

);

endmodule41

inputwire

a_i,b_i,//2输入a_i,b_i

outputwire

x_o,y_o,z_o

//3输出x_o,y_o,z_o

EasyDSa_ib_ix_oz_oy_o

assignx_o=a_i;

assigny_o=~b_i;//取反

assignz_o=a_i&b_i;//相与标识符定义IdentifierDefinition“

标识符是用于定义常数、变量、信号、端口、子模块或参数名称,是一组由字母、数字、$和下划线任意组合的字符串,并且必须以字母或下划线开头。在VerilogHDL中,标识符对大小写敏感,也就是说大小写不同的标识符被视为不同的名称。此外,VerilogHDL中定义的关键词不能被用作标识符使用。3.242标识符举例①合法标识符:clk_50mhz_irst_n_iled_oLED_OFF//与led_off不同_bus3n$65743②不合法标识符:3sum//不允许数字开头ab@cd//不允许包含字符@a%b//不允许包含%not//关键字不允许做标识符input

//关键字wire

//关键字逻辑值集合Logicalvalueset“

在二进制计数中,单比特逻辑值只有0”和“1”两种状态,而在Verilog语言中,为了对电路了进行确的建模,又增加了两种逻辑态,即“X”和“Z”。其中,0表示逻辑低电平,1表示逻辑高电平,X表示未知或不确定的电平,Z表示高阻态,X和Z不区分大小写。3.344逻辑值45逻辑0:表示低电平,也就对应电路中的GND、VSS逻辑1:表示高电平,也就是对应电路中的VCC、VDD逻辑X:表示末知,有可能是高电平,也有可能是低电平逻辑Z:表示高阻态,当外部没有激励信号时,是一个悬空状态,通常用来对三态总线进行建模。常量Constant“在程序运行过程中,其值不能被改变的量称为常量(constants),VerilogHDL中主要有三种类型的常量:整数型常量、实数型常量和字符串型常量。其中,整数型常量是可以综合的,而实数型和字符串型常量是不可综合的。除此之外,还可以用参数的形式来表示常量,即参数型常量。3.446整数型常量

在VerilogHDL中,整数型常量有四种进制表示形式:二进制整数(b或B)、八进制整数(o或O)、十进制整数(d或D)、十六进制整数(h或H)。<符号><位宽>'<进制><数字>

符号为“+”时表示正数,符号项必须省略;位宽和进制是可选项。位宽是指该数据以二进制位计算时的数据长度,当省略位宽项时,表示采用默认位宽(由具体的计算机系统决定,至少32位);当省略进制项时,表示采用默认的十进制表示方式;数字则是基于该进制项时的数值,当值为x、z以及十六进制中的a到f时,不区分大小写。47整数型常量示例484'b1010

//位宽为4的二进制数10104'o7

//位宽为4的八进制数799

//十进制数99,位宽由计算机决定8'h4F

//位宽为8的十六进制数4F-8'd5

//位宽为8的十进制数-5(5的8位二进制补数)26'd49_999_999

//位宽为26的十进制数499999994'b11x0

//位宽为4的二进制数从低位数起第2位为不定值4'b101z

//位宽为4的二进制数从低位数起第1位为高阻值10'dz

//位宽为10的十进制数,其值为高阻值8'h4x

//位宽为8的十六进制数,其低4位值为不定值实数型常量

实数型常量采用十进制法或者科学计数法表示,这种类型用于存储非整数,即有小数部分的数字。实数型常量是不可综合的类型,通常只在VerilogHDL的测试文件中使用。实数型变量用关键字real来声明,声明时不能带有范围,默认值为0。如果将一个实数型常量或变量赋值给一个整数型变量,则该实数值会采用四舍五入的方式将整数部分会赋值给整数型变量。十进制法/科学计数法49实数型常量示例504.5

//十进制数表示4.53.8e-2

//科学计数法表示0.038reals_r=4.49;//声明一个实数型变量s_r,值为4.49,

赋值给整数型变量时为4wire[3:0]a=12.1;

//赋值后a值为12reg

[3:0]b=-12.5;

//赋值后b值为-13字符串型常量

一个字符串(strino)型常量是由英文双引号括起来并包含在一行中的字符序列,不能分成多行进行书写。在表达式和赋值中,用作操作数的字符被视为由8位ASCII值表示的无符号整数常量,每一个8位ASCII值表示一个字符。“字符串序列”51字符串型常量示例52“C”;//字符C“characterstring”;//字符串characterstring当字符串作为变量时,是wire/reg类型的变量,其宽度等于字符串中的字符数乘以8wire[8*14:1]stringvar;//定义了一个14个ASCII值的wire变量,[8*14-1:0]assignstringvar=“Helloworld!”;//字符串参数型常量

为提高程序的可读性和可维护性,在VerilogHDL中,通常使用关键词parameter来定义参数型常量,即用parameter来定义一个标识符代表一个常量,称为符号常量。parameter参数名=表达式;

表达式中只能包含已经定义的参数或者常量数字。53参数型常量示例54

parameterLED0_ON=8'b0001;//LED0点亮

parameterLED1_ON=8'b0010;//LED1点亮

parameterLED2_ON=8'b0100;//LED2点亮

parameterLED3_ON=8'b1000;//LED3点亮

parameterLED_OFF=8'b0000;//全部LED熄灭数据类型DataType“

Verilog中数据类型的作用是表示硬件中的数据存储和传输,总体上数据类型可以分为网络(net)和变量(variable)两类,代表不同的赋值方式和硬件结构。其中,网络表示不同结构实体之间的物理连接,其本身不能存储值,它的值由它的驱动器上的值决定,常用类型为wire型;变量则表示数据存储单元,对其赋值会改变物理上数据存储单元中的值,常用类型为reg型。3.555线网(wire)型

wire型数据常用来表示以assign关键字指定的组合逻辑信号。使用wire定义的变量,主要用于结构化器件之间物理连接建模,不存储逻辑值,必须由器件驱动,通常由assign进行赋值。当一个wire类型的信号没有被驱动时,缺省值为z(高阻)。wire信号名;

//定义一个1位的wire型数据wire[width-1:0]

信号名;

//定义一个位宽为width的wire型数据56wire型示例57outputwire[3:0]led_o;//4bit位宽的led_o,且为输出端口wires_clk_1hz;//1bit位宽的1Hz时钟信号wire[1:0]s_cnt;//2bit位宽的计数信号wire[0:2]s_data;//3bit位宽的数据信号wire

[8*14:1]stringvar;//定义了一个14个ASCII值的wire变量wire[3:-2]s_d;//6bit位宽的信号,s_d[3:0]和s_d[-1:-2]可以用于

表示不同的数据,提高程序的可读性寄存器(reg)型

寄存器是数据存储单元的抽象,寄存器数据类型的关键字为reg。通过赋值语句可以改变寄存器存储的值,其作用相当于改变触发器存储的值,可用于对存储单元如D触发器、ROM存储器的描述。reg 信号名;

//定义一个1位的wire型数据reg[width-1:0]信号名;//定义一个位宽为width的wire型数据注意,reg型数据常用来表示always块中的指定信号,常代表寄存器或触发器的输出,在always语句中进行描述的变量必须申明为reg类型。58reg型示例59outputreg

[3:0]led_o;//4bit位宽的led_o,且为输出端口regs_clk_1hz;//1Hz时钟信号reg[1:0]s_cnt;//计数信号,2位reg

[0:2]s_data;//3bit位宽的数据信号reg

[2:-3]s_d;//6bit位宽的信号,s_d[2:0]和s_d[-1:-3]可以用于

表示不同的数据,提高程序的可读性运算符Operator“

在Verilog中,运算符按所带操作数的个数来区分,可分为三类:只带一个操作数的单目运算符,可带两个操作数的双目运算符以及可带三个操作数的三目运算符。按功能则可分为算数运算符、关系运算符、赋值运算符、位运算符、逻辑运算符、位拼接运算符、条件运算符和移位运算符等。3.660算术运算符

算术运算符用来执行算术运算操作,在进行算术运算操作时,如果某一个操作数有不确定的值x,则整个结果也为不定值x。assignSum=A*8’b0110_11x0;//Sum=x61算术运算符描述+加,A+B-减,A-B*乘,A*B/除,A/B,结果只取整数部分%模除(求余),A%B关系运算符32<45

//结果为Ture(1)4’b1000>5’b10010

//等价于5’b01000>5’b10010,不等式不成立,返回结果为False(0)52<8’hxF

//结果为未知(x)62关系运算符描述(返回结果真/假/未知)==等于,A==B!=不等于,A!=B<小于,A<B>大于,A>B<=小于等于,A<=B>=大于等于,A>=B赋值运算符rega=1’d0;regb=1’d1;regd=1’d0;rege=1’d1;regc,f;assignled_o=0001;63赋值运算符描述=阻塞赋值,用于对参数赋值、赋初始值和在assign语句中赋值,常用于组合逻辑电路对信号进行赋值<=非阻塞赋值,常用于时序逻辑电路对信号进行赋值,常用于以always定义的块语句中。always@(posedgeclk_i)//时钟上升沿触发alwaysbeginb=a;c=b;e<=d;f<=e;

end

//always块结束后,b=c=0,e=0,f=1;位运算符wire[7:0]A=00111100;wire[7:0]B=00001101;assignY1=~B;//取反,Y1=11110010

assignY2=A&B;//与运算,Y2=00001100assignY3=A|B;//或运算,Y3=00111101assignY4=A^B;//异或,Y4=0011000164位运算符描述~按位非,~A&按位与,A&B|按位或,A|B^按位异或,A^B^~按位同或,A^~B逻辑运算符

逻辑运算符用来执行逻辑运算操作。操作数可以是reg和wire类型的数据,无论操作数有多少位,运算结果只有一位,值为0或者1。其中“&&”和“||”是双目运算符(即要求运算符两侧各有一个操作数),其优先级别低于关系运算符,而“!”高于算术运算符。assigny1=!a&&b;//a取反后与b相与

assigny2=!(a||b);//a和b相或的结果取反65逻辑运算符描述!逻辑非,!A&&逻辑与,A&&B||逻辑或,A||B位拼接运算符reg[3:0]x=4'b1100;reg[3:0]y=4'b0010;assignz1={x,y[3],y[2],y[1],y[0]};//z1=8'b11000100assignz2={1'b1,1'b1,1'b0,1'b0,1'b0,1'b0,1'b1,1'b0};//z2=8'b1100001066位拼接运算符描述{,,,}用于位的拼接,将小表达式合并形成大表达式条件运算符条件表达式?表达式1:表达式2//如果条件表达式成立,取值表达式1,否则取值表达式2例:assignz=(a>0)?x:y;//如果a>0,z=x,否则z=y67条件运算符描述?:能够根据条件表达式的值来选择表达式移位运算符68移位运算符描述<<左移,A<<n>>右移,A>>n

其中A代表要进行移位的操作数,n代表要移几位,这两种移位运算都用0来填补移出的空位。此外,左移和右移还可以用于实现乘以2n和除以2n的功能。wire[7:0]A=00111100;//60(D)assignY1=A<<2;//Y1=11110000(B)=240(D),相当于乘以4assignY2=A>>3;//Y2=00000111(B)=7((D),相当于除以8运算符优先级69名称运算符优先级求非、求反~,!高乘、除、取模*,/,%↓加、减+,-移位<<,>>关系<,<=,>,>=等式==,!=按位与&按位异或/同或^,^~按位或|逻辑与&&逻辑或||条件?:低常用语句UsefulSentences“

VerilogHDL语句包括过程语句、块语句、赋值语句、条件控制语句、循环控制语句、编译导向语句、实例引用语句等。其中,较为常用的有assign(赋值语句)、initial和always(过程语句)、if...else和case(条件控制语句)、for和while(循环控制语句)、模块例化(实例引用语句)等。3.770assign语句

assign语句用在数据流描述中,表示对信号赋值。assign相当于连线,将一个信号的值不间断地赋值给另一个信号,或将逻辑表达式赋值给信号变量。assign语句常用于组合逻辑电路的建模中,只能对线网型(wire型)信号变量赋值。assignwire型变量=表达式;当右边表达式的变量值或运算结果发生变化时,等式右边的值便会被更新赋值给左边的wire型变量,例如将产生的时钟信号s_clk赋值给时钟输出clk_o。assignclk_o=s_clk;//clk_o随s_clk的变化而变化71initial语句

initial语句主要用于VerilogHDL的测试文件中,用来产生测试环境和设置信号记录,如果在某一条语句前面存在延迟#<delay>,那么这条initial语句的仿真将会停顿下来,在经过指定时长的延迟之后再继续执行,延迟时长与timecale定义的时延单位有关,一个模块中可以有许多个initial块,它们都是并行运行的,且initial语句只执行一次。72initialbegin

语句1语句2…语句nend;initial语句示例73`timescale

1ns/1ps…//端口定义、信号定义等initialbegina=1'b1;#10

a=1'b0;//延迟10ns后a值由1变为0,即高电平信号持续了10nsendalways语句

always语句几乎在所有的时序逻辑设计中都会使用,“敏感事件列表”用于触发always语句的执行,符合触发条件便可以一直重复执行。只有reg类型数据能够在这种语句中被赋值,reg类型数据在被赋新值前保持原有值不变。一个模块可以包含多个always块,它们都是并行执行的。74always@(敏感事件列表)begin

代码部分(详细电路设计)end;always语句示例75

always@(posedges_clk_1hz)

//在s_clk_1hz的上升沿触发

begins_data<={s_rx_data,s_data[7:1]};//逻辑右移s_cnt<=s_cnt+1'b1;//计数end条件控制语句——if...else语句

if...else语句用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的几种操作之一。if...else语句是顺序执行语句,不能单独使用,需要在always块语句中才能使用。76if(表达式1)begin

逻辑电路1endelseif(表达式2)

begin

逻辑电路2end…elsebegin

逻辑电路nendif...else语句示例77always@(posedges_clk_1hzor

negedgerst_n_i)//在s_clk_1hz的上升沿和rst_n_i的下降沿触发beginif(rst_n_i==0)s_cnt<=

2'b0;elseif(s_cnt>=CNT_MAX)s_cnt<=2'b0;else

s_cnt<=s_cnt+1'b1;end条件控制语句——case语句

case语句是多分支选择语句,同样也是顺序执行语句,不能单独使用,要在always语句中使用。78case(控制表达式)分支表达式1:begin

逻辑电路1end分支表达式2:begin

逻辑电路2end

…default:begin

逻辑电路nendendcasecase语句示例79always@(s_cnt)begincase(s_cnt)

2'b00:led_o=LED3_ON;

2'b01:led_o=LED2_ON;

2'b10:led_o=LED1_ON;

2'b11:led_o=LED0_ON;

default:led_o=LED_OFF;endcaseend循环控制语句——for循环语句

for循环语句可以根据指定的条件执行代码块多次,从而大大提高了编程效率。for循环语句可以用来实现以下基本功能:a.重复执行特定的语句或者语句块;b.在满足特定条件时跳出循环;c.根据指定的步长迭代循环变量。for循环语句同样也是顺序执行语句,不能单独使用,要在always语句中使用。80for(初始条件;循环条件;步长)begin

循环体endfor循环语句示例81reg[7:0]s_data;reg[2:0]s_count;integeri;always@(s_data)begins_count=3’b000;for(i=0;i<8;i=i+1)beginif(s_data[i]==0)begin

s_count=s_count+1;endendend循环控制语句——while循环语句

while循环语句首先判断循环条件表达式是否为真,若为假,则其后的语句一次也不执行。在循环语句中,必须有一条改变循环执行条件表达式值的语句,类似于for循环语句中的步长部分。while语句同样不能单独使用,要在always语句中使用。82while(循环条件)begin

循环体endwhile循环语句示例83reg[7:0]s_data;reg[2:0]s_count;integeri;always@(s_data)begins_count=3’b000;i=0;while(i<8)

begin

if(s_data[i]==0)

begins_count=s_count+1;

endi=i+1;endend模块例化语句

FPGA逻辑设计中通常是一个大的模块中包含了一个或多个功能子模块,通过模块调用或称为模块实例化的方式来实现这些子模块与高层模块的连接有利于简化每一个模块的代码,易于维护和修改。Verilog模块的例化有两种方式,一种是基于端口位置来例化模块,另一种则是根据端口名称来例化。84模块名例化名(

.模块端口1(与端口1连接的信号1/留空),.模块端口2(与端口2连接的信号2/留空),....模块端口n(与端口n连接的信号n/留空));模块名例化名(信号1,信号2,...,信号n);//信号与该模块声明时对应位置的端口相连,未连接的端口则在两个逗号间加上空格模块例化语句示例85moduleclk_gen_1hz(

inputwireclk_i,//时钟输入,50MHz

inputwirerst_n_i,//复位输入,低电平有效

outputwireclk_o//时钟输出,1Hz);

......endmodule

//被调用的模块moduleled(

inputwireclk_50mhz_i,//时钟输入,50MHz

inputwirerst_n_i,//复位输入,低电平有效

outputreg[7:0]led_o//8位流水灯输出);

wires_clk_1hz;//1Hz时钟信号

reg[2:0]s_cnt=3'b000;//计数信号,3位,初始值为000clk_gen_1hzu_clk_gen_1hz(.clk_i(clk_50mhz_i),.rst_n_i(rst_n_i),.clk_o(s_clk_1hz));//clk_gen_1hzu_clk_gen_1hz(clk_50mhz_i,rst_n_i,s_clk_1hz);......endmodule描述方法DescriptionMethod“

VerilogHDL语句对电路功能的描述有三种方式,分别是数据流描述、结构化描述、行为级描述。三种描述方式抽象级别不同,各有优缺点,相辅相成,需要配合使用。下面以二选一数据选择器模块的实现来分别介绍三种不同的描述方法。3.886二选一数据选择器——真值表、逻辑表达式、电路图87输入输出SY0D01D1Y=̅SD0

+SD1数据流描述

数据流描述使用连续赋值语句(assign语句)对电路的逻辑功能进行描述,该描述方法用于组合逻辑电路的实现。组合逻辑电路的信号传输其实就类似于数据的流动,数据从中经过但是不会存储,一旦输入改变,输出随之改变。88modulemux2to1_dataflow(

inputwireD0,D1,//输入数据定义

inputwireS,//输入选择信号定义

outputwireY//输出信号定义);

assignY=((~S)&D0)|(S&D1);//门电路逻辑表达式

//assignY=(S==1)?D1:D0;//条件运算符实现endmodule结构化描述——门级描述

结构化描述是在描述中按照层级电路的结构形式使用已有的或者已经写好的功能模块对电路进行描述。其中,使用门级原语描述的方式为门级描述,使用自定义功能模块描述的方式为结构级描述。89modulemux2to1_gatelevel(

inputD0,D1,S,//输入数据定义

outputY//输出信号定义);

wires_not,and1,and2;//定义内部信号notU1(s_not,S);//调用非门元件

andU2(and1,s_not,D0);//调用与门元件

andU3(and2,S,D1);

orU4(Y,and1,and2);//调用或门元件endmodule结构化描述——结构级描述90modulemux2to1_gatelevel(

inputD0,D1,S,//输入数据定义

outputY//输出信号定义);

wires_not,s_and1,s_and2;//定义内部信号

not1U1(S,s_not);//调用非门元件and2U2(s_not,D0,s_and1);//调用与门元件and2U3(S,D1,s_and2);or2U4(s_and1,s_and2,Y);//调用或门元件endmodulemodulenot1(//自定义非门模块

input

wireA,

outputwireY);

assignY=~A;endmodulemoduleand2(//自定义与门模块inputwireA,B,outputwireY);

assignY=A&B;endmodulemoduleor2(//自定义或门模块

inputwireA,B,

outputwireY);assignY=A|B;endmodule行为级描述

行为级(Behavioral)描述是最抽象的一种描述方法,也称寄存器传输级描述,使用always语句或initial语句对电路进行描述。91modulemux2to1_behave(

inputwire

D0,D1,S,//输入端口声明

outputregY//输出端口声明);

always@(S,D0,D1)

begin

if(S==1)Y=D1;

elseY=D0;

endendmodule抽象级别92结构化描述:抽象级别最低、最接近于实际硬件结构,可以通过Verilog的形式来描述电路都需要哪些元器件以及器件之间的连接关系数据流描述:比结构化描述抽象级别高、可以比较直观的表达底层逻辑的行为行为级描述:抽象级别最高、概括能力最强,规模稍大的设计往往都以行为级描述为主可综合与不可综合Comprehensiveandnocomprehensive“3.993综合的概念综合是根据Verilog描述的RTL级的电路模型构造出门级网表的过程。综合只是个中间步骤,综合后生成的网表文件,就是由导线相互连接的寄存器传输级功能块(像是触发器、算术逻辑单元和多路选择器等)组成的电路逻辑网络,将其烧录进FPGA后,可以找到与之对应的硬件元件。综合器就是能自动实现上述转换的软件工具,能将原理图或者HDL语言描述的电路功能转化为具体电路网表的工具。94什么是不可综合?

Verilog有不同的抽象层次,可以从门级、RTL级、行为级以及算法级进行建模。但并不是所有层次上的描述方式都可以被综合成想要的硬件元件,即有些语法是不可综合的。比如Verilog中存在一些用于仿真验证的子集,属于仿真验证语言,因为没有相应的硬件元件与其对应,故只能在仿真时候使用,不能被综合成电路。如延时语句#,initial语句等。95可综合语句96Verilog语句可综合性说明module语句√数据类型wire,reg,integer√parameter语句√端口声明input,output,inout√运算符大部分可综合

全等运算符(===,!==)不可综合

对于除法“/”

的运算,只有除数为2的指数时才可综合基本门元件√赋值语句(assign,=,<=)√条件语句(if-else,case)√循环语句

(for,while)只有当循环的次数在编译之前就已确定时可综合,动态改变循环次数的语句不可综合always语句√function语句√编译向导`define,`include等√不可综合语句97Verilog语句可综合性说明延时控制#xx×初始化语句initial×数据类型real×循环语句repeat,forever×字符串常量×全等运算符===,!==×与X,Z的比较把数据和X(或Z)进行比较是不可综合的敏感列表里一个信号同时带有posedge和negedge例always@(posedgeclkornegedgeclk)

这种always块是不可综合的建立可综合模型的原则98不使用initial语句、延时语句#以及循环次数不确定的循环语句尽量使用同步方式设计电路。除非关键路径的设计,一般不采用条用门级元件来描述,建议采用行为语句完成设计。所有的内部寄存器都应该能够被复位。对时序逻辑描述和建模,尽量使用非阻塞赋值方式。组合逻辑和时序逻辑实现的电路尽量分配到不同的always

块中。用always块描述组合逻辑时,应在敏感信号列表中列出所有的输入信号。不能在多个的always块中对同一个变量赋值;在同一个块中,不要同时用阻塞赋值(推荐)和非阻塞赋值。避免混合使用上升沿和下降沿触发的触发器。同一个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或不同的时钟沿)控制。避免在case语句的分支项中使用X值或Z值。资源占用Occupationofresources“

前面说过,FPGA是一种可编程逻辑器件,可以根据用户的需求进行逻辑电路的重新配置。在FPGA设计中,使用VerilogHDL语言编写的代码将在综合后变成逻辑电路,并且映射到FPGA的可编程逻辑资源上。因此,在资源不充足时,如何优化FPGA设计,提高资源的利用率也是需要考虑的一个问题。下面简单介绍一下Verilog中比较占用逻辑资源的语法。3.1099时序逻辑

在Verilog中,可以使用组合逻辑和时序逻辑来描述电路行为。组合逻辑仅基于输入信号的当前值,而时序逻辑还需要考虑输入信号的变化过程。因此,相比于组合逻辑,时序逻辑通常需要使用寄存器来存储状态信息,因此会占用更多的FPGA逻辑资源。100rega;always@(posedgeclk_50mhz_i)begina=b+1;

endwirea;assigna=b+1;寄存器

寄存器是时序逻辑的基本构建单元,用于存储状态信息。在Verilog中,寄存器占用的逻辑资源与其位宽和数量相关。较宽的寄存器和大量的寄存器会占用更多的FPGA逻辑资源,因此,设计电路时,一般不建议用Verilog语言去写一个数组,如果不能避免使用这种数据,最好使用带地址的RAM,而不用寄存器直接进行数据存储。101reg[8:0]

s_data[127:0];//128个8位宽的数据组成的数组多路选择器和复用器

多路选择器和复用器是常用的逻辑电路,可以将多个输入信号选择或复用到一个输出信号上。在Verilog中,多路选择器和复用器可以使用条件运算符

、case语句和if语句来实现,不同实现方式占用的资源数量也各不相同。条件运算语句主要用于组合逻辑电路中,资源占用相对较小;case语句和if语句则主要用于时序逻辑,其中,if语句可以处理更加复杂的判断条件,但在实际电路中占用的资源也会更多,因此,一般能用case语句实现的选择电路就不用if语句。102高层次抽象

Verilog中提供了一些高层次的抽象语法,如generate语句、函数和任务,这些抽象语法可以简化Verilog的设计和提高可读性。代价则是会导致更多的逻辑资源的占用,造成逻辑资源的浪费。因此,在使用这些抽象语句时,应当权衡其对逻辑资源的消耗和代码的可读性,避免资源的滥用。103算术运算和位操作在Veri1og中,算术运算和位操作是常见的操作。然而,一些复杂的算术运算(*,/,%)和位操作会占用更多的逻辑资源,在进行算术运算和位操作时,我们应该尽量使用简单的操作,避免过多的嵌套和复杂的逻辑。104reg[3:0]a;wire[1:0]y;assigny=(a[3]==1’b1)?2’b00:(a[2]==1’b1)?2’b01:

(a[1]==1’b1)?2’b10:

(a[0]==1’b1)?2’b11:3’b00;FPGA开发实用教程——基于Xilinx和VerilogPracticalTutorialforFPGADevelopment——BasedonXilinxandVerilog第4讲分频器实验105实验原理ExperimentalPrinciples“

设计一个分频器,对50MHz的系统时钟进行分频,输出一个占空比为50%、频率为1Hz的方波信号,并将该方波信号约束到FPGA高级开发系统上编号为LED0的发光二极管,达到该发光二极管500ms更改一次状态,除此之外,该分频器还可以通过编号为RESET的按键进行低电平复位。4.1106LED电路原理图

分频器实验涉及的硬件电路包括一个位于FPGA高级开发系统上的LED0以及与LED0串联的限流电阻,LED0通过电阻连接到芯片的G14引脚,除此之外,还包括系统时钟引脚和系统复位引脚,其中,系统时钟引脚连接50MHz时钟模块,是芯片的时钟源,系统复位引脚连接RESET按键,低电平复位,G14为高电平时,LED0点亮,G14为低电平时,LED0熄灭。107时钟分频

分频就是对较高频率的信号进行处理,得到较低频率的信号。一个高频信号的频率降低为原来的1/N,就叫N分频。例如,将50MHz的信号经过2分频得到25MHz的信号,经过5分频得到10MHz的信号,经过10分频得到5MHz的信号。1081Hz分频原理

本实验LED0每500ms更改一次状态,闪烁频率为1Hz,而我们的系统时钟频率为50MHz,因此,1Hz时钟的分频数为50MHz/1Hz=50000000(50M)。通过定义一个计数器s_cnt,对50MHz时钟进行计数,在每个时钟上升沿,s_cnt执行一次加1操作,当s_cnt在0和24999999(25M-1)之间时,clk_o输出低电平,当s_cnt在25000000(25M)和49999999

(50M-1)之间时,clk_o输出高电平,并在49999999之后的下一个时钟上升沿将s_cnt清零重新开始计数。109内部电路图

clk_i和rst_n_i分别为50Mhz时钟信号和复位信号的输入端,clk_o为1Hz时钟信号输出端;s_cnt和s_clk分别为用于计数和分频的寄存器;CNT_MAX和CNT_HALF则为常量,其中CNT_MAX可以调节输出时钟的频率,CNT_HALF可以调节输出时钟的占空比。本实验中CNT_MAX为49999999,CNT_HALF为24999999。110实验步骤ExperimentalProcedure“4.2111设计流程112步骤1:ISE软件标准化设置步骤2:创建FPGA工程步骤3:新建Verilog文件步骤4:完善clk_gen_1hz.v文件步骤5:检查Verilog文件语法步骤6:通过Synplify综合工程步骤7:新建Verilog测试文件进行仿真步骤8:新建引脚约束文件步骤9:下载程序步骤10:固化程序本章任务Tasksinthischapter“4.3113本章任务114

学习完本章后,严格按照实验步骤,进行ISE软件标准化设置、创建FPGA工程、新建Verilog文件、测试文件和引脚约束文件,并且最终生成.bit文件和.mcs文件,将其分别下载到FPGA高级开发系统中,查看运行结果。本章习题Exercisesinthischapter“X.4115本章习题116为什么要对ISE软件进行标准化设置?2.FPGA高级开发系统上的FPGA芯片型号是什么?封装是什么?3.简述时钟分频原理。4.分频器实验主要基于计数器,简述50MHz时钟分频到1Hz时钟的过程。5.generic引导的参数说明和传递语句中的参数与constant关键字定义的常量有何区别?6.如何在结构体的声明部分定义一个信号类型为std_logic、取值范围为000~111、初值为000的计数器s_cnt?7.通过查找资料,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论