v3学院教你FPGA-赋值语句

此文章为v3学院原创 www.v3edu.org

开发过程中,我们用的最多的恐怕就是赋值语句了,我们常用的赋值方式有两种:阻塞赋值和非阻塞赋值。我刚开始学的时候就被这两种赋值方式搞晕了,当时脑子里面有几个问题总是一团乱麻-什么是阻塞赋值?什么是非阻塞赋值?什么时候用阻塞赋值?什么时候用非阻塞赋值?这两种赋值方式到底有哪些不同?什么时候两种赋值方式结合起来用?

当时由于好的教材比较少,因此我被这些简单的问题困扰了很久,今天通过本节课程的学习,我们将通过一些实际的例子来说明这些问题。

一非阻塞赋值语句

以赋值操作符“<=”来标识的赋值操作称为“非阻塞型过程赋值(Nonblocking Assignment)”。非阻塞型过程赋值语句的特点如下:

1.在begin-end串行语句块中,一条非阻塞过程语句的执行不会阻塞下一条语句的执行,也就是说在本条非阻塞型过程赋值语句对应的赋值操作执行完之前,下一条语句也可以开始执行。

2.仿真过程在遇到非阻塞型过程赋值语句后首先计算其右端赋值表达式的值,然后等到仿真时间结束时再将该计算结果赋值变量。也就是说,这种情况下的赋值操作是在同一仿真时刻上的其他普通操作结束后才得以执行。

如有这样一段程序1:

initial

begin

A<=B;//语句S1

B<=A; //语句S2

end

上述initial语句中包含了两条非阻塞型过程赋值语句S1和S2,当仿真进程遇到initial过程块后(0时刻),语句S1首先开始执行,赋值表达式“B”的值得到计算(但是对被赋值变量A的赋值操作要等到当前时间步结束才执行),同时由于S1是一条非阻塞型赋值语句,所以S1的执行不会阻塞S2的执行;由于S2也随即开始执行,其对应的赋值表达式“A”的值得到计算,由于这时S1对A的赋值操作还没有执行,所以此时计算得到的赋值表达式取值是A的初值。由于S2也是一条非阻塞型赋值语句,它对应的为变量B进行赋值操作也要等到当前时间步结束时才会得到执行;所以在当前时间步结束时,S1、S2两条语句对应的赋值操作同时执行,分别将计算得到的A和B初值赋给变量B和A,这样就交换了A与B的取值。

1.实例1代码

接下来,大家一起来看一个实例,代码如下:


01 module Assignment1(clk,rst_n);

02  //系统输入

03 input clk;//系统时钟输入

04 input rst_n;//低电平复位信号

05  //内部寄存器定义

06 reg [1:0]a;//内部寄存器

07 reg [1:0]b;//内部寄存器

08  //赋值语句块

09 always@(posedge clk or negedge rst_n)

10     begin

11         if(!rst_n)

12             begin

13                  a<=2;//寄存器赋初值

14                  b<=1;//寄存器赋初值

15             end

16         else

17             begin

18                  a<=b;//寄存器数据交换

19                  b<=a;//寄存器数据交换

20             end

21     end

22 endmodule

2.实例1测试代码

编写测试代码如下:


