03-Verilog基础_2
Verilog语法
1 Register
组合逻辑-->寄存器-->组合逻辑-->寄存器
Register是一个变量,用于存储值,并不代表一个真正的硬件DFF。
reg A,C;
// assignments are always done inside a procedure
A = 1;
C = A; //C gets the logical value 1
A = 0; //C is still 1
C = 0; //C is now 0
2 Vectors--矢量
- Represent buses
wire [3:0] busA;
reg [1:4] busB;
reg [1:0] busC;
- Left number is MS bit--左侧的数值是最高位
- Slice management
/*
busA位宽为4,表示4根线0,1,2,3
busA[2:1] 表示选择其中的第2和第3根,分别为1,2
busC=busA[2,1] 相当于 [1:0]连接到[1,2] 1与0相连,2与1相连
*/
busC = busA[2:1]
- Vector assignment (by position!)
busB = busA
/*
1 最高位 3
2 2
3 1
4 最低位 0
最高位连最高位
最低位连最低位
*/
3 Integer & Real Data Types
integer i,k;
real r;
- Use as a register(in procedure)
i = 1; // assignments occur inside procedure
r = 2.9;
k = r; // k is rounded to 3
- Integers are not initialized!--Integer是没有初始值的
- Reals are initialized to 0,0!--Real初始值为0,0
4 Time Date Type
- Special data type for simulation time measuring
- Declaration
time my_time;
- use inside procedure
//使用一个内置的系统函数
my_time=$time // get current sim time 返回当前仿真的时间
- Simulation runs at simulation time,not real time
5 Arrays
- Syntax
//类型 数组名[start:end]
integer count[1:5];// 5 integers
reg var[-15:16]; // 32 1-bit regs
reg [7:0] mem[0:1023]; //1024 8-bit regs //memory 有1024个位置,每个位置放8位数据
- Accessing array elements
- Entire element:
//mem[index] 索引
mem[10]= 8‘b10101010
- Element subfield(needs temp storage)
reg [7:0] temp;
..
temp = mem[10];
var[6] = temp[2]; //mem[10][2]
- Limitation:Cannot access array subfield or entire array at once
var[2:9] = ??? //wrong 数组的2-9,不能进行切片赋值
- 数组是不允许进行切片赋值的
- vector是可以进行切片赋值的
- 没有多维数组,前面只是类似多维数组
reg ver[1:10] [1:100]; // wrong
- Arrays don't work for the Real data type
real r[1:10]; //wrong 不能用于Real类型
6 String
- Implemented with regs:
//一般8位存储一个字符
reg [8*13:1] string_val;// can hold up to 13 chars..
string_val = "Hello World";
string_val = "Hello"; //MS Bytes are filled with 0
string_val = "I am overflowed"; //超过存储空间会被截断,显示不全,存储的时候从低位开始存储,I显示不出来
- Escaped chars:
- \n--换行
- \t--tab键
- \--\
- \'--\'
- %%--%
7 Logical Operators--逻辑运算符
- &&--AND
- ||--OR
- !-NOF
- Result is one bit value:0,1 or x
A = 6; //非零数字表示真,1
B = 0;
C = x;
A && B //0
A || B //1
C || B //x
C && B //0
8 Bitwise Operators
按位操作
- &--按位与
- |--按位或
- ~--按位取反
- ^--按位异或
- ~^ or ^~ --按位同或 异或取反就是同或
a = 4'b1010
b = 4'b1100
c = a ^ b = 0110
d = ~a = 0101
9 Reduction Operator
递减操作符(Reduction Operators)为一目运算符,后面跟一变量,如“&C”表示将C的第一位与第二位相与,再将结果与第三位相与,再与第四位.......一直到最后一位。
递减操作运算符 | 含义 |
---|---|
& | AND |
| | OR |
^ | XOR |
~& | NAND |
~ | NOR |
~^ or^~ | XNOR |
a = 4'b1001;
c = |a ; // 1001-->10得1,10得1,11得1
- 单目运算符,满足多位输入,单位输出
对异或(^)运算的补充
异或运算符满足交换律与结合律
- 一组二进制数据进行异或操作,有奇数个1时,结果为1,有偶数个1时,结果为0。
一个无规律的二进制数据异或:
A = 1001010001110......0101001。
^A则可表示为: ^1001010001110......0101001 = 1^0^0^1^0......0^1^1^1^0
=(1^1^1...^1^1)^(0^0^0...^0^0)
= (1^1^1...^1^1)^0
- 当有奇数个1时,上式等价为1^0=1,当有偶数个1时,上式等价为0^0=0。
10 Shift Operator
- >>--shift right
- <<--shift left
在移位过程中如果位数不够,用0进行填充
a = 4'b1010
d = a >> 2 //d=0010
c = a << 1 //c=0100
11 Concatenation Operator(拼接操作符)
- {op1,op2},花括号中写两个变量,中间中逗号隔开,拼接之后变为一个vector
reg a;
reg [2:0] b,c;
a = 1'b 1;
b = 3'b 010;
c = 3'b 101;
catx = {a,b,c}; //catx = 1_010_101
caty = {b,2'b11,a};//010_11_1
catx = {b,1}; //wrong ,1可能是十进制的,在使用的时候必须指定size
//可以使用倍数
catr = {4{a}, b, 2{c}}; // catr = 1111_010_101101
12 Relational Operators(比较运算符)
- > 大于
- < 小于
- >= 大于等于
- <= 小于等于
结果有三种情况:0,1,x,比较的项中有x或z,结果就是x
1>0 结果1
'b1x1 <=0 结果x
10<z 结果x
等号操作符
- == 相等
- != 不等于
- === 用于判断由x和z的情况
- !== 用于判断有x和z的情况
4'b 1z0x == 4'b 1z0x x ==有x或z,就会返回x
4'b 1z0x != 4'b 1z0x x !=有x或z,就会返回x
4'b 1z0x === 4'b 1z0x 1 === 有x或z,只要两边相等就会返回1
4'b 1z0x !== 4'b 1z0x 0 === 有x或z,只要两边不相等就会返回0
13 Conditional Operator(三目运算符)
- 条件表达式?A:B
- 条件表达式成立返回A,条件表达式不成立返回B
- 可以用于建立二选一mux
14 Arithmetic Operators(i) (算术运算符)
- +,-,*,/,%
- 有x,结果为x
- Negtive Register,reg数据类型是可以用负数赋值,但是被当作是一个无符号数
- reg可以被认为是无符号数,存储有符号数就不是被赋值的原始值了
reg [15:0] regA;
reg A = -4b'd12; //存储的值是 2^16-12=65524
regA/2 值是21861
- Negtive Integer:
- 整数类型是可以被赋负值的,支持无符号数
- integer是32位位宽的
reg [15:0] regA;
integer intA;;
intA = -12/3; //-4
intA = -d'12/3; //结果为1431655761
整数的表达方法
- 一个无位宽(size)、无基数(base)的整数(例如:12,默认32bit)
- 一个无位宽、有基数的整数(例如:'d12、'sd12,默认32bit)
- 一个有位宽、有基数的整数(例如:16’d12、16’sd12,16bit)
integer IntA;
IntA = -12 / 3; // The result is -4. -12为32bit有符号负数,3为32bit有符号正数
IntA = -’d 12 / 3; // The result is 1431655761. -’d 12为32bit无符号数,3为32bit有符号正数
IntA = -’sd 12 / 3; // The result is -4. -’sd12为32bit有符号负数,3为32bit有符号正数
IntA = -4'sd 12 / 3; // The result is 1. -4’sd12为4bit有符号正数4,3为32bit有符号正数
此示例展示了verilog的四种书写表达式“负12 除以 3”的方式。我们要特别注意:-12 和 -'d12 虽然都是以相同的二进制补码的形式表示,但是在verilog表达式中,-'d12 被认为是无符号数,而-12被认为是有符号数。
总结:没有基数base说明符的整数的负值应与具有基数说明符的整数的含义不同,没有基数说明符的整数应看作是有符号数,而带有无符号基数说明符的整数应看作为无符号数。
14操作符优先级
- 搞不清楚优先级,加括号
Hierachical Design
- Top module中可以有很多小的module,再嵌套小的module....
- 通过点操作符,可以找到module中的变量 Top.sub1.sub2.a-->找到模块中的a
15.补充知识点
15.1 移位运算符
- 移位运算符是以二进制为基准进行运算的
a = 0011;
b = a << 2;
- 算数右移和逻辑右移
// 逻辑右移补0
a = 4'b1100;
b = a >> 2; // b = 0011
// 算数右移,补符号位
a = $signed(4'b1100);
b = $sigend(a) >> 2;
b = 1111;// 符号位进行扩展
无符号数逻辑右移,有符号数补码算数右移
15.2 比较运算符
- ==和!= 是逻辑相等或者不等,两边的数值中有x就返回x
- != 是用异或门搭建的,两边有x一定返回x
- === 和!==,两边值中的0,1,x,z都参与比较,按位进行比较,x和z当作是值进行比较
- ?和!通配符条件等,通配符条件不等,仅将右侧的值中的x和z当作是统配符号
A:010z
B:0101
A ==? B // x,左侧有z不能匹配值
B ==? B //1'b1 右侧有z,可以通配0,1
- 1'bx在if语句中是false
15.3 自定义数据类型
typedef bit [3:0] uint;
typedef logic [3:0] vec;
vec a;
vec b;
15.4 数据类型转换
logic signed [31:0] a;// 有符号
logic [31:0] b; // 无符号
logic [31:0] c;
assign c = a * b; // 有符号数 * 无符号数,数据类型不匹配
assign c = unsigned(a) * b;
15.5 动态数组
bit [7:0] payload []; // 不写长度,就是动态数组,size可以扩展
int temp = $random;
payload = new [(temp%3)+2]; // 0-4 size的数组
payload = new [uint(temp%3)+2];//长度为(2,3,4)的数组
15.6 循环变量
int i=0;
for(int i=0;i<10;i++) // 和 外部定义的i不同
for(int i=0;i<10;i++) // 局部变量,循环结束消亡,不会影响全局变量
15.7 casez和casex
- case语句从上向下执行
- case语句进行全等判断0,1,x,z
- casez:不关心匹配之中z的值
sel = 4'b1100;
casez(sel)
4'bzz00:data = 4'b1;// 成立
endcase
- casex不关心匹配值中的x和z的值
15.8一些语句
wait(expr) ....等到时间成立执行后面的语句
- return - 结束task和function,从而结束循环
- repeat (循环次数) begin ... end
- foreach(表达式) begin... end