




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
FPGA设计与应用大连理工大学软件学院王洁
2016年春季第二章VerilogHDL基础了解硬件描述语言特点。掌握VerilogHDL语言要素。掌握VerilogHDL建模(描述)方法。掌握Testbench编写方式。VerilogHDL历史GDA推出Verilog仿真器Verilog-XL:仿真速度快,具有交互式调试手段GatewayDesignAutomation公司推出Verilog语言,开发了仿真与验证工具Synopsys公司的综合软件开始接受Verilog输入1983年1985年1987年1989年Cadence公司收购GDA,进一步扩大Verilog的影响VerilogHDL历史OVI推出Verilog2.0,作为IEEE提案提出申请OpenVerilogInternational(OVI)成立,推广VerilogHDLIEEE通过VerilogHDL标准IEEE1364-19951990年1993年1995年2001年IEEE发布了VerilogHDL标准IEEE1364-2001VerilogHDL现状VerilogHDL是最广泛使用的、具有国际标准支持的硬件描述语言,绝大多数的EDA厂商都支持;在工业界和ASIC设计领域,VerilogHDL应用更加广泛。VHDLVHDLVery-High-SpeedIntegratedCircuitHardwareDescriptionLanguage诞生于1982年;1987年底被IEEE和美国国防部确认为标准硬件描述语言。IEEE1076(1983)IEEE1076-1995……HDL建模层次12345系统级(system)用高级语言结构实现设计模块的外部性能的模型。算法级(algorithmic)用高级语言结构实现设计算法的模型。RTL级(RegisterTransferLevel)描述数据在寄存器之间流动和如何处理这些数据的模型。门级(gate-level)描述逻辑门以及逻辑门之间的连接的模型。开关级(switch-level)描述器件中三极管和储存节点以及它们之间连接的模型。VerilogHDL与VHDL的建模层次VerilogHDLVHDLVerilogHDL与VHDL对比相同点都能形式化抽象表示电路行为和结构;支持逻辑设计中层次与范围的描述;具有电路仿真和验证机制;与工艺无关。不专门面向FPGA设计。不同点Verilog与C语言相似,语法灵活;VHDL源于Ada语言,语法严格;Verilog更适合ASIC设计。VerilogHDL与VHDL对比SystemVerilogSystemCC一种软/硬件协同设计语言,既是系统级语言,也是硬件描述语言。IEEE1364Verilog-2001标准的扩展增强,兼容Verilog2001,将硬件描述语言(HDL)与现代的高层级验证语言(HVL)结合。VivadoHLS支持C语言子集,实现高层次综合。系统建模描述方式数据流描述:描述电路数据流行为(assign)行为描述:描述功能(initial,always)结构化描述:描述元器件间连接关系(例化)混合描述:Verilog允许多描述方式共存于同一模块设计方法学自顶向下自底向上混合式moduletrist1(out,in,enable);
outputout; /*输出信号*/
inputin,enable;//输入信号
mytritri_inst(out,in,enable);endmodulemodulemytri(out,in,enable);
outputout;
inputin,enable;
assignout=enable?in:'bz;endmoduleVerilog程序示例三态门模块trist1调用模块mytri的实例元件tri_inst通过这种结构性模块构造可构成特大型模块Verilog程序示例三态门电路(综合)Verilog程序基本特征VerilogHDL程序是由模块构成的;每个模块要进行端口定义,并说明输入输方向,然后对模块的功能进行逻辑描述;VerilogHDL程序的书写格式自由,一行可以写几个语句,一个语句也可以分写多行;除了endmodule语句外,每个语句和数据定义的最后必须有分号。modulemuxtwo(out,a,b,sl);
inputa,b,sl;
outputout;
wirensl,sela,selb;
not#1u1(nsl,sl);//#1仿真延迟
and#1u2(sela,a,nsl);
and#1u3(selb,b,sl);
or#1u4(out,sela,selb);endmodule
同一电路的多种描述方法:二路选通门级(结构化)描述modulemuxtwo(out,a,b,sl);
inputa,b,sl;
outputout;
regout;
always@(sloraorb)
if(!sl)out=a;
elseout=b;endmodule
modulemuxtwo(out,a,b,sl);
inputa,b,sl;
outputout;
assignout=sel?b:a;endmodule
同一电路的多种描述方法:二路选通RTL级行为描述布尔代数级行为描述同一电路的多种描述方法:二路选通二选选通电路(综合)moduleFA_Mix(A,B,Cin,Sum,Cout);
inputA,B,Cin;
outputSum,Cout;
regCout;
regT1,T2,T3;
wireS1;
xorX1(S1,A,B); //门实例语句。
always@(AorBorCin) //always语句。
begin T1=A&Cin; T2=B&Cin; T3=A&B; Cout=(T1|T2)|T3;
end
assignSum=S1^Cin; //连续赋值语句。endmodule混合描述:1位全加器实例混合描述:1位全加器实例module
模块名(端口列表);
端口I/O说明;
内部信号声明;
功能定义;endmodule例如:moduleblock(a,b,c,d);
input a,b;
output c,d;
assign c=a&b;
assign d=a|b;endmodule模块基本结构如果没有这样的编译器指令,VerilogHDL模拟器会指定一个缺省时间单位。IEEEVerilogHDL标准中没有规定缺省时间单位。仿真时延VerilogHDL模型中的所有时延都根据时间单位定义。assign#2Sum=A^B;#2指2个时间单位。编译器指令需在模块描述前定义:`timescale1ns/100ps。此语句说明时,延时间单位为1ns并且时间精度为100ps。语言要素:标识符标识符用户为程序描述中的Verilog对象所起的名字:
模块名、变量名、常量名、函数名、任务名。必须以英语字母(a-z,A-Z)或下横线符(_)起头。其中可以包含数字、$符和下划线符。最长可以达到1023个字符。模块名、端口名和实例名都是标识符。Verilog语言大小写敏感:如sel和SEL是两个不同的标识符。所有的关键词都是小写的。语言要素:任务与函数任务与函数以$字符开始的标识符表示系统任务或系统函数。任务可以返回0个或多个值,函数除只能返回一个值以外与任务相同。函数在0时刻执行,即不允许延迟,而任务可以带有延迟。常用于测试模拟,一般不用于源代码设计。$display("Hi,youhavereachedLTtoday"); /*$display系统任务在新的一行中显示。*/$time //该系统任务返回当前的模拟时间。语言要素:编译质量编译指令以`(反引号)开始的某些标识符是编译器指令:`define和`undef,很像C语言中的宏定义指令`ifdef、`else和`endif,用于条件编译`include文件既可以用相对路径名定义,也可以绝对路径`timescale编译器指令将时间单位与实际时间相关联,该指令用于定义时延的单位和时延精度。语言要素:值集合值集合:基本值0:逻辑0或“假”1:逻辑1或“真”x:未知z:高阻(x,z不区分大小写)值集合:常量整型实数型字符串型语言要素:整数常量表达方式<位宽>’<进制><数字>:标准方式’<进制><数字>:默认位宽,与机器类型有关<数字>:不指明进制默认为十进制进制二进制(b或B):8'b10101100,‘b1010十进制(d或D):4'd13,512十六进制(h或H):8'ha2八进制(o或O):6'O41语言要素:整数常量x值和z值x:不确定:4'b100xz:高阻:16'hzzzz,没有驱动元件连接到线网,线网的缺省值为z。思考:程序设计时,何时出现x值?1.未初始化的寄存器2.……语言要素:整数常量负数在位宽表达式前加一个减号,如-8’d5减号不可以放在位宽和进制之间,也不可以放在进制和具体的数之间,如8’d-5下划线只能用在具体的数字之间,如12'b1010_1111_1010位数指的是二进制位数。语言要素:整数常量位数扩展最高位是0、1,高位用0扩展:
8’b1111
等于8’b00001111
最高位是z、x,高位自动扩展:
4’bz
等于4’bzzzz位数截断如果长度定义得更小,最左边的位被截断,如:3'b1001_0011
等于3'b0115'H0FFF等于5'H1F语言要素:实数常量十进制计数十进制数,例如:
2.0
5.68科学计数法23_5.1e2
其值为23510.0,忽略下划线3.6E2
其值为360.0(e与E相同)***实数通常不用于FPGA源代码的常量语言要素:字符串常量字符串字符串是双引号内的字符序列,不能分成多行书写。例如:
"INTERNALERROR""REACHED->HERE"ASCII字符***字符串较少用于FPGA源代码的常量用8位ASCII值表示的字符可看作是无符号整数。存储“INTERNALERROR”,变量需要8*14位。reg[1:8*14]Message;语言要素:数据类型线网型wire //FPGA设计中,通常只用wire型tri
//其他类型用于仿真wortriorwandtriandtriregtri1tri0supply0supply1语言要素:数据类型线网型wire[msb:lsb]reg1,reg2,...regN;msb和lsb定义了范围,并且均为常数值表达式。范围定义是可选的。如果没有定义范围,缺省值为1位线网。 wireReset; wire[3:0]data_in;
wire[3:2]select;
wire[0:2]point;语言要素:数据类型寄存器型reg //FPGA设计中,通常只用reg型,默认初始值eger//其他类型用于仿真timerealrealtime语言要素:数据类型寄存器型reg[msb:lsb]reg1,reg2,...regN;msb和lsb定义了范围,并且均为常数值表达式。范围定义是可选的。如果没有定义范围,缺省值为1位寄存器。
regReset;
reg[3:0]data_in;
reg[3:2]select;
reg[0:2]point;语言要素:数据类型存储器存储器是一个寄存器数组,使用如下:reg[msb:lsb]memory1[upper1:lower1];
reg[3:0]MyMem[63:0] //MyMem为64个4位寄存器的数组。
regBog[1:5] //Bog为5个1位寄存器的数组。***存储器赋值不能在一条赋值语句中完成。***存储器常用于FPGA外围器件的仿真建模。语言要素:数据类型存储器赋值(1)对每个单元逐一赋值reg[0:3]Xrom[0:2];...Xrom[0]=4'hA;Xrom[1]=4'h8;Xrom[2]=4'hF;注意:后面章节中会描述此类赋值语句一般在initial或者always语句中进行,不能独立存在。语言要素:数据类型存储器赋值(2)系统任务赋值reg[3:0]RomB[7:0];$readmemb("ram.patt",RomB);//Romb是存储器。文件“ram.patt”必须包含二进制值。文件也可以包含空白空间和注释。
右边是文件中可能内容的实例。11011110100001110000100100110001语言要素:数据类型参数参数是一个常量,常用于定义时延和变量的宽度。
parameterLINELENGTH=132;
parameterALL_X_S=16'bx;
parameterBIT=1,BYTE=8,PI=3.14;
parameterSTROBE_DELAY=(BYTE+BIT)/2;下划线参数值可以在编译时被改变。使用参数定义语句或通过在模块初始化语句中定义参数值。语言要素:空白符、注释空白符除了字符串中的空白符,其他空白符编译被忽略。注释多行注释/**/(不允许嵌套)单行注释//语言要素:空白符、注释语言要素:空白符、注释语言要素:空白符、注释语言要素:空白符、注释语言要素:空白符、注释使用`timescale编译器指令的目的是什么?写出产生下图所示波形的变量BullsEye的初始化语句。使用数据流描述方式编写下图所示的异或逻辑的VerilogHDL描述,并使用规定的时延。下列表达式的位模式是什么?
7'o44,'Bx0,5'bx110,'hA0,10'd2,'hzF
练习一表达式由操作数和操作符组成;表达式可以在出现数值的任何地方使用;表达式是数据流描述的基础。语言要素:表达式A&BAddr1[3:0]+Addr2[3:0]Count+1(a[0]^b[0])|(a[1]&~b[1])语言要素:表达式常数参数线网寄存器函数调用位选择部分选择存储器单元操作数类型语言要素:操作数常数表达式中的整数值可被解释为有符号数或无符号数;如果整数是基数型整数,作为无符号数对待。参数参数类似于常量,并且使用参数声明进行说明。12 01100的5位向量形式 (有符号)-12 10100的5位向量形式 (有符号)5’b01100
十进制数12 (无符号)parameterLOAD=4'd12,STORE=4'd10;LOAD和STORE为参数,值分别被声明为12和10。语言要素:操作数线网线网中的值被解释为无符号数,表达式中可使用:标量线网(1位)和向量线网(多位)。wire[3:0]led; //4位向量线网。wireline; //标量线网。assignled=4d’ha;//被赋于位向量1010,为十进制10。思考:为何没有用assign语句赋值?寄存器参数类似于常量,并且使用参数声明进行说明。
integer型的值被解释为有符号的二进制补码数,
reg型或time型的值被解释为无符号数,
real型和realtime的值被解释为有符号浮点数。reg[4:0]state;State=5'b01011; //值为位向量01011,十进制值11。State=9; //值为位向量01001,十进制值9。语言要素:操作数语言要素:操作数位选择 位选择从向量中抽取特定的位。形式如下:
net_or_reg_vector[bit_select_expr]State[1]&&State[4] //寄存器位选择。led[0]|line //线网位选择。***如果选择表达式的值为x、z或越界,则位选择的值为State[x]值为x。(FPGA设计中禁用)***选择范围越界或为x、z时,部分选择的值为x。(FPGA设计中禁用越界)部分选择net_or_reg_vector[msb_const_expr:lsb_const_expr]State[4:1] //寄存器部分选择。reg[4:0]state;led[2:0] //线网部分选择。wire[3:0]led;语言要素:操作数语言要素:操作数存储器单元 存储器单元从存储器中选择一个memory[word_address]reg[7:0]Dram[63:0];Dram[60]; //存储器的第61个单元。***不允许对存储器变量值部分选择或位选择。思考:在存储器中读取一个位或部分选择一个字?/*$time是系统函数,并且SumOfEvents是在别处定义的用户自定义函数。*/函数调用表达式中可使用函数调用。$time+SumOfEvents(A,B)语言要素:操作数算术关系相等逻辑按位归约移位条件拼接语言要素:操作符操作符类型操作符从最高优先级到最低优先级排列。语言要素:操作符操作符操作操作符操作+一元加|归约或-一元减~|归约或非!一元逻辑非*乘~一元按位取反/除&归约与%取模~&归约与非+二元加^归约异或-二元碱^~或~^归约异或非<<左移操作符从最高优先级到最低优先级排列。语言要素:操作符操作符操作操作符操作>>右移!==非全等<小于&按位与<=小于等于^按位异或>大于^~或~^按位异或非>=大于等于|按位或==逻辑相等&&逻辑与!=逻辑不等||逻辑或===全等?:条件运算符语言要素:操作符关联顺序除条件操作符从右向左关联外,其余所有操作符自左向右关联。圆括号圆扩号能够用于改变优先级A+B-C 等价于:(A+B)-C //自左向右A?B:C?D:F 等价于:A?B:(C?D:F) //从右向左(A?B:C)?D:F语言要素:操作符算术运算符除条件操作符从右向左关联外,其余所有操作符自左向右关联。 + (加) -
(减)
*
(乘)
/ (除)
% (取模)后三种不常用,视具体设计结构而定;任意操作数是X或Z,那么整个结果为X;结果的长度由最长的操作数决定;reg和wire保存无符号数。语言要素:操作符 > (大于) < (小于) >= (不小于) <= (不大于)关系操作符的结果为真(1)或假(0);如果操作数中有一位为X或Z,那么结果为X。关系操作符比较两个操作数求下列表达式真值:23>4552<8'hxFF'b1000>='b011100X0语言要素:操作符相等运算符判断两个操作数相等关系。 == (逻辑相等) != (逻辑不等) === (全等) !== (非全等)如果比较结果为假则结果为0,为真结果为1;在全等比较中,值x和z严格按位比较。语言要素:操作符===01xz==01xz01000010xx10100101xxx0010xxxxxz0001zxxxx求下列表达式真值:假定 Data=‘b11x0; Addr=‘b11x0;求 Data==Addr
Data===AddrX1语言要素:操作符 && (逻辑与) || (逻辑或)
!
(逻辑非)只对逻辑值运算,结果一位,逻辑值1、0或x;对于向量操作,非0向量作为1处理;如果任意一个操作数包含x,结果也为x。逻辑操作符两个操作数的逻辑运算。语言要素:操作符010111假定: C='b0;//0为假 D='b1;//1为真
A_Bus='b0110; B_Bus='b0110;求 C&&D C||D !D A_Bus&&B_Bus A_Bus||B_Bus !A_Bus求下列表达式真值:语言要素:操作符按位操作符操作数对应位上按位操作,并产生向量结果。 ~ (一元非) & (二元与) | (二元或) ^ (二元异或) ~^或^~(二元异或非)逻辑操作符产生一位真值,按位操作符产生向量值。逻辑操作符多用于判断条件,按位操作符用于向量运算。语言要素:操作符&01xz00000101xxx0xxxz0xxx|01xz000xx10111xx1xxzx1xx^01Xz001xx110xxxxxxxzxXxx^~01xz010xx101xxxxxxxzxxxx~01xz10xx语言要素:操作符假定 A='b0110; B='b0100;求 A|B A&B
A||B A&&B4'b01104'b010011逻辑操作符产生一位真值,按位操作符产生向量值。逻辑操作符多用于判断条件,按位操作符用于向量运算。求下列表达式真值:语言要素:操作符 & (归约与) ~& (归约与非) | (归约或) ~| (归约或非) ^ (归约异或) ~^ (归约异或非)符号形式与按位操作符类似。一元操作符。常用于某些特定值的判断。归约操作符在单一操作数的所有位上操作,并产生1位结果。语言要素:操作符假定: A=‘b0110; B=‘b0100;
MyReg=4‘b01x0;求 ~&A ^A |B &B |MyReg ^MyReg
11101x求下列表达式真值:语言要素:操作符移位操作符操作数的逻辑移位。 << (左移) >> (右移)左侧操作数移动右侧操作数表示的次数,逻辑移位,空闲位添0补位;如果右侧操作数的值为x或z,移位操作的结果为x。例:使用移位操作为2-4解码器建模wire[3:0]DecodeOut;assignDecodeOut=4'b1<<Address[1:0];语言要素:操作符假定: reg[7:0]Qreg;
Qreg=4'b0111;移位 Qreg>>2
Qreg<<
1
4'b00014'b1110思考:如何使用移位操作符实现算术移位?
符号位不变,数据位按照补码规则移位补位。求Qreg的值:语言要素:操作符?:三目运算符例:条件操作符根据条件表达式的值选择表达式,形式: cond_expr?expr1:expr2wire[2:0]Student;assignStudent=Marks>18?Grade_A:Grade_C;语言要素:操作符拼接操作符连接操作,将小表达式合并形成大表达式操作:
{expr1,expr2,...,exprN}复制操作,指定重复次数来执行操作:
{repetition_number{expr1,expr2,...,exprN}wire[7:0]Dbus,[11:0]Abus;assignDbus[7:4]={Dbus[0],Dbus[1],Dbus[2],Dbus[3]};assignAbus={3{4'b1011}};//位向量12'b1011_1011_1011assignAbus={{4{Dbus[7]}},Dbus}; /*符号扩展*/说明参数GATE_DELAY,参数值为5。假定长度为64个字的存储器,每个字8位,编写Verilog代码,按逆序交换存储器的内容。即将第0个字与第63个字交换,第1个字与第62个字交换,依此类推。假定32位总线Address_Bus,编写一个表达式,计算从第11位到第20位的归约与非。假定一条总线Control_Bus[15:0],编写赋值语句将总线分为两条总线:Abus[0:9]和Bbus[6:1]。编写一个表达式,执行算术移位,将Qparity中包含的8位有符号数算术移位。练习二使用条件操作符,编写赋值语句选择NextState的值。如果CurrentState的值为RESET,则NextState的值为GO;如果CurrentState的值为GO,则NextState的值为BUSY;如果CurrentState的值为BUSY;则NextState的值为RESET。如何从标量变量A,B,C和D中产生总线BusQ[0:3]?如何从两条总线BusA[0:3]和BusY[20:15]形成新的总线BusR[10:1]?练习二modulemodule_name(port_list); Declarations_and_Statements;endmodule模块基本单元定义成模块形式端口队列port_list列出了该模块通过哪些端口与外部模块通信。模块与端口模块与端口缺省的端口类型为wire型;output或inout能够被重新声明为reg型,但是input不可以;线网或寄存器必须与端口说明中指定的长度相同。端口模块的端口可以是
input (输入端口) output(输出端口) inout (双向端口)moduleMicro(PC,Instr,NextAddr);//端口说明input [3:1] PC;output [1:8] Instr;inout [16:1] NextAddr;//重新说明端口类型:wire [16:1]NextAddr;//该说明是可选的,但如果指定了,就必须与它的端口说明保持相同长度。reg [1:8] Instr;//Instr已被重新说明为reg型,因此能在always语句或在initial语句中赋值。...endmodule模块与端口:一个例子module_nameinstance_name(port_associations);信号端口可以通过位置或名称关联;但是关联方式不能够混合使用。端口关联形式port_expr //通过位置,隐式关联PortName(port_expr) //通过名称,显示关联,强烈推荐!一个模块能够在另外一个模块中被引用,这样就建立了描述的层次。模块实例语句形式:模块与端口MicroM1(UdIn[3:0],{WrN,RdN},Status[0],Status[1],&UdOut[0:7],TxData);模块实例语句模块与端口12345标识符(reg型或wire型)位选择部分选择上述类型的合并表达式(只适用于input型信号)port_expr可以是以下的任何类型思考:
port_expr显式关联的优势?端口关联与高级语言参数传递的区别?moduleHA(A,B,S,C);inputA,B;outputS,C;assignS=A^B;assignC=A&B;endmodulemoduleFA(P,Q,Cin,Sum,Cout);inputP,Q,Cin;outputSum,Cout;wireS1,C1,C2;HAh1(P,Q,S1,C1); //通过位置隐式关联。HAh2(.A(Cin),.S(Sum),.B(S1),.C(C2));//显式关联。orO1(Cout,C1,C2); //或门实例语句。endmodule模块与端口:构造全加器考虑如何模块参数化?使用两个半加器模块构造全加器moduleHA(A,B,S,C);inputA,B;outputS,C;parameterAND_DELAY=1,XOR_DELAY=2;assign
#XOR_DELAYS=A^B;assign
#AND_DELAYC=A&B;EndmodulemoduleFA(P,Q,Cin,Sum,Cout);inputP,Q,Cin;outputSum,Cout;parameterOR_DELAY=1;wireS1,C1,C2;HAh1(P,Q,S1,C1); //通过位置隐式关联。HAh2(.A(Cin),.S(Sum),.B(S1),.C(C2));//显式关联。or
#OR_DELAYO1(Cout,C1,C2); //或门实例语句。endmodule模块与端口:构造全加器使用两个半加器模块构造全加器(参数化)DFFd1( .Q(QS), .Qbar(), .Data(D), .Preset(), .Clock(CK));通过将端口表达式表示为空白来指定为悬空端口。模块与端口悬空端口模块与端口moduleChild(Pba,Ppy);input[5:0]Pba;output[2:0]Ppy;...endmodulemoduleTop;
wire[1:2]Bdl;wire[2:6]Mpr;ChildC1(.Pba(Bdl),.Ppy(Mpr));endmodule通过无符号数的右对齐或截断方式进行匹配。端口匹配543210Ppy12Bdl21023456MprPbamoduleTOP(NewA,NewB,NewS,NewC);inputNewA,NewB;outputNewS,NewC;defparamHa1.XOR_DELAY=5;//实例Ha1中的参数XOR_DELAY。
defparamHa1.AND_DELAY=2;//实例Ha1中参数的AND_DELAY。HAHa1(NewA,NewB,NewS,NewC);endmodule模块中使用defparam语句,不能在模块外定义。模块与端口:改变参数值参数定义语句模块与端口:改变参数值moduleTOP(NewA,NewB,NewS,NewC);inputNewA,NewB;outputNewS,NewC;HA#(5,2)Ha1(NewA,NewB,NewS,NewC);//第1个值5赋给参数AND_DELAY,该参数在模块HA中说明。//第2个值2赋给参数XOR_DELAY,该参数在模块HA中说明。endmodule模块例化时直接改变参数,有利于代码重用。带参数引用moduleScram_B(.Data(Arb),.Control(Ctrl),.Mem_Word(Mem_Blk),.Addr(Byte));input[0:3]Arb;inputCtrl;input[8:0]Mem_Blk;output[0:3]Byte;...endmodule显式地指定外部端口。(较少使用)模块与端口外部端口练习三模块实例语句与门实例语句的区别是什么?当端口悬空时,即端口没有被连接时,端口的值是什么?用本章讲述的模块FA编写执行加法和减法的4位ALU的结构模型。门级建模多输入门:and,nand,or,nor,xor,xnor多输出门:buf,not三态门:bufif0,bufif1,notif0,notif1上拉、下拉电阻:pullup,pulldownMOS开关:cmos,nmos,pmos,rcmos,rnmos,rpmos双向开关:tran,tranif0,tranif1,rtran,rtranif0,rtranif1内置基本门VerilogHDL中提供丰富的内置基本门。***FPGA设计中较少使用数据流建模wireZ1,Preset,Clear; //线网说明assignZ1=Preset&Clear; //连续赋值语句wire[15:0]data_in;wire[15:0]data_tmp;wiredata_tmp={data_in[7:0],data_in[15:8]};基本方法连续赋值用于数据流建模,生成组合逻辑电路。连续赋值使用连续赋值语句assign语句,格式为:assignLHS_target=RHS_expression;数据流建模执行方式只要右端表达式的操作数上有事件发生(值变化),表达式立即被计算,新结果就赋给左边的线网。赋值目标1)标量线网 assignZ1=…;2)向量线网 assigndata_tmp=…;3)向量的常数型位选择assigndata_tmp[2]=…;4)向量的常数型部分选择assigndata_tmp[7:0]=…;5)上述类型的任意的拼接运算结果
assign{Z1,data_tmp[15]}=2’b10;数据流建模例:数据流描述的一位全加器moduleFA_Df(A,B,Cin,Sum,Cout);inputA,B,Cin;outputSum,Cout;assignSum=A^B^Cin;assignCout=(A&Cin)|(B&Cin)|(A&B);endmoduleassign语句之间是并发的,与其书写的顺序无关;线网的赋值可以在声明时赋值,例如:wireSum=A^B^Cin;数据流建模数据流建模的时延assign#2Sum=A^B^Cin;#2表示右侧表达式的值延迟两个时间单位赋给Sum;那么时间单位是多少?由谁来决定?`timescale1ns/100psFPGA设计中的时延仅在功能仿真时有效,不影响实际电路生成。数据流建模注意事项1)wire型变量如果不赋值,默认值为z;2)数据流建模没有存储功能,不能保存数据;3)wire型变量只能在声明时赋值或者assign语句赋值;4)assign语句并发执行,实际的延迟又物理芯片的布线结果决定;5)最基本的FPGA设计源代码描述语句之一,用于生成组合逻辑,定制LUT的逻辑功能。常作为中间信号的描述用于控制寄存器的输入输出。使用assign语句描述一个时钟信号clk,频率为100MHz。
assign#5clk=~clk;请指出下列语句是否合法?描述了怎样的功能?assignMux=(S==0)?A:'bz;assignMux=(S==1)?B:'bz;assignMux=(S==2)?C:'bz;assignMux=(S==3)?D:'bz;练习四行为建模基本方法过程赋值用于行为建模(描述)行为建模的主要机制: 1)initial语句主要用于仿真文件(模拟) 2)always语句 用于源文件和仿真文件所有initial语句和always语句之间都是并发执行;执行顺序与其在模块中书写顺序无关。initial[timing_control]procedural_statement行为建模:initial语句执行方式initial语句只执行一次;在模拟开始时执行,即在0时刻开始执行;不能嵌套使用。procedural_statement方式较多,体现出行为建模的灵活性。procedural_continuous_assignment过程赋值(阻塞或非阻塞)conditional_statement -> ifcase_statement -> caseloop_statement -> for,forever,repeat,whilewait_statement -> waitdisable_statement -> disable(相当于C的break)event_trigger -> @(event)sequential_block -> begin...endparallel_block -> fork...jointask_enable(userorsystem)行为建模:initial语句procedural_statement可以是:行为建模:initial语句例regCurt;initial#2Curt=1;例parameterSIZE=1024;reg[7:0]RAM[0:SIZE-1];regRibReg;initialbeginintegerIndex;RibReg=0;for(Index=0;Index<SIZE;Index=Index+1) RAM[Index]=0;end parameterAPPLY_DELAY=5; reg[0:7]port_A;
initial begin Port_A='h20; #APPLY_DELAYPort_A='hF2; #APPLY_DELAYPort_A='h41; #APPLY_DELAYPort_A='h0A; end行为建模:initial语句initial语句在仿真文件构造数据示例‘h20‘hF2‘h41‘h0A101550
parameter
CYC_PERIOD=5;
regclk;
initial
begin clk=0;
while(1) //或者forever
clk=#(CYC_PERIOD/2)~clk;
//或者#(CYC_PERIOD/2)
clk=~clk;
end行为建模:initial语句initial语句在仿真文件产生时钟示例always[timing_control]procedural_statement行为建模:always语句procedural_continuous_assignment过程赋值(阻塞或非阻塞)conditional_statement -> ifcase_statement -> caseloop_statement -> for,forever,repeat,whilewait_statement -> waitdisable_statement -> disable(相当于C的break)event_trigger -> @(event)sequential_block -> begin...endparallel_block -> fork...jointask_enable(userorsystem)always语句重复执行,语法和initial语句完全相同。procedural_statement可以是:行为建模:always语句两种典型的always语句1.电平触发reg
c;always@(aorborsel) c=sel?a:b;说明:(1)虽然c是reg型,但综合的结果可能是组合电路。(2)等同于数据流描述
wirec;
assignc=sel?a:b;(3)FPGA设计中不建议使用;此外,容易产生意外锁存器。行为建模:always语句综合后生成的电路图行为建模:always语句两种典型的always语句2.时钟沿触发(时序逻辑)
reg
[8:0]count;always@(posedgeclkornegedgereset)
begin
if(~reset) count=0;
else
begin
if(count==511) count=0;
else
count=count+1;
end
end行为建模:always语句always语句在always语句中所有被赋值的信号必须是reg型;综合为触发器,推荐使用;同步或者异步时序逻辑。常见过程语句reg
Stream;initialBegin
Stream=0; #12Stream=1; #5Stream=0; #3Stream=1; #4Stream=0; #2Stream=1; #5Stream=0;end时序控制语句,仅用于仿真测试1.时序控制常见过程语句时序控制语句,仅用于仿真测试2.事件控制reg[9:0]addr;integeri;initialbegin
for(i=0;i<5;i=i+1)
@(posedgeclk) addr=addr+1;end边沿触发事件电平触发事件initialbegin
wait(Sum>22) Sum=0;end顺序语句块begin…end源程序、测试文件块内语句顺序执行思考:
initial语句若使用fork…join如何描
述下图时序?fork…join测试文件块内语句并行执行并行语句块常见过程语句时序电路的行为具有并行特性:寄存器都受到时钟的控制,流水线…既然fork…join不能在源文件中使用,在行为描述中如何描述并行语句?
begin…end中的语句是顺序执行,在同一时钟边沿触发下,每个寄存器变量为何赋值有先有后?这与实际电路是否矛盾?常见过程语句问题过程赋值语句定义:initial和always语句中的赋值语句区别于数据流描述的连续赋值语句(assign)分为阻塞过程赋值和非阻塞过程赋值两种常见过程语句always@(posedgeclkor
negedgerst)begin
if(~rst) …//寄存器复位
elseif(…)
begin a=1'b1; b=a;
endendalways@
(posedgeclkor
negedgerst)begin
if(~rst) …//寄存器复位
elseif(…)
begin a<=1'b1; b<=a;
endendb=?常见过程语句阻塞过程赋值非阻塞过程赋值结论源代码设计推荐使用非阻塞过程赋值“<=”可以有效综合为寄存器逻辑电路符合实际,时序分析简单语句之间并行执行,不再有顺序关系阻塞过程赋值“=”多用于仿真测试文件适合构造仿真模型和仿真行为不容易直接综合为FPGA资源常见过程语句initialbeginClr=#5 0;Clr=#4 1;Clr=#10 0;endinitialbeginClr<=#5 1;Clr<=#4 0;Clr<=#10 0;end常见过程语句过程赋值连续赋值在always语句或initial语句内出现在一个模块内出现执行与周围其他语句有关与其他语句并行执行;在右端操作数的值发生变化时执行驱动寄存器驱动网线使用”=“或”<=“赋值符号使用”=”赋值符号无assign关键词有assign关键词常见过程语句过程赋值与连续赋值的比较
与C语言类似If
(condition_1)
procedural_statement_1{elseif(condition_2)
procedural_statement_2}{else
procedural_statement_3}条件语句必须在过程块语句中使用,不能单独使用;if后面的表达式的值只有为1时才按“真”处理。常见过程语句if语句if(表达式1)
if(表达式2)语句1;
else
语句2;
else
if(表达式3)语句3;
else
语句4;else总是与它最上面的最近的if配对;如果if与else的数目不一样,为了实现程序设计者的目的,可以用begin…end语句确定配对关系;强烈建议保留else分支。常见过程语句if语句的嵌套always@(posedgeclkor
negedgerst)begin
if(~rst)
begin ctrl <=#12’b00; flag <=#10;
end
elseif(~flag)
begin ctrl <=#12’b01; flag <=#11;
endelse flag <=#10;end常见过程语句例常见过程语句综合电路类似C语言的switchcase语句
case(case_expr) case_item_expr{,case_item_expr}: procedural_statement...... [default:procedural_statement]endcase常见过程语句case语句rege;always@(posedgeclkor
negedgerst)begin
if(~rst) e<=#10; else
case({a,b})2'b00:e<=#1d;2'b01:e<=#1~c;2'b11:e<=#11'b0;2'b11:e<=#11'b1;
default:; //空语句,强烈建议保留default分支表达式
endcaseend常见过程语句常见过程语句综合电路常见过程语句casex语句和casez语句语法与case非常相似不建议使用casez(ir)8b’1???????:instruction1(ir);8b’01??????:instruction2(ir);8b’00010???:instruction3(ir);8b’000001??:instruction4(ir);endcase思考:用四种循环语句分别实现initial中的时钟产生:在100ns出开始;周期10ns。常见过程语句循环语句forever语句
repeat语句
while语句
for语句
连续执行的循环;只用于测试程序的initial块中;综合工具很难综合成FPGA的逻辑电路。练习五描述电路行为:该电路在每一个时钟下跳沿(负沿)检查输入数据,当输入数据Usg为1011时,输出Asm被置为1。描述电路行为:输入为12位的向量。如果其中1的数量超过0的数量,输出设置为1。当Data_Ready为1时,才对输入数据进行检查。
提示:输入信号均有clk和rst,采用时序逻辑设计(always语句)自顶向下设计采用数据流建模、行为建模、结构化建模三种方式基于本章内容,可以设计FPGA可实现的Verilog源代码VerilogHDL源代码设计开始你的第一个Verilog功能模块源代码设计VerilogHDL源代码设计12345根据需求,进行模块功能划分,自顶向下设计定义各个模块的接口信号(包括方向、类型、宽度)定义全局时钟信号和全局复位信号编写顶层模块,例化子模块子模块功能设计,以时序逻辑设计为主与软件源代码设计最大的不同:时序的严格性!基本设计流程VerilogHDL源代码设计如何验证源代码设计的正确性功能仿真(前仿真)进行语法检查,error和warning设计testbench,根据激励输入验证逻辑功能逻辑综合……Testbench验证如何验证源代码设计的正确性模拟实际环境的输入激励和输出校验的一种“虚拟平台”以输入激励为主,输出校验可以通过波形观测Testbench验证1234Testbench和源代码都是.v文件Testbench和源代码都是moduleTestbench不能综合成FPGA内部电路接口信号定义被测试模块的输入激励设置为reg型;被测试模块的输出设置为wire型;双向端口inout在测试中需要进行特殊处理。Testbench验证为什么信号方向与类型的对应关系与之前的要求不同源代码看作testbench子模块源代码顶层的输入是testbench的输出源代码顶层的输出是testbench的输入Testbench验证Testbench中inout信号的使用inout[15:0]data;wire[15:0]data;reg[15:0]data_out;regdata_enable;方法1assigndata=data_enable?data_out:16‘hz;方法2IOBUF(.I(data_out),.O(),.T(data_enable),.IO(data));moduletestbench();//信号类型定义(wire或者reg),注意testench没有输入输出。…//例化顶层模块…//激励行为描述,通常都包含clk和rst的产生描述initial… //可使用各种合法语句always…assign…task… //类似于函数endmoduleTestbench验证Testbench的结构Testbench验证1在同一项目中的VerilogTestFixtureXilinxISE工具提供testbench的自动生成模板与哪个源代码文件关联就生成对应层次的Testbench23Testbench自动生成模板Testbench验证Testbench验证空模板样例需增加clk的产生rst的使能描述。输入信号的行为描述。initialbeginReset=0;#100Reset=1;#80Reset=0;#30Reset=1;endTestbench验证值序列产生产生值序列的最简单是使用initial语句。例如:parameterREPEAT_DELAY=35;integerCoinValue;always begin CoinValue=0; #7CoinValue=25; #2CoinValue=5; #8CoinValue
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 志愿者服务工作总结与计划
- 如何设定具有挑战性的年度目标计划
- 培养员工领导能力的途径计划
- 如何合理分配仓库资源计划
- 2025年高性能铜镍合金带、线材项目建议书
- 提升财务职能参与战略管理的水平计划
- 激发学生学习兴趣的行动方案计划
- 建立班级评价体系的必要性计划
- 2025年脉冲反应堆及配套产品项目发展计划
- 修理厂入股合同协议书(2025年版)
- 滥用抗生素现状及危害课件
- 机械制造技术基础(课程课件完整版)
- 上下级关系与领导力管理制度
- 堆垛机保护保养手册
- 2024年卫生资格(中初级)-初级药师考试近5年真题集锦(频考类试题)带答案
- 2024年职业病防治考试题库附答案(版)
- 【呋塞米合成工艺的探究进展5300字(论文)】
- GB/T 18385-2024纯电动汽车动力性能试验方法
- 浙江省杭州市杭州二中钱江学校2024-2025学年高一物理下学期月考试题含解析
- 公路冲击碾压应用技术指南
- 修复征信服务合同模板
评论
0/150
提交评论