硬件描述语言(Hardware Description Languages,HDL)
基本设计单元:模块
1.数值表示
1 | //数值信号 |
2.数据(变量)类型
(1)线网型
1 | //注:矢量表示即[range]默认[MSB:LSB]即[高位:低位] |
(2)寄存器型
1 | //寄存器型 |
3.操作符
(1)单目操作
单目操作符对数字的二进制形式进行逐位操作得到单比特结果
(2)算术操作
- 将负数赋值给 reg 或其他无符号变量使用二进制补码;
- 如果操作数的某一位是x或z ,则结果为x;
- 在整数除法中,余数舍弃;
- 模运算中使用第一个操作数的符号。
(3)逻辑操作
- 逻辑与&&
- 逻辑或||
- 逻辑非!
其得到的结果为逻辑数值0,1,x。分别表示假,真,未定。对于非零操作数,等同于逻辑真,为零的操作数,等同于逻辑假。操作数中任意一位为x,z,其等同于逻辑不确定x。
(4)关系操作
(5)等价操作
(6)移位操作
(7)条件操作
< condition >?< true >:< false >;
(8)拼接操作
1 | reg a,b; |
注:操作符优先级
4.赋值方式
(1)连续赋值
1 | //显式连续赋值: |
- 连续赋值通过关键字”assign”声明,其中,net_name必须是一个标量或线网型向量,不可为寄存器型。
- assign赋值可以视为电路中左侧赋值目标与右侧赋值表达式直接相连,左侧赋值目标实时随右侧赋值表达式变化而变化(即连续赋值语句总处于激活状态)。故一个被连续赋值后的赋值目标不可被再次连续赋值。(如果同一赋值目标被两次连续赋值,可以认为两个赋值表达式在电路中直接相连,可能会引发无法预料的错误)
(2)过程赋值
过程赋值语句的左值可以是以下类型之一:
- reg、整形数、实型数、时间寄存器变量或存储器单元
- 上述各种类型的位选(例如:addr[3])
- 上述各种类型的域选(例如:addr[31:16])
- 上面三种类型的拼接
过程赋值语句只能在initial或always语句内进行赋值,只能对变量数据类型赋值,同时initial和always中只能使用过程赋值语句。
阻塞赋值 =
阻塞赋值语句顺序执行,变量赋值在语句执行后实现改变,语句执行一次后不会持续执行,直到下一次进行改变。
1 | //begin...end为一个块语句 |
- 非阻塞赋值 <=
同一块语句中,非阻塞赋值语句在块结束时并行执行,同时进行赋值。
1 | //非阻塞赋值 |
所以非阻塞赋值可以实现如下操作:
1 | always @(posedge clk) begin |
2 个 always 块中语句并行执行,赋值操作右端操作数使用的是上一个时钟周期的旧值,达到交换寄存器值的目的。