4.7 过程性赋值语句

引言

1. 过程性赋值语句是行为建模中使用的赋值语句,包括阻塞式赋值非阻塞式赋值,这两种都必须出现在 initial结构和 always结构中。

2. 建立可综合模型时,赋值语句的左端必须是 reg类型。

一、阻塞性赋值语句 “ = ”

1. 在顺序块中(begin...end),一条阻塞赋值语句执行结束后,才能继续执行下一条阻塞赋值语句。

2. 语句执行结束后,左值会立即改变,位于程序前面部分的语句赋值结果可以被后面的语句使用。

二、非阻塞性赋值语句 “ <= ”

1. 同一时间点,前面语句的赋值不能立刻被后面的语句使用。

2. 所有赋值是在一个时间点结束的时候统一完成的。

三、区分阻塞和非阻塞赋值

1. 阻塞和非阻塞代码

(1) 阻塞:

initial begin
  a=0;
  b=1;
  c={a,b};
  d={b,a};
end

处理方式:四条语句依次执行,没一条语句执行结束后才能执行下一条语句。这样,当 c 的赋值语句执行时, a ,b 已经有了值,d 同理。

(2) 非阻塞:

initial begin
  a<=0;
  b<=1;
  c<={a,b};
  d<={b,a};
end

处理方式:先把各个赋值式右侧的计算值,储存在不同的临时变量中,在仿真某个时间点结束的时候统一把这些临时变量的值赋给左侧。

2. 执行时的具体事件

(1)非阻塞式赋值,仿真器会看到如下事件。

① 仿真零时刻,按照顺序块的语法要求,看到 a<=0 这句代码。仿真器会把右侧的值赋值到某个临时寄存器中,而不会直接赋值。由于赋值语句的右侧仅有一个数值,不涉及计算,没有运算的过程,仅消耗把 0 赋值到中间寄存器的时间,然后第一个事件结束了。注意此时 a 并未得到赋值。
② 依然在仿真的零时刻,仿真器看到了 b<=1 这句代码。和①类似,仿真器会把 1 值赋给某个临时寄存器,赋值结束后,第二个事件结束, b 也未得到赋值。
③ 依然在仿真的零时刻,仿真器看到了 c<={a,b} 这句代码,类似地,会把 {a,b} 赋值给某个临时寄存器,但注意,此时a、b在前面都没有得到赋值,即没有得到新的值,所以c得到的是a、b的旧值,这就是在非阻塞赋值中,前面语句的赋值不能立刻被后面的语句使用的原因。第三个事件结束时 c 也没有得到新的值。
④ 本步骤也在零时刻,仿真器看到 d<={b,a},和③做类似的操作,赋值给某个临时寄存器,这些寄存器由仿真器维持,不在设计者的思考范围之内。
⑤ 仿真器发现在仿真零时刻所有需要做的事情都处理了(即已经看到了所有要在仿真零时刻执行的语句),此时仿真器要结束此仿真时间点,于是把前面所有临时寄存器中的值赋到赋值式的左侧,此时a、b、c、d得到了赋值。
⑥ 仿真零时刻结束,仿真器沿时间轴继续运行,进入下一个仿真时间点。

(2)阻塞式赋值,仿真器会看到如下事件。

① 仿真零时刻,仿真器看到a=0,由于是阻塞赋值,仿真器立刻会执行改行语句,并把0值赋给a,第一个事件结束,此时a已经得到了新的值。
② 仿真零时刻,仿真器继续运行,看到 b=1,立刻把 1 赋给 b ,第二个事件结束, b 也得到了新的值。
③ 仿真零时刻,仿真器看到了c={a,b}这句代码,立刻将a、b值作拼接操作并送至c,这样第三个事件也结束了,c此时得到的值是a、b刚刚更新的值,注意对比与非阻塞赋值第三步的区别。
④ 仿真零时刻,同③一样,把b、a的拼接值赋给d,d也得到了赋值,第四步结束。
⑤ 仿真器发现仿真零时刻待执行的语句都已经执行完毕,仿真零时刻结束,仿真器沿时间轴继续运行,进入下一个仿真时间点。

(3)总结

  • 阻塞赋值在其动作特点上更像是组合逻辑电路的行为:当前的赋值必须立刻完成,更新信号值后再被后续的语句使用;
  • 非阻塞赋值在其动作特点上更像是时序电路的行为:当前的赋值暂不更新,等待某一个时刻同时完成信号值的更新。所以在阻塞赋值和非阻塞赋值的选择上有着如下比较统一的指导原则。
    (1)组合逻辑电路 使用 阻塞赋值 来建模。
    (2)时序逻辑电路 使用 非阻塞赋值 来建模。
posted @   烤冷面多加醋  阅读(280)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示