亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Verilog

Verilog 用户定义原语

标准 Verilog 原语,例如 nandnot 可能并不总是容易或足以表示复杂的逻辑。称为 UDP 的新原始元素 或用户定义的原语 可以定义为对组合逻辑或顺序逻辑进行建模。

所有 UDP 都只有一个输出,可以是 0、1 或 X,而不是 Z(不支持)。任何具有值 Z 的输入都将被视为 X。

Verilog UDP 符号

Verilog 用户定义的原语可以写在与 module 相同的级别 定义,但从不在 module 之间 和 endmodule .它们可以有多个输入端口,但始终只有一个输出端口,双向端口无效。所有端口信号都必须是标量,这意味着它们必须是 1 位宽。

硬件行为被描述为原语 状态表,列出了 table 中不同可能的输入组合及其对应的输出 和 endtable .输入输出信号的值用以下符号表示。

符号 评论
0 逻辑 0
1 逻辑1
x 未知,可为逻辑0或1。可用作顺序UDP的输入/输出或当前状态
? 逻辑 0、1 或 x。不能输出任何UDP
- 无变化,仅允许在 UDP 的输出中
ab 从 a 到 b 的值变化,其中 a 或 b 为 0、1 或 x
* 同??,表示输入值有任何变化
r 同 01 -> 输入上升沿
f 与 10 相同 -> 输入下降沿
p 输入的潜在上升沿; 0->1、0->x 或 x->1
n 输入的潜在下降沿; 1->0, x->0, 1->x

组合 UDP 示例

  
  
// Output should always be the first signal in port list
primitive mux (out, sel, a, b);
	output 	out;
	input 	sel, a, b;
	
	table
		// sel 	a 	b 		out
			0 	1 	? 	: 	1;
			0 	0 	? 	: 	0;
			1 	? 	0 	: 	0;
			1 	? 	1 	: 	1;
			x 	0 	0 	: 	0;
			x 	1 	1 	: 	1;
	endtable
endprimitive

  

? 表示信号可以是 0、1 或 x,与决定最终输出无关。

下面显示的是一个测试平台模块,它实例化了 UDP 并向其应用输入刺激。

  
  
module tb;
  reg 	sel, a, b;
  reg [2:0] dly;
  wire 	out;
  integer i;
  
  // Instantiate the UDP - note that UDPs cannot
  // be instantiated with port name connection
  mux u_mux ( out, sel, a, b);
  
  initial begin
    a <= 0;
    b <= 0;
    
    $monitor("[T=%0t] a=%0b b=%0b sel=%0b out=%0b", $time, a, b, sel, out);
    
    // Drive a, b, and sel after different random delays
    for (i = 0; i < 10; i = i + 1) begin
      	dly = $random;
      #(dly) a <= $random;
      	dly = $random;
      #(dly) b <= $random;
      	dly = $random;
      #(dly) sel <= $random;
    end
  end
endmodule

  
<无脚本> verilog udp mux 模拟日志
xcelium> run
[T=0] a=0 b=0 sel=x out=0
[T=4] a=1 b=0 sel=x out=x
[T=5] a=1 b=1 sel=x out=1
[T=10] a=1 b=1 sel=1 out=1
[T=15] a=0 b=1 sel=1 out=1
[T=28] a=0 b=0 sel=1 out=0
[T=33] a=0 b=0 sel=0 out=0
[T=38] a=1 b=0 sel=0 out=1
[T=40] a=1 b=1 sel=0 out=1
[T=51] a=1 b=1 sel=1 out=1
[T=54] a=0 b=0 sel=1 out=0
[T=62] a=1 b=0 sel=1 out=0
[T=67] a=1 b=1 sel=1 out=1
[T=72] a=0 b=1 sel=1 out=1
[T=80] a=0 b=1 sel=0 out=0
[T=84] a=0 b=0 sel=0 out=0
[T=85] a=1 b=0 sel=0 out=1
xmsim: *W,RNQUIE: Simulation is complete.

顺序 UDP 示例

顺序逻辑可以是电平敏感或边沿敏感,因此有两种顺序 UDP。输出端口也应该声明为 reg 在 UDP 定义中键入,并且可以选择在 initial 中初始化 声明。

顺序 UDP 在输入和输出字段之间有一个附加字段,由 : 分隔 代表当前状态。

级别敏感的 UDPs

  
  
primitive d_latch (q, clk, d);
	output 	q;
	input 	clk, d;
	reg  	q;
	
	table
		// clk 	d 		q 	q+
			1 	1 	:	? :	1;
			1 	0 	: 	? : 0;
			0 	? 	: 	? : -;
	endtable
endprimitive

  

在上表中,连字符 - 表的最后一行表示 q+ 的值没有变化。

  
  
module tb;
  reg clk, d;
  reg [1:0] dly;
  wire q;
  integer i;
  
  d_latch u_latch (q, clk, d);
  
  always #10 clk = ~clk;
  
  initial begin
    clk = 0;
    
    $monitor ("[T=%0t] clk=%0b d=%0b q=%0b", $time, clk, d, q); 
    
    #10;  // To see the effect of X
    
    for (i = 0; i < 50; i = i+1) begin
      dly = $random;
      #(dly) d <= $random;
    end
    
    #20 $finish;
  end
