Documente Academic
Documente Profesional
Documente Cultură
Technote Library
Published: 5/Nov/02
ModelSim /VHDL, ModelSim /VLOG, ModelSim /LNL, and ModelSim /PLUS are
produced by Model Technology, a Mentor Graphics Corporation company.
Copying, duplication, or other reproduction is prohibited without the written consent
of Model Technology.
The information in this manual is subject to change without notice and does not
represent a commitment on the part of Model Technology. The program described
in this manual is furnished under a license agreement and may not be used or
copied except in accordance with the terms of the agreement. The online
documentation provided with this product may be printed by the end-user. The
number of copies that may be printed is limited to the number of licenses
purchased.
ModelSim is a registered trademark and Signal Spy, TraceX, ChaseX and Model
Technology are trademarks of Mentor Graphics Corporation. PostScript is a
registered trademark of Adobe Systems Incorporated. UNIX is a registered
trademark of AT&T in the USA and other countries. FLEXlm is a trademark of
Globetrotter Software, Inc. IBM, AT, and PC are registered trademarks, AIX and
RISC System/6000 are trademarks of International Business Machines
Corporation. Windows, Microsoft, and MS-DOS are registered trademarks of
Microsoft Corporation. OSF/Motif is a trademark of the Open Software Foundation,
Inc. in the USA and other countries. SPARC is a registered trademark and
SPARCstation is a trademark of SPARC International, Inc. Sun Microsystems is a
registered trademark, and Sun, SunOS and OpenWindows are trademarks of Sun
Microsystems, Inc. All other trademarks and registered trademarks are the
properties of their respective holders.
Copyright (c) 1990 -2002, Model Technology, a Mentor Graphics Corporation
company. All rights reserved. Confidential. Online documentation may be printed
by licensed customers of Model Technology and Mentor Graphics for internal
business purposes only.
Model Technology
10450 SW Nimbus Avenue / Bldg. R-B
Portland OR 97223-4347 USA
phone: 503-641-1340
fax: 503-526-5410
e-mail: sales@model.com
home page: http://www.model.com
Table of contents
Tool usage
Sampling signals at a clock change . . . . . .
Converting signal values to strings . . . . . .
Hiding library cell signals when saving a waveform file .
Examining constants in a package . . . . . .
Performance affected by scheduled events being cancelled
Rounding of delay values when backannotating SDF .
Inlining modules and the -forcecode option . . . .
Issue with +nocheckALL and certain optimized cells .
$sdf_done system task . . . . . . . . .
`uselib and the -compile_uselib argument . . . .
Using the -g argument to modify a generic of type string
Using virtual regions to reconstruct bit-blasted busses .
Run-time error when using time'POS(x) . . . . .
Out-of-range error message . . . . . . . .
Case choice error: "must be a locally static expression" .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
5
6
6
7
7
8
9
11
12
13
14
15
16
17
Language
Delta delays . . . . . . . . . .
Event ordering in Verilog designs
. . . .
Verilog simulator resolution . . . . . .
Hierarchical references in a mixed-language design
Incorrect use of VHDL bidirectional ports . .
WAIT statementsVHDL vs. Verilog
. . .
Verilog tran gate in mixed-language designs . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
18
20
24
27
28
31
33
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
34
37
39
42
44
46
47
Platform
NFS problems with Red Hat 7.0, 7.1, and 7.2 . . .
Window manager bug with early versions of KDE . .
Memory addressing above 2GB on an HP platform . .
Problems loading an FLI/PLI compiled on HP-UX 11.0 .
Problems when linking a PLI application on Windows .
RPC_Init error on HPUX . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
48
48
49
49
50
50
.
.
.
.
.
.
.
Introduction
Introduction
This document discusses various issues related to running simulations in ModelSim.
Tool usage
Sampling signals at a clock change
You can do this easily using the add list command with the -notrigger argument.
-notrigger disables triggering the display on the specified signals. For example:
add list clk -notrigger a b c
When you run the simulation, List window entries for clk, a, b, and c appear only when clk
changes.
If you want to display on rising edges only, you have two options:
1 Turn off the List window triggering on the clock signal, and then define a repeating
strobe for the list window
2 Define a "gating expression" for the List window that requires the clock to be in a
specified state
When myConvertedSignal is displayed in the Wave, List or Signals window, the string
"state0" appears when mysignal == 0, "state1" when mysignal == 1, "state2" when
mysignal == 2, and so on.
See the virtual type command in the ModelSim Command Reference for further details.
Tool usage
To examine constant a1, first define a process with a variable that references the constant.
For example:
use work.bpack.all;
entity x is
port (a : in bit; b : out bit);
end x;
architecture simple of x is
begin
dummy : process
variable x1 : integer := 0;
begin
x1 := a1;
wait;
end process;
end simple;
Now when you load entity x, you can examine variable x1 to get the value of constant a1.
vsim x
view source
examine x1
# 4
At time 0 process p makes an event for time 10 ms. When synch goes to 1 at 10 ns, the event
at 10 ms is marked as cancelled but not deleted, and a new event is scheduled at 10 ms +
10 ns. The cancelled events are not reclaimed until time 10 ms is reached, and the cancelled
event is processed. As a result there will be 500000 (10 ms/20 ns) cancelled but undeleted
events. Once 10 ms is reached, memory no longer increases because the simulator is
reclaiming events as fast as they are added.
For projected waveforms, the following behaves the same way:
signals synch : bit := '0';
...
p: process(synch)
begin
output <= '0', '1' after 10ms;
end process;
synch <= not synch after 10 ns;
If the simulator's resolution is set to 10 ps, then the delays that get annotated are rounded
as follows:
MINIMUM delays
TYPICAL delays
MAXIMUM delays
In order to get the exact delay value as it is specified in the SDF file, the simulator's
resolution must be set to 1 ps.
Tool usage
inv_a
inv_b
inv_c
inverter
PO
PI
If the +nocheck argument is not used, the compiler issues the following warning:
WARNING[10]: cell.v(xx): [OPRD] - Not optimizing library module because
output port is read internally by module
Overriding this condition with the +nocheckALL argument and causing the cell to
optimize is not normally an issue, but in some cases it can cause problems. For instance,
assume this cell has the following iopaths specified:
A => Z
A => PO
PI => PO
10
Tool usage
The optimized cell cannot recognize the A => PO path. In the optimized cell, the inputs to
the NAND gate are seen as Z and PI. Since there is not an iopath declared from Z => PO,
no delay is annotated. Only the A => Z delay that has already been annotated to the output
Z is seen:
A
Z
PO
A => Z
However, if you prevent the cell from optimizing, the correct delay values are seen:
A
Z
PO
A => Z
A => PO
11
ModelSim waits for the second $sdf_annotate() call before removing zero-delay MIPDs.
However, variable a is always 0, so the second $sdf_annotate() call never executes.
Because the second call never happens, the zero-delay MIPDs are not removed.
Extraneous MIPDs reduce simulator performance. The solution is to "manually" remove
the MIPDs by calling $sdf_done.
Note: $sdf_annotate() cannot be called after $sdf_done has been called.
Since $sdf_done is a ModelSim-specific task, your design will not be portable if the task is
present in the code. To prevent errors if you run your design in other simulators, you can
qualify $sdf_done with the MODEL_TECH environment variable. MODEL_TECH is set
automatically by ModelSim upon invocation. The following code shows you how to use it
with $sdf_done:
module amod;
integer a = 0;
initial
begin
$sdf_annotate("a.sdf");
if ( a )
begin
$sdf_annotate("b.sdf");
`ifdef MODEL_TECH
$sdf_done;
`endif
end
end
endmodule
12
Tool usage
This behaves similarly to a LIBRARY/USE clause in VHDL. As with VHDL, the correct
mappings must be setup if the library does not exist in the current working directory. The
-compile_uselibs argument does not affect this usage of `uselib.
2 It can reference a directory or directories containing source code. The "libext" argument
is used to identify the type of files to search. For example:
`uselib dir=./src1 libext=.v
However, using the -y switch causes needed objects to be compiled into the same library
with the rest of the design. Using -compile_uselibs with a `uselib statement causes the
referenced objects to be compiled into a different library (as described below).
3 It can reference a file(s). For example:
`uselib file=./src1/mux21.v file=./src2/mux41.v
Like -y, the -v switch causes needed objects to be compiled into the same library with the
rest of the design. Using -compile_uselibs with a `uselib statement causes the referenced
objects to be compiled into a different library.
When using -compile_uselibs, ModelSim determines where to compile the source files
based on the following:
Explicit directory name given to the argument (e.g., -compile_uselibs=./components).
The MTI_USELIBS_DIR environment variable.
If no explicit name is given to the argument, and the environment variable is not set,
ModelSim creates a directory called mti_uselibs.
13
Using this generic with configurations and generic maps works correctly. However,
ModelSim cannot modify this generic from the command line. For example, invoking the
following command from csh returns a warning, and the value of the generic is not
changed:
vsim -gmessage="The signal has changed" gen_test
** Warning: "The signal has changed" is not a valid value for generic message
Additionally, if you use this syntax at the ModelSim command line or in a DO file,
ModelSim reports that it cannot find work.signal.
What is going on?
The trick with modifying generics/parameters of type string is that the double quotes ("")
MUST make it into ModelSim. Shells often strip away the double quotes and parse the text
on the whitespace. To prevent this from happening, you must vary the syntax depending on
how/where you invoke vsim:
csh (UNIX/Linux)
vsim -gmessage='"The signal has changed"' gen_test
14
Tool usage
Alternatively, you can create a virtual region and signal to use for the comparison:
virtual region gate:/ top
virtual region gate:/top count
virtual signal -install gate:/top/core {(concat_range 31:0) &
"gate:/synthesized_name_*"} q
.
.
.
compare add /top/count/q
The first command creates a virtual region named "top" and sets its parent to the root of the
flattened gate-level design. The second command creates a virtual region named "count"
and sets its parent to gate:/top. The third command creates a virtual bus, with range 31
downto 0, that is the concatenation of the synthesized_name_* signals .
15
The error may be doubly confusing because the code runs without error in Cadence. What
is going on?
The difference lies in how the two simulators handle the scaling of the base units for the
physical data type "time". The base units for "time" are femtoseconds. When we set the
simulator resolution, we do not change the base units of that physical data type. The
Cadence simulator must change these base units. This is just a difference in
implementation, not a violation of the IEEE standard.
In the current example, the user is passing 9100 nanoseconds to the attribute:
time'POS(9100 ns)
This attribute returns the position number as an integer. For physical data types, the position
number is the integer value of the base units. Since the base units of the physical data type
"time" are femtoseconds, regardless of the resolution set in ModelSim, the attribute is
returning 9100 nanoseconds converted to femtoseconds:
9,100 ns => 9,100,000,000 fs
16
Tool usage
PROCESS (clk)
BEGIN
IF (rst = '1') THEN
cnt <= 0;
ELSIF clk'EVENT AND clk = '1' THEN
cnt <= cnt + 1;
IF (cnt = 7) THEN
cnt <= 0;
END IF;
END IF;
END PROCESS;
Though the error is valid, you may not want to see it. To turn off run-time range checking,
use the following argument during compilation:
vcom -nocheck range_check.vhd
17
However, since using these constants does not adversely affect the simulation, we have
implemented the -nocasestaticerror argument to vcom to disable this checking and make
code using these constants compatible between simulators.
18
Language
Language
Delta delays
Event-based simulators such as ModelSim may process many events at a given simulation
time. Multiple signals may need updating, statements that are sensitive to these signals
must be executed, and any new events that result from these statements must then be
queued and executed as well. The steps taken to evaluate the design without advancing
simulation time are referred to as "delta times" or just "deltas."
The exact event queuing process varies for Verilog and VHDL. See "Event ordering in
Verilog designs" (20) for details on Verilog. The diagram below represents the process for
VHDL. This process continues until the end of simulation time.
Execute
concurrent
statements at
current time
Advance
simulation
time
Advance
delta time
No
Any transactions
to process?
Yes
Any events to
process?
No
Yes
Execute concurrent
statements that are
sensitive to events
This mechanism in event-based simulators may cause unexpected results. Consider the
following code snippet:
.
.
.
clk2 <= clk;
process (rst, clk)
begin
if(rst = '0')then
s0 <= '0';
elsif(clk'event and clk='1') then
s0 <= inp;
Delta delays
19
end if;
end process;
In this example you have two synchronous processes, one triggered with clk and the other
with clk2. To your surprise, the signals change in the clk2 process on the same edge as they
are set in the clk process. As a result, the value of inp appears at s1 rather than s0. What is
going on?
Here is whats happing. During simulation an event on clk occurs (from the testbench).
From this event ModelSim performs the "clk2 <= clk" assignment and the process which
is sensitive to clk. Before advancing the simulation time, ModelSim finds that the process
sensitive to clk2 can also be run. Since there are no delays present, the effect is that the
value of inp appears at s1 in the same simulation cycle.
In order to get the expected results, you must do one of the following:
1 insert delay at every output
2 make certain to use the same clock
3 insert a delta delay
To insert a delta delay, modify the code like this:
process (rst, clk)
begin
if(rst = '0')then
s0 <= '0';
elsif(clk'event and clk='1') then
s0 <= inp;
s0_delayed <= s0;
end if;
end process;
process (rst, clk2)
begin
if(rst = '0')then
s1 <= '0';
elsif(clk2'event and clk2='1') then
s1 <= s0_delayed;
end if;
end process;
The best way to debug delta delay problems is observe your signals in the List window.
There you can see how values change at each delta time.
20
Language
Event queues
Section 5 of the IEEE Std 1364-1995 LRM defines several event queues that determine the
order in which events are evaluated. At the current simulation time, the simulator has the
following pending events:
active events
inactive events
non-blocking assignment update events
monitor events
future events
- inactive events
- non-blocking assignment update events
The LRM dictates that events are processed as follows 1) all active events are processed;
2) the inactive events are moved to the active event queue and then processed; 3) the
non-blocking events are moved to the active event queue and then processed; 4) the monitor
events are moved to the active queue and then processed; 5) simulation advances to the next
time where there is an inactive event or a non-blocking assignment update event.
Within the active event queue, the events can be processed in any order, and new active
events can be added to the queue in any order. In other words, you cannot control event
order within the active queue. The example below illustrates potential ramifications of this
situation.
Say you have these four statements:
1 always@(q) p = q;
2 always @(q) p2 = not q;
3 always @(p or p2) clk = p and p2;
4 always @(posedge clk)
and current values as follows: q = 0, p = 0, p2=1
21
The tables below show two of the many valid evaluations of these statements. Evaluation
events are denoted #, where # is the statement to be evaluated. Update events are denoted
<name>(old->new) where <name> indicates the reg being updated and new is the updated
value.
Table 1: Evaluation 1
Event being processed
q(0 1)
1, 2
p(0 1), 2
p(0 1)
3, 2
clk(0 1), 2
clk(0 1)
4, 2
p2(1 0)
p2(1 0)
clk(1 0)
clk(1 0)
<empty>
Table 2: Evaluation 2
Event being processed
q(0 1)
1, 2
p(0 1), 2
p(0 1)
3, p2(1 0)
p2(1 0)
Again, both evaluations are valid. However, in Evaluation 1, clk has a glitch on it; in
Evaluation 2, clk doesnt. This indicates that the design has a zero-delay race condition on
clk.
22
Language
If written this way, a value on d1 always takes two clock cycles to get from d1 to q2.
If you change clk1 = master and clk2 = clk1 to non-blocking assignments or q2 <= q1 and
q1 <= d1 to blocking assignments, then d1 may get to q2 is less than two clock cycles.
23
ModelSim helps you track down event order dependencies with the following compiler
arguments: -compat, -hazards, and -keep_delta.
See the vlog command for descriptions of -compat and -keep_delta.
Hazard detection
The -hazard argument to vsim detects event order hazards involving simultaneous reading
and writing of the same register in concurrently executing processes. vsim detects the
following kinds of hazards:
WRITE/WRITE:
Two processes writing to the same variable at the same time.
READ/WRITE:
One process reading a variable at the same time it is being written to by another process.
ModelSim calls this a READ/WRITE hazard if it executed the read first.
WRITE/READ:
Same as a READ/WRITE hazard except that ModelSim executed the write first.
vsim issues an error message when it detects a hazard. The message pinpoints the variable
and the two processes involved. You can have the simulator break on the statement where
the hazard is detected by setting the break on assertion level to error.
To enable hazard detection you must invoke vlog command with the -hazards argument
when you compile your source code and you must also invoke vsim with the -hazards
argument when you simulate.
Limitations of hazard detection
Reads and writes involving bit and part selects of vectors are not considered for hazard
detection. The overhead of tracking the overlap between the bit and part selects is too
high.
A WRITE/WRITE hazard is flagged even if the same value is written by both processes.
A WRITE/READ or READ/WRITE hazard is flagged even if the write does not modify
the variable's value.
Glitches on nets caused by non-guaranteed event ordering are not detected.
24
Language
The Verilog LRM 1364-2001 defines the arguments of the directive as follows:
"The time_unit argument specifies the unit of measurement for times and delays."
"The time_precision argument specifies how delay values are rounded before being used
in simulation. The values used are accurate to within the unit of time specified here, even
if there is a smaller time_precision argument elsewhere in the design. The smallest
time_precision argument of all the `timescale compiler directives in the design
determines the precision of the time unit of the simulation."
Here is an example of a `timescale directive:
`timescale 1 ns / 100 ps
This directive causes time values to be read as ns and to be rounded to the nearest 100 ps.
The smallest time precision in all timescale directives is 10 ps, so in accordance with the
LRM, the simulator uses that value for its resolution. Since instance dut1 does not have a
timescale directive, it inherits the simulator resolution of 10 ps for time_unit and
time_precision. This equates to dut1 having the following timescale directive:
`timescale 10 ps / 10 ps
25
Now assume that instance mod1 contains the following code fragment:
parameter d = 1.55;
initial
begin
set = 1'bz;
#d set = 1'b0;
#d set = 1'b1;
end
Parameter d has a time value of 1.55. Due to the inheritance, 1.55 is seen as a delay of 15.5
ps rounded to 20 ps. Consequently, signal set toggles from '0' to 'z' after 20 ps and then to
'1' after 20 ps more.
This is most likely not the intended behavior. You probably assumed the time would be
seen as a 1.55 ns delay, and, with a 10 ps resolution, would be rounded to 1550 ps.
To highlight this potential error, ModelSim reports the following warning during
elaboration of the example design:
# WARNING: [TSCALE] - Module 'mod1' has a `timescale directive in effect, but
previous modules do not
This message is often ignored or disabled during simulation. However, the warning points
out a situation like that in the example above and should ALWAYS be checked.
Example 2
Per the LRM, ModelSim uses the time_precision argument to round delay values in the file
in which it is specified. This is true even if that number is not used in setting simulator
resolution.
Consider a design with a testbench mem_tb containing the following timescale directive:
`timescale 1 ns / 1 ps
Since 1 ps is the smaller of the two time precision values, 1 ps is used for the simulator
resolution. However, module sp_syn_ram has the following code fragment initializing a
memory:
repeat (`MEMDEPTH)
begin
#0.001 mem[init] = 8'h00;
init = init + 1;
end
The time_unit for this module is 1 ns, so ModelSim reads the delay in the repeat statement
as 1 ps. Using the 10 ps time_precision for rounding, ModelSim rounds the 1 ps delay to
zero. Once the delay is rounded to zero, all iterations of the repeat statement occur in one
time step. If the value of MEMDEPTH is greater than the value set for iteration loop limits,
the following message is issued during a simulation run:
# Iteration limit reached. Possible zero delay oscillation. See the manual.
Increasing the iteration loop limit to a number greater than MEMDEPTH allows simulation
to proceed, but that ignores the real issue and still does not produce the intended results.
26
Language
The real solution is to use the correct timescale directive (`timescale 1 ns / 1 ps) for module
sp_syn_ram. The delay is then read as 1 ps, and ModelSim iterates over the repeat
statement in real time instead of many delta steps.
27
dut2 (VHDL)
mod_b (Verilog)
tb.dut1.mod_a.im0
28
Language
a
out_1
AND
b
OR
out_2
Consider the associated VHDL code. In this case the compiler reports an error due to a bad
assignment.
--------------------------------------- source: bad_init.vhd
-------------------------------------LIBRARY ieee ;
USE ieee.std_logic_1164.ALL;
ENTITY bad_init IS
PORT (
a
: IN std_logic;
b
: IN std_logic;
c
: IN std_logic;
out_1 : OUT std_logic;
out_2 : OUT std_logic
);
END bad_init ;
ARCHITECTURE behavioral OF bad_init IS
BEGIN
out_1 <= a AND b;
-- This is a bad assignment.
out_2 <= out_1 OR c;
END behavioral;
29
The code compiles and simulates fine provided no external drivers are applied to the port.
If that happens, though, there is the possibility of bus contention, and debugging can be
difficult.
The correct way to write this piece of code is to assign the first logical operation to a
temporary signal and then use that temporary signal in other operations.
--------------------------------------- source: good_change.vhd
-------------------------------------LIBRARY ieee ;
USE ieee.std_logic_1164.ALL;
ENTITY good_change IS
PORT (
a
: IN std_logic;
b
: IN std_logic;
c
: IN std_logic;
out_1 : OUT std_logic;
out_2 : OUT std_logic
);
END good_change ;
ARCHITECTURE behavioral OF good_change IS
SIGNAL temp : std_logic;
30
Language
BEGIN
temp
<= a AND b;
Note: The assignment operator ( <= ) is not a "netcon", or simple wire connection as it
appears in the schematic. The VHDL code actually generates a buffered connection.
31
because of the rules for the construction of the default sensitivity clause."
In VHDL the expression is checked only after the WAIT statement is executed and there is
an event on any signals in the expression. If the expression is already TRUE upon entering
the WAIT, the semantics are identical to just using WAIT; (LRM sec 8.1 line 95). This
form causes the process to suspend for the remainder of the simulation.
"If the value of enable is 1 when the block is entered, the wait statement delays the
evaluation of the next statement (#10 a = b;) until the value of enable changes to 0. If
enable is already 0 when the begin-end block is entered, then the assignment "a = b" is
evaluated after a delay of 10 and no additional delay occurs."
In Verilog the expression is checked before the WAIT statement is executed and if TRUE
the wait never occurs.
32
Language
Example
Here is an example of a Verilog and a VHDL AND gate. Both of these AND gates have an
enable signal en with a WAIT statement:
// Verilog
always
begin
wait (en) #10 z_v = a & b;
end
-- VHDL
PROCESS
BEGIN
z_vhd <= a AND b AFTER 10 ns;
WAIT UNTIL en = '1';
END PROCESS;
When simulated the Verilog output z_v changes 10 ns after the input a toggles. However,
there is no corresponding toggle on the VHDL output z_vhd. This signal does not toggle
until 10 ns after the enable signal en toggles.
a
b
en
z_vl
z_vhd
33
This problem occurs in the VHDL language because of the resolution function. You must
model the tran gate behavior in VHDL so the resolution function has time to determine
drivers on the two ports.
Modeling tran gate behavior relies on a concept called "break before make." The code
"breaks" the connection upon sensing a transaction on either port by driving a 'Z' onto both
ports. This break gives the resolution function time to determine the drivers for each port.
A "WAIT FOR 0 ns" statement helps to insure driver resolution. Finally, the swap signal
assignment performs the "make" operation. The following code demonstrates this
modeling:
tran_gate: PROCESS
VARIABLE last_time : time;
BEGIN
WAIT ON a'TRANSACTION, b'TRANSACTION UNTIL last_time /= NOW;
-- Break
last_time := NOW;
a <= 'Z';
b <= 'Z';
WAIT FOR 0 ns;
-- Make
a <= b;
b <= a;
END PROCESS tran_gate;
34
Example
$setuphold(posedge clk, negedge d, 5, -3, Notifier,,, clk_dly, d_dly);;
d violation
region
3
0
clk
ModelSim calculates the delay for signal d_dly as 4 time units instead of 3. It does this to
prevent d_dly and clk_dly from occurring simultaneously when a violation isnt reported.
Note: ModelSim accepts negative limit checks by default, unlike current versions of
Verilog-XL. To match Verilog-XL default behavior (i.e., zeroing all negative timing
check limits), use the +no_neg_tcheck argument to vsim.
35
A simple example helps clarify the algorithm. Assume you have the following timing
checks:
$setuphold(posedge
$setuphold(posedge
$setuphold(posedge
$setuphold(posedge
clk,
clk,
clk,
clk,
posedge
negedge
posedge
negedge
d,
d,
t,
t,
3, -2 ,
6, -5 ,
20, -12
18, -11
d violation
regions
20
18
12
11
3
6
5
0
clk
Note that the delays between clk/clk_dly, t/t_dly, and d/d_dly are not edge sensitive, and
they must be the same for both rising and falling transitions of clk, t, and d. A d => d_dly
delay of 5 satisfies the negedge case (transitions of d from 5 to 0 before clk won't be
latched), but valid transitions of posedge d, in the region of 5 to 3 before clk, won't latch
correctly. Therefore, to find convergence, the algorithm starts zeroing negative $hold
limits (-12, then -11, and then -5). The check limits on t are zeroed first because of their
magnitude.
ModelSim displays messages when limits are zeroed if you use the +ntc_warn argument.
The messages look similar to the following:
# WARNING: ./src/SDFFX.v(36): No solution possible for delayed timing check
nets. Setting negative limit to zero.
d violation
regions
45
216
70
-68
0
clk
36
The delay net delay analysis in this case does not provide a solution. The required negative
hold delay of 68 between d and dd could cause a non-violating posedge d transition to be
delayed on dd so that it arrive after dclk for functional evaluation. By default the -68 hold
limit is set pessimistically to 0 to insure the correct functional evaluation.
Alternatively, you can use -extend_tcheck_data_limit to overlap the regions. In this
example we must specify the percentage by which to "decrease" the negative hold limit in
order to overlap the positive setup limit. In other words, you must extend the 216, -68
region to 216, -44. You calculate the percentage as follows:
1 Calculate the size of the negative edge violation region:
216 - 68 = 148
2 Calculate the gap between the negative hold limit and the positive setup limit and add
one timing unit to allow for overlap:
68 - 45 = 23 + 1 = 24
3 Divide the gap size by the violation region size:
24 / 148 = .16
Hence, you set -extend_tcheck_data_limit to 16.
Note: ModelSim extends the limit only as far as is needed to derive a solution. So if you
used 100 in the previous example, it still only extends the limit 16 percent. Indeed, in
some cases it may be easiest to select a large percentage number and not worry about an
exact calculation.
37
d0
d1
d2
d3
d2
d3
MUX41
z
MUX21
d0
z
MUX41
d4
d5
d4
d5
d6
d7
d6
d7
d1
z
When this design is simulated with the SDF file applied, the simulator reports the following
runtime warning:
# WARNING: mux81.sdf(54): Annotating cell drivers of INTERCONNECT source port
This warning indicates that an interconnect delay from z on MUX21 to the top-level port z
on MUX81 exists and is being annotated. This interconnect delay is a special case and has
to be treated differently from regular interconnect delays in the design. Cadence tools
handle this exactly the same way and produce a very similar warning message.
Explanation
The SDF standard specifies only that interconnect delays can go from a module
output/inout port to a module input/inout port. It does not address the case where
interconnect delays go from a module output port to the top-level output port.
Almost all tools that write SDF files specify delays as ABSOLUTE delays. This means that
when a delay is annotated, it overwrites any existing value. This is to ensure that any default
values defined in the actual cells are replaced with the correct values from the SDF file.
Delays can also be INCREMENT delays, but these are almost never used. These are added
to any existing delay information instead of overwriting them.
As the simulator reads through the SDF file from top to bottom, it finds each instance and
annotates the specified delay to that instance. Since the interconnect delay from the output
of the MUX21 to the output port of the MUX81 is a special case, it does not have a defined
38
location to put the delay information as do the interconnect delays between the modules and
the path delays through the modules.
Since there is no defined location to store the delay information for this special case, the
delay information is added to any existing path delay information on the MUX21, in effect
ignoring whether or not the delay is INCREMENT or ABSOLUTE for this interconnect
delay. This is how both MTI and Cadence handle this special case.
Because this interconnect delay is being added to the path delay from the MUX21, the
INTERCONNECT line in the SDF file must be AFTER any lines that specify IO path
delays for the MUX21. If it occurs before the IO path lines, the IO path delay overwrites
the interconnect delay. The designer thinks things are being annotated, but he/she is really
losing the final interconnect delay.
Most tools that write SDF files write these special case interconnect delays at the end of the
SDF file since this is how Cadence requires them. However, when this warning is issued,
check that the delay is not lost due to improper placement of the delay in the SDF file.
39
a0
NOR
#3ns
a1
OR
a2
#2ns
z0
There is also a 4 ns path delay in a specify block from a1 to z0. The SDF file contains an 8
ns path delay from a1 to z0. Thus the cell is driven as follows:
a0
a1
a2
z0
XX
A
The delays being observed at the various points on the outputs don't seem to be correct
under various cases:
using +delay_mode_distributed during compile
using +delay_mode_path during compile
using +delay_mode_zero during compile
applying SDF with and without a specify block in the module
Which delay is used?
40
The distributed delays and the path delays are independent of each other. Distributed delays
are placed on the output driver for each primitive. Path delays are placed on a special driver
created during the compile when a specify block is present.
For distributed delays, the delays are assigned as signals propagate through the primitives.
This means that the logic of the circuit affects the delay value seen on the output. For
example consider the diagrams on the previous page:
The change in the output occurring at point B could be caused by the change on the a1
input or the a2 input. Before the toggle, the values seen on the OR gates inputs are (1,1).
Both a1 and a2 inputs change at the same time. The change from a2 is seen immediately
on the input to the OR gate. However, the value of (1,0) into the OR gate does not cause
the output to change. The change in a1 causes the output of the NOR gate to change, but
only after the 3 ns delay. Therefore, the 0 from the NOR gate arrives at the input to the
OR gate after 3 ns. This makes the value on the inputs to the OR gate (0,0), causing a
change on its output after another 2 ns delay. This creates the observed delay of 5 ns (3
+ 2) at point B on the output.
The change in the output at point F looks similar to the change at point B (both a1 and
a2 inputs change together). However, the delay seen here is only 2 ns. The difference
exists because the a0 input is now 1 and any change in the a1 input has no affect on the
NOR gates output.
When a specify block is present in the module, a special driver is created for the delay.
Essentially a break is created between the output of the primitive and the output of the
module:
OR
z0
A
The primitive retains its drivers so any distributed delays are still seen at point A of the
break. If a change occurs at point A, the following steps are used to determine when to
schedule the assignment of the value at point A to point B:
1 Only ENABLED paths to the output are considered. This means a conditional path delay
is considered only if the condition is true.
2 The input change time for each of these paths is examined, and the delay for the input
with the latest time is used.
3 If multiple paths have the same input change time, the one with the shortest delay path
is used.
The delay is determined by computing the difference between the time the input changed
and the time the output at point A changed. If only path delays are used, that difference is
zero. The value at point A is then scheduled for assignment to point B after the computed
delay value has elapsed.
However, when distributed delays are present with path delays, the difference is not
necessarily zero. If the difference is 2 ns and the path delay is determined to be 4 ns, then
the scheduled assignment of point A to point B will be 2 ns in the future. It is also possible
for the calculated difference to be negative. In this case the scheduled assignment will be
immediate, essentially setting the path delay to zero.
41
This situation is caused by the distributed delays being larger than the path delays. As a
general rule, distributed delays should always be smaller than any path delays.
When trying to determine the delay when both path and distributed delays are present, the
rule to apply is described in the Verilog LRM (Section 13.5):
"If a module contains path delays and distributed delays, the larger of the two delays for
each path shall be used."
ModelSim provides various compiler arguments to turn delays on and off. The
+delay_mode_distributed basically removes the specify block so any path delays are no
longer present. The +delay_mode_path sets all distributed delays to zero. The
+delay_mode_zero does both.
The application of an SDF file modifies the values of path delays and the calculation done
to this point still apply. However, if an SDF file is applied to a cell that contains primitives
and no specify block (or one that has been compiled with the +delay_mode_distributed
macro), a delay is still annotated to the output driver of the last primitive.
This delay is now seen as a distributed delay since it is being annotated to the same location
as the distributed delay. Whether or not it overwrites any values already there depends on
whether the delay type in the SDF file is ABSOLUTE or INCREMENT. Most path delays
in SDF files are ABSOLUTE. ABSOLUTE delay types overwrite any existing values.
In this example, if the SDF file with an 8 ns delay is annotated to the module, and that
module does not have a specify block, the result is a 3 ns delay through the NOR gate and
an 8 ns delay through the OR gate (overwriting the original 2ns delay). The delay at point
B on the timing diagram is 11 ns (3 + 8), just as it was 5 ns (3 + 2) in the above example
without the SDF file.
An SDF file may describe multiple delay paths through a module. If this SDF file is applied
to a module with no specify block, a choice must be made about which path gets annotated
to the one available location. The path that is selected is the last path listed in the SDF file,
because the annotation occurs line-by-line. If the module in the above example had path
delays for inputs A, B, and C defined in that order in the SDF file, each is annotated in turn
to the one available location. If these are ABSOLUTE delays, each overwrites the previous
value, and the delay value from a2 to z0 will be the remaining value.
42
Glitch filtering
This tech note discusses On-Detect and On-Event glitch filtering. On-Detect filtering is not
supported before the IEEE 1364-2001 standard. On-Event filtering is the default for
Verilog.
The following timing diagram shows an input (a) and output (z) to a buffer that has a 4 ns
delay.
a
6
z (On-Event)
10
12
z (On-Detect)
8
12
Glitch filtering
43
For example, if the above buffer had a rise/fall delay specified as 4/7, the trailing edge (B)
is scheduled for an earlier time than the leading edge (A):
No showcancelled:
12 13
z (default)
Showcancelled:
z (On-Event)
z (On-Detect)
8
13
44
-----
port (
O : out STD_ULOGIC;
I1: in STD_ULOGIC;
I0: in STD_ULOGIC);
attribute VITAL_LEVEL0 of and_gate : entity is TRUE;
end and_gate;
(100))
(200))
45
300ps
350ps
I0
I1
450ps
500ps
O (VITAL)
O (Verilog)
As you can see from this result, VITAL used the I1=>O path delay, and Verilog used the
I0=>O path delay.
46
c_2
Buffer
(VITAL)
N01
tbi0
c_1
(VHDL)
TBI0
c_1_V
(Verilog)
Looking at the waveforms after simulation, youd see something like the following:
617ps
/test/c2/N01
730ps
/test/c1/tbi0_dly
724ps
/test/c1_V/TBI0_dly
The delay from N01 to c_1/tbi0 is 113 ps, but for N01 to c_1_V/TBI0 it is only 107 ps. This
is expected behavior.
Note that if you use the +transport_int_delays argument to vsim, then interconnect delays
will behave more like path delays, and the delay selection will behave the same for VITAL
and Verilog. Refer to 13.4.2 in IEEE Std 1364-1995 for details.
47
CLK
PB
98ps
Recovery
97ps
Removal
121ps
and the following timing check is in the SDF file:
(RECREM (posedge PB) (posedge CLK) (0.097) (0.121))
The 98 ps transition is outside the timing window, so a violation message should not be
reported. And, the warning does not occur if the timing check is split into two separate
entries:
(RECOVERY (posedge PB) (posedge CLK) (0.097))
(REMOVAL (posedge PB) (posedge CLK) (0.121))
48
Platform
Platform
NFS problems with Red Hat 7.0, 7.1, and 7.2
Red Hat releases 7.0, 7.1, and 7.2 cause an error when running a Verilog design across a
network. This error occurs only when the library is located on an NFS remote mounted file
system. ModelSim reports the following error at elaboration:
.
.
Loading work.mem_comp
** Fatal: ERROR: Bad library format
Time: 0 ns Iteration: 0 Region: FATAL ERROR while loading design
This error is related to an NFS problem with these releases that corrupts the *.asm files in
the libraries. The work-around for this problem is to disable NFS caching. This should be
done in the invocation shell by setting the NOMMAP environment variable:
setenv NOMMAP 1
This solution may impact compile times for designs that have large *.asm files.
49
The 4p command provides addressing into the 3-4GB block, and the 3p provides addressing
into the 2-3GB block. The 4p command is supported by 11.11 and 11.i.
This design runs fine on HP-UX 10.20 as well as other platforms. What is wrong?
This problem occurs during the linking of the FLI/PLI. The older HP-UX platforms require
the -lc switch during the linking:
ld -b -o app.sl app.o -lc
On HP-UX 11.0, this switch causes the incorrect version of the standard C library to be
loaded with the design. The "Exec format error" message is the most obvious clue that this
is the problem. Use the following command line instead on HP-UX 11.0:
ld -b -o app.sl app.o
50
Platform
The library LIBC.lib is a general purpose library that contains many common C functions
(printf, etc.). This error most likely occured because the directory containing this library is
not mapped correctly.
When Visual C is setup, an environment variable called "lib" is created. This variable
should point at the directory that contains the LIBC.lib library file. For example:
lib = "C:\Program Files\Microsoft Visual Studio\VC98\lib"
Another common problem on Windows machines is when users try to use GNU compilers.
These compilers do not create Windows DLLs correctly. Any applications compiled and
linked with these compilers do not work correctly in ModelSim.
When ModelSim starts up, it tries to open a socket on the host machine. As stated in the
first line of the message, ModelSim couldnt open a socket.
This error most likely results from not having a "localhost" defined on your system.
Systems must have a localhost setup in their /etc/hosts file (or equivalent) to run the
ModelSim GUI. The first line in this file should be:
127.0.0.1
localhost loopback
Without this line you should not be able to ping localhost. The following command should
return the localhost and the correct address, 127.0.0.1:
/usr/sbin/ping localhost
Even though ping works, the host may still be unreachable. A second thing to try is to run
ifconfig lo and verify that this also contains the correct address for localhost. The key is to
make certain that the localhost is reachable, or ModelSim will never start.