《CPLD FPGA设计与应用基础教程》课件第三章.ppt

上传人(卖家):momomo 文档编号:5716482 上传时间:2023-05-05 格式:PPT 页数:64 大小:1.77MB
下载 相关 举报
《CPLD FPGA设计与应用基础教程》课件第三章.ppt_第1页
第1页 / 共64页
《CPLD FPGA设计与应用基础教程》课件第三章.ppt_第2页
第2页 / 共64页
《CPLD FPGA设计与应用基础教程》课件第三章.ppt_第3页
第3页 / 共64页
《CPLD FPGA设计与应用基础教程》课件第三章.ppt_第4页
第4页 / 共64页
《CPLD FPGA设计与应用基础教程》课件第三章.ppt_第5页
第5页 / 共64页
点击查看更多>>
资源描述

1、第三章 Verilog HDL 语法要素LOREM IPSUM DOLOR目 录CONCENT3.1 标识符3.2 数值集合3.3 数据类型3.4 数组3.5 内建门级原语3.6 操作数3.7 操作符3.8 编译指令3.9 实例:带可预置数据的 8 位自增/减计数器设计 3.1 标识符GRADUATION THESIS3.1 标识符标识符就像一个人的姓名一样,是用来描述一个对象或者变量的名称,可以用于模块、寄存器、端口、联机、语句块或者实例化模块名称,这个名称可以在设计的其他地方引用,一个标识符在一个模块中对应唯一的对象。在 Verilog HDL 语法中,标识符可以是任意一组字母、数字、$符

2、号和_(底线)符号的组合,但第一个字符必须是字母或者底线。Verilog HDL中的标识符对字母大小写敏感,如 Reg 和 REG 是两个不同的标识符。以下几个都是合法标识符的例子:_Count _COUNT R5 Four_To_1 Time_4$以下是非法标识符:3to1/不能数字开头$monitor/此为系统任务,非标识符Verilog HDL 有一类特殊的标识符,叫做转义标识符。转义标识符和 C 语言定义的一样,也是以“”反斜杠符合开始,以空白结尾(空白可以是一个空格、一个制表符或者一个换行符)。反斜杠和空白格不是转义标识符的一部分,如标识符qqq 和和标识符 qqq 是恒等的。以下是

3、一些合法标识符的例子。”.*s 2018year但需要注意的是,转义标识符和关键词并不是完全相同。如标识符begin 和关键词 begin是不相同的。3.1 标识符可以使用如下代码序列输出特殊字符:n 换行t 制表符 字符”字符“OOO 值为八进制的字符,例如:$display(“Simulation time is%t”,$time);$display(“Simulation time is n%t”,$time);模拟后的执行结果如下(假设当前时刻为 10):Simulation time is 10Simulation time is10可以看出,执行到第二条语句n 时,语句换行,然后再

4、输出当前时刻值 3.2 数值集合GRADUATION THESIS3.2 数据集合Verilog HDL 语法有四种基本的值类型:0、1、x 和 z。0 对应的是低电平或者逻辑“假”,1 表示高电平或者逻辑“真”,x 表示未定状态,即无法判断其逻辑值是 1 还是 0。当线型变量的驱动无效或者断开时,该线型变量处于高阻 z 状态。x 和 z 值不区分大小写。也就是说,x 和 X 表示的意思是相同的。当逻辑门的输入是 x 或者 z 状态时,一般会被解释为 x。在程序运行过程中,其值不能改变的量称为常量。在 Verilog HDL 中,有三种类型的常量:数字、字符串以及参数。3.2.1 数字在 Ve

5、rilog HDL 中,有两种数位类型:整数和实数。在数字类型中,数字与数字之间可以使用底线符号“_”来连接。该连接线对于数字本身来说毫无意义,只是为了提高代码的可读性。唯一的限制是底线符号不能作为首字符。如:8b1010_0101/合法数字8b_1010_0101/非法数字1.整数整数主要有四种表示方式:二进制整数(采用 b 或者 B 表示)八进制整数(采用 o 或者 O 表示)十进制整数(采用 d 或者 D 表示)十六进制整数(采用 h 或者 H 表示)3.2 数据集合整数格式有三种:,这是一种严格的描述方式,如:8hFF,表示位宽为 8 的十六进制数字 FF。如果定义的位宽比数字的长度要

