Verilog基础语法讲解
1、基础语法讲解
在编写程序之前,我们先学习Verilog语法知识,我们之前写的程序用到了运算符,例如我们用Verilog描述1个非门,我们就用到了 取反运算符‘~’,我们写求和模块用到了求和运算符’+’ , 那还有没有别的运算符呢?这里我们要拓展这方面的知识。在实际项目中边学边练是最好的方式。
Verilog HDL语言的运算符范围应用很广,其运算符按照功能可分为以下几类:
(1)算术运算符( + , - , *, /, %)
(2)赋值运算符 ( = , <=)
(3)关系运算符 (>, <, >=, <= )
(4)逻辑运算符 (&&, ||, ! )
(5)条件运算符 ( ?: )
(6)位运算符 (~, |, ^, &, ~^)
(7)移位运算符 ( <<, >> )
(8) 拼接运算符( {} ) A [3:0] = 4’b1011, B[3:0] = 4’b1100, 1’b1, {A[3], B[2:1], 1’b1} = 4’b1101
在Verilog HDL 语言中运算符所能带的操作数是不同的,按照运算符所带的操作数的个数,运算符可分为3种。
- 单目运算符:可以带1个操作数,操作数放在运算符的右边。
- 双目运算符:可以带2个操作数,操作数放在运算符的两边。
- 三目运算符:可以带3个操作数,
示例:
assign OUT = ~A; // 这个语句是将A取反并赋值给OUT, ‘~’就是一个取反运算符,’A’是1个被这个运算符操作的数,被操作的只有1个, 因此’~’是1个单目运算符。
assign OUT = A + B;// ’+’是加法运算符,它能让两个数相加,因此’+’是双目运算符
assign r = s ? t:u ; // ?: 是三目运算符, s, t, u是操作数,这条语句的意思是当s成立时,将t赋给r, 当s不成立时,将u赋值给r,?:是条件运算符,因此我们就知道了’?:’运算符是可以实现选择的功能。
基本的算术运算符
在Verilog HDL语言中,共有下面几种:
- + (加法运算符)
示例:assign Y = A + B ; //将A与B相加,计算结果赋值给Y
- - (减法运算符)
示例:assign Y = A - B; //将A的值减去B的值,计算结果赋值给Y
(3)* (乘法运算符)
示例:assign Y = A * B;//将A与B乘积的结果赋值给Y
(4)/ (除法运算符)
示例:assign Y = A / B; //将变量A的值除以B结果赋值给Y
(5)% (模运算符, 或者称为求余运算符,要求%两侧均为整型数据,例如7%3的值为1)
位运算符
Verilog HDL作为一种硬件描述语言,是针对硬件电路而言的,在硬件电路中信号有4种状态值,即:0 1 x z 在电路中信号进行与、或、非运算时,反应在Verilog HDL中则是相应的操作数的位运算, Verilog提供了以下5种位运算符。
- ~ //取反
- & //按位与操作
- | //按位或
- ^ //按位异或
- ^~ //按位同或(异或非)
说明:位运算符中除了~是单目运算符之外,其他均为双目运算符,即要求运算符两边各有1个操作数。
示例说明:
(1)取反运算符 ~ :
assign Y = ~A;//若A = 4’b1011; 则Y的值为4’b0100, 即按照每个bit位进行取反操作。
- 按位与操作 & :
assign Y = A & B; //若A的值为4’b1011, B的值为4’b0101, 则Y的值为4’b0001
- 按位或操作 | :
assign Y = A | B; //若A的值为4’b1011, B的值为4’b0101, 则Y的值为4’b1111
- 按位异或 ^ :
assign Y = A ^ B;//若A的值为4’b1011, B的值为4’b0101, 则Y的值为4’b1110
(6)按位同或 ^~ /~^
assign Y = A ^~ B;//若A的值为4’b1011, B的值为4’b0101, 则Y的值为4’b0001
关系运算符
Verilog HDL语法中表示关系运算的有:大于(>); 小于(<); 大于等于(>=); 小于等于(<=)
程序示例:
大于(>):
Y = (a>b) ? 8’d0:8’d1; //如果a的值大于b, 则将8’d0赋值给Y, 否则将8’d1赋值给Y
Y = (a>b) ? c:d; //如果a的值大于b,则将变量c的值赋给Y,否则将变量d的值赋给Y
小于(<):
Y = (a<b) ? 8’d0:8’d1; //如果a的值小于b, 则将8’d0赋值给Y, 否则将8’d1赋值给Y
Y = (a<b) ? c:d; //如果a的值小于b,则将变量c的值赋给Y,否则将变量d的值赋给Y
大于等于(>=):
Y = (a>=b) ? 8’d0:8’d1; //如果a的值大于等于b, 则将8’d0赋值给Y, 否则将8’d1赋值给Y
Y = (a>=b) ? c:d; //如果a的值大于等于b,则将变量c的值赋给Y,否则将变量d的值赋给Y
小于等于(<=):
Y = (a<=b) ? 8’d0:8’d1; //如果a的值小于等于b, 则将8’d0赋值给Y, 否则将8’d1赋值给Y
Y = (a<=b) ? c:d; //如果a的值小于等于b,则将变量c的值赋给Y,否则将变量d的值赋给Y
逻辑运算符
Verilog HDL语法中的逻辑运算符有 逻辑与(&&), 逻辑或(||), 逻辑非(!)
程序示例
逻辑与 && 用法:
//当a>b并且c>d都成立的时候,将1’b0赋值给Y, 否则将1’b1赋值给Y, 我们可以看出逻辑与在这里表示2个条件都成立,例如,有车 && 有房 才能找到媳妇
assign Y = ((a>b) && (c>d))? 1’b0 : 1’b1 ;
逻辑或 || 用法:
//当a>b或者c>d成立,将1’b0赋值给Y, 否则(这2个条件都不成立)将1’b1赋值给Y, 例如,有车 || 有房 才能找到媳妇
assign Y = ((a>b) || (c>d))? 1’b0 : 1’b1 ;
逻辑非 !的用法
//当a<b不成立的时候,将1’b1赋给Y, 否则将1’b0赋给Y
// !(银行卡里低于5000) 等价于 (余额大于等于5000)
assign Y = (!(a<b)) ? 1’b1 : 1’b0;
移位运算符
在Verilog HDL中有2种移位运算符, 左移运算符 << , 右移运算符 >> ,其使用方法如下:
a >> n //表示将变量a右移n位
a <<n //表示将变量a左移n位
代码示例:
若A = 4’b0010, 变量A的值换算成十进制为4’d2。 Y的位宽为4,
Y = (A<<1); //此时Y的值为4’b0100, 此时Y的值换算成十进制为4’d4
Y = (A<<2);//此时Y的值为4’b1000, 此时Y的值换算成十进制为4’d8
Y = (A<<3);//此时Y的值为4’b0000, 此时Y的值换算成十进制为4’d0,如果将Y的位宽改成8位,则此时Y的值为8’d16
Y = (A>>1); //此时Y的值为4’b0001,此时Y的值换算成十进制为4’d1
结论:
- 左移1位,结果是原来的2倍
- 左移2位,结果是原来的2*2倍,
- 左移3位,结果是原来的2*2*2倍,以此类推。
- 在编写程序的时候如果需要将1个数乘以2倍,4倍,8倍...。可以使用移位运算符(左移运算符);如果需要将1个数除以2倍,4倍,8倍...。可以使用右移运算符
- 注意移位后的结果需要使用位宽足够的变量来表示
拼接运算符
在Verilog HDL语言中有1个特殊的运算符:位拼接运算符 {} ,用这个运算符可以把两个或者是多个信号的某些位拼接起来进行运算操作。其使用方法如下:
{信号1的某几位,信号2的某几位,..., ..., 信号n的某几位}
即把某些信号的某些位详细地列出来,中间必须用逗号分开,最后用大括号括起来表示1个整体信号。