首页 > 其他分享 >FPGA 第12讲 阻塞赋值和非阻塞赋值

FPGA 第12讲 阻塞赋值和非阻塞赋值

时间:2024-11-22 13:46:43浏览次数:3  
标签:语句 12 always 阻塞 sys reg 赋值

时间:2024.11.19

一、学习内容

1.阻塞赋值

      阻塞赋值的赋值号用“=”表示。

      对应的电路结构往往与触发沿没有关系,只与输入电平的变化有关系。阻塞赋值的操作可以认为是只有一个步骤的操作,即计算赋值号右边的语句并更新赋值号左边的语句,此时不允许有来自任何其他 Verilog 语句的干扰,直到现行的赋值完成时刻,即把当前赋值号右边的值赋值给左边的时刻完成后,它才允许下一条的赋值语句的执行。

      串行块(begin-end)中的各条阻塞型过程赋值语句将以它们在顺序块后的排列次序依次执行。(顺序执行)    

        阻塞型过程赋值语句的执行过程是:首先计算赋值号右边的值,然后立即将计算结果赋值给左边,赋值语句结束,变量值立即发生改变。

      阻塞的概念是指在同一个 always 块中,其后面的赋值语句从概念上是在前一句赋值语句结束后再开始下面的赋值。

2.非阻塞赋值

非阻塞赋值的赋值号用“<=”表示。

      对应的电路结构往往与触发沿有关系,只有在触发沿的时刻才能进行非阻塞赋值。非阻塞操作开始时计算非阻塞赋值符的赋值号右边的语句,赋值操作结束时刻才更新赋值号左边的语句,可以认为是两个步骤(赋值开始时刻和结束时刻)来完成非阻塞赋值。在计算非阻塞语句赋值号右边的语句和更新赋值号左边的语句期间,其他的 Verilog 语句包括其他的 Verilog 非阻塞赋值语句都能同时计算赋值号右边的语句和更新赋值号左边的语句,允许其他的 Verilog 语句同时进行操作。

      非阻塞赋值的操作可以看作为两个步骤的过程:在赋值开始时刻,计算赋值号右边的语句。在赋值结束时刻,更新赋值号左边的语句。(并列执行)

注意:

非阻塞操作只能用于对寄存器类型变量进行赋值,因此只能用于“initial”和“always”块中,不允许用于连续赋值“assign”。

3.总结

阻塞赋值(=):该语句结束时就完成赋值操作,前面的语句没有完成前,后面的语句是不能执行的。在一个过程块内多个阻塞赋值语句是顺序执行的。
非阻塞赋值(<=):一条非阻塞赋值语句的执行是不会阻塞下一条语句的执行,也就是说在本条非阻塞赋值语句执行完毕前,下一条语句也可开始执行。非阻塞赋值语句在过程块结束时才完成赋值操作。在一个过程块内的多个非阻塞赋值语句是并行执行的。

二、实验

1.准备工作

建立文件夹存放工程

2.绘制波形图和模块框图

模块框图

波形图

3.编写代码-阻塞赋值

module blocking
(
input  wire         sys_clk   ,
input  wire         sys_rst_n ,
input  wire   [1:0] in        ,
output reg    [1:0] out

);
//定义中间变量,方便仿真波形的观察
reg  [1:0]  in_reg;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
begin
in_reg = 2'b0;
out    =2'b0;
end
else   //当复位信号无效时,对两个变量进行赋值
begin
in_reg =in;
out    =in_reg;
end
endmodule

4.仿真验证-阻塞赋值

