Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
comprehensive RTL verifcation solution chooses not to truncate it. However, the foreach constraint will
iterate according to the size of the array during randomization, not the actual number of elements in the
array. After randomization, the actual size of the array will be 100 or more and will be different from the value
of lendespite the size() == len constraintif len is less than 100. It is thus a good idea to trim arrays
in the post_randomize() method to ensure consistency with other class properties.
class eth_frame;
rand bit [47:0] dst;
rand bit [47:0] src;
rand bit [15:0] len;
rand bit [ 7:0] data[];
constraint valid_frame {
len inside {46:1500};
data.size() == len;
foreach (data[i]) {
data[i] != h00;
}
}
function void post_randomize();
if (this.data.size() > this.len) begin
this.data = new [this.len] (this.data);
end
endfunction: post_randomize
endclass: eth_frame
2006 Synopsys, Inc.
8
Additionally, the LRM does not specify what happens should the size of a randomized array be left unconstrained.
One e-based tool has an implicit soft constraint on list sizes to keep them less than a confgurable valuewith
a default of 50. VCS solution chooses not to modify the size of randomized arrays if their size is unconstrained.
Randomizing arrays of scalars works very well in SystemVerilog. But randomizing arrays of objects creates a
challenge. Should the array be lengthened during randomization, what should the additional array elements
be flled with? Because randomization does not allocate new object instances, they are flled with null.
In most cases, what is desired is a random-length array populated with randomized object instances. To
achieve the desired functionality, it is necessary to pre-fll the array with the maximum number of object
instances. The array can then be truncatedand the extra object instances reclaimed by the garbage
collectorshould the array size be randomized to something shorter.
Soft Constraints
Soft constraints are usually used to specify default values or relationships that can be optionally modifed to
inject errors or corner cases. Soft constraints are required in e because constraints are strictly additive. Once
a constraint is specifed, it cannot be removed. But injecting errors requires that constraints limiting data
generation to valid solutions be relaxed to allow the generation of invalid data under controlled conditions.
Soft constraints, in cases, can provide this optional constraint specifcation.
struct eth_frame {
dst: uint (bits:48);
src: uint (bits: 48);
len: uint (bits: 16);
data: list of byte;
keep soft len in [46..1500];
keep data.size() == len;
};
extend eth_frame {
keep len < 46;
};
SystemVerilog does not have the concept of a soft constraints. All active constraints in SystemVerilog are
hard and always considered when randomizing a class instance. Any inconsistency will cause a runtime
error. But the key word here is active.
SystemVerilog constraints are built on the object-oriented framework. They have names and thus can be
referenced outside of the class that contains them, much like data properties or methods.This enables
SystemVerilog to allow constraint blocks to be turned off or on procedurally.
class eth_frame;
rand bit [47:0] dst;
rand bit [47:0] src;
rand bit [15:0] len;
rand bit [ 7:0] data[];
constraint valid_len {
len inside {46:1500};
}
constraint valid_frame {
data.size() == len;
}
endclass: eth_frame
eth_frame fr = new;
fr.valid_len.constraint_mode(0);
fr.randomize() with {
len < 46;
};
2006 Synopsys, Inc.
9
So, instead of relying on a contradiction to turn off a soft constraintif and only if a contradiction is created
and then turning off all previously defned soft constraints on that same feldSystemVerilog allows specifc
constraints to be reliably turned off to relax them, even if a solution would exist otherwise. For example, the
e code below will not have the intended effect because a solution exists that intersects the soft constraints
and the new constraint. Of course, the soft constraint on the len feld could be reset to turn it off, but this
would also turn off all other soft constraints on that same feld, potentially creating a different solution space
than the desired one.
extend eth_frame {
keep len in [0, 46, 1500, 65535];
};
Because SystemVerilog constraints are built on the object-oriented framework, like virtual methods, they can
be added to or overloaded based on the name of the constraint blocks in class extensions. So unlike the
strictly additive constraints in e, SystemVerilog constraints are additive, substitutive and negative.
class runt_eth_frame extends eth_frame;
constraint valid_len {
len <46;
}
endclass: runt_eth_frame
A short note on the use of curly braces in constraint blocks instead of begin/end keywords: The foreach
loop and if statements exist both for procedural code and constraints. When used in procedural contexts,
they use the begin/end keywords to group multiple statements in their bodies. When used in constraint
blocks, they use curly braceslike the constraint block itselfto group iterated or conditional constraints.
Why the difference?
begin/end keywords are used to defne procedural regions. These procedural regions can contain local vari-
able declarations. These regions are entered, executed and then exited. Procedural regions can be stepped
through in a debugger.
Curly braces are used to defned declarative regions. Constraints are declarative. Unlike procedural regions,
the sequence in which they are specifed is not functionally relevant. They are considered in parallel, not
sequentially. It is not possible to step through constraints, nor is it possible to declare local variables in a
declarative region.
Temporal Expressions
Temporal expressions in e are functionally equivalent to properties in SystemVerilog. As in e, these properties
can be used to trigger events, or they can be asserted to make sure they are never violated.
The major difference between e and SystemVerilog is the location where the properties are specifed. In e,
temporal expressions are specifed as events in structs or units. Both constructs should be implemented as
classes in SystemVerilog. However, properties cannot be specifed in classes. Properties can only be
specifed in interfaces or modules.
Although this appears to be a signifcant difference between e and SystemVerilog, in practice it does not
present a signifcant challenge when mapping the functionality of temporal expressions to SystemVerilog.
In almost all cases, temporal expressions are used to verify or detect specifc behavior in the design.
SystemVerilog properties can perform the same functionality by locating them in the same construct that
implements that behavior or in an interface that has visibility over all of the signals implementing a
protocol behavior. Using cross-module references, properties can also verify behavior across module
boundaries, when necessary.
2006 Synopsys, Inc.
10
property req_ack_p(req, r_data, ack, a_data, clk, reset);
logic [$bits(r_data)-1:0] data;
@(posedge clk) disable iff (reset)
(req, data = r_data) ##0 ack[->1]
|-> (r_data == a_data);
endproperty : req_ack_p
interface my_itf(
input logic my_req, my_ack,
input logic [15:0] my_data_in, my_data_out,
input logic clk, reset);
my_data_check: assert property (
req_ack_p(my_req, my_data_in,
my_ack, my_data_out, clk, reset));
endinterface : my_itf
As in e, local variables can be used to store values within a temporal property. The property can be reused
in different contexts. In the example above, it is instantiated in an interface that can then be instantiated
as a checker.
If it is desirable to specify properties outside of the module or interface implementing the functionality to
be observed, a program, interface or module encapsulating those properties can be bound, after the fact,
to a specifc instance or all instances of the interface or module implementing the observed functionality. In
the example below, an instance of the interface containing the temporal assertion is bound to all instances of
data_module.
bind data_module
my_itf check_data(
start_b, stop_b, id_in, id_out, ck, rst);
The ability to bind properties to all instances of a module or interface simplifes the equivalent process in e
where a unit containing the equivalent temporal expressions must be explicitly instantiated and its
hdl_path() appropriately set for each instance of the target interface or module.
There can be temporal expressions observing or checking behavior in the unit or struct itself. Those tend
to be relatively simple and often used solely to trigger an associated coverage group. Simple temporal
expressions can be easily implemented using equivalent behavioral code and coverage group can be easily
triggered procedurally using the implicit sample() coverage group method.
When Inheritance and Aspect-Oriented Programming (AOP)
When inheritance and aspect-oriented programming are two different mechanisms in e. But a proper e
methodology requires that both be used in tandem to achieve the desired results. Therefore, they must be
considered together when describing how they can be mapped to equivalent SystemVerilog.
When inheritance and AOP are used to implement many different functional aspects of verifcation. These
different aspects are implemented using different techniques in SystemVerilog, and thus must be considered
separately.
Data Modeling
When inheritance is used to model different variations of the same transaction or data descriptor. Under
different variances, some felds may or may not be available and the behavior of some methods may
be different.
struct operand {
mode: [SHORT, IMMEDIATE, REGISTER];
2006 Synopsys, Inc.
11
assemble(): list of bit is empty;
arg(): list of uint is empty;
};
extend SHORT operand {
value: uint (bits: 10);
assemble(): list of bit is only {
result = %{b110100, value};
};
};
extend IMMEDIATE operand {
value: uint (bits: 32);
assemble(): list of bit is only {
result = b110000;
};
arg(): list of uint is only {
result = {value};
};
};
extend DIRECT operand {
R: uint (bits: 4);
assemble(): list of bit is only {
result = %{b00, R};
};
};
It is tempting to implement the same data model using class inheritance in SystemVerilog. However,
because SystemVerilogs inheritance is similar to es like inheritance, it will be diffcult to randomly select
different variations or to constrain the data variation. Using class inheritance to model different variants will
cause the nature of the class instance to determine the variance. Since the nature of the class instance
cannot be modifed without allocating a different one, randomizing a specifc class instance will always
yield the same data variant.
Once stripped of its syntactic coating, all felds from different when extensions are located in the same
struct. The proper approach in SystemVerilog is thus to use the same implementation and explicitly declare
all properties in the same class.
class operand;
rand enum {SHORT, IMMEDIATE, REGISTER} mode;
rand bit [31:0] imm;
rand bit [ 3:0] R;
...
};
The when inheritance in e creates variant-centric model method descriptions: the unique attributes of each
variation in all methods are coded in separate extensions. Understanding the complete behavior of an par-
ticular method requires the understanding of the composition of each of the variations.
Data modeling in SystemVerilog is procedure-centric: the unique attributes of all variations for each method
are coded in the method itself. The composition of all variations is explicitly coded.
class operand;
rand enum {SHORT, IMMEDIATE, REGISTER} mode;
rand bit [31:0] imm;
rand bit [ 3:0] R;
2006 Synopsys, Inc.
12
function int assemble(output bit [31:0] image);
case (mode)
SHORT: begin
image = {b110100, imm[9:0]};
return 16;
end
IMMEDIATE: begin
image = b110000;
return 6;
end
SHORT: begin
image = {b00, R};
return 6;
end
endcase
endfunction: assemble
function void arg(output bit [31:0] image[]);
case (mode)
IMMEDIATE: begin
image = new [1];
image[0] = imm;
end
default: image = new [0];
endcase
endfunction arb
endclass: operand
The VMM for SystemVerilog guidelines 4-68 through 4-72 detail how to properly model data and transac-
tions with multiple variants.
Instance-Specifc Extensions
In e, aspect-oriented extensions extend all instances of the extended type. Their effect is global and per-
manent. If it is desirable to limit the effect of extensions to a specifc instance or for a specifc duration, it is
necessary to conditionalize the extension using when inheritance.
For example, the following code segment instantiates four instances of the same generator. Any extension
to the eth_frame struct type will affect all four instances.
unit eth_gen {
fr: eth_frame;
main(): @sys.any is {
while (1) {
gen me.fr;
send(fr);
};
};
...
};
extend sys {
gen: eth_gen[4] is instance;
};
To be able to specify instance-specifc extensions, it is necessary to introduce a when extension of the
generator and constrain the appropriate generator instance to be of the appropriate variation.
extend eth_gen {
IS_SPECIAL: bool;
keep soft not IS_SPECIAL;
};
2006 Synopsys, Inc.
13
extend IS_SPECIAL eth_gen {
keep fr.len == 46;
};
extend sys {
keep for each in gen {
(index == 2) => it.IS_SPECIAL;
};
};
The same functionality is implemented in SystemVerilog using a factory pattern. A factory pattern is a stan-
dard object-oriented technique that is used to implement classes that create other classesi.e., generators.
The example below shows a generator implemented using the factory pattern.
class eth_gen;
eth_frame fr;
task main();
forever begin
this.fr.randomize();
send(fr);
end
endtask: main
...
endclass: eth_gen
class sys;
eth_gen gen[4];
...
endclass: sys
Figure 1: Factory Pattern
Modifying a single instance of the generator is accomplished by replacing the instance of the randomized
class by an instance of an appropriately extended class. Because SystemVerilogs randomization does not
allocate a new instance, it will randomize the replacement, not the original one. And because the random-
ize() method is a virtual method, the randomization will be performed according to the rules defned in the
extended class, not the original class.
class short_eth_frame extends eth_frame;
constraint short_frames {
len == 46;
}
endclass: eth_frame
program test;
sys env = new;
Generated
Stream
Different
Stream
Extended
Factory
Test Test
Copy
Generator
Generator
Factory
2006 Synopsys, Inc.
14
initial
begin
short_eth_frame fr = new;
env.gen[2].fr = fr;
...
end
endprogram: test
The VMM for SystemVerilog guidelines 5-6 and 5-19 to 5-22 detail how to implement generators and how
to control them using the factory pattern.
Exception Injection
Exceptions are deviations from the standard and default behavior of a verifcation component. It is simple
to write a transactor that always does the correct thing, always acknowledges every transaction and
operates as fast as possible. But that is not very interesting from a verifcation standpoint. It must be
possible to introduce errors, refuse or drop transactions, or introduce delays.
In e, this is accomplished by extending the methods or redefning events that implement the default functionality.
Because methods can only be prepended or appended tonot extended in the middleit is necessaryand
just plain good coding practiceto provide empty methods that are initially empty for the express purpose of
extending them to modify the default behavior. The e language itself contains several such methods, such
as the pre_generate() and post_generate() methods. Failing to provide such method results in large-scale
code duplication with is only extensions to introduce minute differences in the method implementation.
unit usb_device {
reply_with(usb_packet req;
usb_packet *resp): @sys.any is empty;
main(): @sys.any {
while (1) {
var req, resp: usb_packet;
req = usb_port.rx();
resp = default_resp(req);
reply_with(req, resp);
usb_port.tx(resp);
};
};
...
};
extend usb_device {
reply_with(usb_packet req;
usb_packet *resp): @sys.any is also {
gen resp keeping {
kind == STALL;
...
};
};
};
extend usb_device {
reply_with(usb_packet req;
usb_packet *resp): @sys.any is also {
wait delay(20);
};
};
A similar approach is used with SystemVerilog. Virtual methods, designed specifcally to be overloaded to
introduce functional deviations, are provided in verifcation components.
2006 Synopsys, Inc.
15
Figure 2: Virtual Methods
class usb_device;
virtual task reply_with( usb_packet req,
ref usb_packet resp);
endtask: reply_with
task main();
forever begin
usb_packet req, resp;
req = usb_port.rx();
resp = default_resp(req);
reply_with(req, resp);
usb_port.tx(resp);
end
endtask: main
...
endclass: usb_device
class stalled_usb_device extends usb_device;
virtual task reply_with( usb_packet req,
ref usb_packet resp);
resp.randomize() with {
kind == STALL;
...
};
endtask: reply_with
endclass: stalled_usb_device
class slow_usb_device extends usb_device;
virtual task reply_with( usb_packet req,
ref usb_packet resp);
#20;
endtask: reply_with
endclass: slow_usb_device
The problem with the example above is that, unlike aspect-oriented extensions, object-oriented extensions
create new data types and follow a strict hierarchy and lineage. To combine orthogonal extensions, it is
necessary to put these extensions on the same class lineage. Then, the original instance of the verifcation
component in the verifcation environment must be replaced with an instance of the extended class, with
all of the potential connectivity issues that it entails. In contrast, all aspect-oriented extensions in e are
cumulative and are added to the original data type without creating a new one.
Fortunately, there is a simple mechanism in SystemVerilogin fact in all object-oriented languagesthat
allows the orthogonal extension of verifcation components, without creating new classes and without
having to replace existing instances. It is the faade pattern. All extension methods are defned in a separate
class called a faade. Extensions are then implemented by extending the faade, not the actual verifcation
component class. Instances of the faade extensions are then registered with the verifcation components.
To support multiple orthogonal extensions, a verifcation component should support multiple faade
registrations using a queue.
xactor
Virtual Method
Extension
2006 Synopsys, Inc.
16
Figure 3: Faade Pattern
class usb_device_callbacks;
virtual task reply_with( usb_packet req,
ref usb_packet resp);
endtask: reply_with
endclass: usb_device_callbacks
class usb_device;
usb_device_callbacks cbs[$];
task main();
forever begin
usb_packet req, resp;
req = usb_port.rx();
resp = default_resp(req);
foreach (this.cbs[i]) begin
this.cbs[i].reply_with(req, resp);
end
usb_port.tx(resp);
end
endtask: main
...
endclass: usb_device
class stalled_usb_device extends usb_device_callbacks;
virtual task reply_with( usb_packet req,
ref usb_packet resp);
resp.randomize() with {
kind == STALL;
...
};
endtask: reply_with
endclass: stalled_usb_device
class slow_usb_device extends usb_device_callbacks;
virtual task reply_with( usb_packet req,
ref usb_packet resp);
#20;
endtask: reply_with
endclass: slow_usb_device
program test;
usb_env sys = new;
initial begin
stalled_usb_device cb1 = new;
slow_usb_device cb2 = new;
xactor
sys.dev[3].cbs.push_back(cb1);
sys.dev[0].cbs.push_back(cb2);
sys.run();
end
endprogram: test
As shown in the example above, specifc instances of verifcation components can be extended by simply
registering the appropriate callback faade extension instances with the appropriate verifcation component
instance. There is no need to create conditional extensions as is needed in e.
The VMM for SystemVerilog guidelines 4-154 to 4-163 detail how to implement extensible verifcation
components and how to extend them using the faade pattern.
Other Differences
There are other differences between e and SystemVerilog that are not mentioned in this paper. For example,
struct felds in e are randomized by default unless they are prefxed with a !, whereas SystemVerilog class
properties must be prefxed with the rand attribute to be randomized. Some constructs do not have a direct
correspondence in the SystemVerilog language but can be mapped to utility classes providing similar
functionality. For example, e ports can be replaced with vmm_channels. This and other differences are
minor and do not present any challenges when migrating e code to SystemVerilog.
Other differences exist in the constructs and approaches defned in the eReuse Methodology (eRM). But
since the eRM and the additional language constructs it defnes are not part of the 1647 IEEE standard
and remain proprietary extensions to the IEEE e language, it is not possible for this paper to legally address
these differences. However, all Synopsys customers who have migrated their eRM-based verifcation
environment and tests found the publicly-available methodology and support classes specifed in the
Verifcation Methodology Manual for SystemVerilog to provide an effcient migration path.
Conclusions
SystemVerilog and e are different languages, so some changes to how verifcation environments are
developed is to be expected. However, any environment coded in e can easily and effciently be developed
in SystemVerilog. It is no different than Verilog and VHDL: these two languages have fewer features and are
even more similar to each other than SystemVerilog is to e, yet they have semantic differences that require
certain functionality to be implemented differently in each language. Verifcation teams can confdently move
from e to SystemVerilog, knowing they are not giving up language expressiveness or productivity and are
joining a broadly supported industry standard with a vibrant ecosystem of supporting tools, services,
IP and people.
Given nearly equivalent language capabilities, moving from e to SystemVerilog enables users to adopt
a widely-supported industry standard, reduce cost of ownership, increase verifcation performance, and
leverage a single unifed language to improve overall productivity across the entire verifcation and
design process.
More Information
More information on SystemVerilog, and Synopsys e to VCS Native Testbench Migration Services, can be
found at www.synopsys.com/SystemVerilog/etoVCS.
700 East Middlefeld Road, Mountain View, CA 94043 T 650 584 5000 www.synopsys.com
Synopsys, and the Synopsys logo are registered trademarks. All other trademarks or registered trademarks
mentioned in this release are the intellectual property of their respective owners and should
be treated as such. All rights reserved. Printed in the U.S.A.
2006 Synopsys, Inc. 5/06.CE.WO.06-14332