2012年11月1日 星期四

User Defined Primitives Part-I




../images/main/bullet_green_ball.gifIntroduction

Verilog has built-in primitives like gates, transmission gates, and switches. This is a rather small number of primitives; if we need more complex primitives, then Verilog provides UDP, or simply User Defined Primitives. Using UDP we can model
space.gif
  • Combinational Logic
  • Sequential Logic
space.gif
We can include timing information along with these UDP to model complete ASIC library models.
space.gif
../images/main/bulllet_4dots_orange.gifSyntax
UDP begins with reserve word primitive and ends withendprimitive. Ports/terminals of primitive should follow. This is similar to what we do for module definition. UDPs should be defined outside module and endmodule
space.gif

  1 //This code shows how input/output ports
  2 // and primitve is declared
  3 primitive udp_syntax (
  4 a, // Port a
  5 b, // Port b
  6 c, // Port c
  7 d  // Port d
  8 );
  9 output a;
 10 input b,c,d;
 11 
 12 // UDP function code here
 13 
 14 endprimitive
You could download file udp_syntax.v here
space.gif
In the above code, udp_syntax is the primitive name, it contains ports a, b,c,d.
space.gif
The formal syntax of the UDP definition is as follows:
space.gif
<UDP>
   ::= primitive <name_of_UDP> ( <output_terminal_name>,
      <input_terminal_name> <,<input_terminal_name>>* ) ;
   <UDP_declaration>+
   <UDP_initial_statement>?
   <table_definition>
   endprimitive

<name_of_UDP>
   ::= <IDENTIFIER>

<UDP_declaration>
   ::= <UDP_output_declaration>
   ||= <reg_declaration>
   ||= <UDP_input_declaration>

<UDP_output_declaration>
   ::= output <output_terminal _name>;
<reg_declaration>
   ::=   reg <output_terminal_name> ;

<UDP_input_declaration>
   ::= input <input_terminal_name> <,<input_terminal_name>>* ;

<UDP_initial_statement>
   ::= initial <output_terminal_name> = <init_val> ;

<init_val>
   ::= 1'b0
   ||= 1'b1
   ||= 1'bx
   ||= 1
   ||= 0

<table_definition>
   ::= table
         <table_entries>
      endtable

<table_entries>
   ::= <combinational_entry>+
   ||= <sequential_entry>+

<combinational_entry>
   ::= <level_input_list> : <OUTPUT_SYMBOL> ;

<sequential_entry>
   ::= <input_list> : <state> : <next_state> ;

<input_list>
   ::= <level_input_list>
   ||= <edge_input_list>

<level_input_list>
   ::= <LEVEL_SYMBOL>+

<edge_input_list>
   ::= <LEVEL_SYMBOL>* <edge> <LEVEL_SYMBOL>*

<edge>
   ::= ( <LEVEL_SYMBOL> <LEVEL_SYMBOL> )
   ||= <EDGE_SYMBOL>

<state>
   ::= <LEVEL_SYMBOL>

<next_state>
   ::= <OUTPUT_SYMBOL>
   ||= -    
space.gif
../images/main/bulllet_4dots_orange.gifUDP ports rules
space.gif
  • An UDP can contain only one output and up to 10 inputs.
  • Output port should be the first port followed by one or more input ports.
  • All UDP ports are scalar, i.e. Vector ports are not allowed.
  • UDPs can not have bidirectional ports.
  • The output terminal of a sequential UDP requires an additional declaration as type reg.
  • It is illegal to declare a reg for the output terminal of a combinational UDP
space.gif
space.gif
../images/main/bulllet_4dots_orange.gifBody
Functionality of primitive (both combinational and sequential) is described inside a table, and it ends with reserved word 'endtable' as shown in the code below. For sequential UDP, we can use initial to assign an initial value to output.
space.gif

  1 // This code shows how UDP body looks like
  2 primitive udp_body (
  3 a, // Port a
  4 b, // Port b
  5 c  // Port c
  6 );
  7 output a;
  8 input b,c;
  9 
 10 // UDP function code here
 11 // A = B | C;
 12 table
 13  // B  C    : A
 14     ?  1    : 1;
 15     1  ?    : 1;
 16     0  0    : 0;
 17 endtable
 18 
 19 endprimitive
You could download file udp_body.v here
space.gif
Note: An UDP cannot use 'z' in the input table
space.gif
TestBench to check the above UDP

  1 `include "udp_body.v"
  2 module udp_body_tb();
  3 
  4 reg b,c;
  5 wire a;
  6 
  7 udp_body udp (a,b,c);
  8 
  9 initial begin
 10   $monitor(" B = %b C = %b  A = %b",b,c,a);
 11   b = 0;
 12   c = 0;
 13    #1  b = 1;
 14    #1  b = 0;
 15    #1  c = 1;
 16    #1  b = 1'bx;
 17    #1  c = 0;
 18    #1  b = 1;
 19    #1  c = 1'bx;
 20    #1  b = 0;
 21    #1  $finish;
 22 end  
 23 
 24 endmodule
You could download file udp_body_tb.v here
space.gif
Simulator Output
space.gif
  B = 0 C = 0  A = 0
  B = 1 C = 0  A = 1
  B = 0 C = 0  A = 0
  B = 0 C = 1  A = 1
  B = x C = 1  A = 1
  B = x C = 0  A = x
  B = 1 C = 0  A = 1
  B = 1 C = x  A = 1
  B = 0 C = x  A = x
space.gif
../images/main/bullet_star_pink.gifTable
Table is used for describing the function of UDP. Verilog reserved word table marks the start of table and reserved word endtablemarks the end of table.
space.gif
Each line inside a table is one condition; when an input changes, the input condition is matched and the output is evaluated to reflect the new change in input.
space.gif
../images/main/bullet_star_pink.gifInitial
Initial statement is used for initialization of sequential UDPs. This statement begins with the keyword 'initial'. The statement that follows must be an assignment statement that assigns a single bit literal value to the output terminal reg.
space.gif

  1 primitive udp_initial (a,b,c);
  2 output a;
  3 input b,c;
  4 reg a;
  5 // a has value of 1 at start of sim
  6 initial a = 1'b1;               
  7 
  8 table
  9 // udp_initial behaviour
 10 endtable
 11 
 12 endprimitive
You could download file udp_initial.v here
space.gif
../images/main/bulllet_4dots_orange.gifSymbols
UDP uses special symbols to describe functions like rising edge, don't care and so on. The table below shows the symbols that are used in UDPs:
space.gif
Symbol
Interpretation
Explanation
?
0 or 1 or X
? means the variable can be 0 or 1 or x
b
0 or 1
Same as ?, but x is not included
f
(10)
Falling edge on an input
r
(01)
Rising edge on an input
p
(01) or (0x) or (x1) or (1z) or (z1)
Rising edge including x and z
n
(10) or (1x) or (x0) or (0z) or (z0)
Falling edge including x and z
*
(??)
All transitions
-
no change
No Change

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...