0% found this document useful (0 votes)
259 views7 pages

DVCon 08 abstractBFM Final

This document discusses two approaches for connecting object-oriented testbenches to RTL designs in SystemVerilog - using virtual interfaces or embedding BFMs directly in the design. It outlines some limitations of directly accessing signals from testbenches, such as lack of timing abstraction and reusability. The document then presents embedding BFMs in the design as an alternative that addresses these issues by separating testbench and design concerns.

Uploaded by

merugu prashanth
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
259 views7 pages

DVCon 08 abstractBFM Final

This document discusses two approaches for connecting object-oriented testbenches to RTL designs in SystemVerilog - using virtual interfaces or embedding BFMs directly in the design. It outlines some limitations of directly accessing signals from testbenches, such as lack of timing abstraction and reusability. The document then presents embedding BFMs in the design as an alternative that addresses these issues by separating testbench and design concerns.

Uploaded by

merugu prashanth
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Abstract BFMs Outshine Virtual Interfaces

for Advanced SystemVerilog Testbenches

David Rich Jonathan Bromley


Mentor Graphics, Inc Doulos Ltd
San Jose, CA Ringwood, England
[email protected] [email protected]

Abstract— Sophisticated functional verification environments using SystemVerilog typically


make use of the language's object-oriented programming features to build a flexible, re-
usable test environment and components that can easily be extended and reconfigured.
Ultimately, though, the test environment must interact with the signals, events, and clock
cycles of the device-under-test (DUT) and its supporting structures. Published tutorial and
methodology material on SystemVerilog has overwhelmingly recommended use of the virtual
interface construct to achieve this interaction. A virtual interface is a reference to a static
interface instance. The class-based test environment, constructed dynamically at the
beginning of a simulation run, can interact with a DUT through such virtual interfaces,
allowing it to be written without knowledge of the detailed static instance hierarchy of the
DUT and its surroundings. In such a test environment, manipulation of DUT signals is
performed by a bus functional model (BFM) object that makes reference to signals in the
DUT only through a virtual interface that will be bound to an interface instance at run time.

This paper reviews this style of using virtual interfaces, and then presents in detail an
alternative approach in which the BFM is not implemented in the class-based SystemVerilog
testbench. Instead, a suitable generic BFM abstract base class is created. Virtual methods in
this base class provide access to all the BFM functionality that will be required by a
testbench, but no implementation is provided. Instead, the concrete BFM is implemented as a
class derived from this generic BFM, but whose code is embedded in the SystemVerilog
module or interface that will be instanced alongside the DUT to connect to its signals. We
show that this approach brings a number of practical and methodological benefits,
minimizing the testbench code's dependence on details of the DUT's connections and
providing a more intuitive separation of concerns at the lowest level of the testbench while
fitting neatly into an object-oriented testbench design style.