6、长,则根据数字是否为有符号数来决定在数字最高位的左边补 0 还是 1。如:8h1F,1F 默认为五位宽,最高三位补 0。如果定义的位宽比数字的长度要短,则左边超出部分自动截断。如 5hFF,事实上等于 5h1F,最高三位被自动截断。,没有显式突出位宽,其位宽由数字本身所需位宽的宽度来决定。如:h8,表示四位位宽的十六进制数字 8。,默认为三十二位宽的十进制数字,位宽宽度取决于具体的机器系统。当整数表示为负数时,需要把负数符号“-”写在位宽前面,否则是非法数字。如:-8d5/合法数字,代表十进制数字 5 的步数8d-5/非法数字在数字电路中,x 和 z 值根据不同的数字进制可以实现不同的位宽扩展

7、。一个 x 可以用来定义十六进制数的 4 位二进制数的状态,八进制数的三位,二进制数的 1 位。z 的表示方式也类似。如:3.2 数据集合b110 x/表示最低位为未定值4b11z1/表示第二位为高阻态4hx/表示十六进制数字,其中四位全是 xz 也可以被写成“?”。在使用 case 语句时,建议采用这种写法,提高代码可读性。注意:位宽不能为表达式,必须是整数。如:(1+2)b110,这是非法的整数表现形式。数值不能为负。在上面描述已经说明。符号“”和进制基数之间不能有空格。如:3 b110,这是非法的表现形式。在表示数字时,字母 x、z 以及从 a 到 f,不区分大小写2.实数实数有两类表示

8、方式:十进制表示法以及科学表示法。十进制表示法和普通的数字表示相同。但需要注意的是,小数点两侧都必须至少要有一位数字。如:3.2 数据集合1.01.340.0121./非法,小数点右边无数字科学表示法和普通的数字科学表示法相同。如:3.6E3/36003e-2/0.0312_3.4e3/1234003.2 数据集合3.2.2 字符串字符串是采用双引号“”包围的字符序列,不能分成多行书写。如:“Hello World!”Verilog HDL 语言中,字符串主要用来仿真说明。常见于系统监控函数、显示和打印函数中,以提高代码可读性。如:$monitor($time,“The sum of%d+%d

9、 is%dn”,a,c,sum);3.2 数据集合3.2.3 参数参数是一模拟较特殊的常量。它采用关键词 parameter 来定义一个标识符代表一个常量,称为符号常量。采用参数标识符来表示一个常量可以提高程序的可读性和可维护性。其基本格式如下:parameter 参数名 1=常量表达式;如:parameter MSB=7;parameter LSB=0;wire MSB:LSB DATA;/表示八位位宽的 DATA 线网注意:常量表达式只能是常数或者先前已经定义过的参数参数经常被用于定义变量宽度和时延。参数只能被赋值一次。在参数调用或者传递过程中,可以通过参数修改语句改变参数值。这将在后续章

10、节中提到3.3 数据类型GRADUATION THESIS3.3 数据类型Verilog HDL 主要有两大数据类型:1.线网类型。线网类型表示结构化组件之间的物理联机。主要用来描述组合逻辑。它的值由驱动组件的值决定,如果没有驱动组件连接到线网,则该线网值为 z。2.变量类型。变量类型表示一个抽象的数据存储单元。只能在行为级建模中使用。其缺省值为 x。3.3 数据类型3.3.1 线网线网类型包含了许多种线网子类型。其中使得最多是 wire 类型。通常,模块端口输入被默认为 wire 类型。此外,被例化模块端口的输出一般连接的也是 wire 类型的信号或变量。在 Verilog HDL 语法中,

11、如果对某个信号的线网类型不予以说明,则该信号默认为 1 位宽的wire 类型线网。也可以使用编译程序指令default_nettype 来改变默认信号类型。例如:default_nettype wor则任何未被显式声明的线网都被默认为 wor 型。各种线网及其具体说明如表 3-1 所述。3.3 数据类型1.wire 线网和 tri 线网wire 线网和 tri 线网的语法和功能都相同。关键词 wire 描述单驱动的逻辑器件之间的连接,而关键词 tri 被单独列出来描述多驱动的逻辑器件之间的连接。当 wire 或者 tri 线型定义的信号或者变量被多重驱动时,其线网有效值如下表所示:如:wire

