Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Verilog

Benutzerdefinierte Primitive von Verilog

Standard-Verilog-Primitive wie nand und not ist möglicherweise nicht immer einfach oder ausreichend, um komplexe Logik darzustellen. Neue primitive Elemente namens UDP oder benutzerdefinierte Primitive kann definiert werden, um kombinatorische oder sequentielle Logik zu modellieren.

Alle UDPs haben genau einen Ausgang, der entweder 0, 1 oder X sein kann und niemals Z (wird nicht unterstützt). Jede Eingabe mit dem Wert Z wird als X behandelt.

Verilog-UDP-Symbole

Benutzerdefinierte Primitive von Verilog können auf der gleichen Ebene wie module geschrieben werden Definitionen, aber niemals zwischen module und endmodule . Sie können viele Eingangsports haben, aber immer einen Ausgangsport, und bidirektionale Ports sind nicht gültig. Alle Port-Signale müssen skalar sein, was bedeutet, dass sie 1 Bit breit sein müssen.

Hardwareverhalten wird als primitiv beschrieben Zustandstabelle, die verschiedene mögliche Kombinationen von Eingaben und ihre entsprechenden Ausgaben innerhalb von table auflistet und endtable . Werte von Eingangs- und Ausgangssignalen werden mit den folgenden Symbolen angezeigt.

Symbol Kommentare
0 Logisch 0
1 Logik 1
x Unbekannt, kann entweder logisch 0 oder 1 sein. Kann als Ein-/Ausgang oder aktueller Status von sequentiellen UDPs verwendet werden
? Logisch 0, 1 oder x. Kann von keinem UDP ausgegeben werden
- Keine Änderung, nur in der Ausgabe eines UDP erlaubt
ab Wertänderung von a nach b, wobei a oder b entweder 0, 1 oder x ist
* Dasselbe wie ??, zeigt jede Änderung des Eingabewerts an
r Wie 01 -> steigende Flanke am Eingang
f Wie 10 -> fallende Flanke am Eingang
p Mögliche positive Flanke am Eingang; entweder 0->1, 0->x oder x->1
n Mögliche fallende Flanke am Eingang; entweder 1->0, x->0, 1->x

Kombiniertes UDP-Beispiel

  
  
// 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

  

Ein ? gibt an, dass das Signal entweder 0, 1 oder x sein kann und spielt keine Rolle bei der Entscheidung über die endgültige Ausgabe.

Unten ist ein Testbench-Modul gezeigt, das das UDP instanziiert und Eingangsstimuli darauf anwendet.

  
  
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

  
Simulationsprotokoll
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.

Sequentielles UDP-Beispiel

Die sequentielle Logik kann entweder pegelempfindlich oder flankenempfindlich sein, und daher gibt es zwei Arten von sequentiellen UDPs. Der Ausgabeport sollte auch als reg deklariert werden Typ innerhalb der UDP-Definition und kann optional innerhalb eines initial initialisiert werden Aussage.

Sequentielle UDPs haben ein zusätzliches Feld zwischen Ein- und Ausgabefeld, das durch einen : begrenzt wird die den aktuellen Stand darstellt.

Level-sensitive 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

  

In der obigen Tabelle ein Bindestrich - in der letzten Zeile der Tabelle gibt keine Wertänderung für q+ an.

  
  
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

  
Simulationsprotokoll
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

Edge-Sensitive UDPs

Im unten gezeigten Beispiel wird ein D-Flip-Flop als benutzerdefiniertes Verilog-Grundelement modelliert. Beachten Sie, dass die steigende Flanke der Uhr durch 01 angegeben wird oder 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

  

In der Testbench wird das UDP nach einer zufälligen Anzahl von Takten mit zufälligen d-Eingabewerten instanziiert und angesteuert.

  
  
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

  

Aus dem Bild ist ersichtlich, dass der Ausgang q dem Eingang d nach einer Verzögerung von 1 Takt folgt, was das gewünschte Verhalten für ein D-Flip-Flop ist.

Simulationsprotokoll
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-Tutorial
  2. Verilog-Verkettung
  3. Verilog-Aufgaben
  4. Verilog-Blockierung und Nicht-Blockierung
  5. Verilog-Funktionen
  6. Verilog-Aufgabe
  7. Verilog-Taktgenerator
  8. Verilog Math-Funktionen
  9. Verilog-Zeitformat
  10. Verilog-Zeitskalenumfang