Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> Verilog

Primitivos Definidos pelo Usuário Verilog


Primitivas padrão Verilog como nand e not pode nem sempre ser fácil ou suficiente para representar uma lógica complexa. Novos elementos primitivos chamados UDP ou primitivas definidas pelo usuário pode ser definido para modelar lógica combinacional ou sequencial.

Todos os UDPs têm exatamente uma saída que pode ser 0, 1 ou X e nunca Z (não suportado). Qualquer entrada que tenha o valor Z será tratada como X.

Símbolos UDP Verilog


Primitivas definidas pelo usuário Verilog podem ser escritas no mesmo nível que module definições, mas nunca entre module e endmodule . Eles podem ter muitas portas de entrada, mas sempre uma porta de saída, e as portas bidirecionais não são válidas. Todos os sinais de porta devem ser escalares, o que significa que eles devem ter 1 bit de largura.

O comportamento do hardware é descrito como um primitivo tabela de estados que lista diferentes combinações possíveis de entradas e suas saídas correspondentes dentro de table e endtable . Os valores dos sinais de entrada e saída são indicados com os seguintes símbolos.
Símbolo Comentários
0 Lógica 0
1 Lógica 1
x Desconhecido, pode ser lógico 0 ou 1. Pode ser usado como entrada/saída ou estado atual de UDPs sequenciais
? Lógica 0, 1 ou x. Não pode ser saída de qualquer UDP
- Nenhuma alteração, permitida apenas na saída de um UDP
ab Mudança no valor de a para b onde a ou b é 0, 1 ou x
* Igual a ??, indica qualquer alteração no valor de entrada
r Igual a 01 -> borda de subida na entrada
f Igual a 10 -> borda descendente na entrada
p Potencial borda positiva na entrada; 0->1, 0->x ou x->1
n Potencial borda de queda na entrada; ou 1->0, x->0, 1->x

Exemplo de UDP Combinacional

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

  

Um ? indica que o sinal pode ser 0, 1 ou x e não importa na decisão da saída final.

Abaixo é mostrado um módulo testbench que instancia o UDP e aplica estímulos de entrada a ele.
  
  
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

  
Registro de simulação
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.

Exemplo de UDP Sequencial


A lógica sequencial pode ser sensível ao nível ou sensível à borda e, portanto, existem dois tipos de UDPs sequenciais. A porta de saída também deve ser declarada como reg tipo dentro da definição UDP e pode ser inicializado opcionalmente dentro de um initial declaração.

UDPs sequenciais têm um campo adicional entre o campo de entrada e saída que é delimitado por um : que representa o estado atual.

UDPs sensíveis ao nível

  
  
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

  

Na tabela acima, um hífen - na última linha da tabela indica nenhuma alteração no valor de 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

  
Registro de simulação
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 sensíveis à borda


Um flip-flop D é modelado como uma primitiva definida pelo usuário Verilog no exemplo mostrado abaixo. Observe que a borda de subida do relógio é especificada por 01 ou 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

  

No testbench, o UDP é instanciado e conduzido com valores de entrada aleatórios d após um número aleatório de relógios.
  
  
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

  

Pode ser visto na imagem que a saída q segue a entrada d após 1 atraso de clock que é o comportamento desejado para um flip-flop D.
Registro de simulação
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. Tutorial Verilog
  2. Concatenação Verilog
  3. Atribuições Verilog
  4. Verilog Blocking &Non-Blocking
  5. Funções Verilog
  6. Tarefa Verilog
  7. Gerador de Relógio Verilog
  8. Funções matemáticas Verilog
  9. Formato de hora Verilog
  10. Escopo da escala de tempo da Verilog