12、 2:0 in1,in2,sum;assign sum=in1&in2;assign sum=in1 in2;假设第一个 assign 语句得出来的结果是 1x0,第二个 assign 语句得出来的有效值为 0z0,那么 sum 的最终有效值是 xx0。3.3 数据类型2.wor 线网和 trior 线网在数字电路中,有一类电路叫做线或逻辑。所谓的线或逻辑,就是把本来要用逻辑或组件的设计采用线网代替并实现逻辑或的功能。当任意一根线网为逻辑高电平时,输出为高电平。线或逻辑一般都是采用发射极耦合逻辑来实现。如图 3-1 所示。wor线网就是用来描述此线或类型的。trior 线网是多驱动的线网类型,

13、用于对三态的线或逻辑。其线网有效值如表 3-3 所示。3.3 数据类型3.wand 线网和 triand 线网 与线或逻辑类似,所谓的线与逻辑,就是把本来要用逻辑或组件的设计采用线网代替并实现逻辑与的功能。当任意一根线网为逻辑低电平时,输出为低电平。线与逻辑一般都是采用集电极开路逻辑来实现。如图 3-2 所示。wand 线网就是用来描述此线或类型的。triand 线网是多驱动的线网类型,用于对三态的线与逻辑。其线网有效值如表 3-4 所示3.3 数据类型4.向量线网与标量线网 在定义向量线网时可选用关键词 scalared 或 vectored。二者的差别在于 scalared 可以对线网进行

14、位选择和部分选择,但 vectored 必须整体赋值。如:wand vectored 7:0 RgB;/不允许单独位选择 RgB0或者 RgB1:0wor scalared 15:0 green;/允许位选择 green1或者 green5:2如果没有显式定义,线网默认为标量3.3 数据类型3.3.2 变量类型变量类型是一种可以保持数值的变量。在Verilog HDL语言中,有五种不同的变量类型。3.3 数据类型reg 变数reg 变量可以用来描述两类组件。一类是寄存器类型,另外一类是内存类型。寄存器类型reg 变量在描述寄存器类型时,默认为 1 位位宽,但是可以在变量声明时显式指定位宽宽度。

15、其基本格式如下:reg signedm:n reg1,reg2,regN;其中,关键词 signed 表示变量值为有符号数(以 2 的补码形式保存),如果没有使用此关键词,则表示为无符号数,缺省值也是无符号数。m 和 n 是常数值表达式,范围定义可选。例如:reg load_n;/一位位宽的寄存器变数reg 31:0 addr;/32 位位宽的变量reg 0:7 data;/8 位位宽变量parameter MSB=15,LSB=0;reg MSB:LSB byte;/16 位位宽变量内存类型内存是由寄存器变量组成的数组。其基本格式是:3.3 数据类型reg m:n memory M:N;表示

16、为有(|M-N|)个(|m-n|)位宽 reg 变量所组成的数组。例如:reg addr31:0;/32 个 1 位 reg 变量的所组成的数组reg 3:0 lpc_data0:15;/16 个 4 位 reg 变量所组成的数组对内存的赋值和对寄存器的赋值不同:寄存器赋值可以在一条赋值语句中完成,但内存赋值不能。例如:reg 31:0 addr;addr=32HA0_B0_C0_D0;/这是合法的赋值reg addr31:0;addr=32HA0_B0_C0_D0;/这是非法的赋值由于内存是由寄存器变量组成的数组,所以可以针对每个寄存器变量进行赋值。例如:reg 15:0 data 3:0;

17、3.3 数据类型data0=16h00_00;data1=16h11_11;data2=16h22_22;data3=16h33_33;通常,可以采用循环语句来实现内存的初始化或者从另外的内存中复制数据。例如把 data 内存初始化为 0:reg 15:0 data3:0;integer i;for(i=0;i=3;i=i+1)datai=16h0;当存储深度过深时,采用 for 语句可以快速实现初始化。但如果每个存储单元的值各不同相同时,采用 for 语句或者直接赋值的方式,就会显得非常繁琐。3.3 数据类型解决的方法是采用系统任务$readmemb 和$readmemh 来为内存赋值。二者

