话说“=”、“<=”、always过程块、initial过程块

本文详细解释了Verilog编程中always和initial过程块中的阻塞赋值和非阻塞赋值的区别,以及它们在时序逻辑和组合逻辑中的角色。强调了在不同逻辑类型中正确选择赋值类型的重要性,并给出了实际代码示例和编程规范。
摘要由CSDN通过智能技术生成

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:第一章 Python 机器学习入门之pandas的使用


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、= 和<=

1.= 和<=

阻塞赋值(=):该语句结束时就完成赋值操作,前面的语句没有完成前,后面的语句是不能执行的。在一个过程块内(always过程块、initial过程块)多个阻塞赋值语句是顺序执行的。

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

阻塞赋值(=):该语句结束时就完成赋值操作,前面的语句没有完成前,后面的语句是不能执行的。在一个过程块(always过程块、initial过程块)内多个阻塞赋值语句是顺序执行的。

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

module block_no_block(
	input wire [0:0] sys_clk  ,
	input wire [0:0] sys_rst_n,
	input wire [0:0] in       ,
	
	output reg [0:0] out
);

reg [0:0] reg_out;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		begin
			reg_out = 1'b0;
			out = 1'b0;
		end
	else
		begin
			reg_out = in;
			out = reg_out;
		end


endmodule

代码说明:在posedge sys_clk的条件下,如in = 1 reg_out = 0 条件下,执行到reg_out = in; out = reg_out; 的时候,reg_out立刻变为1后,out继而也变成1(in赋值给reg_out,reg_out 变化了之后,又赋值给out),所以在一个posedge sys_clk内,两个是顺序执行的,两个有先后顺序,应该就有延迟,只是时间很短

在这里插入图片描述

module block_no_block(
	input wire [0:0] sys_clk  ,
	input wire [0:0] sys_rst_n,
	input wire [0:0] in       ,
	
	output reg [0:0] out
);

reg [0:0] reg_out;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		begin
			reg_out <= 1'b0;
			out <= 1'b0;
		end
	else
		begin
			reg_out <= in;
			out <= reg_out;
		end


endmodule

代码说明:在posedge sys_clk的条件下,如in = 1 reg_out = 0 条件下,进入到always块时,会先定住reg_out(=0) 和in(=1)的值,执行到reg_out <= in; out <= reg_out; 的时候,只是计算赋值右边的表达式(现在右边是一个变量,也可以看作是表达式的一种),还没有进行赋值到左边的操作(因此out <= reg_out;中的reg_out好还是原先定住的值),等这个always块结束时,再将定住的in(=1)值赋给reg_out,将定住的reg_out(=0)的值赋给out(有点类似与c语言中的b = a++),reg_out和out同时变化,always块结束后,reg_out = 1,out = 0,所以在一个posedge sys_clk内,两个是并行执行的。
在这里插入图片描述

2.规范

(1)在编写时序逻辑的代码时采用非阻塞赋值的方式
计算赋值号右手边的信号时,所有的变量值均是触发沿到来前的值,更新的赋值号左手边的信号作为触发沿后的值,并且保持到下一个触发沿到来时候,等待更新。这样,就可以使得在同一个块中非阻塞赋值语句不必要求出现的顺序,都是在全部进行赋值号右手边的信号计算后同时更新赋值号左手边的信号的值。非阻塞赋值可以简单的认为是赋予下一状态的值。
(2)使用always块来编写组合逻辑的代码时要用阻塞赋值的方式
使用always块建立组合逻辑电路模型时不要忘记always块中的敏感列表一定要使用电平触发的方式,然后在always块中使用阻塞赋值语句就可以实现组合逻辑,这样做既简单且方针又快又好,这样的风格是值得推荐的。
(3)在同一个always块中不要既要用非阻塞赋值又用阻塞方式赋值
在同一个always块中对同一个变量既进行阻塞赋值又进行非阻塞赋值会产生综合不可预测的结果,不是可综合的Verilog风格。
(4)虽然锁存器电路建模是我们不推荐的,但是如果使用到要采用非阻塞赋值的方式。
使用非阻塞赋值实现时序逻辑,实现锁存器是最为安全的。
(5)一个always块只一个变量进行赋值
因为always块是并行的,执行的顺序是随机的,综合时会报多驱动的错误,所以严禁在多个always块中对同一个变量赋值;当然也不推荐一个always对多个变量进行赋值,虽然这种方式是允许的,但如果过多会导致代码的混乱且不易后期的维护和修改。对多条语句赋值时使用,因为我们设计RTL代码的原则是一个always块中最好只有一个变量,所以begin…end(类似于C语言中括号的作用)在RTL代码中几乎很少使用,而在Tetbench中使用的更多。

二、always过程块、initial过程块

1.alway块、阻塞赋值非阻塞赋值、时序逻辑组合逻辑的关系

组合逻辑时序逻辑
阻塞赋值always电平敏感列表,阻塞赋值可以用always边沿敏感列表 阻塞赋值可以用
非阻塞赋值always电平敏感列表,非阻塞赋值可以用always边沿敏感列表 非阻塞赋值可以用

总结:1、时序逻辑用的是always边沿敏感列表,而和组合逻辑用的是always电平敏感列表;2、原则上在时序逻辑和组合逻辑中,都可以用阻塞赋值和非阻塞赋值,这个与是什么逻辑无关,只看你想在过程块中立刻变化还是过程块结束后变化,但是官方还是有一些推荐,如时序逻辑中用<=,组合逻辑中用=

2.alway块和initial块

过程块有两种:
initial块,只能执行一次
always块,循环执行
在这里插入图片描述

过程块中有下列部件:

过程赋值语句:在描述过程块中的数据流
高级结构(循环,条件语句):描述块的功能
时序控制:控制块的执行及块中的语句。
initial语句与always语句和begin_end与fork_join是一种高频搭配:
在这里插入图片描述


总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值