Finally this paper will consider how this style of BFM and the more conventional style based
on virtual interfaces interact with other SystemVerilog constructs, such as clocking blocks, to
further isolate the testbench from the design.
Figure 1: Trivial RTL DUT stimulated by a SV object
I. THE TWO KINGDOMS OF THE VERIFICATION WORLD
module dummy_RTL_module(input R);
For the current authors, and for the majority of working ...
verification engineers in our industry, a design-under-test or endmodule
device-under-test (DUT) is most likely to be coded in
Verilog or VHDL using the register-transfer level (RTL) of package stimulus_pkg;
class Stimgen;
abstraction. At this level, information about the current state task run();
of the design is carried on signals (nets or variables, in repeat (10)
Verilog) and the design advances from its current state to a #5 testbench_Top.R = 1'b0;
future state thanks to signal updates executed in response to #5 testbench_Top.R = 1'b1;
signal value changes. The design's topology is determined end
endtask
once and for all at the start of simulation, in a process endclass
generally known as elaboration of the design. endpackage
By contrast, the test environment that is used to exercise module stimulus_module;
a DUT in simulation may be constructed in a variety of import stimulus_pkg::*;
styles. However, recent developments in languages and tools initial begin
for verification have encouraged the adoption of object- Stimgen stimgen;
oriented programming (OOP) techniques for building the test stimgen = new;
stimgen.run();
environment. An environment built using OOP has a end
topology that is determined not in a distinct elaboration step, endmodule
but instead by the action of procedural software that
constructs verification objects and assembles them into a module testbench_Top;
complete testbench. Although it is common (and often very reg R;
dummy_RTL_module DUT(R);
convenient) for this testbench topology to be constructed stimulus_module tester();
early in the simulation, and to be left unmodified endmodule
thenceforward, it is certainly possible in principle for the
testbench topology to be modified dynamically during the While this mechanism clearly works, and is
course of a simulation run. straightforward, it fails to address a number of important
In consequence, we find that typical verification practical concerns for verification environment developers.
environments naturally fall into two sections: on the one Some of the most pressing of these concerns are described
hand the statically-instantiated invariant topology of RTL below.
DUT code and perhaps some support structures for the DUT;
and on the other hand, the dynamically-constructed and A. Synchronous Signal Timing Abstraction
flexible structure of the OOP testbench. The coding styles, In a typical modern design, large groups of signals are
design approaches and dominant concerns of these two likely to be synchronous to a clock (although, of course,
sections are so different that we are tempted to think of them there may be many such clock domains in a big design).
as separate kingdoms in the verification world. But they are Within each clock domain, all synchronous signals should be
kingdoms that must of necessity share a border. It is the driven and/or sampled with some fixed timing relationship
frontier-posts of that border that concern us in this paper. relative to the clock. It is straightforward, but tedious, to
manage these timing relationships using procedural code in
II. THE CHALLENGE OF CONNECTING OBJECTS TO RTL the testbench. Such timing clutters the procedural code and
SystemVerilog [1] offers object-oriented programming confuses two levels of abstraction that most verification
within a language that also fully supports all existing engineers prefer to keep distinct: the event-driven, signal-
constructs of the Verilog Hardware Description level abstraction of the RTL code, and the cycle-based
Language(HDL) [2]. Consequently, verification code written abstraction of the testbench in which timing is expressed in
using SystemVerilog's object-oriented features can directly clock cycles rather than nanoseconds.
read and manipulate nets and variables in an RTL design
using Verilog's hierarchical name resolution mechanism. B. Encapsulation and Re-use of Verification Code
Figure 1 shows how this could be achieved, using a trivial Elements
example in which the RTL design contains only one In good object-oriented programming practice, classes
variable, and that variable is stimulated by code in the form self-contained, re-usable, extensible elements. The
run() method of a SystemVerilog class Stimulus. Note Stimulus class in Figure 1 clearly does not meet these
that the stimulus generator object (instance stimulus of criteria. It contains not merely a hard-coded signal name but
class Stimulus) is constructed dynamically by code in the even a hard-coded Verilog hierarchical path name.
testbench module stimulus_module. Consequently it would be useless in an even slightly
modified verification environment.
Stimulus and monitoring elements are very likely to be Figure 2: The example of Fig.1 modified to use a
written to interact with a standardized set of signals or virtual interface
interface protocol, and therefore have the potential for wide
module dummy_RTL_module(input R);
re-use across verification projects. Any element containing ...
hard-coded path or signal names is immediately disqualified endmodule
from such re-use.
interface dummy_intf();
reg R;
C. Clumsy Code endinterface
The need to specify signal names with full hierarchical
qualification on each occasion the signal is modified leads to package stimulus_pkg;
class Stimgen;
code that is difficult to read and difficult to maintain. It is
virtual dummy_intf V;
clear that some indirection is required between the testbench function new(virtual dummy_intf V);
class and the RTL with which it interacts. this.V = V;
endfunction
task run();
III. VIRTUAL INTERFACE repeat (10)
The indirection mentioned above requires the testbench #5 V.R = 1'b0;
#5 V.R = 1'b1;
class to have some kind of reference or pointer into the RTL end
environment. SystemVerilog provides a specific mechanism endtask
to achieve this, known as a virtual interface. endclass
endpackage
Before discussing virtual interfaces, we will first describe
briefly the interface construct of SystemVerilog. module stimulus_module;
import stimulus_pkg::*;
initial begin
A. Interface Stimgen stimgen;
An interface is a design unit in SystemVerilog, broadly stimgen = new(testbench_Top.di);
similar to a module, but having certain special features that stimgen.run();
end
make it especially well suited to the description of endmodule
interconnect structures. Interfaces are described in more
detail in references [3], [5] and [7]. Interfaces are like module testbench_Top;
modules in that they are statically instantiated, with their dummy_intf di();
instances becoming members of the elaborated hierarchy. dummy_RTL_module DUT(di.R);
stimulus_module tester();
Consequently, any interface instance has a Verilog endmodule
hierarchical path name.
module having a similar external interface. The testbench
B. Taking a Reference to an Interface
class Stimulus no longer needs any knowledge of the
A virtual interface is a SystemVerilog variable that can layout of the DUT and its surrounding infrastructure. Instead
hold a reference to an interface instance. A variable of virtual it merely knows that it is interacting with some instance of a
interface type can be given a value (i.e. can be made to dummy_intf, which is known to contain a well-understood
reference an existing interface instance) by assigning the collection of nets and variables representing the interconnect
hierarchical path name of the chosen interface instance to it. structure of interest. A reference to that instance will be
Once this has been done, members (nets and variables) of the passed into the object via its constructor argument - and,
referenced interface instance can be accessed using the "." indeed, could be updated later in the life of the simulation if
select operator, just as if the variable stood for the interface's required.
full hierarchical path name.
In other respects, though, a virtual interface variable is C. Virtual Interfaces in a Wider Context
like any other variable in that it can be passed as an argument For use in a realistic, generally applicable verification
to a subprogram, copied to another variable of appropriate methodology there remain some unsatisfactory features in
type, compared for equality with another variable and so Figure 2. Although the stimulus class is now usefully
forth. decoupled from the DUT and test environment, and therefore
Figure 2 modifies the code example of Figure 1 to use an can be re-used, it remains tightly coupled to the
interface to contain the signal that will be manipulated by the dummy_intf interface definition; these two pieces of code
testbench, with a virtual interface holding a reference to the therefore must remain locked together. It is also necessary to
appropriate interface instance. The organization of this code hook the DUT to the signals in this interface. In our example
is now much more satisfactory than that of Figure 1. The we have chosen to do it by hierarchical reference into the
interface declaration dummy_intf encapsulates all the interface instance, but other methods are possible (see for
connections needed to hook to the DUT module, or any example [7]).
Finally, we note that it is necessary to pass the Figure 3: UART transmitter BFM
appropriate instance name as an argument to the stimulus
module UART_Tx(output logic line);
class's constructor, but typically the constructor call is not
located in the same piece of code that instantiates the int NBits;
required interface. In the specific example of Figure 2 it is time BitPeriod;
the top-level testbench structure module testbench_Top
task setNBits(input int N);
that instantiates the interface, and therefore controls its if (N>0 && N<=10) NBits = N;
instance name; but it is the verification component, in endtask : setNBits
module stimulus_module, that constructs the stimulus
object and therefore needs to know the interface's instance task setBitPeriod(input time T);
name. This issue is part of the wider problem of verification if (T>0) BitPeriod = T;
endtask : setBitPeriod
component configuration, which will be discussed in more
detail later. task send(input logic [9:0] d);
line = 0; // start bit
None of these problems detract from the usefulness of repeat (NBits) begin
virtual interfaces in providing a flexible connection between #BitPeriod line = d[0];
the dynamic world of software-like verification components d = d >> 1;
and the statically-instantiated environment of the DUT and end
#BitPeriod line = 1; //stop
its support structures. However, it is clear that careful #BitPeriod;
attention to testbench organization is needed in order to endtask : send
maintain the reusability of class-based verification
components. endmodule : UART_Tx