`timescale 1ns/1ns
module  tb_blocking();
reg       sys_clk;
reg       sys_rst_n;
reg  [1:0]     in;
wire  [1:0]    out;
//用initial语句初始化时钟、全局复位信号和输入信号
initial
begin
sys_clk    = 1'b1;
sys_rst_n  <= 1'b0;
in         <= 2'b0;
#20
sys_rst_n  <= 1'b1;
end
//生成模拟时钟
always #10 sys_clk =~sys_clk;
always #20 in <={$random}%2;  //输入信号是两位宽,所以对4取余


//模块实例化
blocking  blocking_inst
(
.sys_clk   (sys_clk),
.sys_rst_n (sys_rst_n),
.in        (in),
.out       (out)

);
endmodule

5.打印结果-阻塞赋值

6.波形图-阻塞赋值

7.编写代码-非阻塞赋值

module blocking
(
input  wire         sys_clk   ,
input  wire         sys_rst_n ,
input  wire   [1:0] in        ,
output reg    [1:0] out

);
//定义中间变量,方便仿真波形的观察
reg  [1:0]  in_reg;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
begin
in_reg = 2'b0;
out    =2'b0;
end
else   //当复位信号无效时,对两个变量进行赋值
begin
in_reg <=in;
out    <=in_reg;
end
endmodule

 

8.仿真验证-非阻塞赋值

`timescale 1ns/1ns
module  tb_blocking();
reg       sys_clk;
reg       sys_rst_n;
reg  [1:0]     in;
wire  [1:0]    out;
//用initial语句初始化时钟、全局复位信号和输入信号
initial
begin
sys_clk    = 1'b1;
sys_rst_n  <= 1'b0;
in         <= 2'b0;
#20
sys_rst_n  <= 1'b1;
end
//生成模拟时钟
always #10 sys_clk =~sys_clk;
always #20 in <={$random}%2;  //输入信号是两位宽,所以对4取余


//模块实例化
blocking  blocking_inst
(
.sys_clk   (sys_clk),
.sys_rst_n (sys_rst_n),
.in        (in),
.out       (out)

);
endmodule

 

9.打印结果-非阻塞赋值

10.波形图-非阻塞赋值

四、知识点和小技巧

编写 RTL 代码时推荐的一些规范总结

(1)在编写时序逻辑的代码时采用非阻塞赋值的方式

       计算赋值号右边的信号时,所有的变量值均是触发沿到来前的值,更新的赋值号左边的信号作为触发沿后的值,并且保持到下一个触发沿到来时候,等待更新。这样,就可以使得在同一个块中非阻塞赋值语句不必要求出现的顺序,都是在全部进行赋值号右边的信号计算后同时更新赋值号左边的信号的值。非阻塞赋值可以简单的认为是赋予下一状态的值。


(2)使用 always 块来编写组合逻辑的代码时要用阻塞赋值的方式

        使用 always 块建立组合逻辑电路模型时不要忘记 always 块中的敏感列表一定要使用电平触发的方式,然后在 always 块中使用阻塞赋值语句就可以实现组合逻辑,这样做既简单且方针又快又好,这样的风格是值得推荐的。

(3)在同一个 always 块中不要既要用非阻塞赋值又用阻塞方式赋值

      在同一个 always 块中对同一个变量既进行阻塞赋值又进行非阻塞赋值会产生综合不可预测的结果,不是可综合的 Verilog 风格。


(4)虽然锁存器电路建模是我们不推荐的,但是如果使用到要采用非阻塞赋值的方
式。

使用非阻塞赋值实现时序逻辑,实现锁存器是最为安全的。


(5)一个 always 块只一个变量进行赋值

      因为 always 块是并行的,执行的顺序是随机的,综合时会报多驱动的错误,所以严禁在多个 always 块中对同一个变量赋值;当然也不推荐一个 always 对多个变量进行赋值,虽然这种方式是允许的,但如果过多会导致代码的混乱且不易后期的维护和修改(本例之所以写在一起时因为变量不多,其次是为了进行对比得出本章的实验效果),不是推荐的设计方法。

标签:语句,12,always,阻塞,sys,reg,赋值
From: https://blog.csdn.net/2201_75297369/article/details/143807988

