Verilog语法简介(3)

您所在的位置:网站首页 哈尔滨哪里有精工手表专柜 Verilog语法简介(3)

Verilog语法简介(3)

2022-11-29 03:21| 来源: 网络整理| 查看: 265

运算符和表达式

Verilog HDL中的操作符可以分为下述类型:

1) 算术操作符

2) 关系操作符

3) 相等操作符

4) 逻辑操作符

5) 按位操作符

6) 归约操作符

7) 移位操作符

8) 条件操作符

9) 连接和复制操作符 下表显示了所有操作符的优先级和名称。

操作符从最高优先级(顶行)到最低优先级 (底行)排列。同一行中的操作符优先级相同。

算术运算符

在常用的算术运算符主要是 :

加法(二元运算符):“+”;

减法 (二元运算符):“-”;

乘法(二元运算符):“*”;

在算术运算符的使用中,注意如下两个问题:

1. 算术操作结果的位数长度

算术表达式结果的长度由最长的操作数决定。在赋值语句下,算术操作结果的长度由操作符左端目标长度决定。考虑如下实例:

reg [3:0] arc, bar, crt;

reg [5:0] frx;

. . .

arc = bar + crt;

frx = bar + crt;

第一个加的结果长度由bar ,crt 和a rc 长度决定,长度为4 位。

第二个加法操作的长度同样由frx 的长度决定(frx 、bat 和crt 中的最长 长度),长度为6位。

在第一个赋值中,加法操作的溢出部分被丢弃;而在第二个赋值中,任何溢 出的位存储在结 果位frx [ 4 ]中。 在较大的表达式中,中间结果的长度如何确定?在Verilog HDL 中定义了如 下规则:表达式中的所有中间结果应取最大操作数的长度(赋值时,此规则也包 括左端目标)。考虑另一个实例:

wire [4:1] box, drt; wire [5:1] cfg;

wire [6:1] peg;

wire [8:1] adt;

. . .

assign adt = (box + cfg) + (drt + peg) ;

表达式右端的操作数最长为6 ,但是将左端包含在内时,最大长度为8 。所以所有的加操作使用8 位进行。

例如:box 和cfg 相加的结果长度为8 位。

2. 有符号数和无符号数在设计中,请先按无符号数进行。

关系运算符

关系运算符有:

?>(大于)

?=(不小于)

? 45 结果为假(0 ),而: 52 < 8'hxFF 结果为x 。

如果操作数长度不同,长度较短的操作数在最重要的位方向(左方)添0 补 齐。例如: 'b1000 > = 'b01110 等价于:'b01000 > = 'b01110 结果为假(0 )。

在逻辑相等与不等的比较中,只要一个操作数含有x 或z,比较结果为未知 (x),如:

假定:

Data = 'b11x0;

Addr = 'b11x0;

那么: Data = = Addr 比较结果不定,也就是说值为x。

逻辑运算符

逻辑运算符有:

&& (逻辑与)

|| (逻辑或)

!(逻辑非)

用法为:(表达式1) 逻辑运算符 (表达式2)

....

这些运算符在逻辑值0(假) 或1(真) 上操作。逻辑运算的结果为0 或1 。 例如,

假定:

crd = 'b0; //0 为假

dgs = 'b1; //1 为真

那么:

crd && dgs 结果为0 (假)

crd || dgs 结果为1 (真)

!dgs 结果为0 (假)

逻辑与(&&)的真值表如下:

逻辑或的真值表如下:

按位逻辑运算符

按位运算符有:

~(一元非) :(相当于非门运算)(一位数可用!)

&(二元与):(相当于与门运算)

|(二元或): (相当于或门运算)

^(二元异或) :(相当于异或门运算)

~ ^, ^ ~(二元异或非即同或):(相当于同或门运算)

这些操作符在输入操作数的对应位上按位操作,并产生向量结果。下表显示 对于不同按位逻辑运算符按位操作的结果:

例如:

假定,

A = 'b0110;

B = 'b0100;

那么:

A | B 结果为0110

A & B 结果为0100

如果操作数长度不相等, 长度较小的操作数在最左侧添0补位。

例如,

'b0110 ^ 'b10000

与如下式的操作相同:

'b00110 ^ 'b10000

结果为'b10110。

条件运算符

条件操作符根据条件表达式的值选择表达式,形式如下:

cond_expr ? expr1 : expr2

如果cond_expr 为真(即值为1 ),选择expr1 ;