IV. BUS FUNCTIONAL MODELS Published verification methodology guidelines such as [6],
[7], and [9] describe in detail how such environments can be
A. Review of traditional module-based BFMs deployed in practice.
In traditional HDL-based verification practice, a bus References [7] and [9] are somewhat dogmatic
functional model (BFM) is a component, typically packaged concerning the use of interfaces and virtual interfaces to
as a module, whose purpose is to mimic the activity found on connect class-based BFMs to the statically instantiated DUT
a collection of signals (such as a bus) without necessarily structures. Other methodologies are less specific in their
mimicking the detailed internal behavior of any specific recommendations, allowing the environment developers
device connected to those signals. Verilog HDL makes it some discretion in implementing this low-level but essential
very easy and convenient to create BFM modules. The part of testbench functionality. In the remaining sections we
signals that will be manipulated by the BFM appear as ports describe an alternative style of connection between BFM and
of the module, and operations that the BFM can perform are DUT using a well-known software engineering design
coded as tasks or functions in the module, which will be pattern that we believe offers significant practical benefits
called by procedural code in a test environment. Figure 3 for re-use and testbench organization.
shows a simple Verilog BFM that imitates the behavior of an
asynchronous serial transmitter. Its only port is the simulated
serial line output. Task calls into the module can configure V. ABSTRACT BFM
the BFM for serial data rate and other features; the necessary
configuration information is stored in variables in the A. Abstract base class to represent the API
module. Another task, send, can be called by the test code Our starting-point for an alternative style of BFM
to cause the BFM to perform appropriate activity on its connection is to note that the public interface (application
output port. programming interface or API) presented to a verification
environment by a re-usable BFM should take the form of a
B. BFMs in an OOP verification environment set of virtual methods. In this way, users of the BFM can
remain ignorant of its implementation details, and class
Module-based BFMS as described in IV.A are useful in
extension can easily be used to create alternative BFM
simple block-level testbenches, but the statically instantiated
implementations that nevertheless present identical APIs to
nature of Verilog modules makes them insufficiently flexible
the rest of the verification environment.
for re-use in large verification environments following a
modern OOP methodology. Instead we prefer to code our Such an API can usefully be encapsulated as an abstract
BFMs as classes. Configuration and stimulus-generation base class whose sole contents are the public methods, coded
tasks are readily modeled as public methods of the BFM as pure virtual methods. Once such an abstract base class has
class. Verification environments of arbitrary complexity and been defined, variables of that class type can be used to hold
flexibility can be constructed dynamically, using procedural references to an instance of any concrete BFM class that
code in a testbench environment class to construct and inherits from the abstract base class. Testbench code that
manage appropriate instances of the BFM and other classes. makes use of such a BFM can do so via variables of the
abstract base class type, conveniently decoupling the Figure 4: Abstract BFM class with concrete
remainder of the test environment from details of BFM implementation in an interface
implementation. In software engineering circles, this
package APB3_pkg_Fig4;
technique is effectively known as the template method virtual class APB3_BFM;
design pattern [13]. From the perspective of this paper, pure virtual task write (
however, the most important aspect of this decoupling is that int unsigned addr, data);
the connection of a BFM to its target HDL signals can also pure virtual task read (
be hidden by this same mechanism. int unsigned addr,
output int unsigned data);
endclass
B. Concrete Implementations Tightly Coupled to the DUT endpackage
interface APB3_TB_intf(input bit PCLK);
It is preferable to decouple an abstract BFM base class import APB3_pkg_Fig4::*;
from the DUT and its supporting structures as completely as logic PENABLE, PWRITE, PSEL, PREADY;
possible in the interests of reusability. However, there must logic [15:0] PADDR, PWDATA, PRDATA;
also be at least one class derived from this base class that class APB3_concrete_BFM extends APB3_BFM;
implements the BFM's concrete functionality. This task write(int unsigned addr, data);
@(posedge PCLK)
implementation class must manipulate the DUT signals PSEL <= 1'b1;
directly, and it is convenient for its code to exist in a scope PENABLE <= 1'b0;
where those signals are directly visible. This scope should be PWRITE <= 1'b1;
the module or interface that implements the set of signals PADDR <= addr;
that the BFM will manipulate. PWDATA <= data;
@(posedge PCLK)
Figure 4 presents an example of an abstract BFM class PENABLE <= 1'b1;
do @(posedge PCLK); while (!PREADY);
APB3_BFM forming the public API to a BFM that can PSEL <= 1'b0;
perform transactions on the well-known APB3 peripheral PENABLE <= 1'b0 ;
bus structure [10]. The base class is declared in a common endtask
package will be imported into a number of different scopes. task read ( int unsigned addr,
Note how the base class is specified to be abstract by means output int unsigned data);
@(posedge PCLK)
of the virtual qualifier in its declaration. The interface PSEL <= 1'b1;
APB3_TB_intf creates the standard set of APB3 bus PENABLE <= 1'b0;
signals, and also declares a derived BFM class PWRITE <= 1'b0;
APB3_concrete_BFM that implements the API declared PADDR <= addr;
@(posedge PCLK)
in the base class. Within the same interface, an instance of PENABLE <= 1'b1;
the concrete BFM class is created and initialized. A reference do @(posedge PCLK); while (!PREADY);
to this instance can then be passed to any part of the PSEL <= 1'b0;
testbench that has a variable of APB3_BFM type, and calls to PENABLE <= 1'b0 ;
data = PRDATA;
the concrete class's methods can be made through that endtask
variable. endclass
APB3_concrete_BFM bfm = new;
endinterface
VI. BENEFITS OF THIS STRUCTURE module APB3_TB_top;
The arrangement outlined in V. has a number of useful import APB3_pkg_Fig4::*;
benefits. Because the concrete BFM implementation class is bit CLK;
always #5 CLK = ~CLK; // clock generator
embedded in the same scope that declares the relevant bus APB3_TB_intf apb3_intf(CLK);
signals, it has direct access to those signals without any form APB3_device DUT(
of hierarchical reference. Furthermore, the BFM code is .PCLK(CLK),
naturally locked to the bus signal declarations, avoiding the .PENABLE(apb3_intf.PENABLE),
need to keep two independent design units together. The ...);
initial begin : Test_Activity
package APB3_pkg that defines our abstract BFM class can APB3_BFM bfm; // abstract BFM reference
readily be imported into any design unit that needs it, int read_data;
without concern for the implementation details of the bus or bfm = apb3_intf.bfm; // reference to BFM
its BFM. bfm.write(100, 1234);
bfm.read(100, read_data);
The bus signals are declared in an interface. This if (read_data != 1234)
interface can easily be extended to incorporate modports $display("error: unexpected read data");
end
[1][5], providing a convenient way to connect the interface to endmodule
SystemVerilog RTL designs that would normally be
connected to a physical bus interface.
VII. USING THIS STRUCTURE WITH VIRTUAL INTERFACES updating or sampling, using the clocking block construct. A
As shown in Figure 4, the abstract BFM mechanism clocking block insulates a class-based verification
makes virtual interfaces unnecessary for accessing the BFM. environment from the nanosecond-by-nanosecond minutiae
However, virtual interfaces may nevertheless be useful in of signal transition timing and allows the testbench to
providing an easy way for class-based verification operate in terms of clock cycles. It also relieves the testbench
components to locate the concrete BFM variable in the of the need to understand the differences between nets and
interface instance. variables at the interface to the DUT; all signals controlled
through a clocking block appear to the testbench as a special
kind of variable known as a clockvar. Tutorial review of the
VIII. CLOCKING BLOCKS FOR TIMING ABSTRACTION clocking block mechanism may be found in [4] and [8].
Within a SystemVerilog module or interface, any Figure 5 shows the code of Figure 4 reworked to use a
collection of signals (nets or variables) may be grouped clocking block in the APB3 bus interface. It is interesting to
according to the clock signal that normally controls their note that the concrete BFM class definition is embedded

