【Verilog 基础】阻塞赋值和非阻塞赋值的区别

2023-11-04

目录

 

阻塞赋值

非阻塞赋值

实际工程仿真

阻塞赋值仿真

编写Verilog代码

编写测试文件代码

综合看RTL图

进行实际仿真

非阻塞赋值仿真

编写Verilog代码

编写测试文件代码

综合看RTL图

实际仿真图

总结


 

阻塞赋值

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

串行块也就是begin end,各条阻塞赋值语句将以它们在顺序块中的排列次序依次执行。

非阻塞赋值

非阻塞赋值的赋值号用 “<=” 表示,对应的电路结构往往与触发沿有关系,只有在触发沿的时刻才能进行非阻塞赋值。

它的操作可以看作为两个步骤的过程:在赋值结束时刻,更新赋值号左边的语句。

在计算非阻塞语句赋值号右边的语句更新赋值号左边的语句期间,允许其他的Verilog语句同时进行操作。

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

实际工程仿真

阻塞赋值仿真

编写Verilog代码

首先是阻塞赋值仿真(blocking),利用 “=” 进行赋值,表示阻塞赋值。

module	blocking
(			
	input	wire			clk,
	input	wire			rst_n,
	input	wire	[1:0]	in,
	output	reg		[1:0]	out

);

reg		[1:0]	in_reg;

always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		in_reg = 2'b0;
		out    = 2'b0;
	end
	else begin
		in_reg = in;
		out    = in_reg;
	end
end
endmodule

编写测试文件代码

`timescale 1ns / 1ns

module tb_blocking();
	
	reg				clk;
	reg				rst_n;
	reg		[1:0]	in;

	wire	[1:0]	out;

	initial	begin
		clk = 1'b1;
		rst_n <= 1'b0;
		in <= 2'b0;
		#20
		rst_n <= 1'b1;
	end
	always #10 clk = ~clk;
	always #10 in <= {$random} % 4;


blocking tb_blocking(
	.clk(clk),
	.rst_n(rst_n),
	.in(in),
	.out(out)
	);
endmodule

综合看RTL图

可以看到只有一个寄存器,因此在实际的仿真图显示的应该是in_reg和out信号应该同时变化,并且两路信号都延时in信号一拍。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

进行实际仿真

与预想的一致

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

 

 

非阻塞赋值仿真

编写Verilog代码

如下:只需要将阻塞赋值的代码将 “=” 改成 “

module	blocking
(			
	input	wire			clk,
	input	wire			rst_n,
	input	wire	[1:0]	in,
	output	reg		[1:0]	out

);

reg		[1:0]	in_reg;

always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		in_reg <= 2'b0;
		out	   <= 2'b0;
	end
	else begin
		in_reg <= in;
		out    <= in_reg;
	end
end
endmodule

编写测试文件代码

和阻塞赋值的测试文件一样

`timescale 1ns / 1ns

module tb_blocking();
	
	reg				clk;
	reg				rst_n;
	reg		[1:0]	in;

	wire	[1:0]	out;

	initial	begin
		clk = 1'b1;
		rst_n <= 1'b0;
		in <= 2'b0;
		#20
		rst_n <= 1'b1;
	end
	always #10 clk = ~clk;
	always #10 in <= {$random} % 4;


blocking tb_blocking(
	.clk(clk),
	.rst_n(rst_n),
	.in(in),
	.out(out)
	);
endmodule

综合看RTL图

可以看到有两个寄存器,从in信号赋值给in_reg信号中有一个寄存器,再从in_reg信号赋值给out信号中也有一个寄存器,因此在实际的仿真图显示的应该是in_reg信号相对于in信号延时一拍,而out信号相对于in_reg延时一拍,也就是相对于in信号延时两拍。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

实际仿真图

与观察RTL图后设想的一致。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATGluZXN0LTU=,size_20,color_FFFFFF,t_70,g_se,x_16

总结