endmodule

  
<无脚本> verilog udp latch 模拟日志
xcelium> run
[T=0] clk=0 d=x q=x
[T=10] clk=1 d=1 q=1
[T=13] clk=1 d=0 q=0
[T=14] clk=1 d=1 q=1
[T=17] clk=1 d=0 q=0
[T=20] clk=0 d=1 q=0
[T=28] clk=0 d=0 q=0
[T=30] clk=1 d=1 q=1
[T=38] clk=1 d=0 q=0
[T=39] clk=1 d=1 q=1
[T=40] clk=0 d=1 q=1
[T=42] clk=0 d=0 q=1
[T=47] clk=0 d=1 q=1
[T=50] clk=1 d=0 q=0
[T=55] clk=1 d=1 q=1
[T=59] clk=1 d=0 q=0
[T=60] clk=0 d=0 q=0
[T=61] clk=0 d=1 q=0
[T=64] clk=0 d=0 q=0
[T=67] clk=0 d=1 q=0
[T=70] clk=1 d=0 q=0
[T=73] clk=1 d=1 q=1
[T=74] clk=1 d=0 q=0
[T=77] clk=1 d=1 q=1
[T=79] clk=1 d=0 q=0
[T=80] clk=0 d=0 q=0
[T=84] clk=0 d=1 q=0
[T=86] clk=0 d=0 q=0
[T=87] clk=0 d=1 q=0
[T=90] clk=1 d=1 q=1
[T=91] clk=1 d=0 q=0
[T=100] clk=0 d=0 q=0
[T=110] clk=1 d=0 q=0
Simulation complete via $finish(1) at time 111 NS + 0

边缘敏感的 UDPs

在下面显示的示例中,D 触发器被建模为 Verilog 用户定义的原语。请注意,时钟的上升沿由 01 指定 或 0?

  
  
primitive d_flop (q, clk, d);
	output  q;
	input 	clk, d;
	reg 	q;
	
	table
		// clk 		d 	 	q 		q+
			// obtain output on rising edge of clk
			(01)	0 	: 	? 	: 	0;
			(01) 	1 	: 	? 	: 	1;
			(0?) 	1 	: 	1 	: 	1;
			(0?) 	0 	: 	0 	: 	0;
			
			// ignore negative edge of clk
			(?0) 	? 	: 	? 	: 	-;
			
			// ignore data changes on steady clk
			? 		(??): 	? 	: 	-;
	endtable
endprimitive

  

在测试台中,UDP被实例化并在随机时钟数后使用随机d输入值驱动。

  
  
module tb;
  reg clk, d;
  reg [1:0] dly;
  wire q;
  integer i;
  
  d_flop u_flop (q, clk, d);
  
  always #10 clk = ~clk;
  
  initial begin
    clk = 0;
    
    $monitor ("[T=%0t] clk=%0b d=%0b q=%0b", $time, clk, d, q); 
    
    #10;  // To see the effect of X
    
    for (i = 0; i < 20; i = i+1) begin
      dly = $random;
      repeat(dly) @(posedge clk);
      d <= $random;
    end
    
    #20 $finish;
  end
endmodule

  

从图中可以看出,输出 q 在 1 个时钟延迟后跟随输入 d,这是 D 触发器所期望的行为。

<无脚本> verilog udp d flip flop 模拟日志
xcelium> run
[T=0] clk=0 d=x q=x
[T=10] clk=1 d=1 q=x
[T=20] clk=0 d=1 q=x
[T=30] clk=1 d=1 q=1
[T=40] clk=0 d=1 q=1
[T=50] clk=1 d=1 q=1
[T=60] clk=0 d=1 q=1
[T=70] clk=1 d=0 q=1
[T=80] clk=0 d=0 q=1
[T=90] clk=1 d=1 q=0
[T=100] clk=0 d=1 q=0
[T=110] clk=1 d=1 q=1
[T=120] clk=0 d=1 q=1
[T=130] clk=1 d=1 q=1
[T=140] clk=0 d=1 q=1
[T=150] clk=1 d=0 q=1
[T=160] clk=0 d=0 q=1
[T=170] clk=1 d=0 q=0
[T=180] clk=0 d=0 q=0
[T=190] clk=1 d=0 q=0
[T=200] clk=0 d=0 q=0
[T=210] clk=1 d=1 q=0
[T=220] clk=0 d=1 q=0
[T=230] clk=1 d=1 q=1
[T=240] clk=0 d=1 q=1
[T=250] clk=1 d=1 q=1
[T=260] clk=0 d=1 q=1
[T=270] clk=1 d=1 q=1
[T=280] clk=0 d=1 q=1
[T=290] clk=1 d=1 q=1
[T=300] clk=0 d=1 q=1
[T=310] clk=1 d=1 q=1
[T=320] clk=0 d=1 q=1
[T=330] clk=1 d=1 q=1
[T=340] clk=0 d=1 q=1
[T=350] clk=1 d=1 q=1
[T=360] clk=0 d=1 q=1
[T=370] clk=1 d=0 q=1
[T=380] clk=0 d=0 q=1
[T=390] clk=1 d=0 q=0
[T=400] clk=0 d=0 q=0
[T=410] clk=1 d=1 q=0
[T=420] clk=0 d=1 q=0
[T=430] clk=1 d=1 q=1
[T=440] clk=0 d=1 q=1
[T=450] clk=1 d=1 q=1
[T=460] clk=0 d=1 q=1
[T=470] clk=1 d=1 q=1
[T=480] clk=0 d=1 q=1
Simulation complete via $finish(1) at time 490 NS + 0


Verilog

  1. Verilog 教程
  2. Verilog 连接
  3. Verilog 作业
  4. Verilog 阻塞和非阻塞
  5. Verilog 函数
  6. Verilog 任务
  7. Verilog 时钟发生器
  8. Verilog 数学函数
  9. Verilog 时间格式
  10. Verilog 时间刻度范围
  11. Verilog 文件 IO 操作
  12. Verilog Hello World