Specify blocks include statements to do the following:
The specify block is a separate block and does not appear within other blocks such as always or initial. An example is shown below with a specify block defining pin-to-pin delays for the module A.
module A( q, a, b, c, d )
input a, b, c, d;
output q;
wire e, f;
// specify block containing delay statements
specify
( a => q ) = 6; // delay from a to q
( b => q ) = 7; // delay from b to q
( c => q ) = 7; // delay form c to q
( d => q ) = 6; // delay from d to q
endspecify
// module definition
or o1( e, a, b );
or o2( f, c, d );
exor ex1( q, e, f );
endmodule
Every delay statement has a source field and a destination field. A parallel connection, denoted by the => symbol, is specified below:
Usage: ( <source_field> => <destination_field> ) = <delay_value>
Each bit in the source coresponds to its equivalent bit in the destination. Source fields and destination fields must have the same number of bits, otherwise there is a mismatch.
// single bit connection
( a => q ) = 7;
// vector connection, both a and q are eight bit registers, a[7:0], q[7:0]
( a => q ) = 12;
// this is shorthand for:
( a[0] => q[0] ) = 12;
( a[1] => q[1] ) = 12;
( a[2] => q[2] ) = 12;
......
( a[7] => q[7] ) = 12;
A full connection, denoted by the *> symbol, is specified below:
Usage: ( <source_field> *> <destination_field> ) = <delay_value>
Figure 2 shows this type of connection, in which each bit in the source affects each bit in the destination. The source and destination need not have the same number of bits.
Module A was previously defined using a parallel connection, but it could be coded with a full connection:
module A( q, a, b, c, d )
input a, b, c, d;
output q;
wire e, f;
// specify block containing full connection statements
specify
( a, d *> q ) = 6; // delay from a and d to q
( b, c *> q ) = 7; // delay from b and c to q
endspecify
// module definition
or o1( e, a, b );
or o2( f, c, d );
exor ex1( q, e, f );
endmodule
The full connection is useful for specifying the delay between each bit of an input and each bit of an output when the bit width is large, as the next example shows:
// a[63:0] is a 64 bit input register and q[7:0] is an 8 bit output register
// this would require 64 x 8 = 512 parallel connections, but only 1 full
specify
( a *> q ) = 8; // eqivalent to 512 parallel connections
endspecify
Special parameters can be defined for use within the specify block. They are declared using the specparam keyword. Instead of directly coding delays into the specify block it is common to define specify parameters with specparam then use these parameters to define the delays as before. The specparam values are often useful for storing values for non simulation tools such as delay calculators, and synthesis tools.
//Use of specify parameters
specify
//Define specify parameters within the specify block
specparam d_q = 12;
specparam clk_q = 14;
( d => q ) = d_q;
( clk => q ) = clk_q;
endspecify
Specify parameters are used only within their specify block, they are not general purpose parameters such as those declared by the parameter keyword. Specify parameters are often used in place of hard-coded delays for convenience, so that if timing delays for a circuit change, only a few parameters have to change.
Conditional path delays, sometimes called state dependent path delays, are used to model delays which are dependent on the values of the signals in the circuit. This type of delay is expressed with an if conditional statement. The operands can be scalar or vector module input or inout ports, locally defined registers or nets, compile time constants (constant numbers or specify block parameters), or any bit-select or part-select of these. The conditional statement can contain any bitwise, logical, concatenation, conditional, or reduction operator. The else construct cannot be used.
//Conditional path delays
Module A( q, a, b, c, d );
output q;
input a, b, c, d;
wire e, f;
// specify block with conditional timing statements
specify
// different timing set by level of input a
if (a) ( a => q ) = 12;
if ~(a) ( a => q ) = 14;
// delay conditional on b and c
// if b & c is true then delay is 7 else delay is 9
if ( b & c ) ( b => q ) = 7;
if ( ~( b & c )) ( b => q ) = 9;
// using the concatenation operator and full connections
if ( {c, d} = 2'b10 ) ( c, d *> q ) = 15;
if ( {c, d} != 2'b10 ) ( c, d *> q ) = 12;
endspecify
or o1( e, a, b );
or o2( f, c, d );
exor ex1( q, e, f );
endmodule
Timing delays between pins can be expressed in greater detail by specifying rise, fall, and turn-off delay values. One, two, three, six, or twelve delay values can be specified for any path. The order in which the delay values are specified must be strictly followed.
// One delay used for all transitions
specparam delay = 15;
( a => q ) = delay;
// Two delays gives rise and fall times
specparam rise = 10, fall = 11;
( a => q ) = ( rise, fall );
// Three delays gives rise, fall and turn-off
// rise is used for 0-1, and z-1, fall for 1-0, and z-0, and turn-off for 0-z, and 1-z.
specparam rise = 10, fall = 11, toff = 8;
( a => q ) = ( rise, fall, toff );
// Six delays specifies transitions 0-1, 1-0, 0-z, z-1, 1-z, z-0
// strictly in that order
specparam t01 = 8, t10 = 9, t0z = 10, tz1 = 11, t1z = 12, tz0 = 13;
( a => q ) = ( t01, t10, t0z, tz1, t1z, tz0 );
// Twelve delays specifies transitions:
// 0-1, 1-0, 0-z, z-1, 1-z, z-0, 0-x, x-1, 1-x, x-0, x-z, z-x
// again strictly in that order
specparam t01 = 8, t10 = 9, t0z = 10, tz1 = 11, t1z = 12, tz0 = 13;
specparam t0x = 11, tx1 = 14, t1x = 12, tx0 = 10, txz = 8, tzx = 9;
( a => q ) = ( t01, t10, t0z, tz1, t1z, tz0, t0x, tx1, t1x, tx0, txz, tzx );
Min, typical and maximum delays can be specified for inter-pin delays. Any delay from previous examples can be expressed in min:typ:max format.
// specify two delays each with min typ and max
specparam rise = 10:12:13, fall = 8:9:11;
( a => q ) = ( rise, fall );
Verilog uses the pessimistic approach to calculate delays for transitions to the x state, this means that unless the transition delay is explicitly stated,
A path delay specification with six delays is shown below:
//Six delays
//Transitions 0->1, 1->0, 0->z, z->0, 1->z, z->1
specparam t01 = 10, t10 = 14, t0z = 9, tz1 = 10. t1z = 12, tz0 = 15;
(clk => q) = (t01, t10, t0z, tz1, t1z, tz0);
From this the transition delays to and from x can be calculated:
Transition |
Delay Value |
0->x |
min(t_01, t_0z) = 9 |
1->x |
min(t_10, t_1z) = 12 |
z->x |
min(t_z0, t_0z) = 9 |
x->0 |
max(t_10, t_z0) = 15 |
x->1 |
max(t_01, t_z1) = 10 |
x->z |
max(t_1z, t_0z) = 12 |
Timing checks, discussed in the next section, are set up within the specify block using system tasks such as $width, $setup and $hold.