如果cond_expr 为假(值为0 ), 选择expr2 。

如果cond_expr 为x 或z ,结果将是按以下逻辑expr1 和expr2 按 位操作的值: 0 与0 得0 ,1 与1 得1 ,其余情况为x 。

如下所示:

wire [2:0] student = marks > 18 ? grade_a : grade_c;

计算表达式marks > 18; 如果真,grade_a 赋值为student;

如果marks < =18, grade_c 赋值为student 。

连接运算符

连接操作是将小表达式合并形成大表达式的操作。

形式如下:

{expr1, expr2, . . .,exprN}

实例如下所示:

wire [7:0] Dbus;

assign Dbus [7:4] = {Dbus [0], Dbus [1], Dbus[2], Dbus[ 3 ]}; //以反转的顺序将低端4 位赋给高端4 位。

assign Dbus = {Dbus [3:0], Dbus [7:4]}; //高4 位与低4 位交换。

由于非定长常数的长度未知, 不允许连接非定长常数。

例如,下列式子非法:

{Dbus,5} //不允许连接操作非定长常数。

条件语句

if 语句的语法如下:

if(condition_1)

procedural_statement_1

{else if(condition_2)

procedural_statement_2}

{else procedural_statement_3}

如果对condition_1 求值的结果为个非零值, 那么 procedural_statement_1 被执, 如果condition_1 的值为0 、x 或z ,那么 procedural_statement_1 不执行。如果存在一个else 分支,那么这个分支被执 行。

以下是一个例子。

if (sum < 60)

begin

grade = c;

total_c = total _c + 1;

end

else if(sum < 75) begin

grade = b;

total_b = total_b + 1;

end

else begin

grade = a;

total_a = total_a + 1;

end

注意条件表达式必须总是被括起来,如果使用if - if - else 格式,那么 可能会有二义性,如下例 所示:

if (clk == 1)

if (reset== 1)

q = 0;

else q = d;

问题是最后一个else 属于哪一个if?它是属于第一个if 的条件(clk)还是 属于第二个if的条件(reset)? 这在Verilog HDL 中已通过将else 与最近的没 有else 的if 相关联来解决。在这个例子中,else 与内层if 语句相关联。

规范建议:

1、条件表达式需用括号括起来。

2、若为if - if 语句,请使用块语句 begin --- end : if(clk == 1) begin if (reset== 1) q = 0; else q = d; end 以上两点建议是为了使代码更加清晰,防止出错。 3、对if 语句,除非在时序逻辑中,if 语句需要有else语句。若没有缺省 语句,设计将产生一个锁存器,锁存器在asic设计中有诸多的弊端。 如下一例: if (t == 1)

q = d;

没有else 语句,当t为1(真)时,d 被赋值给q,当t为0(假)时,因为没 有else 语句,电路保持 q 以前的值,这就形成一个锁存器。

case 语句

case 语句是一个多路条件分支形式,其语法如下:

case(case_expr) case_item_expr{ ,case_item_expr} :procedural_statement

. . .

[default:procedural_statement]

endcase

case 语句首先对条件表达式case_expr 求值,然后依次对各分支项求值并 进行比较,第一个与条件表达式值相匹配的分支中的语句被执行。可以在1 个分 支中定义多个分支项;这些值不需要互斥。缺省分支覆盖所有没有被分支表达式 覆盖的其他分支。

例:

case (HEX)

4'b0001 : led = 7'b1111001; // 1

4'b0010 : led = 7'b0100100; // 2

4'b0011 : led = 7'b0110000; // 3

4'b0100 : led = 7'b0011001; // 4

4'b0101 : led = 7'b0010010; // 5

4'b0110 : led = 7'b0000010; // 6

4'b0111 : led = 7'b1111000; // 7

4'b1000 : led = 7'b0000000; // 8

4'b1001 : led = 7'b0010000; // 9

4'b1010 : led = 7'b0001000; // a

4'b1011 : led = 7'b0000011; // b

4'b1100 : led = 7'b1000110; // c

4'b1101 : led = 7'b0100001; // d

4'b1110 : led = 7'b0000110; // e

4'b1111 : led = 7'b0001110; // f

default : led = 7'b1000000; // 0

endcase

规范建议: case 的缺省项必须写,防止产生锁存器。

说明: 只有组合逻辑才可能产生锁存器,时序逻辑不会产生锁存器。

本文摘录于Verilog 红宝书_语法篇



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3