You are on page 1of 9

USER-DEFINED PRIMITIVES (UDP)

UDPs are basically of two types combinational and sequential.


A combinational UDP is used to define a combinational scalar
function and
A sequential UDP for a sequential function.
Combinational UDPs:
example: it shows a simple UDP for an AND operation.
UDP can have only one output port. It has to be the first in the
port list.
All the ports following the first are input ports and are all scalars,
inout ports are not permitted.
Output and input are declared in the body of the UDP.

primitive udp_and (out, in1, in2); //starts with the


//keyword primitive,
output out;
input in1, in2;
table
// In1 In2 Out
0 0: 0;
0 1: 0;
1 0: 0;
1 1: 1;
endtable
endprimitive
More General Combinational UDPs
The output/s s 0, 1, or x. It cannot take the value z.
However if an input takes the value z, it is taken as x.
A two-input UDP has nine rows of tabular entries; their number
increases rapidly as the number of input logic variables
increases. The symbol ? can be used to signify all the possible
values that is, 0, 1, or x. Wherever possible, one can use the
symbol b to signify 0 or 1 values and reduce the table size
further.
Primitive udp_and (out, in1, module tst_udp_and();
in2); reg in1,in2; wire out;
Output out; udp_and uand(out,in1,in2);
Input in1, in2; initial begin
Table in1=1'b0;in2=1'b0; end
// In1 In2 Out always begin
0 0: 0; #2 in1=1'b0; in2=1'b1;
0 1: 0; #2 in1=1'b1; in2=1'b0;
1 0: 0; #2 in1=1'b1; in2=1'b1;
1 1: 1; end
X 0: 0; initial $monitor($time ,"in1 =
X 1: X; %b ,in2 = %b ,out = %b",in1,
X X: X; in2,out);
0 X: 0; initial #18 $stop;
1 X: X; endmodule
Endtable
Endprimitive
Simulation results: //# 8in1 = 0 , in2 = 1 , out = 0
//# 0in1 = 0 , in2 = 0 , out = 0 //# 10in1 = 1 , in2 = 0 , out = 0
//# 2in1 = 0 , in2 = 1 , out = 0 //# 12in1 = 1 , in2 = 1 , out = 1
//# 4in1 = 1 , in2 = 0 , out = 0 //# 14in1 = 0 , in2 = 1 , out = 0
//# 6in1 = 1 , in2 = 1 , out = 1 //# 16in1 = 1 , in2 = 0 , out = 0

The full adder accepts three input bits and outputs


two bits a sum bit and a carry bit.
primitive primitive
udpsum(sum,in1,in2,carryi);udpcar(caro,in1,in2,cari);
output sum; output caro;
input in1, in2, carryi; input in1, in2, cari;
table table
// in1 in2 carryi: sum // in1 in2 cari caro
0 0 0: 0; 0 0 ? : 0 ;
1 1 0: 0; 0 ? 0 : 0 ;
0 1 1: 0; ? 0 0 : 0 ;
1 0 1: 0; b 1 1 : 1 ;
1 0 0: 1; 1 b 1 : 1 ;
0 1 0: 1; 1 1 b : 1 ;
0 0 1: 1; endtable
1 1 1: 1; endprimitive
endtable
endprimitive
Primitive udp_and_b (out, in1, in2);
Output out; // UDP of an AND gate defined compactly
Input in1, in2;
Table
// In1 In2 Out
? 0: 0;
0 ?: 0;
x X x
1 1: 1;
Endtable
Endprimitive
module fa (car_o, sum_o, in1, in2, car_i);
input in1, in2, car_i; output car_o, sum_o;
udpcar aa(car_o,in1,in2,car_i);
Simulation
udpsum bb(sum_o, in1,in2,car_i);
results
endmodule
# 1a=001, cs=01
# 2a=010, cs=01
module fa_tst;
# 3a=011, cs=10
reg [2:0] a;wire c,s;integer i;
# 4a=100, cs=01
fa cc(c,s,a[0],a[1],a[2]);
# 5a=101, cs=10
initial for(i=1;i<8;i=i+1)
# 6a=110, cs=10
begin a=i;
# 7a=111,
#1 $display($time, "a=%b, cs=%b%b",a, c, s);
end
initial #10 $stop;
endmodule

Observations:
With three inputs and three states for each input (0, 1, and x),
the full table of definition has 27 entries. Such definitions
become cumbersome as the number of inputs increase to even
moderate values say 4 or 5.
Only the entries essential to the definition of the primitive are
included here. Others which lead to x output are left out
intentionally. Thus with the carry primitive if any two inputs
have x values, the output car_o too has x value. Hence such a
row has not been specified.
? and b have been used in the primitive definition to make
the tables more compact

