你真的懂Verilog吗?
来源:内容来自「知乎」,作者:王君实,谢谢 。
要想深入理解Verilog就必须正视Verilog语言同时具备硬件特性和软件特性。在当下的教学过程中,教师和教材都过于强调Verilog语言的硬件特性和可综合特性。将Verilog语言的行为级语法只作为语法设定来介绍,忽略了Verilog语言的软件特性和仿真特性。使得初学者无法理解Verilog语言在行为级语法(过程块、赋值和延迟)背后隐藏的设计思想。本文尝试从仿真器的角度对Verilog语言的语法规则进行一番解读。
“精分”的Verilog语言
-
综合工具读入源文件,通过综合算法将设计转化为网表,比如DC。能够综合的特性要求Verilog语言能够描述信号的各种状态(0,1,x,z)、信号和模块的连接(例化)以及模块的逻辑(赋值以及各种运算符)。 -
仿真器读入源文件,生成一个可执行程序用于仿真硬件的行为,比如VCS。 能够仿真的特性要求Verilog语言又具有软件特性,对每一条语句的执行语义和顺序给出定义(延迟语句)。同时,软件特性使得Verilog语言更加灵活,具备了丰富的行为级仿真能力(条件分支、循环等)。
仿真器基本架构
过程块
always @ (posedge clk) begin
q <= d;
end
经过仿真器的转换就变成为如下的响应函数:
function always_block1 :
q = d;
赋值语句
a = b; // 阻塞赋值
a <= b; // 非阻塞赋值
always @(a, b, c) begin : add_mux1
t = a + b;
d = t * c;
end
上述代码转化后的事件响应函数为
function add_mux1 :
t = a + b;
d = t * c;
always @(a, b, c) begin : add_mux2
t <= a + b;
d <= t * c;
end
上述代码转化后的事件响应函数为
function add_mux2 :
t_update = a + b;
d_update = t * c;
t = t_update;
d = d_update;
当阻塞赋值和非阻塞赋值混合的时候,也遵循同样的规则。例如
always @(a, b, c) begin : add_mux3
t <= a + b;
d = t * c;
end
上述代码转化后的事件响应函数为
function add_mux3 :
t_update = a + b;
d = t * c;
t = t_update;
延迟行为
#3 a = b; //延迟语句在赋值语句之间
a = #3 b; //延迟语句在赋值语句内部
always @(a, b, c) begin : add_mux4
t <= a + b;
#1 d = t * c;
end
上述代码转化后的事件响应函数为
function add_mux4_1 :
t_update = a + b;
t = t_update;
addEvent( curr_time + 1, add_mux4_2 );
function add_mux4_2 :
d = t * c;
Verilog文件中的1个过程块被转换为两个函数。第一个函数
add_mux4_1
对应于延迟语句之前的部分,第二个函数
add_mux4_2
对应于延迟语句之后的部分。
add_event
是本文定义的一个原语,表示向事件队列中添加一个事件。第一个参数表示事件响应的时间,第二个参数表示响应事件需要调用的事件响应函数。从第三个参数开始,之后的参数会作为事件响应函数的参数,传递给事件响应函数。
add_event( curr_time + 1,
add_mux4_2
)
表示在当前时间(
curr_time
)后1个时间单位的时候响应这个事件。事件需要调用
add_mux4_2
函数。响应函数不需要额外的参数。在调用
add_mux4_2
时,信号t已经完成更新。
在赋值语句中间的延迟语句将评估和更新阶段分割到两个时刻进行。评估过程仍然在语句执行的时候进行,但是更新过程延后到延迟语句指定的时刻进行。延迟语句是否阻塞过程块的执行,取决于赋值语句本身。如果是阻塞赋值语句,赋值语句中间的延迟语句会阻塞过程块的执行;如果是非阻塞赋值,延迟语句不会阻塞过程块的执行。例如
always @(a, b, c) begin : add_mux5
t <= #1 a + b;
d = #2 t * c;
end
上述代码转化后的事件响应函数为
function add_mux5_1:
t_update = a + b; // 1
d_update = t * c; // 2
addEvent( curr_time + 1, update_t, t_update );
addEvent( curr_time + 2, add_mux5_2, d_update );
function update_t( t_update ) :
t = t_update; // 3
function add_mux5_2( d_update ) :
d = d_update; // 4
update_t
。
t_update
作为事件响应函数的参数,在
update_t
中更新给信号t。由于第二个语句中的延迟语句,过程块被打断为两个部分,第二个函数需要在当前时刻之后2个时间单位时执行,即
add_mux5_2
。
add_mux5_2
需要使用
d_update
作为参数。
module test;
reg x,y,z;
assign #25 a = 1;
always begin
#20;
x = #10 a;
#3 y = a;
#3 z = a;
#7;
end
endmodule
经过仿真器的转换,上面的Verilog语句会形成如下的事件响应函数。
function assign1 :
a = 1;
function always1_1 :
addEvent( curr_time + 20, always1_2 );
function always1_2 :
x_update = a;
addEvent( curr_time + 10, always1_3, x_update );
function always1_3( x_update ) :
x = x_update;
addEvent( curr_time + 3, always1_4 );
function always1_4 :
y = a;
addEvent( curr_time + 3, always1_5 );
function always1_5 :
z = a;
addEvent( curr_time + 7, always1_6 );
function always1_6 :
addEvent( curr_time + delta, always1_1 );
在仿真开始时候,首先向事件队列中添加两个事件,分别是在0+25时刻调用
assign1
,以及在0+0时刻调用
always1_1
。事件响应过程如图4所示。always过程块被延迟语句分割成了6个响应函数。每个部分都向事件队列添加能够触发下一个响应函数的事件。信号
x
的第1次评估发生在20时刻,而第1次更新发生在30时刻,所以信号x的第一次赋值仍为
X
。直到第2次评估时(63时刻)才能获得有效的信号
1
,并且在73时刻更新给信号x。
需要说明的是,虽然本文提供了一种思路能够比较轻松地理解行为级描述的执行过程,但是仍然不建议大家在过程块中混用阻塞赋值和非阻塞赋值。混用赋值语句是危险的。
Assign赋值
前面介绍的侧重于过程块。对于Assign赋值语句,原理其实是也一样的。例如
assign a = #5 b & c;
这条assign语句同样可以看做一个事件响应函数。这个函数绑定的事件是信号
b
或信号
c
发生变化。延迟语句的效果也是一样的。延迟语句将评估和更新过程分开。当信号
b
或信号
c
发生变化时进行评估,并在事件队列中添加一个新的更新事件。5个时间单位之后,响应更新事件,将评估的值更新给信号
a
。
转换后的事件响应函数如下。
function assign1:
a_update = b & c;
addEvent( curr_time + 5, update_a, a_update );
function update_a( a_update ) :
a = a_update;
调试
结语
作者简介
*免责声明:本文由作者原创。文章内容系作者个人观点,半导体行业观察转载仅为了传达一种不同的观点,不代表半导体行业观察对该观点赞同或支持,如果有任何异议,欢迎联系半导体行业观察。
今天是《半导体行业观察》为您分享的第2113期内容,欢迎关注。
推荐阅读
★ 英特尔的存储野心
★ 江苏芯片发展历程
半导体行业观察
『 半导体第一垂直媒体 』
实时 专业 原创 深度
识别二维码 ,回复下方关键词,阅读更多
AI| 射频 |中国芯 |谷歌量子|CMOS |华为 | 集成电路 | 德州仪器
回复
投稿
,看《如何成为“半导体行业观察”的一员 》
回复 搜索 ,还能轻松找到其他你感兴趣的文章!
- 半导体行业观察
- 摩尔芯闻
最新新闻
热门文章 本日 七天 本月
- 1 进迭时空完成A+轮数亿元融资 加速RISC-V AI CPU产品迭代
- 2 探索智慧实践,洞见AI未来!星宸科技2024开发者大会暨产品发布会成功举办
- 3 MediaTek 发布天玑 8400 移动芯片,开启高阶智能手机全大核计算时代
- 4 DAC 61周年 | 日观芯设携一站式数字后端签核平台重磅亮相