18、之间的区别在于$readmemb 读取二进制文本,$readmemh 读取十六进制文本。其基本语法如下:reg 7:0 data 7:0;$readmemb(“initial.txt”,data,m,n);其中,initial.txt 为将要写入内存的文本数据,m 和 n 为要写入内存的起始和结束地址。例如:假设 initial.txt 文本的内容如下,0000 0001 0010 00110100 0101 0110 0111文本中的内容可以以空白格、换行符和制表符等分隔,可以含有注释$readmemb(“initial.txt”,data,6:4);即:把 initial 的前三位 000

19、0、0001 和 0010 分别写进 data6、data5和 data4。$readmemb(“initial.txt”,data,6);即:把 initial.txt 的内容从开始逐个读取文件中的数据,并从地址 6 开始存储到内存,直到地址 0 结束3.3 数据类型$readmemb(“initial.txt”,data);即:和上一条语句不一样的地方在于,该语句把读取出来的数据,按照内存默认的存储索引逐个放入到内存中,此例是从地址 7 到地址 0。当然,在文本文件中也可以直接指定数据要存入到内存的地址位置。如修改initial.txt 的档内容如下1 00002 00014 00103

20、00110 01005 01016 01107 0111$readmemb(“initial.txt”,data);此时,后面指定了内存的位置以及要写入的数据内容,因此地址 1,写入的是 0000的内容,而不是上一句的 0001 的内容。3.3 数据类型integer 变数integer 变量是一种用于计算和操纵数据的通用变量类型。其默认位宽为 32 位,可存储有符号数,采用补码形式进行描述。数据的最高位是符号位。integer 变量不能进行位选取或部分选取。其变量声明基本格式如下:integer variable_namem:n;符号m:n指定了一个可选范围,表示一个整数数组。例如:inte

21、ger instr;/32 位的整数型变量instr=6;/0000_0000_0000_0000_0000_0000_0000_0110integer instr3:0;/4 个 32 位的整数型变量通过赋值语句,integer 变量和 reg 变量可以自动转化,不必使用专用的函数。赋值总是从最右端的位开始,至最左端,多余的位自动截断。例如:reg 3:0 instr;integer a;a=5;/a 的值是 32h00_00_00_053.3 数据类型instr=a;/instr 的值是 4h5instr=4h7;/instr 的值是 4h7a=instr;/a 的值是 32h00_00_

22、00_07a=-5;/a 的值是 32hff_ff_ff_f5instr=a;/instra 的值是 4hD和内存一样,整型数据的赋值和初始化可以采用直接对每一个 integer 变量进行赋值或者采用循环语句进行赋值time 变数time 变量用于存储和处理时间值。其声明的基本格式如下:time time1,time2,timeNm:n;time 变量的默认位宽为 64 位,只能存储无符号数。例如:time current_time;time timeList15:0;real 变量和 realtime 变量real 变量和 realtime 变量完全相同,其缺省值为 0。在变量声明时,不允许

23、对位宽做任何指定。例如:real current_time;realtime top_mark;3.4 数组GRADUATION THESIS3.4 数组和 C 语言一样,Verilog HDL 语言也可以针对线网和变量定义二维或者多维数组。数组的元素可以是标量值或者向量值。其基本格式如下:数据类型 位宽 数组名 数组每一维的字界数组每一维的字界;相关示例如下:wire linear_mem0:15;/一个由 16 个元素组成的数组,每个元素位宽 1 位的 wire 变量reg 7:0 addr0:31;/一个由 32 个 8 位位宽 reg 变量类型的元素组成的数组tri 0:31 data

24、0:10:7;/2*8 的三态二维线网数组,每个元素位宽 32 位其中一位 reg 变量数组称之为内存。对于数组的赋值,和存储型的赋值一样,不能使用一句赋值语句把某个数组的值复制给另外一个数组,而是需要使用循环语句或者直接对数组中的一个元素进行赋值操作或者初始化,也可以选择数组元素中的某一个位或者某些位进行存取或者赋值操作。如:data01=32hff_ff_ff_ff;/合法赋值data00:7=1;/非法赋值3.5 内建门级原语GRADUATION THESIS3.5 内建门级原语在 2.6.1 节中有介绍 Verilog HDL 语言关于内建门级原语的结构体描述。Verilog HDL语

