Browse >
Home /
信息中心 /
SNUG /
2009论文集 / A migration from Vera to SystemVerilog in a stepped approach Part II
A migration from Vera to SystemVerilog in a stepped approach Part II
Samuel Zhang, Freescale SuZhou Design Center, China
Joachim Geishauser, Freescale Halbleiter Deutschland GmbH
Terry Gong, Freescale SuZhou Design Center, China
Samuel.Zhang@freescale.com
Joachim.Geishauser@freescale.com
Terry.Gong@freescale.com
Abstract
The legacy Vera code existing for SoC and module verification in most companies is huge and the key to success for bug-free designs. A direct migration from Vera to SystemVerilog for a new Chip, re-using peripherals or even just a derivative SoC can be a high risk and impact the time to market significantly. Besides the language conversion in modern testbenches base classes are used, but they create an additional dependency if no API compliant version in System Verilog is available. In most cases third party Verification IP (VIP) is also involved in such complex testbenches. And mostly this third party VIP does not provide the same API to SystemVerilog as to Vera. This paper follows and completes the methodology we presented last year, and mainly focuses on the discussion of the NTB-OV to SystemVerilog migration.
1. Introduction
Verification is still the bottleneck in the chip development flow. The usage of high level verification languages that support randomization and functional coverage is one of the main gating factors to reduce the effort to ensure a functional correct design. End of last decade and into the beginning of this decade, proprietary languages emerged in the market and were heavily used in the industry. With the development of the SystemVerilog language as an extension to the Verilog language a public, tool independent language became available. To leverage best in class tools that emerge on top of the SystemVerilog language and not to be locked into expensive proprietary language based tools, companies are moving to the new language.
We have introduced a low risk conversion process from Vera via NTB to SystemVerilog called “product cycle embedded conversion flow”, which enables to release well verified products at every step of the conversion approach and presented in [1].
This paper describes second part of our journey to Systemverilog following product cycle embedded conversion flow. This journey will cover the past and the present experience on Native Testbench OpenVera (NTB-OV)2 to SystemVerilog(SV)3 conversion. This paper is focusing on the details of conversion flow, instead of discussing the benefits of using System Verilog which is not the intention of this paper.
2. Background
2.1 Modular testbench Architecture
To enable maximum re-use and best quality it makes sense to develop the testbenches in a modular way. This allows developing testbench code in the smallest possible environment and thus allows the best turn-a-round time during debugging. Furthermore, updates can be done in isolation to other testbenches or design code and reduce the dependency on other testbench components or design code not of interest for this testbench. The quality of each testbench component is ensured at the lowest possible layer, so simulation speed is very high. When the component is re-used later it does not need to be qualified again. Our testbenches environment consists out of three major layers:
• VIP level
• Module level
• SoC level
Since the reuse of code in the different levels of the testbenches is an important factor for the conversion, the following section gives a brief overview of our reuse model. Module testbenches and VIP testbenches are re-used in the SoC testbench. This is called vertical re-use. Of course not all parts of a module or VIP testbench are directly re-used in the SoC testbench. Some elements needed in the module testbench might be replaced in the SoC level by a part of the design itself – this is then called mapped VIP. For example a CPU is modeled in a module testbench with a Bus Functional Model (BFM) driven directly by the testbench and in the SoC design this is mapped on the real CPU model. VIP which is connected to an external bus is usually re-used in the SoC testbench as it exists in the module level testbench. This is then called keep VIP. Typically these are standardized interfaces such as USB, SATA, CAN and many others. These VIPs can be purchased from third party vendors with good quality (e.g. Synopsys offers USB, PCI, etc…) VIP level testbenches are often created for company internal buses, since no external vendor provides the required VIP components:
• Target Transactor (Memory Model, Receiver)
• Register Transactor (Driver, BFM)
• Register Monitor
The VIP level testbenches have the simplest design to achieve best performance for the verification of the VIP components. The design in the VIP testbench consists of the wiring of the memory model to the BFM to create a functional system. Of course the monitor gets also connected into this system. The stimulus of these testbenches consists of generic stimulus and of response checkers. In our case, the scope of the testbenches to be converted from Vera to SystemVerilog is:
• 9 VIP level testbenches
• 39 Module level testbenches
• 3 SoC level testbenches
2.2 Steps for conversion from Vera to SystemVerilog
The following picture shows the conversion life cycle over time.

