Verilog基础语法(10)之赋值语句

文章详细介绍了Verilog编程语言中的三种赋值方式:过程性赋值、连续赋值和过程连续赋值。过程性赋值常用于always和initial块,变量的值会保持不变直到下次赋值;连续赋值用于组合逻辑,当右值改变时立即更新线网;过程连续赋值包括assign...deassign和force...release,用于临时覆盖变量或线网的赋值。
摘要由CSDN通过智能技术生成

赋值语句将值放到线网或者变量上,它有三种基本形式:

  • 过程性赋值
  • 连续赋值
  • 过程连续赋值

赋值要求

一个赋值语句有两个部分–右值(RHS)和左值(LHS),中间有一个相等的符号(=)或一个小于相等的符号(<=)。
=为阻塞赋值,<=为非阻塞赋值。
在过程性赋值中,合理的左值应该是:

  • 变量(矢量/标量)
  • 向量reg、integer或time变量的位选择或部分选择。
  • 存储器(Memory word)
  • 上述任何一项的合并

过程赋值通常发生在块语句中,例如initial块,always块,还有task以及function中。

在连续性赋值中,合理的左值应该是:

  • 线网(矢量/标量)
  • 矢量线网的位选择或部分选择。
  • 位选择和部分选择的合并

连续性赋值通常发生在assign中。

在过程连续性赋值中,合理的左值应该是:

  • 线网或者变量(向量/标量)
  • 线网向量的位选择或者部分选择

RHS可以包含任何计算为最终值的表达式,而LHS表示一个线网或一个变量,RHS中的值被赋值给它。
例如:

module tb;
	reg clk;
	reg a, b, c, d, e;
	wire f, y;
	reg  z;

	// clk is on the LHS and the not of clk forms RHS
	always #10 clk = ~clk;

	// y is the LHS and the constant 1 is RHS
	assign y = 1;

	// f is the LHS, and the expression of a,b,d,e forms the RHS
	assign f = (a | b) ^ (d & e);

	always @ (posedge clk) begin
		// z is the LHS, and the expression of a,b,c,d forms the RHS
		z <= a + b + c + d;
	end

	initial begin
		// Variable names on the left form LHS while 0 is RHS
		a <= 0; b <= 0; c <= 0; d <= 0; e <= 0;
		clk <= 0;
	end
endmodule

过程性赋值

过程性赋值发生在always、initial、task和函数中,用于将值放到变量上。变量将保持该值,直到下一次对同一变量的赋值。

reg [7:0]  data;
integer    count;
real       period;

initial begin
	data = 8'h3e;
	period = 4.23;
	count = 0;
end

always @ (posedge clk)
	count <= count + 1;

当仿真在仿真时间内的某一时刻执行该语句时,该值将被放到变量上。这可以通过使用控制流语句,如if-else-if、case语句和循环机制来控制和修改我们想要的方式。

变量声明赋值

一个初始值可以在变量声明时被放置到变量上,如下图所示。这个赋值没有持续时间,并且在下一次对同一变量的赋值发生之前保持这个值。

注意,不允许将变量声明赋值用给数组。

连续复制

这用于将值分配到标量线网和矢量线网上,只要RHS发生变化就会发生。它提供了一种不需要指定门的互连就能建立组合逻辑模型的方法,并使其更容易用逻辑表达式来驱动线网。

// Example model of an AND gate
wire  a, b, c;

assign a = b & c;

每当b或c的值发生变化时,RHS中的整个表达式将被计算,a将被更新为新的值。

注意:我们仍然可以在线网声明的时候进行连续赋值,例如:

wire  penable = 1;

但我们必须谨慎使用,因为一个网只能声明一次,所以一个网只能有一次声明赋值。

也就是说,一旦我们在声明wire变量的时候进行了连续赋值,后面则不能再次连续赋值,否则就是多驱动。

过程连续性赋值

有两种类型:

  • assign … deassign
  • force … release

assign … deassign

这将覆盖变量的所有过程性赋值,并通过使用与deassign相同的信号来停用。变量的值将保持不变,直到变量通过过程化或过程化连续赋值获得新的值。赋值语句的LHS不能是位选择、部分选择或数组引用,但可以是一个变量或变量的连接。

reg q;

initial begin
	assign q = 0;
	#10 deassign q;
end

force…release

这些语句与assign… deassign语句类似,但也可以应用于网和变量。LHS可以是网的位选择、网的部分选择、变量或网,但不能是数组的引用和变量的位/部分选择。force语句将覆盖所有其他对变量的赋值,直到使用释放关键字释放它。

reg o, a, b;

initial begin
	force o = a & b;
	...
	release o;
end

仿真文件:

`timescale 1ns / 1ps
module assign_tb();

reg o, a = 1, b = 1;
initial begin
    force o = a & b;
    
    #10 a = 0;
    b = 0;
    o = 1;
    
    #10 a = 1;
    b = 1;
    o = 0;
     
    #20 release o;
    
      #10 
    a = 1;
    b = 1;
    o = 0;
    
    #10 
    a = 0;
    b = 1;
    o = 1;

    #10 $finish;
    
end
endmodule

结果:
在这里插入图片描述
在这里插入图片描述

  • 在一开始的时候,由于a和b的初始值都为1, o = a & b 因此,o的值为1;

  • 经过10ns,a和b的值被赋值为0, o 赋值为 1,但未成功,因为强制 o = a & b = 0,

  • 再经过20ns后release o 后,不再强制 o = a & b,即o的值与a和b无关

  • 再过10ns后,o被赋值为0,此时成功拉低,

  • 再过10ns后,o被赋值为1,此时成功拉高,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值