|
11.13 Other Verilog Features
Chapter start
Previous page
Next page
11.13 Other Verilog Features
This section covers
some of the more advanced Verilog features. System tasks and functions
are defined as part of the IEEE Verilog standard [Verilog LRM14].
11.13.1 Display Tasks
The following code
illustrates the display system tasks [Verilog LRM 14.1]:
module test_display; // display system tasks:
initial begin ("string, variables, or expression");
/* format specifications work like printf in C:
%d=decimal %b=binary %s=string %h=hex %o=octal
%c=character %m=hierarchical name %v=strength %t=time format
%e=scientific %f=decimal %g=shortest
examples: %d uses default width %0d uses minimum width
%7.3g uses 7 spaces with 3 digits after decimal point */
// , , print in b, h, o formats
// , , also have b, h, o versions
("write"); // as , but without newline at end of line
("strobe"); // as , values at end of simulation cycle
(v); // disp. @change of v (except v= ,,)
; ; // toggle monitor mode on/off
end endmodule
11.13.2 File I/O Tasks
The following example
illustrates the file I/O system tasks [Verilog LRM 14.2]:
module file_1; integer f1, ch; initial begin f1 = ("f1.out");
if(f1==0) (2); if(f1==2)("f1 open");
ch = f1|1; (ch,"Hello"); (f1); end endmodule
> vlog file_1.v
> vsim -c file_1
# Loading work.file_1
VSIM 1> run 10
# f1 open
# Hello
VSIM 2> q
> more f1.out
Hello
>
The system
task returns a 32-bit unsigned integer called a multichannel descriptor
( f1 in this example) unique to each file. The multichannel
descriptor contains 32 flags, one for each of 32 possible channels or files
(subject to limitations of the operating system). Channel 0 is the standard
output (normally the screen), which is always open. The first call to
opens channel 1 and sets bit 1 of the multichannel descriptor. Subsequent
calls set higher bits. The file I/O system tasks:
, , , and
; correspond to their display counterparts. The first parameter for the
file system tasks is a multichannel descriptor that may have multiple bits
set. Thus, the preceding example writes the string "Hello"
to the screen and to file1.out . The task closes a
file and allows the channel to be reused.
The file I/O tasks
and read a text file into a memory. The file may
contain only spaces, new lines, tabs, form feeds, comments, addresses, and
binary (for ) or hex (for
) numbers, as in the following example:
mem.dat
@2 1010_1111 @4 0101_1111 1010_1111 // @address in hex
x1x1_zzzz 1111_0000 /* x or z is OK */
module load; reg [7:0] mem[0:7]; integer i; initial begin
("mem.dat", mem, 1, 6); // start_address=1, end_address=6
for (i= 0; i<8; i=i+1) ("mem[%0d] %b", i, mem[i]);
end endmodule
> vsim -c load
# Loading work.load
VSIM 1> run 10
# ** Warning: (memory mem) file mem.dat line 2:
# More patterns than index range (hex 1:6)
# Time: 0 ns Iteration: 0 Instance:/
# mem[0] xxxxxxxx
# mem[1] xxxxxxxx
# mem[2] 10101111
# mem[3] xxxxxxxx
# mem[4] 01011111
# mem[5] 10101111
# mem[6] x1x1zzzz
# mem[7] xxxxxxxx
VSIM 2> q
>
11.13.3 Timescale, Simulation,
and Timing-Check Tasks
There are two timescale
tasks, and [Verilog
LRM 14.3]. The specifies the %t format
specification for the display and file I/O system tasks as well as the time
unit for delays entered interactively and from files. Here are examples
of the timescale tasks:
// timescale tasks:
module a; initial (b.c1); endmodule
module b; c c1 (); endmodule
`timescale 10 ns / 1 fs
module c_dat; endmodule
`timescale 1 ms / 1 ns
module Ttime; initial (-9, 5, " ns", 10); endmodule
/* [ ( n, p, suffix , min_field_width ) ] ;
units = 1 second ** (-n), n = 0->15, e.g. for n = 9, units = ns
p = digits after decimal point for %t e.g. p = 5 gives 0.00000
suffix for %t (despite timescale directive)
min_field_width is number of character positions for %t */
The simulation control
tasks are and h [Verilog LRM 14.4]:
module test_simulation_control; // simulation control system tasks:
initial begin ; // enter interactive mode (default parameter 1)
(2); // graceful exit with optional parameter as follows:
// 0 = nothing 1 = time and location 2 = time, location, and statistics
end endmodule
The timing-check tasks
[Verilog LRM 14.5] are used in specify blocks. The following code and comments
illustrate the definitions and use of timing-check system tasks. The arguments
to the tasks are defined and explained in Table 11.11.
TABLE 11.11 Timing-check
system task parameters. |
Timing task argument |
Description
of argument |
Type of argument |
reference_event
|
to establish reference time |
module input or inout
(scalar or vector net) |
data_event
|
signal to check against
reference_event |
module input or inout
(scalar or vector net) |
limit
|
time limit to detect timing
violation on data_event |
constant expression
or specparam |
threshold
|
largest pulse width ignored
by timing check |
constant expression
or specparam |
notifier
|
flags a timing violation
(before -> after):
x->0, 0->1, 1->0, z->z
|
register |
module timing_checks (data, clock, clock_1,clock_2);
input data,clock,clock_1,clock_2; reg tSU,tH,tHIGH,tP,tSK,tR;
specify // timing check system tasks:
/* (data_event, reference_event, limit [, notifier]);
violation = (T_reference_event)-(T_data_event) < limit */
(data, posedge clock, tSU);
/* (reference_event, data_event, limit [, notifier]);
violation =
(time_of_data_event)-(time_of_reference_event) < limit */
(posedge clock, data, tH);
/* (reference_event, data_event, setup_limit,
hold_limit [, notifier]);
parameter_restriction = setup_limit + hold_limit > 0 */
(posedge clock, data, tSU, tH);
/* (reference_event, limit, threshold [, notifier]);
violation =
threshold < (T_data_event) - (T_reference_event) < limit
reference_event = edge
data_event = opposite_edge_of_reference_event */
(posedge clock, tHIGH);
/* (reference_event, limit [, notifier]);
violation = (T_data_event) - (T_reference_event) < limit
reference_event = edge
data_event = same_edge_of_reference event */
(posedge clock, tP);
/* (reference_event, data_event, limit [, notifier]);
violation = (T_data_event) - (T_reference_event) > limit */
(posedge clock_1, posedge clock_2, tSK);
/* (reference_event, data_event, limit, [, notifier]);
violation = (T_data_event) - (T_reference_event) < limit */
(posedge clock, posedge clock_2, tR);
/* (reference_event, data_event, start_edge_offset,
end_edge_offset [, notifier]);
reference_event = posedge | negedge
violation = change while reference high (posedge)/low (negedge)
+ve start_edge_offset moves start of window later
+ve end_edge_offset moves end of window later */
(posedge clock, data, 0, 0);
endspecify endmodule
You can use edge specifiers
as parameters for the timing-check events (except for the reference event
in ):
edge_control_specifier ::= edge [edge_descriptor {, edge_descriptor}]
edge_descriptor ::= 01 | 0x | 10 | 1x | x0 | x1
For example, 'edge
[01, 0x, x1] clock' is equivalent to 'posedge clock'
. Edge transitions with 'z' are treated the same as transitions
with 'x' .
Here is a D flip-flop model
that uses timing checks and a notifier register. The register, notifier,
is changed when a timing-check task detects a violation and the last entry
in the table then sets the flip-flop output to unknown.
primitive dff_udp(q, clock, data, notifier);
output q; reg q; input clock, data, notifier;
table // clock data notifier:state: q
r 0 ? : ? : 0 ;
r 1 ? : ? : 1 ;
n ? ? : ? : - ;
? * ? : ? : - ;
? ? * : ? : x ; endtable // notifier
endprimitive
`timescale 100 fs / 1 fs
module dff(q, clock, data); output q; input clock, data; reg notifier;
dff_udp(q1, clock, data, notifier); buf(q, q1);
specify
specparam tSU = 5, tH = 1, tPW = 20, tPLH = 4:5:6, tPHL = 4:5:6;
(clock *> q) = (tPLH, tPHL);
(data, posedge clock, tSU, notifier); // setup: data to clock
(posedge clock, data, tH, notifier); // hold: clock to data
(posedge clock, tPW, notifier); // clock: period
endspecify
endmodule
11.13.4 PLA Tasks
The PLA modeling
tasks model two-level logic [Verilog LRM 14.6]. As an example, the following
eqntott logic equations can be implemented using a PLA:
b1 = a1 & a2; b2 = a3 & a4 & a5 ; b3 = a5 & a6 & a7;
The following module loads
a PLA model for the equations above (in AND logic) using the array format
(the array format allows only '1' or '0' in the
PLA memory, or personality array). The file array.dat
is similar to the espresso input plane format.
array.dat
1100000
0011100
0000111
module pla_1 (a1,a2,a3,a4,a5,a6,a7,b1,b2,b3);
input a1, a2, a3, a4, a5, a6, a7 ; output b1, b2, b3;
reg [1:7] mem[1:3]; reg b1, b2, b3;
initial begin
("array.dat", mem);
#1; b1=1; b2=1; b3=1;
(mem,{a1,a2,a3,a4,a5,a6,a7},{b1,b2,b3});
end
initial ("%4g",,,b1,,b2,,b3);
endmodule
The next example illustrates
the use of the plane format, which allows '1' , '0'
, as well as '?' or 'z' (either may be used for
don't care) in the personality array.
b1 = a1 & !a2; b2 = a3; b3 = !a1 & !a3; b4 = 1;
module pla_2; reg [1:3] a, mem[1:4]; reg [1:4] b;
initial begin
(mem,{a[1],a[2],a[3]},{b[1],b[2],b[3],b[4]});
mem[1] = 3'b10?; mem[2] = 3'b??1; mem[3] = 3'b0?0; mem[4] = 3'b???;
#10 a = 3'b111; #10 (a, " -> ", b);
#10 a = 3'b000; #10 (a, " -> ", b);
#10 a = 3'bxxx; #10 (a, " -> ", b);
#10 a = 3'b101; #10 (a, " -> ", b);
end endmodule
111 -> 0101
000 -> 0011
xxx -> xxx1
101 -> 1101
11.13.5 Stochastic Analysis
Tasks
The stochastic
analysis tasks model queues [Verilog LRM 14.7]. Each of the tasks return
a status as shown in Table 11.12.
TABLE 11.12 Status
values for the stochastic analysis tasks. |
Status value |
Meaning |
0 |
OK |
1 |
queue full, cannot add |
2 |
undefined q_id |
3 |
queue empty, cannot remove |
4 |
unsupported q_type
, cannot create queue |
5 |
max_length
<= 0, cannot create queue
|
6 |
duplicate q_id
, cannot create queue |
7 |
not enough memory, cannot
create queue |
The following module illustrates
the interface and parameters for these tasks:
module stochastic; initial begin // stochastic analysis system tasks:
/* (q_id, q_type, max_length, status) ;
q_id is an integer that uniquely identifies the queue
q_type 1=FIFO 2=LIFO
max_length is an integer defining the maximum number of entries */
(q_id, q_type, max_length, status) ;
/* (q_id, job_id, inform_id, status) ;
job_id = integer input
inform_id = user-defined integer input for queue entry */
(q_id, job_id, inform_id, status) ;
/* (q_id, job_id, inform_id, status) ; */
(q_id, job_id, inform_id, status) ;
/* (q_id, status) ;
status = 0 = queue is not full, status = 1 = queue full */
(q_id, status) ;
/* (q_id, q_stat_code, q_stat_value, status) ;
q_stat_code is input request as follows:
1=current queue length 2=mean inter-arrival time 3=max. queue length
4=shortest wait time ever
5=longest wait time for jobs still in queue 6=ave. wait time in queue
q_stat_value is output containing requested value */
(q_id, q_stat_code, q_stat_value, status) ;
end endmodule
11.13.6 Simulation Time
Functions
The simulation
time functions return the time as follows [Verilog LRM 14.8]:
module test_time; initial begin // simulation time system functions:
;
// returns 64-bit integer scaled to timescale unit of invoking module
;
// returns 32-bit integer scaled to timescale unit of invoking module
;
// returns real scaled to timescale unit of invoking module
end endmodule
11.13.7 Conversion
Functions
The conversion
functions for reals handle real numbers [Verilog LRM 14.9]:
module test_convert; // conversion functions for reals:
integer i; real r; reg [63:0] bits;
initial begin #1 r=256;#1 i = (r);
#1; r = (2 * i) ; #1 bits = (2.0 * r) ;
#1; r = (bits) ; end
initial ("%3f",,,i,,r,,bits); /*
converts reals to integers w/truncation e.g. 123.45 -> 123
converts integers to reals e.g. 123 -> 123.0
converts reals to 64-bit vector
converts bit pattern to real
Real numbers in these functions conform to IEEE Std 754. Conversion rounds to the nearest valid number. */
endmodule
# 0.000000 x 0 x
# 1.000000 x 256 x
# 2.000000 256 256 x
# 3.000000 256 512 x
# 4.000000 256 512 4652218415073722368
# 5.000000 256 1024 4652218415073722368
Here is an example using the
conversion functions in port connections:
module test_real;wire [63:0]a; driver d (a); receiver r (a);
initial ("%3g",,,a,,d.r1,,r.r2); endmodule
module driver (real_net);
output real_net; real r1; wire [64:1] real_net = (r1);
initial #1 r1 = 123.456; endmodule
module receiver (real_net);
input real_net; wire [64:1] real_net; real r2;
initial assign r2 = (real_net);
endmodule
# 0 0 0 0
# 1 4638387860618067575 123.456 123.456
11.13.8 Probability Distribution
Functions
The probability distribution
functions are as follows [Verilog LRM 14.10]:
module probability; // probability distribution functions:
/* [ ( seed ) ] returns random 32-bit signed integer
seed = register, integer, or time */
reg [23:0] r1,r2; integer r3,r4,r5,r6,r7,r8,r9;
integer seed, start, \end , mean, standard_deviation;
integer degree_of_freedom, k_stage;
initial begin seed=1; start=0; \end =6; mean=5;
standard_deviation=2; degree_of_freedom=2; k_stage=1; #1;
r1 = % 60; // random -59 to 59
r2 = % 60; // positive value 0-59
r3= (seed, start, \end ) ;
r4= (seed, mean, standard_deviation) ;
r5= (seed, mean) ;
r6= (seed, mean) ;
r7= (seed, degree_of_freedom) ;
r8= (seed, degree_of_freedom) ;
r9= (seed, k_stage, mean) ; end
initial #2 ("%3f",,,r1,,r2,,r3,,r4,,r5);
initial begin #3; ("%3f",,,r6,,r7,,r8,,r9); end
/* All parameters are integer values.
Each function returns a pseudo-random number
e.g. returns uniformly distributed random numbers
mean, degree_of_freedom, k_stage
(exponential, poisson, chi-square, t, erlang) > 0.
seed = inout integer initialized by user, updated by function
start, end () = integer bounding return values */
endmodule
2.000000 8 57 0 4 9
3.000000 7 3 0 2
11.13.9 Programming Language
Interface
The C language Programming
Language Interface ( PLI) allows you to access the internal Verilog
data structure [Verilog LRM17-23, A-E]. For example, you can use
the PLI to implement the following extensions to a Verilog simulator:
- C language delay calculator for a cell library
- C language interface to a Verilog-based or
other logic or fault simulator
- Graphical waveform display and debugging
- C language simulation models
- Hardware interfaces
There are three generations
of PLI routines (see Appendix B for an example):
- Task/function (TF) routines (or utility routines),
the first generation of the PLI, start with
'tf_' .
- Access (ACC) routines, the second generation
of the PLI, start with the characters
'acc_' and access delay
and logic values. There is some overlap between the ACC routines and TF
routines.
- Verilog Procedural Interface (VPI) routines,
the third generation of the PLI, start with the characters
'vpi_'
and are a superset of the TF and ACC routines.
Chapter start
Previous page
Next page
|
|