Figure 5: Abstract BFM class and concrete implementation in an interface using clocking block

package APB3_pkg; interface APB3_TB_intf(input bit PCLK);


virtual class APB3_BFM; import APB3_pkg::*;
pure virtual task write ( logic PENABLE, PWRITE, PSEL, PREADY;
int unsigned addr, data); logic [15:0] PADDR, PWDATA, PRDATA;
pure virtual task read (
int unsigned addr, default clocking apb_ck @(posedge PCLK);
output int unsigned data); output PENABLE, PWRITE, PSEL, PADDR, PWDATA;
pure virtual task init (); input PREADY, PRDATA;
pure virtual task idle (int unsigned cycles); endclocking
endclass
endpackage class APB3_concrete_BFM extends APB3_BFM;
task init;
apb_ck.PSEL <= 1'b0;
apb_ck.PENABLE <= 1'b0;
apb_ck.PWRITE <= 1'b0;
endtask
task write(int unsigned addr, data);
##0
apb_ck.PSEL <= 1'b1;
apb_ck.PENABLE <= 1'b0;
apb_ck.PWRITE <= 1'b1;
apb_ck.PADDR <= addr;
apb_ck.PWDATA <= data;
##1
apb_ck.PENABLE <= 1'b1;
module APB3_TB_top; do ##1; while (!apb_ck.PREADY);
import APB3_pkg::*; apb_ck.PSEL <= 1'b0;
apb_ck.PENABLE <= 1'b0 ;
bit CLK; endtask
always #5 CLK = ~CLK; // clock generator task read( int unsigned addr,
output int unsigned data);
APB3_TB_intf apb3_intf(CLK); ##0
apb_ck.PSEL <= 1'b1;
APB3_device DUT( apb_ck.PENABLE <= 1'b0;
.PCLK(CLK), apb_ck.PWRITE <= 1'b0;
.PENABLE(apb3_intf.PENABLE), apb_ck.PADDR <= addr;
...); ##1
apb_ck.PENABLE <= 1'b1;
initial begin : Test_Activity do ##1; while (!apb_ck.PREADY);
APB3_BFM bfm; // abstract BFM reference apb_ck.PSEL <= 1'b0;
int read_data; apb_ck.PENABLE <= 1'b0 ;
bfm = apb3_intf.bfm; // reference to BFM data = apb_ck.PRDATA;
bfm.init; endtask
bfm.idle(5); task idle(int unsigned cycles);
bfm.write(100, 1234); ##(cycles);
bfm.read(100, read_data); endtask
if (read_data != 1234) endclass
$display("error: unexpected read data");
bfm.idle(100); $stop; APB3_concrete_BFM bfm = new;
end
endmodule endinterface
within the same interface that declares the clocking block, easily be given a TLM interface instead of the
and therefore can take advantage of the convenient ##n procedural API outlined in this paper.
notation for cycle delays that becomes available thanks to the
• Reuse of legacy Verilog BFM code is
default clocking specification in that interface. This
straightforward. It is only necessary to add a
makes it easy to add to the BFM a new method idle()that derived-class wrapper to the legacy BFM tasks,
simply idles the bus, with no activity, for a specified number which can remain packaged in a module as before.
of clock cycles. We have also taken advantage of the ##0
feature of clocking blocks to synchronize task execution with • This scheme has low impact on published testbench
the clock, without unnecessarily wasting a clock cycle, as architecture methodologies, and can be retrofitted
described in[11]. This form of cycle delay causes procedural into them without difficulty.
code to wait until the next clock cycle unless simulation has
already reached exactly the moment of a clock event, in REFERENCES
which case ##0 does not wait. This ##0 feature is scheduled [1] "IEEE Standard for SystemVerilog- Unified Hardware Design,
for inclusion in the 2008 revision of the SystemVerilog Specification, and Verification Language," IEEE Std 1800-2005,
standard, but has already been implemented in at least one 2005
commercially available simulator [12]. [2] "IEEE Std 1364 -2005 IEEE Standard for Verilog Hardware
Description Language," IEEE Std 1364-2005 (Revision of IEEE Std
1364-2001) , 2006
IX. CONCLUSIONS
[3] Sutherland, Stuart, S. Davidman, and P. Flake, SystemVerilog for
The style of interaction between testbench and DUT Designers. 2nd ed. Norwell MA: Springer Inc., 2006.
illustrated in this paper offers a number of attractive features: [4] Spear, Chris. SystemVerilog for Verification. Norwell, MA: Springer,
Inc, 2006.
• Its packaging is convenient and easy to manage. The [5] Bromley, Jonathan. "Towards a Practical Design Methodology with
concrete BFM and the interface or module that it SystemVerilog Interfaces and Modports," Conference on Using
connects to are in the same design unit. Hardware Design and Verification Languages, 22 Feb. 2007. San
Jose, CA, Accellera 2007
• The concrete BFM has easy access to all required [6] Fitzpatrick, T, D. Rich, and A. Rose. AdvancedVerification
signals, while the abstract BFM provides an Methodology. Ed. Mark Glasser. 3rd ed. Willsonville, OR: Mentor
appropriate level of abstraction for use by the Graphics, 2007.
testbench. [7] Bergeron, Janick, E. Cerny, A. Hunter, and A Nightingale.
Verification Methodology Manual for SystemVerilog. Norwell, MA:
• A clocking block (if used) can easily be located in Springer, Inc, 2005.
the right place, in the same module or interface as [8] Cummings, Cliff, and A. Salz. SystemVerilog Event Regions, Race
the signals it controls. This makes coding the Avoidance & Guidelines. Synopsys User Group, 21 Sept. 2006,
Synopsys. 5 Dec. 2007 http://www.sunburst-
concrete BFM more straightforward because it has a design.com/papers/CummingsSNUG2006Boston_SystemVerilog_Ev
default clocking in the correct scope, and it ents.pdf
ensures that timing concerns don't leak into OO [9] "URM Class-Based SystemVerilog Library Reference", Cadence
testbench. code Design Systems Inc, San Jose, CA, October 2007
[10] AMBA3 APB Protocol v1.0 Specification, ARM Limited,
• The abstract BFM base class is a good match with Cambridge, England, August 2004. ARM Document number
re-usable OO testbench component methodology, IHI0024B
and could even be applied to much more general [11] Bromley, J. "Synchronizing a BFM with its clock, without wasting a
BFMs applicable to many variants of a bus structure clock cycle". Available at
in which the same base class and API gave access to http://www.svug.org/TipsTricks/tabid/82/Default.aspx
widely different concrete BFMs. In this way, the [12] "Questa 6.3c" tool from Mentor Graphics Inc, Beaverton, OR
OOP testbench could be yet further decoupled from [13] E. Gamma, R.Helm, R. Johnson, J. Vlissides, Design Patterns,
details of the physical interface to the DUT. Elements of Reusable Object-Oriented Software. Addison-Wesley
Publishing Company, Reading Massachusetts, 1995.
• It is easy to fit into a transaction-level modeling
(TLM) testbench structure. The abstract BFM can

You might also like