01  `timescale 1ns/1ps

02 module tb;

03

04 reg clk;

05 reg rst_n;

06

07 initial

08     begin

09          clk=0;

10          rst_n=0;

11         # 1000.1 rst_n=1;

12     end

13

14 always #10 clk=~clk;

15

16  Assignment1 Assignment1(

17     .clk(clk),

18     .rst_n(rst_n)

19  );

20 endmodule

3.实例1对应的仿真波形

查看该实例对应的仿真波形如图3-1所示。

图3-1 非阻塞赋值对应的仿真波形

从仿真图我们可以看出,使用非阻塞型过程赋值语句,把a的初值给b,b的初值给a。因此可以证实我们前面的分析是正确的。非阻塞型过程赋值语句一般应用于时序逻辑。

二阻塞赋值语句

以赋值操作符“=”来标识的赋值操作称为“阻塞型过程赋值(blocking
Assignment)”。阻塞型过程赋值语句的特点是:

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

2.阻塞型过程赋值语句的执行过程是:首先计算右端赋值表达式的值,然后立即将计算结果赋值给“=”左端的被赋值变量。

阻塞型过程赋值语句的这两个特点表明:仿真进程在遇到阻塞型过程赋值语句时将计算表达式的值并立即将其结果赋给等式左边的被赋值变量;在串行语句块中,下一条语句的执行会被本条阻塞型过程赋值语句所阻塞,只有在当前这条阻塞型过程赋值语句所对应的赋值操作执行完后下一条语句才能开始执行。

如有这样一段程序2:

initial

begin

a=0;//语句S1

a=1;//语句s2

end

在这段initial语句中包含两条阻塞型过程赋值语句S1和S2,它们都是在仿真零时刻得到执行的,其对应的赋值操作也都是在0时刻进行的。但由于它们是阻塞型赋值语句,所以在执行S1语句时S2被阻塞而不能得到执行;只有在S1执行完,a被赋值0之后,S2才能开始执行。而S2的执行将使a被重新赋值1,所以上面这个过程块执行后变量a的值最终取值为1。

1.实例2代码

接下来,我们一起下面的实例,代码如下:


01 
module
Assignment2(clk,rst_n);

02 
//系统输入

03 
input
clk;//系统时钟输入

04 
input
rst_n;//低电平复位信号

05 
//内部寄存器定义

06 
reg
[1:0]a;//内部寄存器

07 
reg
[1:0]b;//内部寄存器

08 
//赋值语句块

09 
always@(posedge clk
or
negedge
rst_n)

10     
begin

11         
if(!rst_n)

12             
begin

13                 
b=1;//寄存器赋初值

14                 
a=2;//寄存器赋初值

15             
end

16         
else

17             
begin

18                 
b=a;//寄存器数据交换

19                 
a=b;//寄存器数据交换

20             
end

21     
end

22 
endmodule

2.实例2对应的仿真波形

查看实例2对应的仿真波形如图3-2所示。

图3-2

阻塞赋值对应的仿真波形

可以看出,只是把赋值方式换成了阻塞型,结果就和非阻塞型的不同。阻塞型赋值语句一般用在组合逻辑中。

此文章为v3学院原创
www.v3edu.org

时间: 2024-10-28 10:50:18

v3学院教你FPGA-赋值语句的相关文章

FPGA培训专家 v3学院 教你FPGA-赋值语句

此文章为v3学院原创 www.v3edu.org 开发过程中,我们用的最多的恐怕就是赋值语句了,我们常用的赋值方式有两种:阻塞赋值和非阻塞赋值.我刚开始学的时候就被这两种赋值方式搞晕了,当时脑子里面有几个问题总是一团乱麻-什么是阻塞赋值?什么是非阻塞赋值?什么时候用阻塞赋值?什么时候用非阻塞赋值?这两种赋值方式到底有哪些不同?什么时候两种赋值方式结合起来用? 当时由于好的教材比较少,因此我被这些简单的问题困扰了很久,今天通过本节课程的学习,我们将通过一些实际的例子来说明这些问题. 一非阻塞赋值语

v3学院教你编译xilinx仿真库

1.安win->所有程序->键找到xilinx design tools –>ise design tools 里找到Simulation Library Compilation Wizard,如果modelsim 是64位就要选择64位文件夹下的,32位选择32位文件夹下的 2.找到modelsim 的安装目录把modelsim.ini 的只读属性去掉 3.Ise 仿真库编译工具,选择modelsim se 4.设置modelsim 仿真工具启动工具路径 5.语言选择 Verilog

v3学院带您一起学习FPGA

本文为原创,转载请注明! 课程名称:双buffer乒乓操作项目概况:使用FPGA内部ram作为缓冲器,实现对外部数据流的缓存:为了提升数据的传输及处理速度,在此节课中将用到两个ram进行乒乓操作.结构框图: 效果描述:本实验做到了使用低速模块处理高速数据流,可以将缓冲的数据在没有停顿的情况下送入到数据流处理模块进行处理.应用案例:在我们做FPGA开发时,为了能更好的处理一下数据流,会经常进行一些数据的缓存,在此节课中让学员能够建立一些数据缓存的概念:乒乓操作是一种经常使用的数据流处理技巧,可以在

v3学院 FPGA专家 带你学习FPGA实现格雷码跨时钟域异步fifo

当由慢时钟域到快时钟域,肯定需要一个buffer做缓冲,这样才能完成时钟域的转换.一般这种情况都选择FIFO来做缓冲. 当读写FIFO的时钟不同那么称为异步FIFO,FIFO就是一个"环形存储器"读操作会把读指针指向下一个读数据,写操作会把写指针指向下一个写数据地址.当读指针追上写指针时称作读空,当写地址追上读地址时称作写满. 读空,写满标志的产生 格雷码地址编码产生 异步fifo整体逻辑框图 请扫二维码加入fpga圈 代码实现请持续关注,下次讲解! 本文章原创,来自v3学院 www.

v3学院 FPGA专家 带你玩转DDR3

本文章原创,来自FPGA培训专家,v3学院 www.v3edu.org 本项目基于 Spartan6 xc6slx45t-2fgg484 系列FPGA 第一步:我们先创建ise工程,调取ddr3 ipcore: 打开ISE Core generater,找到MIG核 第二步:设置IPcore 名称 第三步:选择芯片类型,如果建立过IPCORE工程默认设置即可 第四步:根据原理图设置DDR3控制器所在bank 第五步:选择对应DDR3芯片 第六步:控制器相关特性设置(默认设置即可) 第七步:设置给

V3学院带你学习-缩短汉明码Hamming(12,8)的FPGA实现

此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家汉明码是一种实现简单并且可以检测和纠正错误的编码, 汉明码是在原编码的基础上附加一部分数据比特,使其满足纠错码的条件.它属于线性分组码,由于线性码的编码和译码容易实现,至今仍是应用最广泛的一类码.V3学院FPGA Verilog 汉明码实现,Hamming(12,8)表示数据位长K=8,编码后码字长N=12,校验位长R=12-8=4,最小汉明距离是H=3(观察其生成矩阵,不同行向量间最少不同比特的数量),纠错能力为(H-1)

FPGA培训专家 V3学院 FPGA专家 带你学习Verilog语言top_down书写技巧

此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家 为了提高我们代码的复用率,我们可以将不同的功能的代码分模块书写,然后在顶层连线即可.我们举一个简单的例子,如下程序,我们实现的是LED流水. 我们在led模块中先将系统时钟分频为1HZ的时钟,然后用分频后的时钟控制LED灯的流水,但我的分频和LED灯流水完全不是相同的工程,只是把分频后的时钟作为LED灯的控制时钟.这样我们会发现如果我再次用到流水灯的模块的话需要修改很多地方,那么为了让我们的模块复用率更高.更容易复用,我们

FPGA培训专家 V3学院带你学习 按键消抖 和 边缘检测

FPGA培训专家 V3学院 一般情况下,我们从按下按键到松开基本需要大于几十毫秒的时间,系统时钟的周期处于纳秒级,因此我们按下一次按键会被大于十万个时钟的上升沿采集到,然而我们希望的是按下一次按键只被一次上升沿采集到,不然会被认为按了多次按键,所以我们需要对我们的按键进行处理.假设按键在没被按下时为高电平,被按下时处于低电平,如图1所示的波形图. 图1 按键波形图 由图1 分析可知在key被按下时有且仅有一个key的上升沿和一个key的下降沿,我们可以通过检测key的上升沿或者下降沿来确定按键被

V3学院带你学习-缩短汉明码Hamming(12,8)的FPGA实现-第二部分

此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家 测试激励模块 tb_hamming_12_8.V //功能描述:给被测模块提供时钟激励,并统计解码后数据的正确性 `timescale 1ns/1ns module tb_hamming_12_8; reg sclk; wire [11:0] ham_o; wire ham_ov; wire [11:0] deham_o; wire deham_ov; reg [31:0] err_cnt; reg [23:0] buff