相关文章

  • 20241122电路板维修入门之集成块焊接篇
    在没有热风焊台的情况下,也可考虑用烙铁配合焊锡来拆除或焊接集成块,它的方法是用烙铁在芯片的各个引脚都堆满焊锡,然后用烙铁循环把焊锡加热,直到所有的引脚焊锡都同时熔化,就可以把芯片取下来了。把芯片从电路板上取下来,可以考虑用细铜丝从芯片的引脚下穿过,然后从上面用手提起。......
  • 20241121电路板维修入门之CPU断针焊接篇
    CPU断针的情况很常见,370结构的赛扬一代CPU和P4的CPU针的根部比较结实,断针一般都是从中间折断,比较容易焊接,只要在针和焊盘相对应的地方涂上焊膏,上了焊锡后用烙铁加热就可以焊上了,对于位置特殊,不便用烙铁的情况可以用热风焊台加热。赛扬二代的CPU的针受外力太大时往往连根拔起,且......
  • QT 线程 QThread QT5.12.3环境 C++实现
    一、线程  QT主线程称为GUI线程,负责初始化界面并监听事件循环,并根据事件处理做出界面上的反馈。如果把一些比较复杂或者费时的操作放在主线程中,界面就会出现卡顿或者无响应的现象。一般主线程负责影响界面上的操作,子线程负责负责费时的数据处理。二、使用多线程有什么好......
  • QT基础 编码问题 定时器 事件 绘图事件 QT5.12.3环境 C++实现
    一、编码问题        在计算机编程中,流(Stream)是一种抽象的概念,用于表示数据的输入或输出。根据处理数据的不同方式,流可以分为字节流(ByteStream)和字符流(CharacterStream)两大类。1.字节流(ByteStream)        字节流是处理数据的基本单位是字节(8位二进制数......
  • QT基础 窗体 对话框 文件 QT5.12.3环境 C++实现
    一、堆栈窗体1.概念是一种界面设计思路,多个窗体重叠在一起,通过点击对应的按钮,显示对应的界面。2.相关方法PublicFunctions  QStackedWidget(QWidget*parent=0)  //stack如果单纯指定父窗口,但是没有指定大小,那么是不显示的  intaddWidget(QWidget*......
  • LT1121IST-5#TRPBF 规格书 数据手册具有关断功能的微功率低压差稳压器芯片
    LT1121/LT1121-3.3/LT1121-5是具有关断功能的微功率低压差稳压器。这些设备能够以0.4V的压降提供150mA的输出电流。这些设备设计用于电池供电系统,低静态电流(30µA运行,16µA关断)使其成为理想的选择。静态电流得到良好控制,不会像许多其他低压差PNP稳压器那样在压降时上升。LT1121/L......
  • 20241120>Win10/11 干净安装后一些提升效率的快捷命令CMD小帮手
    重装win? ?一些提升效率的快捷命令CMD小帮手,   如果使用笔记本电脑会有些卡顿,那可能得调整一下电源模式.  用管理员打开cmd或者powershell,输入以下命令行: 卓越性能:   powercfg-duplicateschemee9a42b02-d5df-448d-aa00-03f14749eb61 高性能模式......
  • 1121-括号匹配
    括号匹配题目大意:给出包括大中小括号随机排列的一个Strings,判断是否为左右闭合(左右括号顺序对应)解题思路:利用栈的特性去解决该问题,需要考虑边界栈空的情况题解及注释:classSolution{//定义一个hashMap用于匹配括号右边privatestaticfinalMap<Character,Chara......
  • C++ 类和对象(中)(拷贝构造函数、赋值运算符重载)
    目录   一、前言二、正文1.拷贝构造函数1.1拷贝构造函数的使用1.2对于传引用返回的问题2.赋值运算符重载2.1运算符重载2.1.1运算符重载的使用2.2赋值运算符重载2.2.1赋值运算符的使用3.注意事项(构造函数和赋值运算符重载的误判) 三、结语   一、前言......
  • 计算机视觉 | 注意力机制】12种即插即用涨点模块分享!含注意力机制、卷积变体、Transfo
    即插即用模块1.**GAM-全局注意力机制**2.**STN-空间变换网络**3.**SENet-挤压和激励网络**4.**DConv-动态卷积**5.**FAN-完全注意力网络**6.**CA-协调注意力**7.**ASFF-自适应空间特征融合**8.**CFNet-全新多尺度融合**9.**simAM-简单无参数......