阻塞赋值和非阻塞赋值在实际使用上不能随意乱用,否则可能会出现难以预估的后果,根据官方给出的建议,在编写组合逻辑电路时,使用阻塞赋值;在编写时序逻辑时,使用非阻塞赋值。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Verilog 基础】阻塞赋值和非阻塞赋值的区别 的相关文章

  • 如何生成异步复位verilog总是阻塞凿子

    Chisel 始终生成敏感度列表中仅包含时钟的块 always posedge clk begin end 是否可以将模块配置为使用异步重置并生成这样的始终块 always posedge clk or posedge reset begi
  • allegro画PCB如何更新元件的PCB封装

    allegro画PCB如何更新元件的PCB封装 一 更新单个器件的PCB封装 首先菜单栏选择Place gt Update Symbols 如下图 注意此案例是更新了C0805封装 中更新封装 就将上图第二个红色方框中的勾选即可 二 更新某
  • allegro画PCB如何更新元件的PCB封装

    allegro画PCB如何更新元件的PCB封装 一 更新单个器件的PCB封装 首先菜单栏选择Place gt Update Symbols 如下图 注意此案例是更新了C0805封装 中更新封装 就将上图第二个红色方框中的勾选即可 二 更新某
  • 为什么C语言没有被C++所取代呢?

    今日话题 为什么C语言没有被C 所取代呢 C 的复杂编译器实现和嵌入式平台的限制 使C语言保持了其地位 嵌入式系统多数仅支持C 即使支持C 也会限制某些功能 尤其是异常处理和RTTI 此外 C 引入的功能增加了二进制文件大小和运行时内存占用
  • STM32F4XX的12位ADC采集数值超过4096&右对齐模式设置失败

    文章目录 一 前言 二 问题1 数值超过4096 三 问题1的排错过程 四 问题2 右对齐模式设置失败 五 问题2的解决方法 5 1 将ADC ExternalTrigConv设置为0 5 2 使用ADC StructInit 函数 一 前
  • TRICONEX MA2211-100 芯片上相互连接

    TRICONEX MA2211 100 芯片上相互连接 TRICONEX MA2211 100 所有相同的组件 io的电源 处理器 和内存将需要 但是 你可以看到所有这些带存储器和处理器的OO板 针不能嵌入到一个小的单片机上 现在是 普拉克
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • 从测试台访问 uvm_config_db 的最佳方式?

    我想在我的顶级测试平台中创建一个时钟 其周期可以通过测试进行控制 我所做的是将周期设置到 uvm config db 中并将其返回到测试台中 我必须输入 1 以确保构建阶段已完成 否则 get 返回错误值 module testbench
  • if 语句导致 Verilog 中的锁存推断?

    我正在编写用于合成算法的 Verilog 代码 我对哪些情况可能导致推断锁存器有点困惑 下面是这样的一段代码 虽然它在模拟中工作得很好 但我担心它可能会导致硬件问题 always b1 or b2 b1 map b2 map m1 map
  • Verilog 中的“net”代表什么?

    我刚刚开始学习Verilog 据我了解 Verilog有net数据类型 什么是net代表 网络就是这样一种数据类型 您不使用它来存储值 它们代表物理连接 您可以将线路视为一种网络数据类型 你可以去网上看看更多here http www ee
  • 始终块中的 Veriloggenerate/genvar

    我试图让一个模块通过 ISE 12 4 中的语法检查 但它给了我一个我不明白的错误 首先是代码片段 parameter ROWBITS 4 reg ROWBITS 1 0 temp genvar c generate always pose
  • 对象 <名称> 未声明

    这是我的代码 据我所知 LEDs被定义为 module sevenseg LEDs in output reg 6 0 LEDs input 3 0 in always in begin case in 0 LEDs 7 b1000000
  • 开始后跟冒号和变量是什么意思?

    什么是data mux意思是这里 它只是块的名称吗 if PORT CONFIG 32 P0 1 b1 begin data mux end 这些是块名称 它们特别适用于generate块 例如 您可以定义一个generate块如 genv
  • 在 Verilog 中判断总线是否包含单个 x 的最佳方法是什么?

    我有一个监控总线的测试台 总线内的一些信号 位 可以是 1 bx 由于多种原因 我需要知道总线内是否有任何信号是 1 bx 如果总线包含任何 x 测试 不用于综合 仅用于模拟目的 的最佳方法是什么 我曾希望我可以使用减少或然后使用 但这似乎
  • 在 Verilog 设计中产生时钟故障

    我正在使用 Verilog 设计芯片 我有一个 3 位计数器 我希望当计数器处于第 8 次循环时 应该有一个时钟故障 之后就可以正常工作了 在 Verilog 设计中产生时钟故障的可能方法是什么 在时钟信号上注入毛刺的一种方法是使用forc
  • 标识符必须用端口模式声明:busy。 (Verilog)

    我有如下所示的 Verilog 代码 当我编译它时 我收到以下错误消息 并且代码的第一行突出显示 Error 标识符必须用端口模式声明 busy Code module main clk rst start busy ready cnt s
  • 如何在 Verilog 中推断 Block RAM

    我在一个项目中遇到了一个非常具体的问题 这个问题已经困扰我好几天了 我有以下 RAM 模块的 Verilog 代码 module RAM param clk addr read write clear data in data out pa
  • Verilog 按位或 ("|") 单子

    我见过 Verilog 代码 其中使用了按位或运算符 目的是什么 例如 address 15 14 0 or address 15 14 io din ramrd 不能省略 吗在这些情况下 在这种情况下 它充当归约运算符 例如 4 b100
  • 系统 verilog 中没有类型的输入

    我在一个系统 verilog 代码的输入和输出的示例中遇到过module没有说明它们的类型 例如logic wire module mat to stream input 2 0 2 0 2 0 a b input newdata inpu
  • 如何修复实例上的错误:未定义的变量 B?

    我想编译此 Verilog 代码 但在实例中出现错误B模块中的MultiP module error 1 Undefined variable B error 2 near Adder1 syntax error unexpected ID

随机推荐