25、言中,有各种描述数字逻辑门的原语,具体如表 3-6 所示 3.5 内建门级原语3.6 操作数GRADUATION THESIS3.6 操作数表达式由操作数和操作符组成,是 Verilog HDL 语言的基础架构。表达式右侧的运输结果可以赋值给左边的线网或变量。一个表达式可以包含单个操作数、两个操作数或者多个操作数。操作数的基本类型有如下。3.6 操作数第 3.2 和第 3.3 节数值集合已经详细地介绍了常数、参数、线网与变量的格式和具体的各种类型,在此不再赘述。表达式中的整数值可以被认为是有符号数或无符号数。如表达式是十进制数字,如 123,则该数字为有符号数。如果采用的基数型数字,如 2b1

26、0,则解释为无符号数3.6.1 常数、参数、线网与变数采用基数表示的整数和不用基数表示的整数,其对负值处理的方式也不相同。如下例所示:integer a,b;a=-54/6;b=-d54/6;对于数值 a,-54 是有符号数,所以得出的结果是 32HFF_FF_FF_F7;而对于数值 b,则是作为无符号数值处理,得出来的结果是 32H2A_AA_AA_A1。在线网和 reg 变量声明语句中,如果包含关键词 signed,则该线网和 reg 变量的值被解释为有符号数,否则就是无符号数。整型变量的值被解释为有符号的二进制补码数,时间变量中的值被解释为无符号数,实型和实型时间变量的值被解释为有符号浮

27、点数。相关示例如下:3.6 操作数wire 3:0 a=4b1010;wire signed 3:0=-4;integer I=1;time current_time;3.6.2 位选择及部分位选位选择就是从一个向量中抽取其中的一位。比如:reg 4:0 a,b;wire c=a1&b2;在上述表达式中,a 和 b 都是五位宽变量,线网 c 的值等于变量 a 的第二位和变量 b 的第三位的与逻辑。若位选表达式索引的位为 x、z 或者越界,则位选择为 x。部分位选则是指从一个向量中抽取相邻的若干位。位选择是特殊的部分位选。其基本格式是:Net_or_reg_vector msb:lsb;比如:r

28、eg 4:0 a,b;wire 1:0 c=a1:0|b4:3;3.6 操作数在上述表达式中,两位位宽的线网 c 的值等于变量 a 的最低两位和变量 b 的最高两位的或逻辑。另外一种语法形式如下:Net_or_reg_vectorbase_expr+:const_width_expr;Net_or_reg_vectorbase_expr-:const_width_expr;其 中,b a s e _ e x p r 表 示 为 基 表 达 式,可 以 不 是 常 数。Const_width_expr 表示为位的个数,必须是常数。+/-表示在 base_expr 是按递增还是按递减的方式来做位选

29、。比如:integer base;reg 31:0 data;wire 31:0 addr;database+:2;/选择 base,base+1 位的值addrbase-:2;/选择 base,base-1 位的值data31-:8;/选择 data31:24的值addr0+:16;/选择 addr0:15的值3.6 操作数存储单元主要有三类:寄存器、内存以及数组。其中寄存器相当于特殊的内存,而内存相当于一维数组。因此,可以把内存的某一个元素直接赋值给寄存器。比如:reg 31:0 data0:63;/由 64 个 32 位位宽寄存器组成的内存reg 31:0 data_out;/32 位寄

30、存器变量data_out=data0;/把 data 内存元素 0 的值赋给寄存器 data_out;内存和数组也可以做部分位选或者位选。比如:reg 31:0 data0:63;/内存reg 31:0 addr0:630:1;/二维数组reg 7:0 data_high;data_high=data031:24;/把内存元素 data0最高八位赋给寄存器reg15:0 data_low;data_low=data63015:0;/把二位数组 data 的存储单元 data630的低 16 位传给寄存器reg data_lowest;data_lowest=data000;3.6.3 存储单元

31、3.6 操作数功能调用主要是指函数调用。在 Verilog HDL 语言中,主要有两类函数,一类是系统函数以$字符起头,另外一类是用户自定义函数。如:$time+sum(a,b);此表达式中,$time 是系统函数,sum(a,b)为用户自动以函数。函数将在下一章进行详细讨论。3.6.4 功能调用3.7 操作符GRADUATION THESIS3.7 操作符在 Verilog HDL 语言中,有九大类操作符。具体如下表所示:3.7 操作符3.7.1 算术操作符算术操作符Verilog HDL 和 C 语言相似,包含了加、减、乘、除以及求余五类算术操作符。其中,加和减操作又分为一元加减和二元加减