Figure 1: Testbench Conversion Steps
As the first step, the Vera code is converted to NTB-OV code with additional updates that need to be done for SV. The language used is still Vera, but the code is no longer compiled by the Vera compiler, but using VCS.
The second step in the conversion process is to update the code to use the newest version of the Freescale Vera Base Class Library (VBCL). The motivation behind this step is to move from the currently used VBCL 4.x version to the latest VBCL 5.x version where an application programming interface (API) compatible SystemVerilog implementation is available.
The final conversion step moves the NTB-OV code to SystemVerilog code. Along with this, the file organization is updated to meet the defined location of SystemVerilog code files in the Stingray design kit.
For each step, the conversion is divided into a staged process. We always start with the VIP level updates. Since a lot of the VIPs are shared, this step is key in the start-up of a new conversion process. Once all VIPs are updated, the module testbench update can be started. Finally when all module level testbenches, which will be reused in the SoC testbench, are updated, the SoC testbench update is started.
The discussion of the first and second conversion steps has been covered in [1].This paper covers the final conversion step: NTB-OV to SystemVerilog migration step.
3. The NTB-OV to Systemverilog Conversion
3.1 Automated conversion
Since the number of testbenches is large, it makes sense to automate the conversion as much as possible allowing the engineers to concentrate on the difficult cases that can not be automated. For the conversion shown in this paper, two different kinds of automation tools, at different automation levels, were used. One is commercial conversion tool VeriEZ, the other is the simulator VCS.
3.1.1 Commercial conversion tool
The commercial conversion tool used during the conversion process is the VeriEZ tool suite. VeriEZ is an OpenVera-to-SystemVerilog Migration tool suite. Input modules are parsed, analyzed for translatable constructs and translated to equivalent SystemVerilog modules. An important component of VeriEZ is EZCheck, which is used to detect SystemVerilog incompatibilities in the input code, and creates a list of violations that alert the user about problems that will be encountered if the code is translated to SystemVerilog. EZTrans, the SystemVerilog writer creates readable SystemVerilog code while preserving all comment lines, component boundaries and hierarchy during the translation, and also preserving the non-translatable construct which will be raised by simulator syntax check and manually updates will be required.

Figure 2: VeriEZ Use Model4
The tool has been added to the compile flow with predefined options to allow all users to have a smooth conversion of the NTB-OV code to SystemVerilog. The compile flow gathers the files that make up the testbench. These files then are passed to the VeriEZ tool suite along with the appropriate switches and the corresponding SystemVerilog files are generated.
3.1.2 Simulator conversion support
The VCS simulator supports the conversion in two ways:
■ Syntax check: The simulator flags immediate constructs that are no longer supported in the target language.
■ Semantic testbench check: The usage of the testbench in the target and source language allows comparing the behavior of the testbench in the target language against the source language.
3.2 The NTB-OV to SystemVerilog mapping of VeriEZ
Besides the general language syntax conversion, VeriEZ also provides one on one mapping for the NTB-OV constructs to SystemVerilog in most cases, which includes:
• Data Types.
• Primitive Data Types.
• Enumerations.
• Events.
• Virtual Ports / Binds.
• Arrays and Queues.
• Linked Lists.
• Operators.
• Statements and Blocks.
• Tasks and functions.
• Concurrency Control.
• Object-Oriented Programming.
• Functional Coverage.
With the commercial conversion tools like VeriEZ, users can benefit immensely from using a proven migration flow. But no translator can be fully automatic. Besides the cases where a Vera language construct can be mapped to SystemVerilog construct(s) by tools automatically; there are cases where SystemVerilog lacks functionality provided by the Vera language. Vera constructs that do not translate easily are:
• Regions, Aspects and other new NTB-OV constructs
• Some predefined NTB-OV system functions, such as vca( )
• Some predefined class methods for NTB-OV such as pack()/unpack()
Manual interventions are usually required on the generated SystemVerilog code for the constructs listed above, but with the right guidance users can learn to detect translation problems beforehand and solve quickly to minimize the effort spent. Several code migration rules are summarized from the daily migration works which are used to guide the team to address most of the “hard to translate” constructs.
3.3 The NTB-OV to SystemVerilog code migration rules
3.3.1 NTB-OV virtual port and binding migration rules
The biggest update needs to be done in the interface between the testbench and the design. Here the Vera port/interface/bind definitions need to be translated into SystemVerilog interfaces/clocking blocks and modports. The virtual ports used in all the Vera classes need to be mapped as virtual interface.

