基于SparkRoad的《Verilog数字系统设计教程·第三版(夏宇闻)》学习(15)——第14章

学习:

  1. 阻塞赋值与非阻塞赋值——P 196
    1. 非阻塞赋值只能用于寄存器类型变量进行赋值,因此只能用在 initial 块和 always 块中
    2. 非阻塞赋值允许其他 Verilog 语句同时操作,可以看做两个过程
      1. 在赋值开始时刻,计算非阻塞赋值 RHS 表达式
      2. 在赋值结束时刻,更新非阻塞赋值 LHS 表达式
    3. 阻塞赋值的执行可以认为是只有一个步骤的操作,即计算 RHS(计算等号右手方向部分的值) 并更新 LHS,此时不允许有任何其他 Verilog 语句的干扰
    4. 如果在一个过程块中,阻塞赋值的 RHS 变量正好是另一个过程块中 LHS 的变量,且两者又同时受一个时钟信号触发,则此时赋值会出现问题,产生竞争——例子可见 P 195 例 14.1
  2. 避免竞争冒险的赋值使用——P 197
    1. 时序电路建模,用非阻塞赋值
    2. 锁存器电路建模,用非阻塞赋值
    3. 用 always 块建立组合逻辑模型时,用阻塞赋值
    4. 在同一个 always 块中建立时序和组合逻辑电路时,用非阻塞赋值
    5. 在同一个 always 块中不要既用阻塞赋值又用非阻塞赋值
    6. 不要在一个以上的 always 块中为同一个变量赋值
    7. \(stobe 系统任务来显示用非阻塞赋值的变量值 [(33条消息) verilog系统任务——\)display,\(write,\)strobe,\(monitor,\)stop,\(finish_\)display 二进制_Tiger-Li的博客-CSDN博客](https://blog.csdn.net/kebu12345678/article/details/81413150#:~:text=探测任务的语法和显示任务完全相同,也是把信息显示出来。,也有%24strobe%2C%24strobeb%2C%24strobeo%2C%24strobeh四种。 两者的区别在于:%24strobe命令会在当前时间部结束时完成;而%24display是只要仿真器看到就会立即执行。)
      \(display()系统任务来显示当前变量的值。 用\)strobe()系统任务来显示用非阻塞赋值的变量值。
      用$monitor()监控和输出参数列表中的表达式或变量值。
    8. 在赋值时不要使用# 0 延迟
  3. 使用非阻塞赋值实现统一时序逻辑较为简单,非阻塞赋值可以保证仿真和综合的结果都是一致和正确的
  4. 时序反馈移位寄存器(LFSR)——P 205
    线性反馈移位寄存器(Linear Feedback Shift-Register,LFSR)是带反馈回路的时序逻辑
  5. Verilog 语法并没有禁止将阻塞和非阻塞赋值自由地组合在一起 always 块中(但是不建议使用)
  6. 在一个 always 块中同时出现阻塞和非阻塞赋值,使用非阻塞赋值
  7. 严禁在多个 always 块中对同一个变量赋值(会如上述,产生竞争)
  8. 常见的对于非阻塞赋值的误解
    1. 非阻塞赋值和$display
      1. 非阻塞语句的赋值在所有的$display 命令执行以后才更新数据——P 210
      2. $display $ monitor \(strobe [(33条消息) verilog 系统任务——\) display, \(write,\) strobe, \(monitor,\) stop, \(finish_\) display 二进制_Tiger-Li 的博客-CSDN 博客]( https://blog.csdn.net/kebu12345678/article/details/81413150 )
    2. #0 延时赋值
      1. #0 延时将赋值事件强制加入停止运行时间队列中——P 210
      2. 在赋值时,不要使用 #0 延迟
      3. 为了描述没有定义延迟的电路信号发生先后顺序,verilog HDL里面引入了0延迟的概念,如果写了#0就称之为显性0延迟,如果什么都没写则为隐性0延迟不可忽视的verilog零延迟 (IC君给您拜年) - 知乎 (zhihu.com)
    3. 用$strobe 来显示应该用非阻塞赋值的变量值
    4. 在同一 always 块中对同一变量多次赋值,最后一个非阻塞赋值决定了变量的值

思考题:

  1. 用带电平敏感列表触发条件的 always 块表示组合逻辑时,应该用哪一种赋值?
    阻塞赋值
  2. 用带时钟沿触发条件的 always 块表示时序电路时,应该用哪一种赋值?
    应该用非阻塞赋值
  3. 为什么不能在多个 always 块中为同一变量赋值?
    多个always块中为同一个变量赋值可能会导致竞争冒险即使使用非阻塞赋值也可能产生竞争冒险。
  4. 为什么不能用$ display 系统任务来显示用非阻塞赋值的变量值?
    因为非阻塞语句的赋值在所有的Sdisplay 命令执行以后才更新数据。
  5. $ strobe 和 $ display 这两个显示用系统任务有什么不同?各用于什么场合?6.仿真器在处理阻塞和非阻塞赋值操作队列过程中有什么不同?
    $display命令的执行是安排在活动事件队列中,但排在非阻赋值赋值数据更新事件之前: $strobe命令的执行是排在非阻塞赋值数据更新事件之后。 $display适合用来显示阻塞语句的赋值, $strobe适合用来显示非阻塞语句的赋值。
  6. 为什么在可综合 Verilog 模块的设计中,必须注意并遵守本章的8条原则?
    因为遵循本章的8条原则有助于正确的编写可综合硬件,并且可以消除90%~100%在仿真时可能产生的竞争冒险现象。
  7. 仿真器在处理阻塞和非阻塞赋值操作队列过程中有什么不同?
    阻塞赋值是一个一个排队执行;非阻塞赋值允许其他语句同时执行
posted @ 2023-06-05 16:45  江左子固  阅读(45)  评论(0编辑  收藏  举报