32、的操作。一元加减与 C 语言的操作类似【例 3-1】采用一元加实现内存的初始化reg 31:0 addr0:63;integer I;always(*)for(I=0;I b)/a 大于 b 的情形$display(“The large data is%d”,a);else if(a=b)/a 等于 b 的情形$display(“The two datas are equal,the value is%d”,a);3.7 操作符 else/a 小于 b 的情形$display(“The large data is%d”,b);如果操作数中含有一位 x 或者 z,则整个比较结果为 x。如:4b1

33、001 4b100 x,结果是 x,而不是 0 或者 1。3.7.3 相等操作符相等操作符相等操作符有四类操作符:逻辑相等(=)、逻辑不等(!=)、全相等(=)、不全等(!=)。前二者和后两者之间的区别在于四态中的 x 和 z 值是否有物理意义。当采用逻辑相等或者逻辑不等时,x 和 z 的值具有物理意义,因此当任何一个操作数的任何一位出现 x或 z 时,其逻辑相等表达式的结果为 x,而逻辑不等主要看操作数第一位。而全相等和不全等是完全按照数值进行比较,因此比较结果只有真(1)和假(0)的两种状态。逻辑比较可以用于综合,而全等或者不全等只能用于模拟。如:A=b11x001;B=b11x001;C

34、=b010 x;D=b11x0;3.7 操作符A=B;/结果为 x,因为 A 和 B 含有一位 x 状态A=B;/结果是 1,因为 A 和 B 按位完全相等C!=D;/结果为 1,最高位不同当表达式操作数的位宽不一致时,和关系操作符的方式相同,通过对位宽小的操作数进行补 0 或者补符号位进行位宽对齐后再比较3.7.4 逻辑操作符逻辑操作符逻辑操作符有三种:逻辑与(&)、逻辑或(|)以及逻辑非(!)。采用逻辑操作符的表达式的结果有三种结果:0、1 和 x不管操作数的位宽事单位宽还是多位宽。当多位宽操作数进行逻辑操作室,非 0 操作数被当成 1 进行处理。如:A=b1;B=B0;C=2B01;D=

35、2B10;E=2B1X;A&B;/结果为 0A|B;/结果为 1C&D;/结果为 1,因为二者均为非 0 数!C;/结果为 0D&E;/结果为 0A|bx;/结果为 1!x;/结果为 x当操作数中出现 x 或 z,则该操作数整体被视为一位 x,然后再与另外的操作数进行逻辑操作,其最终运算结果取决于另外一个操作数和逻辑操作符,如 1 逻辑或 x,则其结果为1。3.7 操作符3.7.5 按位操作符按位操作符与逻辑操作符类似,也最容易混淆的是按位操作符。按位操作符,顾名思义,则是对操作数逐位操作,产生一个向量的结果其结果位宽与最宽位宽的操作数相同。按位操作符有五类:按位与(&)、按位或(|)、按位非

36、()、按位异或()和按位同或(或者)。取逻辑操作符小节的实例来说明按位操作符如下:A=b1;B=B0;C=2B01;D=2B10;E=2B1X;A&B;/结果为b0A|B;/结果为b1C&D;/结果为 2b00C;/结果为 2b10D&E;/结果为 2b10A|bx;/结果为 1x;/结果为 xC D;/结果是 2b11A C;/结果是 2b113.7 操作符可以看出,当位宽为一位位宽时,按位操作符和逻辑操作符的结果相同,但含义不同按位操作符是指相同位之间的逻辑操作结果,而逻辑操作符是指两个操作数被看成整体后的逻辑操作结果。当向量操作数进行按位操作时,可以很明显看出和逻辑操作符的结果不同。当操

37、作数位宽相同时,结果和操作数的位宽也相同。当操作数位宽不同时,先把位宽小的操作数进行补0 或者补符号位的形式进行位宽补全,然后运算结果3.7.6 缩减操作符缩减操作符和按位操作符相似,缩减操作符也是对操作数进行逐位逻辑操作,但与按位操作符不同的是,除了按位非以外,按位操作符是对两个操作数进行处理,得出来的结果是一个向量,而缩减操作符是对一个操作数进行处理,得出来的结果是一位的操作结果,该结果可能是 1,可能是 0,也可能是 x。缩减操作符有六类:缩减与(&)、缩减或(|)、缩减与非(&)、缩减或非(|)、缩减异或()以及缩减同或()。具体功能和示例如下表所示3.7 操作符3.7.7 移位操作符