Sequential UDPs
Two examples of sequential UDPs are considered here one being
level-sensitive and the other edge-sensitive.
A UDP for a D Latch
The three rows of the table signify the following:
1. When clk = 1, if din = 0, the next state (qn) is also at 0 whatever
be the value of present state (qp).
2. When clk = 1, if din = 1, the next state (qn) is also at 1 whatever
be the value of present state (qp).
3. When clk = 0, the output (next state) does not change even if
din changes.
Symbol Significance Restrictions of use
B or b 0 and 1 values Only in the input or current state fields
? 0, 1 or ,x value Only in the input or current state fields
No change Only in the output field of sequential UDP(mn)
Change of value from m to n
Only in the input field. m & n can be 0, 1, x, b, or ?
* Same as (??)
r Same as (01)
f Same as (10)
p Rise from 0 or x to x or 1
n Fall from 1 or x to x or 0
Only in the input field
primitive dlatch(q,din,clk);
output q; input din,clk; reg q;
table
// din clk qp qn
0 1 : ? : 0; // If clk is at 1 state, the output
1 1 : ? : 1; //follows the input. If clk is at 0
? 0 : ? : -; // state, the output remains frozen
endtable
endprimitive

module dlatch_tst;
wire q; reg din,clk;
dlatch ll(q,din,clk);
initial
begin
clk=1'b1;din=1'b0;
repeat (2) begin #4 din=1'b1; #4 din=1'b0; end
clk=1'b0;
repeat (2) begin #4 din=1'b1; #4 din=1'b0; end
$stop;
end
initial $monitor($time ,"clk = %b, din = %b, q = %b
",clk,din,q);
endmodule
Result:
# 0clk = 1, din = 0, q = 0 # 16clk = 0, din = 0, q = 0
# 4clk = 1, din = 1, q = 1 # 20clk = 0, din = 1, q = 0
# 8clk = 1, din = 0, q = 0 # 24clk = 0, din = 0, q = 0
# 12clk = 1, din = 1, q = 1 # 28clk = 0, din = 1, q = 0

A UDP for an Edge-Triggered Flip-Flop


primitive module dff_pos_tst;
dff_pos(q,din,clk,clr); wire q;
output q; reg din,clk,clr;
input din,clk,clr; dff_pos ll(q,din,clk,clr);
reg q; initial
//initial q = 1'b0; begin
table clr=1'b0;din=1'b0;clk=1'b0;
// din clk clr qp qn #3din=1'b1;
0 (01) 0: ?: 0; repeat (2)
1 (01) 0: ?: 1; begin #4 din=1'b1; #4 din=1'b0; end
? (10) 0: ?: -; clr=1'b1;
(??) ? 0: ?: -; repeat (2)
? ? 1: ?: 0; begin#4 din=1'b1; #4 din=1'b0; end
? ? *: ?: 0; $stop;
endtable end
endprimitive always #2 clk=~clk;
initial $monitor($time ,"clr=%b, clk =
%b, din = %b, q = %b ",clr,clk,din,q);
endmodule
# 0clr=0, clk = 0, din = 0, q = 0 # 18clr=0, clk = 1, din = 1, q = 1
# 2clr=0, clk = 1, din = 0, q = 0 # 19clr=1, clk = 1, din = 0, q = 0
# 3clr=0, clk = 1, din = 1, q = 0 # 20clr=1, clk = 0, din = 0, q = 0
# 4clr=0, clk = 0, din = 1, q = 0 # 22clr=1, clk = 1, din = 0, q = 0
# 6clr=0, clk = 1, din = 1, q = 1 # 23clr=1, clk = 1, din = 1, q = 0
# 8clr=0, clk = 0, din = 1, q = 1 # 24clr=1, clk = 0, din = 1, q = 0
# 10clr=0, clk = 1, din = 1, q = 1 # 26clr=1, clk = 1, din = 1, q = 0
# 11clr=0, clk = 1, din = 0, q = 1 # 27clr=1, clk = 1, din = 0, q = 0
# 12clr=0, clk = 0, din = 0, q = 1 # 28clr=1, clk = 0, din = 0, q = 0
# 14clr=0, clk = 1, din = 0, q = 0 # 30clr=1, clk = 1, din = 0, q = 0
# 15clr=0, clk = 1, din = 1, q = 0 # 31clr=1, clk = 1, din = 1, q = 0
# 16clr=0, clk = 0, din = 1, q = 0 # 32clr=1, clk = 0, din = 1, q = 0
# 34clr=1, clk = 1, din = 1, q = 0

Sequential UDPs and Tasks


Sequential UDPs and tasks are functionally similar.
Tasks are defined inside modules and used inside the
module of definition.
They are not accessible to other modules. In contrast,
sequential UDPs are like other primitives and modules.
They can be instantiated in any other module of a
design.
UDP Instantiation with Delays
Outputs of UDPs also can take on values with time delays. The
delays can be specified separately for the rising and falling
transitions on the output. For example, an instantiation as
udp_and_b # (1, 2) g1(out, in1, in2);
can be used to instantiate the UDF of Figure 9.25 for carry
output generation.
Here the output transition to 1 (rising edge) takes effect with a
time delay of 1 ns.
The output transition to 0 (falling edge) takes effect with a time
delay of 2 ns. If only one time delay were specified, the same
holds good for the rising as well as the falling edges of the
output transition.
Vector-Type Instantiation of UDP
UDP definitions are scalar in nature. They can be used with
vectors with proper declarations.
the full-adder module fa can be instantiated as an 8-bit vector to
form an 8-bit adder. The instantiation statement can be
fa [7:0] aa(co, s, a, b, {co[6:0],1b0});
s (sum), co (carry output), a (first input), and
b(second input) are all 8-bit vectors here.
The vector type of instantiation makes the design description
compact; however, it may not be supported by some simulators.

You might also like