过程块
- always过程块
模板:
1 | always @(<敏感信号表达式>) |
当敏感信号表达式的值改变时候,就执行一遍块内语句。同时always过程块是不能够嵌套使用的。
关键字posedge
与negedge
关键字分别是上升沿以及下降沿
例如:同步时序电路的时钟信号为clk,clear为异步清零信号。敏感信号可写为:
1 | //上升沿触发,高电平清0有效 |
例如当negedge clear
表示当clear==0
时
1 | always @(posedge clk or negedge clear) |
- initial过程块
initial模板:
1 | initial |
对变量和存贮器初始化
1 | initial |
initial语句主要面向功能模拟,通常不具有可综合性。
模拟0时刻开始执行,只执行一次
同一模块内的多个initial过程块,模拟0时刻开始并行执行。
initial与always语句一样,是不能嵌套使用的。即在initial语句中不能再次嵌套initial语句块。
连续赋值
用连续赋值语句表达的是: assign val=newval;
任何一个输入的改变都将立即导致输出更新;
1 | module orand(out,a,b,c,d,e); |
过程赋值语句
过程赋值语句常用于对reg变量进行赋值。一般分为两种,阻塞赋值与非阻塞赋值
阻塞与非阻塞赋值
赋值的类型选择取决于建模的逻辑类型。
在时序块的RTL代码中使用非阻塞赋值
<=
。非阻塞赋值在块结束后才完成赋值操作。此赋值方式可以避免在仿真出现魔仙和竞争现象。在组合的RTL代码中使用阻塞赋值
=
。使用阻塞赋值方式对一个变量进行赋值时,此变量的值在赋值语句执行完后才能之后就立即改变。
compare
使用非阻塞赋值方式进行赋值时,各个赋值语句同步执行;因此通常在一个时钟沿对临时变量进行赋值,而在另一个时钟沿对其进行采样。因为在相同的时钟沿采样赋值,采样的还是原来的值,赋值操作是在块结束时进行。
- 阻塞赋值
下面模块会综合成为触发器
1 | module block(clk,a,b); |
- 非阻塞赋值
下面的模块会综合成两个触发器
1 | module block(clk,a,b); |
上图左侧是阻塞赋值的综合结果,右侧则为非阻塞赋值。相比左侧,右侧的例子会造成一个时钟周期的延迟。