38、移位操作符移位元操作符按照性质来分,可以分为逻辑移位元操作符和算术移位操作符;按照方向来分,可以分为左移操作符和右移操作符。和其他高级语言不同的是,移位操作符没有循环移位操作符。因此,组合起来共有四类操作符:逻辑左移()、算术左移()。逻辑移位元和算术移位的主要区别在于对于最高位的处理。如果是逻辑移位元操作符,移位腾空的位总是填 0,而对于算术移位操作符来说,左移腾出来的位总是填 0,但右移腾出来的位需要确认该操作数是否是有符号数,如果是无符号数,则腾空位填 0,否则填符号位3.7 操作符移位表达式的基本格式如下,其右侧表达式中的操作数总被认为是无符号数。被移位操作数 移位操作符 移位次数,如

39、:reg 6:0 data;reg signed3:0 addr;data=b100_1110;addr=sb1011;data 2;/结果是b001_0011addr 3;/结果是sb1111;addr3;/结果是sb1000;data-1;/因为右侧为无符号数,所以去-1 的补码,因此把 data 左移 2 的(31-1)次3.7 操作符条件操作符的基本语法如下。Condtion?expression1:expression2;该语句表示为如果 Condition 表达式为真,则执行 expression1,否则执行 expression2 表达式。整个语句等同于一个条件语句。条件语句将在

40、下一章具体介绍。如:assign mux_out=select?a:b;表示为一个二选一的选择器当 select 为 1 时,把信号 a 赋给 mux_out,否则把信号b 赋给 mux_out。条件操作符可以嵌套。如:assign sign_out=Cond_A?sigA:Cond_B?sigB:Cond_C?sigC:Cond_D?sigD:sigE;其等效于:assign sign_out=(Cond_A and SigA)OR(NOT Cond_A and Cond_B and SigB)OR(NOT Cond_A and NOT Cond_B and Cond_C and SigC)

41、OR3.7.8 条件操作符条件操作符3.7 操作符(NOT Cond_A and NOT Cond_B and NOT Cond_C and Cond_D and SigD)OR(NOT Cond_A and NOT Cond_B and NOT Cond_C and NOT Cond_D and sigE);嵌套层级过长可能导致综合软件的效率低下,因此不建议使用。替代方式是采用 case语句来实现其功能。3.7.9 拼接复制操作符拼接复制操作符拼接操作符和复制操作符都是采用符号来实现。拼接操作符是把较小表达式中的位拼接起来形成一个多位宽的大表达式。基本格式如下:expr1,expr2,exp

42、r3,;【例 3:-3】通过拼接操作符实现数据翻转Module data_convert(input 7:0 dataIn,output reg 7:0 dataOut,input clk,input rst_);always(posedge clk or negedge rst_)3.7 操作符 if(!rst_)dataOut=8b0;else dataOut=data3:0,data7:4;拼接操作符通常用来做数据翻转,或者组合成总线等功能。如assign dataOut7:4=data7,data5,data3,data0;复制操作符是一类特殊的拼接操作符,复制操作是通过指定复制次数来

43、执行操作数复制。该次数可以是常数,也可以是参数。语句格式如下:repeat_timesexpr1,expr2,;相关示例如下:31b1;/结果是 3b1114ack;/等于ack,ack,ack,ack4dataOut7,dataOut;/符号扩展POWER1b0;/实现参数指定的复制3.8 编译指令GRADUATION THESIS3.8 编译指令在Verilog HDL语法中,有一类特殊的指令来指定和配合编译程序实现特定的编译功能。这些指令语法是采用反引号或者音符标志来引导关键词的形式来实现。这些指令可以加强程序员和编译程序之间互动,并提升代码的鲁棒性。define 类似于 C 语言中的#

