VHDL非阻塞赋值理解(转载)
EDA-VerilogHDL期末复习题总结必过(最新整理)
选择题1.大规模可编程器件主要有FPGA、CPLD 两类,下列对FPGA 结构与工作原理的描述中,正确的是(C)。
A.FPGA 全称为复杂可编程逻辑器件;B.FPGA 是基于乘积项结构的可编程逻辑器件;C.基于SRAM 的FPGA 器件,在每次上电后必须进行一次配置;D.在Altera 公司生产的器件中,MAX7000 系列属FPGA 结构。
2.不完整的IF语句,其综合结果可实现(A)A. 时序逻辑电路B.组合逻辑电C. 双向电路D. 三态控制电路3.综合是EDA设计流程的关键步骤,在下面对综合的描述中,(D)是错误的。
A.综合就是把抽象设计层次中的一种表示转化成另一种表示的过程;B.综合就是将电路的高级语言转化成低级的,可与FPGA / CPLD的基本结构相映射的网表文件;C.为实现系统的速度、面积、性能的要求,需要对综合加以约束,称为综合约束;D.综合可理解为一种映射过程,并且这种映射关系是唯一的,即综合结果是唯一的。
4.大规模可编程器件主要有FPGA、CPLD两类,下列对FPGA结构与工作原理的描述中,正确的是( C )。
A. FPGA全称为复杂可编程逻辑器件;B. FPGA是基于乘积项结构的可编程逻辑器件;C. 基于SRAM的FPGA器件,在每次上电后必须进行一次配置;D. 在Altera公司生产的器件中,MAX7000系列属FPGA结构。
5.以下关于状态机的描述中正确的是(B)A.Moore型状态机其输出是当前状态和所有输入的函数B.与Moore型状态机相比,Mealy型的输出变化要领先一个时钟周期C.Mealy型状态机其输出是当前状态的函数D.以上都不对6.目前应用最广泛的硬件描述语言是(B)。
A. VHDLB. Verilog HDLC. 汇编语言D. C语言7.一模块的I/O 端口说明:“input [7:0] a;”,则关于该端口说法正确的是( A )。
A. 输入端口,位宽为8B. 输出端口,位宽为8C. 输入端口,位宽为7D. 输出端口,位宽为78.基于EDA 软件的FPGA / CPLD 设计流程为:原理图/HDL 文本输入→综合→___ __→→适配→编程下载→硬件测试。
从Verilog仿真原理看阻塞和非阻塞赋值
从Verilog仿真原理看阻塞和非阻塞赋值(续:例子)上一篇/ 下一篇 2006-09-12 00:21:49 / 天气: 晴朗/ 心情: 高兴查看( 577 ) / 评论( 6 ) / 评分( 4 / 0 )按照hwei的指示,我现在举一个例子再深入探讨一下Verilog的阻塞和非阻塞赋值,希望对大家有益,哈哈。
我看过很多文章都说,阻塞赋值适合组合逻辑建模,而非阻塞赋值适合时序逻辑建模。
事实上,在大多数情况下,这样做是正确的。
但是,在某些情况下,不能片面地这样理解。
下面是我以前编的一个匹配滤波器的例子,为了方便理解我截取了其中一段程序:reg signed [5:0] corr_reg;always @ (posedge clk,negedge SysRst_n) beginif (!SysRst_n) begin......endelse begincorr_reg = 0; //寄存器清零for (i = 0;i <= 10;i = i + 1) beginif (barker_code[i] == 1)corr_reg = corr_reg + funcmapping(datain_mem[i]);//funcmapping为自定义函数,目的就是将1bit的数据映射成3位有符号数,以方便求相关值.else if (barker_code[i] == 0)corr_reg = corr_reg - funcmapping(datain_mem[i]);end.....endend我的意图就是,通过匹配滤波的方式并行捕获扩频数据流中的隐含11位barker码,从而完成解扩中的码同步。
datain_mem是11位宽的寄存器,用于存储输入数据(即barker码的扩频数据)的镜像延时。
在捕获的过程中,根据本地barker码的值,来决定corr_reg是加上funcmapping(datain_mem[i])的值,还是减去,从而得到相关值。
任务3 VHDL的赋值语句
nand2_2 OF nand2 IS --结构体2:行为描述方
CONFIGURATION
pz OF nand2 IS
--配置语句,
指明用哪一个结构体 FOR nand2_1 END FOR; END CONFIGURATION;
ENTITY mux21a IS ――实体说明,定义实体名为 mux21 PORT(a,b:IN BIT; ――输入端口说明,定义a,b,s 为输入端口信号 s:IN BIT; y:OUT BIT); ――输出端口说明,定义y为 输出端口信号 END ENTITY mux21a; ARCHITECTURE one OF mux21a IS ――结构体说明 BEGIN y﹤﹦a WHEN s=‘0‟ ELSE ――当s=0时,y=a b; ――当s≠0时,y=b END ARCHITECTURE one;
WITH s SELECT x <= a WHEN ”000” | “001” | “010”, b WHEN "101" | "111", c WHEN OTHERS; 表示或逻辑
构造体 说明语句
构 造 体 结 构 图
功能描述语句 块语句
进程语句 信号赋值语句 子程序调用语句 元件例化语句
进程语句
进程和进程之 间是并行的 进程和进程之 间的数据交换 通过信号完成 进程内部是顺 序语句
PROCESSn
进程语句
基本格式:
[进程名称:] PROCESS(敏感信号1,敏感信号2,……)
〈说明区〉 BEGIN 〈顺序语句〉 END PROCESS [进程名称];
LIBRARY IEEE; --调用IEEE库 USE IEEE.STD_LOGIC_1164.ALL; --调用IEEE库 中的STD_LOGIC_1164.ALL程序包 ENTITY nand2 IS --实体说 (PORT a,b: IN STD_LOGIC; --输入端口说明 Y: OUT STD_LOGIC); --输出端口说明 END nand2; ARCHITECTURE nand2_1 OF nand2 IS --结构体1: 数据流描述方式 BEGIN y﹤﹦a NAND b; --简单并行信号赋值语 句 END nand2_1;
verilog的阻塞和非阻塞赋值
这几天都在看这个经典问题,阻塞和非阻塞赋值,有点收获,也有很多疑问!一、特点:阻塞赋值:1、RHS的表达式计算和LHS的赋值更新,这两个动作之间不能插入其他动作,即所谓计算完毕,立即更新。
2、所谓阻塞就是指在一个“begin...end”块中的多个阻塞赋值语句内,只有上一句完全执行完毕后,才会执行下一语句,否则阻塞程序的执行。
非阻塞赋值:RHS的表达式计算和LHS的赋值更新分两个节拍执行,首先,应该是RHS 的表达式计算,得到新值后并不立即赋值,而是放在事件队列中等待,直到当前仿真时刻的后期才执行(原因下文会提到)。
二、V erilog的分层事件队列:在Verilog中,事件队列可以划分为5个不同的区域,不同的事件根据规定放在不同的区域内,按照优先级的高低决定执行的先后顺序,下表就列出了部分Verilog分层事件队列。
其中,活跃事件的优先级最高(最先执行),而监控事件的优先级最低,而且在活跃事件中的各事件的执行顺序是随机的(注:为方便起见,在一般的仿真器中,对同一区域的不同事件是按照调度的先后关系执行的)。
三、结论:由上表就可以知道,阻塞赋值属于活跃事件,会立刻执行,这就是阻塞赋值“计算完毕,立刻更新”的原因。
此外,由于在分层事件队列中,只有将活跃事件中排在前面的事件调出,并执行完毕后,才能够执行下面的事件,这就可以解释阻塞赋值的第二个特点。
同样是由上表知,非阻塞赋值的RHS计算属于活跃事件,而非阻塞赋值更新事件排在非活跃事件之后,因此只有仿真队列中所有的活跃事件和非活跃事件都执行完毕后,才轮到非阻塞赋值更新事件,这就是非阻塞赋值必须分两拍完成的原因。
但是我有很多疑问,何为当前仿真时间,我认为是在当前CLK触发周期内,但是我使用了很多小程序来验证非阻塞赋值的时序列,结果却与理论不同,对于这个问题,仍然在疑惑中~~~在Verilog HDL中,有两种过程性赋值方式,即阻塞式(blocking)和非阻塞式(no n-blocking)。
VHDL中信号赋值语句的讨论
VHDL中信号与变量赋值语句的讨论一信号与变量赋值语句的理论基础信号声明在子程序、进程等外部,并可以在几个不同的进程里作用;而变量声明在子程序、进程等内部。
信号与变量的赋值不同:在进程中,信号赋值在进程结束时起作用,而变量赋值是立即起作用的。
如果在一个进程中多次为一个信号赋值时,只由最后一个值会起作用;而当为变量赋值时,变量值的改变是立即发生的。
即变量将保持着当前值,直到被赋予新的值。
顺序语句只存在于进程和子程序内部。
二信号的赋值(一) 进程外部信号的赋值(1)进程外部不能为同一信号多次赋值在进程的外部,我们不能够为同一信号多次赋值。
例1:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity test isport(a,b:in std_logic_vector(3 downto 0);s:buffer std_logic_vector(3 downto 0);y:out std_logic_vector(3 downto 0));end entity test;architecture one of test isbegins<=a;y<=s+1;s<=a+b;end architecture one;在例1程序中,我们对信号s进行了多次赋值,经过仿真,系统报如下错误:ERROR: Signal “s” has multiple sources。
(2)进程外部对信号的赋值在进程外部几个信号的赋值语句是并行执行的。
即信号赋值语句中的信号发生变化,便执行该条赋值语句。
例2:library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity test isport(a,b:in std_logic_vector(3 downto 0);s:buffer std_logic_vector(3 downto 0);y:out std_logic_vector(3 downto 0));end entity test;architecture one of test isbeginy<=s+1;s<=a+b;end architecture one;在例2的程序中,如果a或b发生变化,则执行语句s<=a+b;因为a或b变化,影响使得s变化,则执行语句y<=s+1。
Verilog_HDL中阻塞赋值与非阻塞赋值的区别与应用
Verilog HDL中阻塞赋值与非阻塞赋值的区别与应用张文波摘要:Verilog HDL语言是世界上应用最广泛的硬件描述语言之一。
在Verilog HDL语言中最容易混淆的概念之一就是阻塞赋值与非阻塞赋值,甚至一些非常有经验的Verilog HDL设计师也不能完全理解为什么和什么时候使用阻塞赋值和非阻塞赋值。
本文详细阐述了阻塞赋值与非阻塞赋值的概念和区别,通过仿真和举例进一步解释了阻塞赋值与非阻塞赋值在工程中的典型应用和技巧。
本文中的所有程序代码,在ISE10.1应用软件中均测试通过,可以直接引用。
关键词:阻塞赋值;非阻塞赋值;仿真中图分类号:TP368文献标识码:The Difference and Application of Blocking assignment and Nonblocking assignment in Verilog HDLZHANG Wen-bo(China Airboren Missile Academy, Henan Luoyang 471000, China)ABSTRACT:In the world,one of the most extensive hardware description language is Verilog HDL.One of the most misunderstood constructs in the Verilog language is the blocking assignment and nonblocking assignment,even very experienced Verilog designers do not understand when and why blocking assignment and nonblocking assignment should be used.This paper details the difference and the constructs of the blocking assignment and nonblocking assignment,and makes a further explanation about the typical application and skills whit the simulation and examples.In this paper,all of the code were validated by ISE10.1.KEYWORDS:blocking assignment; nonblocking assignment; simulation1 引言Verilog HDL语言是目前世界上最流行的硬件描述语言之一,被广泛的应用于基于可编程逻辑器件的项目开发。
VHDL非阻塞赋值理解(转载)
在always语句块中,verilog语言支持两种类型的赋值:阻塞赋值和非阻塞赋值。
阻塞赋值使用“=”语句;非阻塞赋值使用“<=”语句。
注意,千万不要将这两种赋值方法与assign赋值语句混淆起来,assign赋值语句根本不允许出现在always语句块中。
位于begin/end块内的多条阻塞赋值语句是串行执行的,这一点同标准的程序设计语言是相同的。
但是多条非阻塞赋值语句却是并行执行的,这些非阻塞赋值语句都会在其中任何一条语句执行完成之前开始执行。
这正是硬件电路的特点,因为实际的逻辑门电路都是独立运转的,而不是等到其他门电路运转结束之后自己才开始运转。
下面我们以描述移位寄存器的两种方法为例来讲述两种赋值类型的区别。
在下面的这种描述中,第一个触发器中的数据被移到第二个触发器中,第二个触发器中的数据被移到第三个触发器中……如此继续下去,直到最后一个触发器中的数据被移出该寄存器为止。
1module shiftreg (input clk,2input sin,3outout reg [3:0]q);//这是正确使用非阻塞赋值的实例4a lways @(posedge clk)5b egin6q[0] <= sin;//非阻塞赋值:<=7q[1] <= q[0];8q[2] <= q[1]9q[3] <= q[2];10//这里写作q <= {q[2:0],sin};更简单更好一些11e nd12endmodule非阻塞赋值语句的功能是使得所有语句右侧变量的值都同时被赋给左侧的变量。
因此,在上面的实例中,q[1]得到的是q[0]的原始值,而非sin的值(在第一条语句中,sin的值被赋给了q[0])。
这正是我们期望得到的实际硬件电路。
当然,我们可以把上边的四条语句合并写成一条简短的语句:q<={q[2:0],sin}。
阻塞赋值语句的功能更接近于传统的程序设计语言,但是阻塞赋值语句并不是准确的硬件工作模型。
【干货分享】Verilog中阻塞和非阻塞赋值金规
对于VerilogHDL语言中,经常在always模块中,面临两种赋值方式:阻塞赋值和非阻塞赋值。
对于初学者,往往非常迷惑这两种赋值方式的用法,本章节主要介绍这两种文章的用法。
其实,有时候概念稍微不清楚,Bug就会找到我们,下面一文扫清阻塞赋值和非阻塞赋值所有的障碍。
基本概念阻塞赋值(Blocking Assignment)阻塞赋值的基本描述格式为:[变量] = [逻辑表达式];阻塞赋值在执行的时候,右端表达式执行并赋值到左边变量,不会受任何情况打断。
所以在本次赋值结束之前他“阻塞”了当前其他的赋值任务,阻塞赋值的操作和C语言中的变量赋值非常相似。
1. 非阻塞赋值(Nonblocking assignment)非阻塞赋值的基本描述格式为:[变量] <= [逻辑表达式];非阻塞赋值行为有些细微之处比较难以理解。
我们最好从硬件角度来理解,always模块可以被认为是纯硬件模块,当always模块被激活时,非阻塞赋值的右侧表达式就开始执行;当always模块所有表达式执行结束之后,所有执行结果才赋值到左侧变量当中。
之所以称为“非阻塞”就是在本条赋值语句执行的过程中,其他赋值语句也可以执行。
金规1在组合逻辑电路描述中采用阻塞赋值阻塞赋值和非阻塞赋值虽然都可以用来描述同一电路,以1位比较器举例来解释这种差别。
阻塞赋值实现1bit比较器module eq1_block(input wire i0, i1,output reg eq);reg p0, p1;always @(i0,i1) // i0 和i1 在敏感量列表当中// 语句描述的顺序非常关键beginp0 = ~i0 & ~i1;p1 = i0 & i1;eq = p0 | p1;endendmodule分析:程序中,敏感量列表中包含i0和i1,只要这两个变量有一个发生改变,都会激活always语句,那么p0、p1和eq就会顺序赋值,最终eq赋值就会被更新,所以这三条语句的描述顺序非常关键,假如将最后一条语句提前:always @(i0,i1)begineq = p0 | p1;p0 = ~i0 & ~i1;p1 = i0 & i1;end在第一条描述中,由于p0和p1还没有被赋予新值,所以p0和p1依然保持原来的赋值,这样得到的最终结果显然是错误的。
阻塞和非阻塞赋值语句的用法
例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规定,被赋值 的目标变量接受最接近过程结束的那一个 驱动源的数据。
个人总结阻塞赋值和非阻塞赋值的区别
关于阻塞复制和非阻塞赋值
阻塞赋值和非阻塞赋值的区别
阻塞赋值=
阻塞性过程赋值在其后所有语句执行前执行,即在下一语句执行前该赋值语句完成执行。
非阻塞赋值<=
过程赋值中,对目标的赋值是非阻塞的(因为延时),但可预订在将来某个时间步发生(根据时延;如果是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经过触发器了.。
vhdl不同位宽赋值 -回复
vhdl不同位宽赋值-回复VHDL不同位宽赋值VHDL(VHSIC Hardware Description Language)是一种硬件描述语言,常用于数字电路设计和仿真。
在VHDL中,不同位宽的信号可以被赋值给其他信号,但是需要注意一些细节和规则。
本文将逐步回答关于VHDL不同位宽赋值的问题,并提供相关的示例说明。
1. 什么是VHDL位宽?VHDL位宽指的是信号或者变量的宽度,也就是它所占用的比特数。
比如,一个8位宽的信号表示该信号可以容纳8个二进制位。
2. 如何在VHDL中声明不同位宽的信号?在VHDL中,可以使用`std_logic_vector`来声明不同位宽的信号。
`std_logic_vector`是一个用于存储多个二进制位的数据类型,可以表示任意位宽的信号。
下面是一个例子:vhdlsignal a : std_logic_vector(7 downto 0); 8位宽信号signal b : std_logic_vector(3 downto 0); 4位宽信号在上面的例子中,信号`a`被声明为一个8位宽的`std_logic_vector`类型,信号`b`被声明为一个4位宽的`std_logic_vector`类型。
3. 如何将不同位宽的信号进行赋值?在VHDL中,可以使用`resize`函数将不同位宽的信号进行赋值。
`resize`函数可以将目标信号调整为指定的位宽,它会将目标信号的位宽扩展或者截断至指定的位宽。
下面是一个例子:vhdlb <= resize(a, 4); 将8位宽信号a赋值给4位宽信号b在上面的例子中,函数`resize`被用于将8位宽信号`a`赋值给4位宽信号`b`。
`resize`函数会将信号`a`的位宽扩展或者截断至4位宽。
4. 如何处理不同位宽信号的溢出?在VHDL中,如果将一个较大位宽的信号赋值给一个较小位宽的信号,可能会导致赋值过程中的溢出。
EDA技术与Verilog_HDL(潘松)第四章与第六章课后习题答案
4-5 用Verilog设计一个3-8译码器,要求分别用case语句和if_else语句。比 较这两种方式。
4-5 用Verilog设计一个3-8译码器,要求分别用case语句和if_else语句。比较这两 种方式。
module decoder3_8 ( G1 ,Y ,G2 ,A ,G3 ); input G1, G2, G3; wire G1, G2, G3; input [2:0] A ; wire [2:0] A ; output [7:0] Y ; reg [7:0] Y ; reg s; always @ ( A ,G1, G2, G3) begin s <= G2 | G3 ; if (G1 == 0) Y <= 8'b1111_1111; else if (s) Y <= 8'b1111_1111; else case ( A ) 3'b000: Y = 8'b11111110; 3'b001: Y = 8'b11111101; 3'b010: Y = 8'b11111011; 3'b011: Y = 8'b11110111; 3'b100: Y = 8'b11101111; 3'b101: Y = 8'b11011111; 3'b110: Y = 8'b10111111; 3'b111: Y = 8'b01111111; default:Y = 8'bxxxxxxxx; endcase end endmodule
reg [2:0]A ;
wire[7:0]Y ; reg G1 ,G2 ,G3;
decoder3_8 DUT ( G1 ,Y ,G2 ,A ,G3 );
verilog HDL 名词解释和程序 期末试卷重点
名词解释:1.EDA:是电子设计自动化的缩写,EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言VHDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。
2.HDL:硬件描述语言,是一种以文本形式描述数字电路和数字系统的语言,是指对硬件电路进行行为描述、寄存器传输描述或者结构化描述的一种新兴语言。
3.FPGA(:现场可编程逻辑门阵列,它采用了逻辑单元阵列LCA这样一个概念,内部包括可配置逻辑模块CLB、输入输出模块IOB和内部连线三个部分。
FPGA利用小型查找表(16×1RAM)来实现组合逻辑。
4.CPLD:复杂的可编程逻辑器件, 主要是由可编程逻辑宏单元围绕中心的可编程互连矩阵单元组成。
是一种用户根据各自需要而自行构造逻辑功能的数字集成电路。
其基本设计方法是借助集成开发软件平台,用原理图、硬件描述语言等方法,生成相应的目标文件,通过下载电缆(“在系统”编程)将代码传送到目标芯片中,实现设计的数字系统。
5.IP: IP是知识产权核或知识产权模块,用于ASIC或FPGA/CPLD中的预先设计好的电路功能模块。
6.Testbench: 在设计数字电路系统时,通常将测试模块和功能模块分开设计,其中测试模块也称测试台(Testbench)。
Testbench是通过对设计部分施加激励,然后检查其输出正确与否来完成其验证功能的。
7.reg:是寄存器数据类型的关键字,其表示一个抽象的数据存储单元。
reg只能在initial和always 中赋值。
而reg在过程赋值语句中使用。
reg型数据常用来表示always模块内的指定信号,代表触发器。
通常在设计中要由always模块通过使用行为描述语句来表达逻辑关系。
在always块内被赋值的每一个信号都必须定义为reg型。
8.wire:是最常用的Net型变量。
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)传输延时相对于惯性延时更容易理解,相当于信号通过了一条拥有固定延时的传输线。
精讲阻塞赋值非阻塞赋值
精讲阻塞赋值非阻塞赋值所谓阻塞赋值"="和非阻塞赋值"<="的的区别在于"="是直接赋值。
常见于组合逻辑当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。
下面从功能和执行时间上对其进行分析:阻塞赋值操作符用等号(即= )表示。
Verilog中的阻塞与非阻塞的赋值分析
--------------------
在给出进一步的阻塞与非阻塞赋值语句的解释和例子之前,让我们来先看看8条有助于正
确对硬件的仿真、verilog建模的指导性原则。如果能够坚持这些原则,可以消除多数
Verilog设计人员遇到的90%-100%竞争情况。
规则 #1: 建立时序逻辑模型时,采用非阻塞赋值语句。
6.0 Verilog的 "层次事件队列"
----------------------------
一个Verilog的"层次事件队列"的验证(见图1)有助于解释Verilog如何阻塞和不阻塞赋值
功能。"层次事件队列"是一个抽象的名字,它代表了安排仿真事件的不同的Verilog事件
队列。
"层次事件队列"在IEEE Verilog标准中是一个概念模型。至于各个商家如何实现事件队
* 原则一:在always块中使用阻塞的赋值方式以生成组合逻辑[引文1].
* 原则一:在always块中使用非阻塞的赋值方式以生成时序逻辑[引文1].
为什么?总的来说,这是跟仿真(simulation)相关。如果忽视以上的规则,仍然可以综
合出正确的逻辑,但是前仿真的结果有可能和综合后的电路的表现不一样,即仿真不可
一个时间步执行,比如说在同一个时钟沿。如果阻塞赋值没有正确的顺序,竞争可能会
出现。当阻塞式的赋值语句安排在同一时间步执行时,他们执行的次序是不知道的。
为了验证以上观点,请看下例1.
module fbosc1 (y1, y2, clk, rst);
output y1, y2;
【转】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通过以上代码⽣成电路如图所⽰:此图表明,在下⼀个时钟周期或者本次时钟周期结束时才进⾏赋值操作。
Verilog中阻塞和非阻塞赋值原则
Verilog中阻塞和非阻塞赋值原则阻塞赋值操作符 =阻塞赋值是指当前的赋值语句阻断了其后的语句,也就是说后面的语句必须等到当前的赋值语句执行完毕才能执行。
阻塞赋值可以看成是一步完成的,即计算等号右边的值并同时赋给左边变量。
例如:采用阻塞赋值实现四选一多路选择器。
module mux4_to_1 (out, i0, i1, i2, i3, s0, s1);output out;input i0,i1,i2,i3,s0,s1;reg out;always @(s1 or s0 or i0 or i1 or i2 or i3)begincase ( {s1, s0} )2'b00: out = i0;2'b01: out = i1;2'b10: out = i2;2'b11: out = i3;default: out = 1'bx;endcaseendendmodule非阻塞赋值非阻塞赋值操作符<=非阻塞赋值是指在过程块中,当前的赋值语句不会阻断其后的语句。
非阻塞赋值操作只能用于对寄存器型变量进行赋值,因此只能用在'initial'块和'always'块等过程块中。
非阻塞赋值不允许用于连续赋值。
例如:采用非阻塞赋值实现移位寄存器。
module mux4_to_1 (q3, d, clk);output [7:0] q3;input [7:0] d;input clk;reg [7:0] q3, q2, q1;always @(posedge or clk)beginq1 <= d;q2 <= q1;q3 <= q2;endendmodule简单理解就是,阻塞赋值是按需执行,非阻塞赋值是并行执行。
在编写Verilog代码时,要牢记:•时序电路建模时,用非阻塞赋值。
•锁存器电路建模时,用非阻塞赋值。
•用always块建立组合逻辑模型时,用阻塞赋值。
(完整)verilog考试题
西安电子科技大学考试时间分钟试题班级学号姓名任课教师一、选择题(每题2分,共18分)1. 下面哪个是可以用verilog语言进行描述,而不能用VHDL语言进行描述的级别?( A )(A) 开关级(B)门电路级 (C)体系结构级 (D) 寄存器传输级2.在verilog中,下列语句哪个不是分支语句?( D )(A) if—else (B) case (C) casez (D) repeat3.下列哪些Verilog的基本门级元件是多输出( D )(A) nand (B) nor (C) and (D) not4.Verilog连线类型的驱动强度说明被省略时,则默认的输出驱动强度为( B )(A) supply (B) strong (C) pull (D) weak5。
元件实例语句“notif1 #(1:3:4,2:3:4,1:2:4) U1(out,in,ctrl);”中截至延迟的典型值为( B )(A) 1 (B) 2 (C) 3 (D) 46.已知“a =1b’1;b=3b’001;”那么{a,b}=( C )(A) 4b’0011 (B) 3b’001 (C) 4b'1001 (D) 3b’1017.根据调用子模块的不同抽象级别,模块的结构描述可以分为(ABC )(A) 模块级 (B)门级 (C) 开关级 (D) 寄存器级8.在verilog语言中,a=4b'1011,那么 &a=(D )(A) 4b’1011 (B) 4b’1111 (C) 1b'1 (D) 1b'09.在verilog语言中整型数据与( C )位寄存器数据在实际意义上是相同的。
(A) 8 (B) 16 (C) 32 (D) 64二、简答题(2题,共16分)1.Verilog HDL语言进行电路设计方法有哪几种(8分)1、自上而下的设计方法(Top—Down)2、自下而上的设计方法(Bottom—Up)3、综合设计的方法2.specparam语句和parameter语句在参数说明方面不同之处是什么(8分)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在always语句块中,verilog语言支持两种类型的赋值:阻塞赋值和非阻塞赋值。
阻塞赋值使用“=”语句;非阻塞赋值使用“<=”语句。
注意,千万不要将这两种赋值方法与assign赋值语句混淆起来,assign赋值语句根本不允许出现在always语句块中。
位于begin/end块内的多条阻塞赋值语句是串行执行的,这一点同标准的程序设计语言是相同的。
但是多条非阻塞赋值语句却是并行执行的,这些非阻塞赋值语句都会在其中任何一条语句执行完成之前开始执行。
这正是硬件电路的特点,因为实际的逻辑门电路都是独立运转的,而不是等到其他门电路运转结束之后自己才开始运转。
下面我们以描述移位寄存器的两种方法为例来讲述两种赋值类型的区别。
在下面的这种描述中,第一个触发器中的数据被移到第二个触发器中,第二个触发器中的数据被移到第三个触发器中……如此继续下去,直到最后一个触发器中的数据被移出该寄存器为止。
1module shiftreg (input clk,
2input sin,
3 outout reg [3:0]q);//这是正确使用非阻塞赋值的实例
4always @(posedge clk)
5begin
6 q[0] <= sin;//非阻塞赋值:<=
7 q[1] <= q[0];
8 q[2] <= q[1]
9 q[3] <= q[2];
10//这里写作q <= {q[2:0],sin};更简单更好一些
11end
12endmodule
非阻塞赋值语句的功能是使得所有语句右侧变量的值都同时被赋给左侧的变量。
因此,在上面的实例中,q[1]得到的是q[0]的原始值,而非sin的值(在第一条语句中,sin的值被赋给了q[0])。
这正是我们期望得到的实际硬件电路。
当然,我们可以把上边的四条语句合并写成一条简短的语句:q<=
{q[2:0],sin}。
阻塞赋值语句的功能更接近于传统的程序设计语言,但是阻塞赋值语句并不是准确的硬件工作模型。
下面考虑使用阻塞赋值语句来实现同一模块可以得到什么结果。
在始终clk的上升沿,verilog将会把sin的值赋给q[0],然后q[0]的新值被赋给q[1],如此继续执行下去。
最终所有的四个寄存器都会得到相同的值:sin的值。
本部分内容用意在于:讲述使用always语句块对时序逻辑电路进行建模的时候,如何使用非阻塞赋值。
如果设计者能够充分的灵活应用,比如倒转上例中四条语句的顺序,那么使用阻塞赋值语句仍然能实现相应的功能,但是与使用非阻塞赋值的方法相比,这种方法并不会带来任何好处,相反还暗藏了巨大的风险。
最后需要注意的是:每个always语句块都隐含表示一个独立的逻辑电路模块。
因此,对于特定的
reg类型的变量,只能在一个always语句块中对其进行赋值;否则就可能会出现两个硬件模块同时从同一个输出端口输出数据的情况,这种情况一般称为短路输出(shorted output)。
过程赋值语句多用于对reg型变量进行复制,过程赋值有阻塞复制和非阻塞赋值两种。
非阻塞赋值的符号为:<=
阻塞赋值符号为:=
(1)非阻塞赋值的例子:
reg c,b;
always@(posedge clk)
begin
b <= a;
c <= b;
end
(2)阻塞赋值的例子:
reg c,b;
always @ (posedge clk)
begin
b = a;
c = b;
end
上述例子中,使用非阻塞赋值方法,其中的每个<=都可以理解为一个寄存器。
而在同一个时钟下面采用的非阻塞赋值方法,模块内所有寄存器都同时随时钟跳变。
这是硬件处理的精髓,也是时序电路中大量使用非阻塞赋值的原因。
在实际书写verilog HDL代码的过程中,对于always中reg型变量,如果不是处理组合逻辑,尽量不使用阻塞赋值的方法。
这主要是基于代码的可综合性考虑的,因为在verilog HDL代码编译的时候,对于有些从后编译的编译器,阻塞赋值会找成时序上与预想的不一致。
对于以上阻塞赋值的例子,采用非阻塞方法应该写为
reg c,b;
always @ (posedge clk)
begin
b <= a;
c <= a;
end
实现电路和原方法一样。
而在always用于组合逻辑中,采用阻塞赋值表明未使用寄存器。
如
reg a,A,B,f_a;
always @ (a or A or B)
begin
f_a = a ?A : B;
end
以下是使用阻塞和非阻塞赋值应遵循的一些基本原则,这些原则有利于防止竞态(race condition)的发生。
(1)当用always块来描述组合逻辑(combinational logic)时,应当使用阻塞赋值。
(2)对于时序逻辑(sequential logic)的描述和建模,应当使用非阻塞赋值。
(3)在同一个always模块中,最好不要混合使用阻塞赋值和非阻塞赋值,对同一变量既进行阻塞赋值,又进行非阻塞赋值,在综合时会出错。
所以always中要么全部使用非阻塞赋值,要么把阻塞赋值和非阻塞赋值分在不同的always中书写。
(4)尽量不要再在多个不同的always块中对同一变量赋值。
(5)使用$strobe显示使用非阻塞赋值的变量。
在Verilog HDL中,有两种过程性赋值方式,即阻塞式(blocking)和非阻塞式(non-blocking)。
这两种
赋值方式看似差不多,其实在某些情况下却有着根本的区别,如果使用不当,综合出来的结果和你所想得到的结果会相去甚远。
Tip:所谓过程性赋值就是指在initial或always语句内的赋值,它只能对寄存器数据类型的变量赋值。
阻塞式(blocking)的操作符为“= ”
非阻塞式(non-blocking)的操作符为“ <= ”
首先,我们通过两个例子来看看这两种赋值方式的区别,这里使用的综合工具为Qt ii。
例1:非阻塞式赋值
module
test_non_blocking
(
input clk,
input testa,
input testb,
input testc,
input testd,
output reg testout
);
reg testreg;
always @ (posedge clk)
begin
testreg <= testb | testc;
begin
if (testa) begin
testout <= testreg & testd;
end
else begin
testout <= testd;
end
end
end
endmodule
例1综合后的结果为
例2:阻塞式赋值
module
test_blocking
(
input clk,
input testa,
input testb,
input testc,
input testd,
output reg testout
);
reg testreg;
always @ (testa,testb.testc,testd) begin
testreg = testb | testc;
begin
if (testa) begin
testout = testreg & testd;
end
else begin
testout = testd;
end
end
end
endmodule
例2综合后的结果为:
分析:
可以看到,例1和例2的code写法完全一样,只是在always语句块中使用了不同的赋值方式,就导致综合出来的结果不同。
在例1中,是非阻塞式赋值方式,非阻塞式赋值的赋值对象总是在当前仿真时刻结束时被赋值,所以,当在对语句2中的testout赋值这一时刻,testreg 值还没有得到语句1中的新值,而是原来的值(即上一个时刻的值)。
而在例2中,使用了阻塞式赋值方式,就是在always语句块中是一句一句执行的。
在执行语句2之前,语句1就已经执行完成,testreg被赋好了新值,所以语句2中的testreg值取的是新值。
建议:
1. 阻塞式赋值用于组合逻辑建模;
2. 非阻塞式赋值用于时序逻辑建模。