设计时序逻辑时采用阻塞赋值与非阻塞赋值
Verilog设计练习十例及答案
设计练习进阶前言:在前面九章学习的基础上,通过本章的练习,一定能逐步掌握Verilog HDL设计的要点。
我们可以先理解样板模块中每一条语句的作用,然后对样板模块进行综合前和综合后仿真,再独立完成每一阶段规定的练习。
当十个阶段的练习做完后,便可以开始设计一些简单的逻辑电路和系统。
很快我们就能过渡到设计相当复杂的数字逻辑系统。
当然,复杂的数字逻辑系统的设计和验证,不但需要系统结构的知识和经验的积累,还需要了解更多的语法现象和掌握高级的Verilog HDL系统任务,以及与C语言模块接口的方法(即PLI),这些已超出的本书的范围。
有兴趣的同学可以阅读Verilog语法参考资料和有关文献,自己学习,我们将在下一本书中介绍Verilog较高级的用法。
练习一.简单的组合逻辑设计目的: 掌握基本组合逻辑电路的实现方法。
这是一个可综合的数据比较器,很容易看出它的功能是比较数据a与数据b,如果两个数据相同,则给出结果1,否则给出结果0。
在Verilog HDL中,描述组合逻辑时常使用assign 结构。
注意equal=(a==b)1:0,这是一种在组合逻辑实现分支判断时常使用的格式。
模块源代码:" qual(equal),.a(a),.b(b)); 简单时序逻辑电路的设计目的:掌握基本时序逻辑电路的实现。
在Verilog HDL中,相对于组合逻辑电路,时序逻辑电路也有规定的表述方式。
在可综合的Verilog HDL模型,我们通常使用always块和@(posedge clk)或@(negedge clk)的结构来表述时序逻辑。
下面是一个1/2分频器的可综合模型。
eset(reset),.clk_in(clk),.clk_out(clk_out));endmodule仿真波形:练习:依然作clk_in的二分频clk_out,要求输出与上例的输出正好反相。
编写测试模块,给出仿真波形。
练习三. 利用条件语句实现较复杂的时序逻辑电路目的:掌握条件语句在Verilog HDL中的使用。
不可综合语句——在多个always块中对同一变量赋值
不可综合语句——在多个alwa ys块中对同一变量赋值先从夏老师的书里摘录点东西:QUOTE:“在描述组合逻辑的alway s块中使用阻塞赋值,则综合成组合逻辑的电路结构。
”“在描述时序逻辑的alway s块中使用时序赋值,则综合成时序逻辑的电路结构。
”阻塞与非阻塞赋值的使用原则:原则1:时序电路建模时,用非阻塞赋值。
原则2:锁存器电路建模时,用非阻塞赋值。
原则3:用always块描述组合逻辑时,采用阻塞赋值。
原则4:在同一个块中描述时序逻辑和组合逻辑的混合逻辑时,用非阻塞赋值。
原则5:同一个alwa ys块中只能全用阻塞赋值或者全用非阻塞赋值。
原则6:不能在多个always块中对同一个变量进行赋值。
这个问题也困饶我比较久了,今天终于解决,啦啦啦啦啦~~考虑到菜鸟们大都有夏老师的书了,所以我来说点夏老师书里没有的。
首先让我们看看为什么不能如此赋值。
寄存器输入端是由触发器组成的,用两个alwa ys块对一个寄存器进行赋值,无论其中经过了怎样的条件判断,最终结果毫无疑问是将两个相独立的触发信号连在了寄存器的CLK端上,一端口接入两信号,这显然已经不是一个符合标准的数字逻辑电路了。
所以这样的语句是无法被综合成电路的。
(不同软件的处理似乎不同,quartus2是直接拒绝双always赋值,而有的综合布线软件在警告之后会将两个信号连到一个双端口门上再接入寄存器,这显然会改变程序原有逻辑,画波形图一看就知道了。
)然后来看看小生思考良久得到的解决方法吧。
下面是偶正在做滴那个电子表中计数器模块的入口模块,其中IN2,IN3都是高电平有效的外部按钮产生的信号。
由于要实现手动设置实现功能,所以就需要通过按钮的触发信号对计数器进行操作,但是自动计时状态下对计数器进行赋值的是时钟CLK,这就产生了在a lways@(CLK)和always@(IN2)两个alway s块下对计数器进行的赋值操作。
阻塞和非阻塞赋值语句的用法
例1和例2的RTL Viewer
例1和例2的仿真波形
非阻塞赋值语句也是出现在initial和always块语 句中,赋值符号是“<=”,格式为 赋值变量 <= 表达式;
在非阻塞赋值语句中,赋值号“<=”左边的赋值 变量也必须是reg型变量,其值不象在过程赋值 语句那样,语句结束时即刻得到,而在该块语句 结束才可得到。
建议:在时序逻辑电路的设计中,采用非阻塞型 赋值语句
always @(posedge clock)
m = 3;
n = 75;
ቤተ መጻሕፍቲ ባይዱ
n <= m;
r = n; 语句执行结束后,r的值是75,而不是3,因为第3行 是非阻塞赋值语句“n <= m”,该语句要等到本块语 句结束时,n的值才能改变。
2016/12/5 5
非阻塞式赋值语句与阻塞式赋值语句
例 1: module DDF3(clk,D,Q); input clk,D; output reg Q; reg a,b; always@(posedge clk) begin a<=D; b<=a; Q<=b; end endmodule 例 2: module DFF3(clk,D,Q); input clk,D; output reg Q; reg a,b; always@(posedge clk) begin a=D; b=a; Q=b; end endmodule
非阻塞式赋值
在过程语句中,比较接近真实的电路赋值 和输出。 有一个特殊的延时操作,而且在赋值过程 中不影响其它同类语句的赋值操作。 同阻塞式赋值一样,允许对同一目标信号 多次赋值或驱动。Verilog规定,被赋值 的目标变量接受最接近过程结束的那一个 驱动源的数据。
Verriog HDL学习笔记
下面是一个简单的Verliog HDL的例子。
module reg12(d, clk,,q);define size 11input [size:0] d;input clk;output [size:0] q;reg [size:0] q;always@(posedge clk)q=d;endmoduleVerilog HDL的基本设计单元是“模块(block)”。
一个模块由两部分组成:一部分描述接口,一部分描述逻辑功能,即定义输入是如何影响输出的。
每个程序包括四个主要部分:端口定义、I/O说明、信号类型和功能描述。
有3中方法可以在模块中描述逻辑。
1、用assign语句assign A=B&C;assign语句一般适合于对组合逻辑进行赋值。
称为连续赋值方式。
2、用原件例化or myor3(a,b,c,d);这个语句定义了一个3输入的“或”门3、用always块语句always@(posedge clk) q=d上句表示每当时钟上升沿到来时执行一遍块内的语句。
4、assign # 2 B = A;表示B信号在2个时间单位后得到A信号的值。
常用的赋值语句:连续赋值语句和过程赋值语句连续赋值语句:assign,用于对wire型变量赋值。
过程赋值语句:用于对寄存器型变量赋值,有以下2种赋值方式。
1、非阻塞赋值方式,<=, 该方式在块结束时才完成赋值操作。
2、阻塞赋值方式,=, 在该语句结束是就完成赋值操作。
综合是将电路的高级语言转化为低级的,可与FPGA\CPLD或构成ASIC的门阵列基本结构相映射的网表文件或程序。
综合包括编译,转换,调度,分配,控制器综合和结果的生成等几个步骤。
RTL代码在下载到板子上这个过程之前,要做一个综合、布局、布线,按照FPGA的要求,综合成电路,然后讲bit流文件下到FPGA开发板上,一句话,下板子之前,肯定得综合,只是这部分你做的很快(可能电路比较小,综合很快)。
个人总结阻塞赋值和非阻塞赋值的区别
关于阻塞复制和非阻塞赋值
阻塞赋值和非阻塞赋值的区别
阻塞赋值=
阻塞性过程赋值在其后所有语句执行前执行,即在下一语句执行前该赋值语句完成执行。
非阻塞赋值<=
过程赋值中,对目标的赋值是非阻塞的(因为延时),但可预订在将来某个时间步发生(根据时延;如果是0时延,那么在当前时间步结束)。
当非阻塞性过程赋值被执行时,计算右端表达式,右端值被赋予左端目标,并继续执行下一条语句。
预定的最早输出将在当前的时间步结束时,这种情况发生在赋值语句中没有时延时。
在当前时间步结束或任意输出被调度时,即对左端目标赋值。
在同一个always/initial块里不要混用两种赋值语句
阻塞式过程赋值与非阻塞式过程赋值(VHDL中使用非阻塞式)
c = a & b; 阻塞式过程赋值
c <= a & b; 非阻塞式过程赋值
两种赋值不会对语句本身的赋值有影响,但会影响以后对赋值结果的引用。
书中建议组合逻辑使用阻塞式,时序逻辑使用非阻塞式。
且语句块中如果只有一条赋值语句,是阻塞还是非阻塞都没有任何不一样。
非阻塞式过程赋值的赋值对象是在未来(即当前仿真时刻结束时)被赋值。
例always @ (negedge clockB)
begin
rightshift = rightshift & strobe;
selectfist <= rightshift | xflag;
checkstop <= slectfist ^ mask;
end
endmodule
左边的红线是rightshift,其未经过触发器,右边的是selectfist经过触发器了.。
FPGA学习系列:5.阻塞赋值与非阻塞赋值
9 always @ (posedge clk)
10 begin
11 if(!rst_n) //复位时用非阻塞给寄存器输出赋初值
12 begin
13 q1 <= 0;
14 q <= 0;
15 end
16 else //非阻塞语句进行赋值
17 begin
18 q1 <= d;
19 q <= q1;
20 end
1
2 module tb;
3
4 reg clk;
5 reg rst_n;
6 reg [1:0] d;
7 wire [1:0] q;
8
9 initial begin
10 clk = 1;
11 rst_n = 0;
12 d = 0;
13
14 #200.1 rst_n = 1;
15
16 #100 d = 2;
1 //输入输出端口
2 input clk;
3 input rst_n;
4 input [1:0] d;
5 output reg [1:0] q;
6
7 reg [1:0] q1; //定义一个寄存器
8
9 always @ (posedge clk)
10 begin
11 if(!rst_n) //复位时用阻塞给寄存器输出赋初值
17 #100 d = 0;
18
19 end
20
21 always #10 clk = ~clk;
22
23 study_4 dut(
24 .clk(clk),
25 .rst_n(rst_n),
26 .d(d),
Verilog中的延时、阻塞与非阻塞赋值仿真
从仿真语义的角度看Verilog中的延时、阻塞与非阻塞赋值1 Verilog中的延时Verilog没有和VHDL中类似的最小延时概念,所有的延时都由符号“#”来定义,如果没有这个符号就意味着没有延时,清单1中描述了一个有关延时的简单例子。
清单1 简单的延时wire #5 Y = A & B;清单1 中使用持续赋值语句描述了一个两输入端与门逻辑,并且在表达式前插入了5ns (#5)的延时,意义为Verilog仿真器会在5ns的延时后将A和B相与赋值给Y。
通过这个例子可以看出,延时的插入只需要在原本的语句中加入“#”关键字即可,但在实际的使用中却经常产生错误,实际中的延时时间是由具体的硬件电路来决定的。
使我们更深入的理解Verilog中的延时,更加关注描述的电路意义而不是描述语句本身,Verilog也是一种机于硬件的语言。
1.1 实际中的延时在实际的电路中,只存在着两种延时行为,一个是惯性延时,另一个是传输延时。
1.1.1 惯性延时(Inertial Day)惯性延时通常在信号通过逻辑门的时候发生,图1所示是信号通过一个具有5ns延迟的非门时的行为。
图1 惯性延时输入信号WireIn有两个高电平脉冲,一个宽度为3ns,另一个宽度为9ns。
当第一个3ns 的脉冲到达非门时,因为其宽度小于非门的本身延时(5ns),输出还来不及建立低电平,输入脉冲就已经过去,所以在输出信号WireOut上没有体现出第一个3ns脉冲的响应。
第二个脉冲宽度为9ns,大于非门的本身延时,所以在脉冲上升沿5ns之后,WireOut输出了一个宽度为9ns的低脉冲,这个脉冲与输入脉冲等宽、反向而且延迟了5ns。
这种延时称为惯性延时或惰性延时。
如果输入的变化过快,小于逻辑门本身的延时,就不会被体现在输出上。
1.1.2 传输延时(Transport Delay)传输延时相对于惯性延时更容易理解,相当于信号通过了一条拥有固定延时的传输线。
阻塞赋值与非阻塞赋值
阻塞赋值与非阻塞赋值作者:zhsj 日期:2015-7-27在Verilog语法中,阻塞赋值和非阻塞赋值是非常难理解的一个概念,尤其是对于初学者,往往搞不懂何时使用非阻塞赋值及何时使用阻塞赋值才能设计出符合要求的电路。
本文是笔者学习此概念时的学习笔记,主要分为概念解析和实例分析,并对一些编程要点进行总结分析,希望对各位初学者有所帮助。
在正式讲解之前先定义两个英文缩写字:RHS——赋值符合右边的表达式或变量;LHS——赋值符号左边的表达式或变量。
一、概念解析1.1 阻塞赋值阻塞赋值操作符为等号(即“=”),当采用阻塞赋值方式赋值时,需要先计算等号右手方向(RHS)部分的值,这时赋值语句不允许任何别的Verilog语句的干扰,直到现行的赋值完成时刻,即把RHS赋值给LHS的时刻,它才允许别的赋值语句的执行。
一般可综合的阻塞赋值操作在RHS不能设定有延迟,即使是零延迟也不允许。
若在RHS上加上延迟,则在延迟期间会阻止赋值语句的执行,延迟后才执行赋值,这种赋值语句是不可综合的,在需要综合的模块中不可使用这种风格的代码。
阻塞赋值的执行可以认为是只有一个步骤的操作,即计算RHS并更新LHS,此时不允许有来自任何其他Verilog语句的干扰。
所谓阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上是前一句赋值语句结束后在开始赋值的,请注意,这只是概念上的先后,而无实质上的延迟。
在使用阻塞赋值时,如果在一个过程块中阻塞赋值的RHS变量正好是另一个过程块中阻塞赋值的LHS变量,这两个过程块又使用同一个时钟沿触发,这时阻塞赋值操作会出现问题,即如果阻塞赋值的顺序安排不好,就会出现竞争。
若这两个赋值操作用同一个时钟沿触发,则执行的顺序是无法确定的,在后面的例子中会看到这一问题。
1.2 非阻塞赋值非阻塞赋值操作符为小于等于号(即“<=”),当采用非阻塞赋值时,在赋值操作开始的时刻计算非阻塞赋值符RHS表达式,赋值操作结束的时刻才更新LHS。
深入理解阻塞和非阻塞赋值
阻塞赋值的特点
顺序执行
阻塞赋值是顺序执行的,先计算等号右边的表达式,再将结果赋 值给左边的变量。
等待完成
阻塞赋值会等待赋值操作完成后再继续执行后续的代码。
适合简单赋值场景
阻塞赋值适用于简单的赋值场景,如将一个常量赋值给变量。
非阻塞赋值的含义
01
非阻塞赋值是指在进行赋值操作时,不会阻塞程序的执行流程,赋值操作会在 后台异步进行。
02
在非阻塞赋值中,赋值语句的执行不会等待赋值操作完成,而是立即返回,继 续执行后续的代码。
03
非阻塞赋值通常用于需要同时进行多个操作的情况,例如在多线程编程中,多 个线程同时进行数据更新时,可以使用非阻塞赋值来避免线程间的竞争和死锁 。
适用场景比较
阻塞赋值
阻塞赋值适用于需要保护共享变量免受并发修改影响的场景。例如,当多个线程需要同时读取共享变量,但只有 特定线程需要写入时,阻塞赋值可以确保数据的一致性和完整性。
非阻塞赋值
非阻塞赋值适用于需要最大化并发性能的场景。例如,在高性能计算或实时系统中,非阻塞赋值可以减少线程之 间的竞争和上下文切换,从而提高整体性能。
06
总结与展望
对阻塞赋值和非阻塞赋值的总结
01 02
阻塞赋值
在阻塞赋值中,当一个线程对共享变量进行写操作时,其 他线程必须等待直到该线程完成写操作,才能对共享变量 进行读或写操作。这确保了数据的一致性和同步性,但可 能导致线程阻塞和性能下降。
非阻塞赋值
非阻塞赋值允许线程在不等待其他线程完成写操作的情况 下对共享变量进行读或写操作。这样可以提高并发性能, 但可能导致数据不一致或竞争条件。
不可综合语句——在多个always块中对同一变量赋值
module HUB_IN
(
CLK, reset, IN2, IN3, STATUS, CP, POS
);
input CLK;
input reset;
input IN2;
input IN3;
input [1:0] STATUS;
output CP;
output [2:0] POS;
然后来看看小生思考良久得到的解决方法吧。
下面是偶正在做滴那个电子表中计数器模块的入口模块,其中IN2,IN3都是高电平有效的外部按钮产生的信号。由于要实现手动设置实现功能,所以就需要通过按钮的触发信号对计数器进行操作,但是自动计时状态下对计数器进行赋值的是时钟CLK,这就产生了在always@(CLK)和always@(IN2)两个always块下对计数器进行的赋值操作。
不可综合语句——在多个always块中对同一变量赋值
先从夏老师的书里摘录点东西:
QUOTE:
“在描述组合逻辑的always块中使用阻塞赋值,则综合成组合逻辑的电路结构。”
“在描述时序逻辑的always块中使用时序赋值,则综合成时序逻辑的电路结构。”
阻塞与非阻塞赋值的使用原则:
原则1:时序电路建模时,用非阻塞赋值。
方法二:考虑到IN3仅在手动设置时间的时候起作用的,而此时对计数器屏蔽CLK(暂停自动计数)对功能的实现并没有太大关系。所以我引入了模块外部的总状态机(其值表示当前是处于自动计数还是手动调整时间),根据状态机的值判断该接入什么信号。并屏蔽另一个。
代码很简单,组合逻辑就可以实现。
CODE:[Copy to clipboard]
注:
1、在我的设计中,自动计时→手动调整时间的状态转换是由另一个外部键盘的信号触发的,从而IN3的高电平在状态机转换完成并且把新的状态值送到组合逻辑入口之后很多个时钟才可能到来,因此IN3_CLK由输出CLK转为输出IN3时IN3的触发沿还没有到来,不存在由CLK高电平转为输出IN3高电平而没有出现触发沿的危险。(这段可能比较难理解,画个波形图吧,包括CLK、状态机STATUS、改变状态的外部信号IN1,以及记数信号IN3)
非阻塞赋值和阻塞赋值
非阻塞赋值和阻塞赋值非阻塞赋值和阻塞赋值,听起来像个程序员的外星语,别担心,咱们慢慢来聊聊,保证让你明白得通透透。
想象一下,你在厨房忙得不可开交,家里一堆事情等着你去做。
这个时候,非阻塞赋值就像一个聪明的助手,你给了他一个任务,他就会立刻去做,根本不管你有没有空。
你可以继续切菜,煮汤,甚至顺便打个电话,反正这位助手会自动完成他的工作,等他做好了再告诉你。
就这么简单。
你心里想着,哎,这个助手真不错,我可以省出好多时间来。
再说说阻塞赋值,这就有点儿像你的亲戚来访,非得跟你聊个痛快,才能离开。
你一边听着他滔滔不绝,心里想着还有一大堆事情没做,完全无法分身。
这个过程就像程序里的阻塞赋值,你要等到这个亲戚说完,才能继续做自己的事。
可能你心里已经默念无数遍“快点吧,赶紧聊完”,可是他就是不知好歹,唠唠叨叨。
哦,生活就是这样,有些时候你只能耐心等待,没办法。
我们再深入聊聊,非阻塞赋值在实际应用中就像你在跑步机上健身。
你可以同时做很多事情,放歌、看视频,甚至吃零食,根本不影响你跑步的节奏。
程序执行的时候,可以同时进行多个操作,效率极高,简直像飞一样。
那种爽快感,仿佛自己是个超人,可以处理无数任务而不觉得累。
但是,前提是你得有个好心态,不然就容易分心了,这时候就得小心了,跑步机可不会等你。
反观阻塞赋值,咱们就得把这比作在电影院看电影。
你得等着前面的广告结束,才能看到你想看的剧情,心里那种着急感,简直要炸了。
好不容易等到广告结束,你才终于能看到精彩的片段。
就像程序里,某个任务必须完成,才能进行下一个,这个时候你就得耐心等待。
虽然有时候觉得无聊,但也好比是人生的一种沉淀,等到对的时机,所有的努力都能水到渠成。
聊到这儿,有趣的是,非阻塞和阻塞赋值在实际编程中其实是相辅相成的。
你可以选择在合适的时候用非阻塞赋值,让自己轻松应对更多任务;又能在某些关键时刻用阻塞赋值,确保数据的一致性。
两者之间的平衡,就像生活中的甜与咸,缺一不可。
verilog赋值原则之阻塞赋值与非阻塞赋值
verilog赋值原则之阻塞赋值与⾮阻塞赋值⼀. 阻塞赋值与⾮阻塞赋值的区别阻塞赋值(Blocking)符号为“ = ”,如:b = a ;可以认为是只有⼀个步骤的操作,计算RHS(等号右边)并更新LHS(等号左边),和C语⾔的赋值很类似。
其中“阻塞”⼆字的意思是在同⼀个块语句中,后⾯的赋值语句是在前⼀个语句赋值结束后才开始赋值的。
⾮阻塞赋值(Non_blocking)符号为“ <= ”,如:b <= a ;当⼀个块语句中有多条赋值语句时,同时计算RHS,计算完成后同时更新LHS。
举⼀个例⼦:`timescale 1ns/1nsmodule blocking ();reg[1:0] a,b,c;initial begina = 2'd1;b = 2'd2;c = 2'd3;#10a = 2'd0;b = a;c = b;$display("a=%d b=%d c=%d ",a,b,c);endendmodule运⾏结果为:若将上述代码的阻塞赋值都改为⾮阻塞赋值,则运⾏结果为:⼆. 赋值原则1. ⾮阻塞赋值只能⽤于寄存器型变量,只能在initial块和always块中使⽤。
阻塞赋值既可以⽤于寄存器型变量,也可以⽤于线⽹型变量。
2. 通常在设计可综合的RTL代码时,描述组合逻辑⽤阻塞赋值,描述时序逻辑⽤⾮阻塞赋值。
3. 在同⼀个块语句中描述组合逻辑和时序逻辑的混合逻辑时,⽤⾮阻塞赋值。
4. 尽量不要在同⼀个always块中同时使⽤阻塞赋值和⾮阻塞赋值。
5. 不能在多个always块中对同⼀个变量进⾏赋值(如果⽤两个always块对同⼀个变量赋值,⽆论其中经过了怎样的条件判断,最终都相当于将两个触发信号连在同⼀个寄存器的CLK端,这显然不合符数字逻辑电路的规则,这样的代码在综合时会报错)。
sv阻塞赋值和非阻塞赋值
sv阻塞赋值和非阻塞赋值1. 引言在硬件描述语言(HDL)中,阻塞赋值和非阻塞赋值是两种常见的赋值方式。
这两种方式在行为和实现上有一些区别,对于设计和模拟电路的工程师来说,理解它们的差异非常重要。
本文将详细介绍sv阻塞赋值和非阻塞赋值的概念、用法以及它们之间的区别。
2. sv阻塞赋值2.1 概念sv阻塞赋值是一种顺序执行的赋值方式,它在执行过程中会阻塞后续的代码执行,直到当前赋值完成。
在sv中,阻塞赋值使用“=”符号进行赋值操作。
2.2 用法sv阻塞赋值通常用于描述组合逻辑电路,其中信号的赋值会立即生效。
下面是一个简单的例子,展示了sv阻塞赋值的用法:module blocking_assignment;reg a, b;wire c;always @(a or b)beginc = a & b;// 其他代码endendmodule在上述代码中,当输入信号a或b发生变化时,阻塞赋值语句c = a & b;会被执行,并立即将结果赋值给信号c。
在阻塞赋值语句执行期间,其他代码会被阻塞,直到赋值完成。
2.3 特点sv阻塞赋值具有以下特点:•执行顺序:阻塞赋值按照代码的顺序执行,每次只能执行一个赋值语句。
•顺序执行:阻塞赋值是顺序执行的,每次只处理一个赋值语句,不会并行执行多个赋值操作。
•实时更新:阻塞赋值在赋值完成后立即更新信号的值,可以实时反映出信号的变化。
•代码简洁:阻塞赋值通常比非阻塞赋值的代码更简洁,易于理解和维护。
3. sv非阻塞赋值3.1 概念sv非阻塞赋值是一种并行执行的赋值方式,它不会阻塞后续的代码执行,而是在一个时钟周期结束后才会生效。
在sv中,非阻塞赋值使用“<=”符号进行赋值操作。
3.2 用法sv非阻塞赋值通常用于描述时序逻辑电路,其中信号的赋值会在时钟的上升沿或下降沿发生变化。
下面是一个简单的例子,展示了sv非阻塞赋值的用法:module nonblocking_assignment;reg clk, a, b;reg [3:0] count;always @(posedge clk)begina <= b;count <= count + 1;// 其他代码endendmodule在上述代码中,当时钟信号clk的上升沿到来时,非阻塞赋值语句a <= b;和count <= count + 1;会被执行,并在时钟周期结束后生效。
VerilogHDL 可综合设计的注意事项
VerilogHDL 可综合设计的注意事项一、逻辑设计(1)组合逻辑设计下面是一些用Verilog进行组合逻辑设计时的一些注意事项:①组合逻辑可以得到两种常用的RTL 级描述方式。
第一种是always 模块的触发事件为电平敏感信号列表;第二种就是用assign 关键字描述的数据流赋值语句。
②always 模块的敏感表为电平敏感信号的电路可几乎可以完成对所有组合逻辑电路的建模。
always模块的敏感列表为所有判断条件信号和输入信号,但一定要注意敏感列表的完整性(注意通配符*的使用)。
由于赋值语句有阻塞赋值和非阻塞赋值两类,建议读者使用阻塞赋值语句“=”,原因将在“阻塞赋值和非阻塞赋值”中(现在还没有写)进行说明。
always 模块中的信号必须定义为reg 型,不过最终的实现结果中并没有寄存器。
这是由于在组合逻辑电路描述中,将信号定义为reg 型,只是为了满足语法要求。
③assign 语句的描述,利用条件符“?”可以描述一些相对简单的组合逻辑电路,左边的赋值信号只能被定义为wire 型。
当组合逻辑比较复杂时,需要很多条语句assign 语句或者多重嵌套“?”,使得代码可读性极差,因此此时推荐always组合逻辑建模方式。
④设计时要注意不要出现组合逻辑环路:不要在组合逻辑中引入环路,在组合逻辑中引入环路会导致电路产生振荡、毛刺以及冲突等问题,从而降低设计的稳定性和可靠性,此外,环回逻辑的延时完全依靠组合逻辑门延迟和布线延迟。
一旦这些传播时延有所变化,则环路的整体逻辑将彻底失效。
其次,环路的时序分析是个死循环过程。
目前的EDA 开发工具为了计算环路的时序逻辑都会主动割断时序路径,引入许多不确定的因素。
因此要彻底避免环路。
(2)时序逻辑设计①时序电路的行为决定了其只能通过always 块语句实现,通过关键词“posedge”和“negedge”来捕获时钟信号的上升沿和下降沿。
在always 语句块中可以使用任何可综合的标志符。
精讲阻塞赋值非阻塞赋值
精讲阻塞赋值非阻塞赋值所谓阻塞赋值"="和非阻塞赋值"<="的的区别在于"="是直接赋值。
常见于组合逻辑当C=B;B=A;这种情况下,在一个时钟周期里,B和C可以同时等于A;也就是说这时候B 的原始数据将会丢失。
而<=是非阻塞赋值。
常见于时序逻辑,也就是与CLK有关的always块里,当C<=B;B<=A;此时C得到A的值需要两个时钟周期来完成,也就是第一个时钟周期A的值赋给B,第二个周期B赋给C。
也就是说B的原始数据在第一个时钟周期会保留在C中。
B非瞬间丢失。
所以阻塞可以理解成瞬间丢失;而非阻塞即可以理解成非瞬间丢失。
简单的就是阻塞理解成丢失。
非阻塞理解成非丢失。
看下面两个程序:1.module top(clk,a,c);input a,clk;output c;reg c,b;always @( posedge clk )beginb<=a;c<=b;endendmodule2.module top(clk,a,c);input a,clk;output c;reg c,b;always @( posedge clk )beginb=a;c=b;endendmodule第一个程序用的是非阻塞赋值,对其生成模块如下:clk信号的上升沿到来时,b就等于a,c就等于b,这里应该用到了两个触发器。
请注意:赋值是在"always"块结束后执行的,c应为原来b的值。
(这里的理解是,在第一拍时钟下,第二个触发器不可能取到a 值作为输入的D端,若采到即保持时间违例。
)第二个程序用的是阻塞赋值,对其生成模块如下:clk信号的上升沿到来时,将发生如下的变化:b马上取a的值,c马上取b的值(即等于a),生成的电路图如下所示只用了一个触发器来寄存器a的值,又输出给b和c。
下面从功能和执行时间上对其进行分析:阻塞赋值操作符用等号(即= )表示。
【转】VeriLogHDL阻塞性过程赋值与非阻塞性过程赋值
【转】VeriLogHDL阻塞性过程赋值与⾮阻塞性过程赋值VeriLog HDL 阻塞性过程赋值与⾮阻塞性过程赋值⾸先来看⼀下定义:阻塞性过程赋值 “=” :即,在下⼀条语句执⾏前,完成当前语句执⾏。
⾮阻塞性过程赋值 “<=”:即,在当前输出时间同步结束后,或者任意输出被调度时,完成该语句执⾏。
下⾯解释⼀下上⾯的说法,根据以上说法与实际综合来看,即:阻塞赋值 “=” 为同⼀个时钟时刻内赋值完成所有操作。
如果模块⽐较⼤,则会增加逻辑速度延迟开销。
⾮阻塞赋值 “<=” 为当且仅当下⼀个时钟到来时候,或者本次触发完毕,进⾏赋值操作。
如果模块⽐较⼤,则插⼊寄存器,增⼤逻辑模块数量开销。
下⾯我们看⼀段代码来通过综合⽐较上⾯的说法:1:“=”阻塞性赋值:`default_nettype wand`timescale 1ns/100psmodule top(clk,rst,d,q,qout);input clk,rst,d;output q,qout;reg q,qout;/*********************************/always @(posedge clk or negedge rst)beginif(!rst)beginq = 0;qout = 0;endelsebeginq = d;qout = ~q;endendendmodule通过以上代码⽣成电路如图所⽰:此图表明,在同⼀个时钟周期到来的时候,即完成 q 与qout 的完全赋值。
2:“<=”⾮阻塞性赋值:`default_nettype wand`timescale 1ns/100psmodule top(clk,rst,d,q,qout);input clk,rst,d;output q,qout;reg q,qout;/*********************************/always @(posedge clk or negedge rst)beginif(!rst)beginq <= 0;qout <= 0;endelsebeginq <= d;qout <= ~q;endendendmodule通过以上代码⽣成电路如图所⽰:此图表明,在下⼀个时钟周期或者本次时钟周期结束时才进⾏赋值操作。
systemverilog 赋值格式
SystemVerilog 是一种硬件描述语言(HDL),用于设计和验证数字电路。
在 SystemVerilog 中,赋值是一种常见且重要的操作,它可以用来为变量赋值、更新寄存器的值等。
而 SystemVerilog 中的赋值格式有多种,包括非阻塞赋值(nonblocking assignment)、阻塞赋值(blocking assignment)、连续赋值(continuous assignment)等。
本文将对这些赋值格式进行介绍,帮助读者更好地理解SystemVerilog 中的赋值操作。
一、非阻塞赋值(Nonblocking assignment)非阻塞赋值是 SystemVerilog 中最常用的赋值格式之一,它用来对寄存器进行赋值操作,通常用于时序逻辑中。
非阻塞赋值使用“<=”符号表示,语法格式为:reg [7:0] data;always @(posedge clk) begindata <= in_data;end在上述代码中,当时钟信号 clk 上升沿到来时,将 in_data 的值非阻塞地赋给 data 寄存器。
二、阻塞赋值(Blocking assignment)阻塞赋值也是 SystemVerilog 中常见的赋值格式之一,它用来对变量进行赋值操作,通常用于组合逻辑中。
阻塞赋值使用“=”符号表示,语法格式为:always @(posedge clk) beginsum = a + b;end在上述代码中,a 和 b 的值将阻塞地相加,并将结果赋给 sum 变量。
三、连续赋值(Continuous assignment)连续赋值主要用于对电路中的线网(wire)进行赋值操作,它可以在模块的顶层中使用。
连续赋值使用“assign”关键字表示,语法格式为:input a, b;output reg [7:0] result;assign result = a & b;在上述代码中,当 a 和 b 的值变化时,result 会连续地与 a 和 b进行逻辑与操作,并将结果赋给自己。
ASIC实验报告(8位CPU的设计)
ASIC设计实验报告学院:电子工程学院学号:2014*******姓名:***指导老师:***2014年11月13日一、实验目的:通过对ASIC实验课的学习,应当学会以下几点:1.熟悉Linux操作系统的应用环境,基本命令行的应用,以及对vi编辑器熟练应用。
2.熟练掌握Verilog编程语言,包括基本组合逻辑电路的实现方法,基本时序逻辑电路的实现方法,怎样使用预定义的库文件,利用always块实现组合逻辑电路的方法已经着重了解assign与always 两种组合逻辑电路实现方法之间的区别,深入了解阻塞赋值与非阻塞赋值的概念以及应用的差别,有限状态机(FSM)实现复杂时序逻辑的方法,以及学会在Linux 系统环境当中应用Synopsys工具VCS进行仿真。
3.熟悉电路设计当中的层次化、结构化的设计方法。
4.熟悉CPU当中有哪些模块组成,模块之间的关系,以及其基本的工作原理。
5.学会利用汇编语言设计程序,注意代码规范性要求。
二、实验要求:按照实验指导书上的要求即:CPU各个模块的Verilog语言代码的编写、编译及仿真正确,并在规定的时间内完成。
要求对CPU进行语言级系统仿真结果正确之后,利用该实验当中采用的八个汇编关键字,编写一个能够实现某种功能的小程序。
然后对其中的控制器电路进行综合,并检查Timing 和Power,进行门级仿真。
三、实验内容:设计一个8位RISC_CPU 系统。
(RISC: Reduced Instruction Set Computer),它是一种八十年代才出现的CPU,与一般的CPU相比,不仅只是简化了指令系统,而且通过简化指令系统使计算机的结构更加简单合理,从而提高了运算速度。
从实现的方法上,它的时序控制信号部件使用了硬布线逻辑,而不是采用微程序控制方式,故产生控制序列的速度要快的多,因为省去了读取微指令的时间。
此CPU所具有的功能有:(1)取指令:当程序已在存储器中时,首先根据程序入口地址取出一条程序,为此要发出指令地址及控制信号。
组合逻辑 阻塞赋值 时序逻辑 非阻塞赋值
组合逻辑阻塞赋值时序逻辑非阻塞赋值组合逻辑和时序逻辑是数字电路中两个基本概念,也是数字电路设计中最重要的两个概念之一。
组合逻辑和时序逻辑在数字电路设计中都有着非常重要的作用,而阻塞赋值和非阻塞赋值则是两者中的重要设计方式,本文将详细讲解这些概念。
组合逻辑是数字电路中的一种基本逻辑,其输出仅取决于输入,并不取决于时序的状态。
换句话说,组合逻辑的输出仅取决于输入的状态,而不受任何时序的限制。
在数字电路设计中,使用组合逻辑可以实现不同的功能,例如加法器、比较器、门等等。
而时序逻辑则与时序相关,其输出结果取决于当前时钟周期的状态和历史状态。
时序电路中,每个时钟周期的状态都会对下一个时钟周期的状态产生影响,因此时序电路需要考虑时序的限制和顺序。
时序逻辑的典型例子包括时钟、触发器、计数器等。
在数字电路设计中常常需要使用时序逻辑与组合逻辑相结合,以实现更加复杂的功能。
这时需要考虑如何设计合适的时序电路,使其能够与组合电路协同工作。
此时,就需要用到阻塞赋值和非阻塞赋值这两种重要的设计方式。
阻塞赋值是一种赋值方式,在阻塞赋值中,当前执行的语句必须等到前一个语句执行完成后才能继续执行。
在数字电路设计中,阻塞赋值通常用于时序逻辑中,以便建立电路的状态和寄存器之间的关系。
相比之下,非阻塞赋值则是一种不需要等待的赋值方式。
在非阻塞赋值中,当前赋值语句的执行不会受到其他语句的影响,它会立即执行,并将结果写入目标寄存器。
通常情况下,时序逻辑中使用阻塞赋值方式,而组合逻辑中使用非阻塞赋值方式。
这是因为在时序逻辑中,我们需要确保状态能够及时更新,因此需要等到前一个状态完成后才能执行下一个语句。
而在组合逻辑中,我们不需要考虑时序问题,因此使用非阻塞赋值更加高效。
在数字电路设计中,选择合适的赋值方式非常重要。
如果错误的使用赋值方式,会导致电路的错误和混乱,最终导致电路失效。
因此,在数字电路设计中,我们需要仔细地选择和使用赋值方式,以确保电路的正确性和稳定性。