44、define 指令,用于定义文本替代的宏命令。一旦编译程序检测到define 指令,则将替换预定义的宏文本。其基本格式是:define text_macro macro_text3.8 编译指令和参数定义不同,编译指令无需以“;”结束,但在引用宏文本时,需要使用“”。如define MAX_ADDR_WIDTH 32reg MAX_ADDR_WIDTH-1:1 addr;undef 指令用于取消之前的宏定义。如:undef MAX_ADDR_WIDTHifdef,ifndef、else、elseif 和endif 用于条件编译。ifdef 用于检测该宏定义是否存在,而ifndef 用于该宏定义

45、是否不存在。else 用于和ifdef、ifndef 配对使用,但非必要。如:ifdef WINDOW64 parameter MAX_ADDR_WIDTH=64;else parameter MAX_ADDR_WITDH=32;endif当前面代码定义了 WINDOW64 这个宏文本时,则定义 MAX_ADDR_WIDTH 为 64,否则为 32。elseif 相当于else 编译指令后加ifdef 指令,表示为多分支编译指令。所有条件编译指令以endif 指令结束。3.8 编译指令和参数定义不同,编译指令无需以“;”结束,但在引用宏文本时,需要使用“”。如define MAX_ADDR_W

46、IDTH 32reg MAX_ADDR_WIDTH-1:1 addr;undef 指令用于取消之前的宏定义。如:undef MAX_ADDR_WIDTHifdef,ifndef、else、elseif 和endif 用于条件编译。ifdef 用于检测该宏定义是否存在,而ifndef 用于该宏定义是否不存在。else 用于和ifdef、ifndef 配对使用,但非必要。如:ifdef WINDOW64 parameter MAX_ADDR_WIDTH=64;else parameter MAX_ADDR_WITDH=32;endif当前面代码定义了 WINDOW64 这个宏文本时,则定义 MAX

47、_ADDR_WIDTH 为 64,否则为 32。elseif 相当于else 编译指令后加ifdef 指令,表示为多分支编译指令。所有条件编译指令以endif 指令结束。3.8 编译指令default_nettype 编译指令在前面讲述线网时已经简单描述过。该指令外隐式线网指定相应的线网类型。如default_nettype wor则所有的未被显式声明的线网类型均为定义为 wor 类型。注意:default_nettype 指令智能放在模块外进行声明 如没有采用default_nettype,则系统默认隐式线网类型为 wire 型 none 也可以用来指定缺省的线网类型,表示不允许使用隐含的线

48、网类型,include 编译指令用于在代码中引用其他文本的内容。被包含的文件可以采用相对路径,也可以采用绝对路径。如:include“/topdefinition.v”resetall 编译指令是指将所有的编译指令重置为缺省值,如resetall,则会将线网类型重置为 wire 类型。timescale 编译指令是仿真时非常常用的指令。用于指定延时的时间单位和精度。其基本格式是:3.8 编译指令timescale time_unit/time_precision如timescale 1ns/100ps表示为延迟的时间单位是 1ns,精度是 100ps。timescale 编译指令只能放在模块外

49、部,用于影响其后的模块延时时间。在一个系统中,可能有多个timescale 对应不同的模块,在这个情况下,仿真器总是依据所有模块中的最小时间精度来进行,其他所有延时将相应的转换为最小延时精度。unconnected_drive 和nounconnected_drive 用于指定未连接的输入端口的状态,可以是上拉状态或者下拉状态。如:unconnected_drive pull1/该段的所有未连接的输入端口均为上拉。nounconnected_drivecelldefine 和endcelldefine 用于把模块标记为单元模块。单元模块一般由某些 PLI 子程序使用。单元模块名和端口通常都采用

50、大写字母,模块内通常具有一个指定该单元延迟的块。PLI 子程序可以通过 specify block 中的信息对这些单位进行延迟计算。如:3.8 编译指令celldefine module DFF(D,CLK,Q,RST_);input D,CLK,RST_;output Q;endmodule endcelldefineline 编译指令是 Verilog 2001 新添加的内部编译预先处理指令,用于表示将行号和文件名复位到指定的值。当自动生成的 Verilog HDL 档被编译时,自动将指令值相关联的原始档复制到档的指定行。一般用户不会直接使用到本编译指令。如:line 10“reset.v

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 大学
版权提示 | 免责声明

1,本文(《CPLD FPGA设计与应用基础教程》课件第三章.ppt)为本站会员(momomo)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|