Verilog初级教程(21)Verilog中的延迟控制语句

前言

Verilog中的延迟控制有两种类型–延迟和事件表达式。

下面一一道来。

正文

延迟控制语句

如果延迟表达式的值为未知值或高阻抗值,将被解释为零延迟。对于这个语句会用即可,用于仿真延时使用嘛,例如:

`timescale 1ns/1ps

module tb;

  reg [3:0] a, b;

  initial begin
  	
  	{a,b} = 0;
  	
  	$display ("T=%0t a=%0d b=%0d", $realtime, a, b);
  	
  	#10
  	
  	a = 10;
  	
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);

		#(2*10)
		
		b = 8;
    $display ("T=%0t a=%0d b=%0d", $realtime, a, b);		

		#('dz)
		a = 2;
		b = 2;
		$display ("T=%0t a=%0d b=%0d", $realtime, a, b);		
		
		#('h10)
		
		a = 3;
		b = 3;
		$display ("T=%0t a=%0d b=%0d", $realtime, a, b);		

  
  end

endmodule
# run 1000ns
T=0 a=0 b=0
T=10000 a=10 b=0
T=30000 a=10 b=8
T=30000 a=2 b=2
T=46000 a=3 b=3

事件控制语句

线网和变量的值变化可以作为同步事件来触发执行其他程序语句,是一个隐含事件。该事件也可以基于变化的方向,比如朝0的变化使其成为negedge,朝1的变化使其成为posedge。(并不一定非要是时钟)

  • negedge是指从1到X、Z或0,以及从X或Z到0的过渡。
  • posedge是指从0到X、Z或1,以及从X或Z到1的过渡。
module tb;
  reg a, b;

  initial begin
    a <= 0;

    #10 a <= 1;
    #10 b <= 1;

    #10 a <= 0;
    #15 a <= 1;  
	end
// Start another procedural block that waits for an update to 
// signals made in the above procedural block 
	initial begin 
		@(posedge a); $display ("T=%0t Posedge of a detected for 0->1", $time); 
		@(posedge b); $display ("T=%0t Posedge of b detected for X->1", $time);
    	@(posedge (a + b)) $display ("T=%0t Posedge of a+b", $time);
    	@(a) $display ("T=%0t Change in a found", $time);
  end
endmodule

在这里插入图片描述

Time resolution is 1 ps
T=10000 Posedge of a detected for 0->1
T=20000 Posedge of b detected for X->1
T=30000 Posedge of a+b
T=45000 Change in a found

如果是这样:

module tb;
  reg a, b;

  initial begin
    a <= 0;
 $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    #10 a <= 1;
     $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    #10 b <= 1;
 $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    #10 a <= 0;
     $display ("T=%0t a=%0d b=%0d", $realtime, a, b);
    #15 a <= 1;  
	end
// Start another procedural block that waits for an update to 
// signals made in the above procedural block 
	initial begin 
		@(posedge a); $display ("T=%0t Posedge of a detected for 0->1", $time); 
		@(posedge b); $display ("T=%0t Posedge of b detected for X->1", $time);
    	@(posedge (a + b)) $display ("T=%0t Posedge of a+b", $time);
    	@(a) $display ("T=%0t Change in a found", $time);
  end
endmodule

则仿真log为:

Time resolution is 1 ps
T=0 a=x b=x
T=10000 a=0 b=x
T=10000 Posedge of a detected for 0->1
T=20000 a=1 b=x
T=20000 Posedge of b detected for X->1
T=30000 a=1 b=1
T=30000 Posedge of a+b
T=45000 Change in a found

Named Events

关键字event可以用来声明一个可以明确触发的命名事件。一个事件不能保存任何数据,没有时间长度,可以在任何特定的时间发生。命名的事件可以通过在命名的事件句柄前加上->操作符来触发。命名事件可以通过使用上面描述的@操作符来等待。

module tb;
  event a_event;
  event b_event;

  initial begin
    #20 -> a_event;

    #30;
    ->a_event;

    #50 ->a_event;
    #10 ->b_event;
  end

  always @ (a_event) $display ("T=%0t [always] a_event is triggered", $time);

  initial begin
    #25;
    @(a_event) $display ("T=%0t [initial] a_event is triggered", $time);

    #10 @(b_event) $display ("T=%0t [initial] b_event is triggered", $time);
  end
endmodule
Time resolution is 1 ps
T=20000 [always] a_event is triggered
T=50000 [initial] a_event is triggered
T=50000 [always] a_event is triggered
T=100000 [always] a_event is triggered
T=110000 [initial] b_event is triggered

Event or operator

或操作符可以用来等待,直到表达式中的任何一个事件被触发。也可以用逗号 ,代替or操作符。

module tb;
  reg a, b;

  initial begin
    $monitor ("T=%0t a=%0d b=%0d", $time, a, b);
    {a, b} <= 0;

    #10 a <= 1;
    #5  b <= 1;
	#5  b <= 0;
  end

  // Use "or" between events
  always @ (posedge a or posedge b)
    $display ("T=%0t posedge of a or b found", $time);

  // Use a comma between
  always @ (posedge a, negedge b)
    $display ("T=%0t posedge of a or negedge of b found", $time);

  always @ (a, b)
    $display ("T=%0t Any change on a or b", $time);
endmodule
Time resolution is 1 ps
T=0 Any change on a or b
T=0 posedge of a or negedge of b found
T=0 a=0 b=0
T=10000 Any change on a or b
T=10000 posedge of a or b found
T=10000 posedge of a or negedge of b found
T=10000 a=1 b=0
T=15000 Any change on a or b
T=15000 posedge of a or b found
T=15000 a=1 b=1
T=20000 Any change on a or b
T=20000 posedge of a or negedge of b found
T=20000 a=1 b=0

好了,不再多说,其实最常用还是:

@(posedge a)
...

@(b)
...

#10
....




往期回顾

Verilog初级教程(20)Verilog中的`ifdef 条件编译语句

Verilog初级教程(19)Verilog中的参数

Verilog初级教程(18)Verilog中的函数与任务

Verilog初级教程(17)Verilog中的case语句

Verilog初级教程(16)Verilog中的控制块

Verilog初级教程(15)Verilog中的阻塞与非阻塞语句

Verilog初级教程(14)Verilog中的赋值语句

Verilog初级教程(13)Verilog中的块语句

Verilog初级教程(12)Verilog中的generate块

Verilog初级教程(11)Verilog中的initial块

Verilog初级教程(10)Verilog的always块

Verilog初级教程(9)Verilog的运算符

Verilog初级教程(8)Verilog中的assign语句

Verilog初级教程(7)Verilog模块例化以及悬空端口的处理

Verilog初级教程(6)Verilog模块与端口

Verilog初级教程(5)Verilog中的多维数组和存储器

Verilog初级教程(4)Verilog中的标量与向量

Verilog初级教程(3)Verilog 数据类型

Verilog初级教程(2)Verilog HDL的初级语法

Verilog初级教程(1)认识 Verilog HDL

芯片设计抽象层及其设计风格

Verilog以及VHDL所倡导的的代码准则

FPGA/ASIC初学者应该学习Verilog还是VHDL?

参考资料及推荐关注

Verilog `ifdef Conditional Compilation

个人微信公众号: FPGA LAB

交个朋友

猜你喜欢

转载自blog.csdn.net/Reborn_Lee/article/details/107752232
今日推荐