Figure 3 : Testbench to Design Connection
On the right hand side of Figure 3 the SystemVerilog connection of an SRAM model is shown. The Vera port is converted into parts of the SystemVerilog interface definition. Beside the Vera port, the direction and clock relations of the Vera interface definition needs to be defined in the SystemVerilog interface. The hdl_node definition of the Vera interface will be translated into the SystemVerilog assign statements. The Vera bind is expressed as the instantiation of the SystemVerilog interface. The virtual port mapping in class is presented in Table 1 below.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
class Sram_Responder {
string name;
bit [31:0] out_data;
sram_port sram_resp_port;
…
function new(string name=
“Sram_Responder”,
sram_port sram_resp_port_inst){
this.name = name;
this.sram_resp_port=
sram_resp_port_inst;
}
task send_data(){
…
// Drive outputs:
this.sram_resp_port.$dout=
this.out_data;
// Consume one clock
@(posedge this.sram_resp_port.$clk);
…
} }
|
class Sram_Responder ;
string name;
reg [31:0] out_data;
virtual sram_port.responder_mp sram_resp_port;
…
function new(string name = “Sram_Responder”,
virtual sram_port.responder_mp
sram_resp_port_inst);
this.name = name;
this.sram_resp_port= sram_resp_port_inst;
endfunction
task send_data();
…
// Drive outputs:
this.sram_resp_port.$dout = this.out_data;
// Consume one clock
@(sram_resp_port.responder_cb);
…
endtask
endclass
|
Table 1 : Virtual Port Mapping inside Class
On the left hand of table 1, the Vera port is created and used in a Sram_Responder class and the Vera physical interface defined in Table 1 is passed via constructor argument. On the right hand in SystemVerilog, the virtual interface instance is created and the virtual connection is passed via constructor argument, the signals are driven or sampled using virtual interface.
A group of functions are provided to return properties of interface signals or statically bound port signals in Vera, most of which are not supported by SystemVerilog and need manually updates. For example, the feature vera_is_bound() in Vera is useful to handle optional signals of a VIP and frequently used in our Vera code. An example is presented in Table 2.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
if (vera_is_bound(ips_port.$seq_access))
seq_access = ips_port.$seq_access;
|
If
(`IPS_PORT_SEQ_ACCESS_IS_BOUND)
seq_access = ips_port.cb.$seq_access;
|
Table 2: Vera_is_bound() Workaround
On the left hand of table 2, vera_is_bound() is used to judge whether signal seq_access is bound in the testbench. In fact, there isn’t satisfying equivalent expression in SystemVerilog yet. There is a temporary workaround presented on the right hand for module testbenches. A macro is defined for each optional signal and the macro can be redefined to “true” or “false” in different testbenches. The disadvantage of this workaround is that it is not object-oriented based and it possibly will not work when more than one ips_port used in the same testbench, which occurs very often in SoC testbenches.
Therefore we are seeking a better way. Now we are working on implementing these functions via DPI in SystemVerilog that can retrieve signal properties.
3.3.2 NTB-OV deep copy migration rule
Deep copy is supported in two ways in NTB-OV: one is a predefined function for all Vera classes called object_copy(), which is defined as a virtual function to copy the contents of a source object into a destination object. The object copy is deep, replicating the entire data structure including contained objects and the super object. The other way is through new().However, there is no oject_copy() similar predefined deep copy methods available for SystemVerilog tasks, and copy via new() is no longer deep copy but shallow copy in SV. Table 3 below presents an issue caused by the semantic differences between NTB-OV and SystemVerilog during the base class migration.
|
NTB-OV code
|
SystemVerilog nonequivalent
|
|
virtual function void publish(FSLLoggingBase
caller, RegisterEvent evt){
RegisterEVent evt_copy;
evt_copy = new evt;
evt_copy.add_caller(caller);
evt_copy.add_caller(this);
notify_this(evt_copy);
trigger(ONE_SHOT, update);
}
|
virtual function void
publish(FSLLoggingBase caller,
RegisterEvent evt);
RegisterEVent evt_copy;
evt_copy = new evt;
evt_copy.add_caller(caller);
evt_copy.add_caller(this);
notify_this(evt_copy);
->update;
endfunction
|
Table 3: Deep Copy Migration
On the left hand of table 3, another object evt_copy is created in different memory location with the same content as evt via deep copy new in NTB-OV. The advantage is that evt and evt_copy do not depend on each other but at the cost of a slower and more expensive copy.
On the right hand, evt_copy is also created by new in SystemVerilog. However, this is known as a shallow copy. All of the variables are copied across integers, strings, instance handles, etc. Objects, however, are not copied, only their handles. This results in a situation in which some data is shared between evt and evt_copy, thus modifying the one will alter the other, which means the evt_copy content can still be modified outside publish() even after calling it. This is violating the original NTB-OV semantics of publish() and jeopardize the safety of the Event Communication Mechanism of the base class.
This issue is hidden deeply and discovered in a module testbenches simulation long after the base class released. To handle this kind of semantic differences, a virtual copy method need to be implemented on all class hierarchies of the base class which provides the deep copy capability.
A better solution is presented in table 4 above. Any change in a variable or net can be detected using the @ event control in SV, as in Verilog. If the expression evaluates to a result of more than 1 bit, a change on any of the bits of the result (including an x to z change) shall trigger the event control.
3.3.3 Concurrency control migration rule
3.3.3.1 Wait_var()
In NTB-OV, wait_var() task blocks the current process until one of the specified variables changes value. Only true value changes unblock the process. Reassigning the same value does not unblock. If more than one variable is specified, a change to any of the variables unblocks the process.
Wait_var() is often simply mapped into wait() in SV. However, wait() means wait on the true value, but not value change. So they are not logically equal at all.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
bit eod_sync=0;
…
wait_var(this.eod_sync);
…
|
reg eod_sync = 0;
…
@(this.eod_sync);
…
|
Table 4: Wait_var() Migration
3.3.3.2 sync(ALL/ANY/CHECK, event_a,…) and trigger(ON |OFF|ONE_SHOT | ONE_BLAST,event_a,…)
The ANY or ALL type of sync() suspends the process until any or all of the specified events are triggered in NTB-OV, which can be mapped to @(…) in SystemVerilog in certain way.
In NTB-OV, the CHECK type of sync() does not suspend the thread and checks the status of an event. It returns 1 if the event is triggered in ONE_BLAST mode within a simulation time step, regardless of whether it was called before the trigger was executed. The better solution is to use wait(event_var.triggered) in SV,which is similar to @(event_var), but can also be satisfied by events which happened earlier during the same simulation time, as presented in Table 5.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
event run_event ;
…
sync(CHECK,run_event);
…
task run (){ trigger(ONE_BLAST,run_event);}
|
event run_event ;
…
wait(run_event.triggered);
…
task run (); ->run_event; endtask
|
Table 5: ONE_BLAST Trigger Mapping
However, the CHECK type of sync() checks the status of an event triggered throughout the simulation time but not only within a simulation time step if the event is triggered directly ON or in ONE_SHOT mode, which has no direct equivalent expression in SV. A workable solution can be found in Table 6 below.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
Event run_event ;
….
task monitor_bus () {
while(sync(CHECK,run_event)){
//monitor thread throughout the
simulation
} }
….
task run (){ trigger(ON, run_event); }
task stop (){ trigger(OFF,run_event);}
|
int run_event_int ;
…
task monitor_bus ();
while (run_event_int) begin
//monitor thread throughout the simulation
end
endtask
task run (); run_event_int = 1; endtask
task stop (); run_event_int = 0; endtask
|
Table 6: ONE_SHOT/ON Trigger Mapping
The event run_event is used as flag event to switch on/off the monitor thread with sync(CHECK) and triggered in ONE_SHOT in NTB-OV on the left hand of Table 4. On the right hand, an integer run_event_int is used in SV. The trigger is simulated by doing an assignment to run_event_int SV.
3.3.4 Variable slice of vector and array migration rule
In SV, to access a slice of a bitvector/array, in most cases the difference between end/start index is constant – and for these one can use +: and -:
|
bvpart = bv[startIdx+:(endIdx-startIdx)];
|
However, it is forbidden to access a slice of a bitvector/array when both start and end index, or both start index and the slice width are variables, while it is widely used in NTB-OV. Therefore there is no straight-forward way to do the migration.
To solve this, a ‘for’ loop is used as a workaround to translate a variable slice to fixed width slices with variable start indexes as presented in Table 7.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
integer addr_width;
…
temp_addr_modv[(this.addr_width - 1):0] =
targetCmd.addr[(this.addr_width - 1):0];
|
integer addr_width;
integer i;
…
for (int i=0; i<this.addr_width; i++ )
temp_addr_modv[i] = targetCmd.addr[i+:1] ;
|
Table 7: Variable Slice Access Mapping
To use this approach in a general way, a function with ‘for’ loop needs to be used. However, this may create a warning or error message if the output of the function does not match the calling data types. Therefore a function in a parameterized class is the most generic solution. Class definition is shown below:
|
class DynamicSlice #(type T_in = reg[31:0],type T_out = reg[31:0]);
function T slice( T data_in, int upper, int lower);
int i;
for (i=lower; i<=upper; i++)
slice[i]=data_in[i-lower+:1];
endfunction
endclass
|
3.3.5 Pack/Unpack migration rule
Data packing is integrated into the object-oriented framework of NTB-OV.NTB-OV defines several class methods that are used to pack and unpack data declared within a class. And a set of attributes are provided for class members that designate how data is to be packed and unpacked.
Based on this convenient way on data packing/unpacking, an internal tool named Register Factory Unit (RFU) is used to provide an easy solution for register access of a testbench with Freescale Vera Base Class in NTB-OV.
Figure 4: Pack/Unpack Migration in RFU
As presented in Figure 4, RFU provides a base class named reg_base which implements the methods pack_this/unpack_this() via the predefined pack()/unpack() methods. Each register class like TOY_TIME0 used in the testbench is extended from the reg_base. It only need declare the data by prepending the packed keyword and will inherit the pack_this()/unpack_this() from the parents class. When pack_this()/unpack_this() is called in the methods of class TOY_TIME0, the corresponding methods of the parent class reg_base will execute the packing/unpacking operation the data marked with the keyword “packed” of the current class TOY_TIME0. In summary, because of the predefined data packing/unpacking methods, the base class reg_base can provide the universal pack_this()/unpack_this() methods for all its subclasses in NTB-OV.
However, this kind predefined data packing/unpacking methods as well as the keyword “packed” for variables are no longer available in SV. So the universal data packing solution in base class is not available anymore. The feasible solution for this is that, as presented in the right hand of Figure 4, two new virtual methods called pack()/unpack() are declared as prototype in reg_base and called in pack_this()/unpack_this().Each register class like TOY_TIME0 needs redefine pack()/unpack() according to its own real data structure case by case.
This solution should be also feasible for the SV migration of all the NTB-OV codes which are based on the predefined data packing methods.
3.3.6 Coverage group migration rule
3.3.6.1 Sample event mapping
Generally sample_event expression in NTB-OV can be configured as a SV coverage event in most cases. The simple way to define the trigger of a coverage group is to sample at each positive edge of the clock. However, it will slow down the simulation performance relatively, especially on complex simulation environment. In most cases, an event is defined as sample event and triggered when the sampling condition is satisfied. Both ways can be mapped to SV as below:
|
NTB-OV code
|
SystemVerilog equivalent
|
|
coverage_group size_coverage {
cumulative = OFF;
sample_event = @(posedge ipg_clk);
sample size ;
}
|
covergroup size_coverage ( )@(posedge
ipg_clk) ;
option.per_instance = 0;
coverpoint size ;
}
|
|
coverage_group size_coverage {
cumulative = ON;
sample_event = wait_var(sample_observer);
sample size ;}
|
covergroup size_coverage
( )@(sample_observer) ;
option.per_instance = 1;
coverpoint size;
}
|
Table 8: Sample Event Mapping in Covergroup
3.3.6.2 inst_query(GOAL) mapping
inst_query(GOAL) can be mapped to SV coverage group predefined methods get_coverage() in some certain way as presented in Table 9.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
if (!r.access_c.inst_query(GOAL)) {
debug(psprintf(”Success, using
address %8h.”, address));
break;
}
}
}
|
if (r.access_c.get_coverage()<
r.access_c.option.goal)
begin
debug($psprintf(”Success, using
address %8h.”,address));
break;
end
|
Table 9: Inst_query() Mapping
3.3.6.3 set_bin_activation/inst_set_cov_shape mapping
In NTB-OV, the set_bin_activation and inst_set_bin_activation functions only reflect the hit count of the bins but are ignored for the coverage calculation, which can be mapped into the iff construct of covergroup in SV as presented in Table 10 below. The expression within the iff construct at the end of a bin definition provides a per-bin guard condition. If the guard expression evaluates to false at a sampling point, the coverage point is ignored, and the hit count for the bins is not incremented.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
coverage_group read_data {
……
sample cov_data {
state d0(8′h01);
state d1(8′h02);
state d2(8′h04);
state d3(8′h08);
}____
}
task set_coverage() {
read_data. set_bin_activation
(OFF,STATE,”d3|d2|d1″);
}
|
covergroup read_data( );
……
coverpoint cov_data {
bins d0 = {8′h01} iff(d0_activated);
bins d1 = {8′h02} iff(d1_activated);
bins d2 = {8′h04} iff(d2_activated);
bins d3 = {8′h08} iff(d3_activated);
}
endgroup : read_data
task set_coverage ();
d0_activated = 1; d1_activated = 0;
d2_activated = 0; d3_activated = 0;
endtask : set_coverage
|
Table 10: Set_bin_activation Mapping
The functional coverage depends on the shapes that are created for the coverage groups. Therefore to completely include/exclude a bin from coverage the function inst_set_cov_shape() need to be used, which can be mapped to ignore_bins in SV as presented in Table 11.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
coverage_group read_data {
……
sample cov_data {
state d0(8′h01);
state d1(8′h02);
state d2(8′h04);
wildcard state d3(8′b1xxx_xxxx);
}
}
task set_coverage() {
read_data.inst_set_cov_shape(OFF,STATE,
“d3|d2|d1″);
}
|
covergroup read_data( );
……
coverpoint cov_data {
bins d0 = {8′h01} ;
bins d1 = {8′h02} ;
bins d2 = {8′h04} ;
wildcard bins d3 = {8′b1xxx_xxxx} ;
ignore_bins
ib_d0={8′h01}iff(!d0_activated);
ignore_bins
ib_d1={8′h02}iff(!d1_activated);
ignore_bins
ib_d2={8′h04}iff(!d2_activated);
wildcard ignore_bins
ib_d3={8′b1xxx_xxxx}iff(!d3_activated);
}
endgroup : read_data
task set_coverage ();
d0_activated = 1; d1_activated = 0;
d2_activated = 0; d3_activated = 0;
endtask : set_coverage
|
Table 11: Inst_set_cov_shape Mapping
However, it is also worthy noticing that the code size required to get to the same functionality is worse on SV than on NTB-OV. Maybe this should be addressed by the future SV LRM updates.
3.3.7 Task and function argument passing method migration rule
In NTB-OV,”pass by value” is the method through which arguments are passed into functions and tasks. If the arguments are changed in the body of task or function, the changes do not affect the caller.
“pass by reference” only passes the handle of arguments into functions and tasks. The changes of the arguments in the body of task or function alter the caller. To pass an argument by reference, the declaration of the argument in the task or function prototype must be preceded by the keyword “var”. However, there are exceptions. It is always treated as “pass by reference” even without using “var” in prototype if an object handle is passed to a task or function.
During the conversion,” pass by reference” can be mapped to the “pass by reference” method in SV. “pass by value” also can be mapped to “pass by value. And the above exception also exists in SV.
|
NTB-OV code
|
SystemVerilog equivalent
|
|
class Transaction_Cl{
bit[15:0] da;
}
task Transaction::change_data(Transaction_Cl tc){
tc.da = 16′hffff;
}
|
class Transaction_Cl;
bit[15:0] da;
endclass
task Transaction::change_data(input
Transaction_Cl tc);
tc.da = 16′hffff;
endtask
|
Table 12: Pass by Reference Exception
The task change_data() is regarded as “pass by reference” in NTB-OV for parameter tc by the simulator on the left hand of Table 12. VCS also treats the parameter tc as “pass by reference” since tc is also an object handle in SV on the right hand. Therefore the value changes inside change_data() will alter the caller,even if it is declared as input without the keyword “ref”.
3.3.8 Randomization
As designs grow more complex, it becomes more difficult to create a complete set of testcases needed to check their functionality. The solution is to create test cases automatically using constrained-random tests. The ability to do constraint randomization is also one of the basic features that a high level verification language should provide. The randomization related NTB-OV code can be mapped into SV almost completely by VeriEZ tool and works fine so far.
4. Effot Spent
The overall efforts spent for the NTB-OV to SV conversion is shown in Figure below.
Figure 5: Effort Overview
The NTB-OV to SV conversion started in Q4 2008. The core team was 2 people working on the VIP testbenches conversions as the first stage. The work includes integrating VeriEZ conversion flow and VCSMX Unified User Mode compilation flow with SV support into Freescale Stingray environment, addressing all the issues found in the raw SV code generated by VeriEZ and created the corresponding code migration rules covered in Section 3.3, delivering the full functional SV VIPs. The first stage work lasted the whole Q4 2008, and the effort spent was 8 man month.
The second stage is the mass conversions for all the module testbenches and started in Q1 2009 till May 2009. 7 persons worked part time on conversion and 1 persons full time on supporting and coordinating. The total effort spent was 18.2 man month.
The third stage is the conversion of the SoC testbenches and has been started in Q1 2009 but has not been completed yet. The estimation effort is 4 man month.
So the overall effort can be summed up to be about 30.2 man month. Only 5.8% of the original effort 517 man months on developing NTB-OV code was required to cover the NTB-OV to SV conversion steps.
5. Testbench Improvement
The conversion of the testbench didn’t improve the compile and also the execution time of the VCS simulator too much. Figure 6 shows the achieved runtimes:

Figure 6: Runtime Comparison
The testbenches shown in the figure above represent part of the testbenches which are both available in NTB-OV and in SV. Usually in the relative simple module testbenches, the SV runtime is nearly as good as NTB-OV in VCS in most testbenches such as in Timers, mscan, gpio,iim_fuse, sometimes even better such as in psc_fifo. However, the simulation speed is much slower in SV than in NTB-OV in some testbenches such as clock_grp and nfc_mlc, which may be caused by the usage of inappropriate coding style in SV. This will be investigated and optimized case by case via the simulator profiling.
Besides the runtime, the compile time also is not improved. This seems to be not of big value in the first glance, but during the debug cycle of a testbench where frequent compilations are required; this is an improvement for the turnaround time.

Figure 7: Compile Time Comparisons
Figure 7 shows compile times for part of the testbenches which are both available in NTB-OV and in SV. Due to the methodology of compile once, run many (CORM), the compile time was the time needed to setup the compile, compile the testbench and to compile the design. The plain numbers showed an average compile time slowdown of 105%. The spectrum of variation was between maximum speed improvement of 58% and a slow down of 143%.
Consider SV is a relative new language for the users and the simulator vendors; there are possibilities for the users to optimize the SV code, and the vendors to improve the compile time and runtime of the simulators. An example is that the incremental compilation support will be released soon with VCS. So this is the acceptable outcome.
Finally, the usage of DVE allows now to have just one IDE debug environment for SV testbench code along with the Verilog design code just as in NTB-OV testbench.
6. Conclusions and Future Work
The migration to SV is becoming reality in many companies in the industrial. Migration is one thing but the quality of the verified chips must be ensured in any case. And migration development to a new language is an extremely slow process, often fraught with hidden dependencies. This can be achieved using our stepped approach, especially in NTB-OV to SV conversion stage. By adopting a commercial automation conversion tool based migration flow and training the team with the code migration rules summarized from the daily migration works, most of the conversion problems can be detected beforehand and solved quickly. The effort spent in the NTB-OV to SV conversion stage is only 5.8% of the original NTB-OV code implementation effort. This does leverage our current investment in NTB-OV.
Besides, splitting the translation into separate steps kept the verification and design team operational during the migration and chips could be released in parallel. At the same time the high quality standards required for automotive chips could be held as well. And the migration steps and also the modular testbench concept allowed distributing the translation and debugging work over a worldwide team. Overall the stepped migration approach did pay off and will be used for other projects as well.
7. Acknowledgements
The conversion work so far could only be achieved by a worldwide cooperation of team members. Thanks to our colleagues in Munich, Germany: Daniel Hoheisel, Marc Janssens and Wolfgang Mair. And also thanks to our colleagues in Suzhou, China: Jerry Kang, Alex Wan, Bruce Shen, Chris Fang, Laura Lin, Jet Chen, Benjamin Qian and Seaman Xie.
Also thanks to the always adequate support from Joan Shu, Xingliang Zhao and Suping Tang of Synopsys during the whole migration process. And thanks to the reviewer Chunlin Zhang from Synopsys.
8. Reference
[1] A migration from Vera to SystemVerilog in a stepped approach by Joachim Geishauser/Wolfgang Mair/Daniel Hoheisel 2008
[2] Native Testbench Coding Guide – VCS Y-2006.06-SP2, Synopsys, Inc. 2008
[3] IEEE Std 1800™-2005 , IEEE Computer Society,2005
[4] Solutions for OpenVera®-SystemVerilog® Portability and Migration – Application Note VeriEZ Solutions, Inc.