scispace - formally typeset
Open AccessBookDOI

Transaction Level Modeling with SystemC

Reads0
Chats0
About
The article was published on 2005-01-01 and is currently open access. It has received 351 citations till now. The article focuses on the topics: SystemC & Transaction-level modeling.

read more

Content maybe subject to copyright    Report

Page 1 of 17
Transaction Level Modeling in SystemC
Adam Rose, Stuart Swan, John Pierce, Jean-Michel Fernandez
Cadence Design Systems, Inc
ABSTRACT
In the introduction, we describe the motivation for proposing a
Transaction Level Modeling standard, focusing on the main use
cases and the increase in productivity such a standard will bring.
In Section 2, we describe the core tlm proposal in detail. Section
3 shows refinement of a single master / single slave from a
programmers view model down through various levels of
abstraction to an rtl only implementation. Section 4 shows how to
code commonly occurring System Level design patterns such as
centralized routers, arbiters, pipelines, and decentralized decoding
schemes using the proposed tlm standard. In order to do this we
briefly describe and use some extensions to the core proposals.
Section 5 shows how to combine and recombine the generic
components in section 4 to explore different switch architectures.
In the first Appendix, we outline the uses of sc_export, which
relied on in many of the examples. In the second Appendix, we
briefly discuss some guidelines for using the TLM proposal in a
concurrent SystemC environment in an efficient and safe way.
The final appendix shows the TLM interface inheritance
hierarchy.
Code for all the examples contained in this paper is available in
the OSCI TLM kit available at www.systemc.org.
1. Introduction
Transaction Level Modeling ( TLM ) is motivated by a number of
practical problems. These include :
Providing an early platform for software development
System Level Design Exploration and Verification
The need to use System Level Models in Block Level
Verification.
A commonly accepted industry standard for TLM would help to
increase the productivity of software engineers, architects,
implementation and verification engineers. However, the
improvement in productivity promised by such a standard can
only be achieved if the standard meets a number of criteria :
It must be easy, efficient and safe to use in a concurrent
environment.
It must enable reuse between projects and between
abstraction levels within the same project.
It must easily model hardware, software and designs
which cross the hardware / software boundary.
It must enable the design of generic components such as
routers and arbiters.
Since the release of version 2.0, it has been possible to do TLM
using SystemC. However, the lack of established standards and
methodologies has meant that each TLM effort has had to invent
its own methodologies and APIs to do TLM. In addition to the
cost of reinventing the wheel, these methodologies all differed
slightly, making IP exchange difficult.
This paper will describe how the proposed OSCI TLM standard
meets the requirements above, and show how to use it to solve
various common modeling problems. We believe that widespread
adoption of this proposal will lead to the productivity
improvements promised by TLM.
2. The TLM Proposal
2.1 Key Concepts
There are three key concepts required to understand this proposal.
Interfaces
Blocking vs Non Blocking
Bidirectional vs Uni Directional
2.1.1 Interfaces
The emphasis on interfaces rather than implementation flows
from the fact that SystemC is a C++ class library, and that C++ (
when used properly ) is an object orientated language. First we
need to rigorously define the key interfaces, and then we can go
on to discuss the various ways these may be implemented in a
TLM design. It is crucial for the reader to understand that the
TLM interface classes form the heart of the TLM standard, and
that the implementations of those interfaces (e.g. tlm_fifo) are not
as central. In SystemC, all interfaces should inherit from the class
sc_interface.
2.1.2 Blocking and Non Blocking
In SystemC, there are two basic kinds of processes:
SC_THREAD and SC_METHOD. The key difference between
the two is that it is possible to suspend an SC_THREAD by
calling wait(.). SC_METHODs on the other hand can only be
synchronized by making them sensitive to an externally defined
sc_event. Calling wait(.) inside an SC_METHOD leads to a
runtime error. Using SC_THREAD is in many ways more natural,
but it is slower because wait(.) induces a context switch in the
SystemC scheduler. Using SC_METHOD is more constrained but
more efficient, because it avoids the context switching [2].
Because there will be a runtime error if we call wait from inside
an SC_METHOD, every method in every interface needs to
clearly tell the user whether it may contain a wait(.) and therefore
must be called from an SC_THREAD, or if it is guaranteed not to
contain a wait(.) and therefore can be called from an
SC_METHOD. OSCI uses the terms blocking for the former and
non blocking for the latter.
The OSCI TLM standard strictly adheres to the OSCI use of the
terms “blocking” and “non-blocking”. For example, if a TLM
interface is labeled “non-blocking”, then its methods can NEVER
call wait().

Page 2 of 17
OSCI Terminology Contains wait(.) Can be called from
Blocking Possibly SC_THREAD only
Non Blocking No SC_METHOD or
SC_THREAD
2.1.3 Bidirectional and Unidirectional Transfers
Some common transactions are clearly bidirectional, for example
a read across a bus. Other transactions are clearly unidirectional,
as is the case for most packet based communication mechanisms.
Where there is a more complicated protocol, it is always possible
to break it down into a sequence of bidirectional or unidirectional
transfers. For example, a complex bus with address, control and
data phases may look like a simple bidirectional read/write bus at
a high level of abstraction, but more like a sequence of pipelined
unidirectional transfers at a more detailed level. Any TLM
standard must have both bidirectional and unidirectional
interfaces. The standard should have a common look and feel for
bidirectional and unidirectional interfaces, and it should be clearly
shown how the two relate.
2.2 The Core TLM Interfaces
2.2.1 The Unidirectional Interfaces
The unidirectional interfaces are based on the sc_fifo interfaces as
standardized in the SystemC 2.1 release. Sc_fifo has been used
for many years in many types of system level model, since the
critical variable in many system level designs is the size of the
fifos. As a result, the fifo interfaces are well understood and we
know that they are reliable in the context of concurrent systems.
A further advantage of using interfaces based on sc_fifo is that
future simulators may be able to perform well known static
scheduling optimizations on models which use them. In addition
to this, the interface classes are split into blocking and non
blocking classes and non blocking access methods are
distinguished from blocking methods by the prefix “nb_”.
However, for TLM we have two new requirements
We need some value free terminology, since “read” and
“write” in the current sc_fifo interfaces are very loaded
terms in the context of TLM
These interfaces may be implemented in a fifo, some
other channel, or directly in the target using sc_export.
To address the first of these concerns, when we move a
transaction from initiator to target we call this a “put” and when
we move the transaction from target to initiator we call this a
“get”.
A consequence of the second requirement is that we need to add
tlm_tag<T> to some of the interfaces. This is a C++ trick which
allows us to implement more than one version of an interface in a
single target, provided the template parameters of the interfaces
are different.
2.2.2 The Unidirectional Blocking Interfaces
template < typename T >
class tlm_blocking_get_if :
public virtual sc_interface
{
public:
virtual T get( tlm_tag<T> *t = 0 ) = 0;
virtual void get( T &t ) { t = get(); }
};
template < typename T >
class tlm_blocking_put_if :
public virtual sc_interface
{
public:
virtual void put( const T &t ) = 0;
};
Since we are allowed to call wait in the blocking functions, they
never fail. For convenience, we supply two forms of get, although
since we provide a default implementation for the pass-by-
reference form , an implementer of the interface need only supply
one.
2.2.3 The Unidirectional Non Blocking Interfaces
template < typename T >
class tlm_nonblocking_get_if :
public virtual sc_interface
{
public:
virtual bool nb_get( T &t ) = 0;
virtual bool nb_can_get( tlm_tag<T> *t = 0 )
const = 0;
virtual const sc_event &ok_to_get( tlm_tag<T>
*t = 0 ) const = 0;
};
template < typename T >
class tlm_nonblocking_put_if :
public virtual sc_interface
{
public:
virtual bool nb_put( const T &t ) = 0;
virtual bool nb_can_put( tlm_tag<T> *t = 0 )
const = 0;
virtual const sc_event &ok_to_put( tlm_tag<T>
*t = 0 ) const = 0;
};
The non blocking interfaces may fail, since they are not allowed
to wait for the correct conditions for these calls to succeed. Hence
nb_put and nb_get must return a bool to indicate whether the
nonblocking access succeeded. We also supply nb_can_put and
nb_can_get to enquire whether a transfer will be successful
without actually moving any data.
These methods are sufficient to do polling puts and gets. We also
supply event functions which enable an SC_THREAD to wait
until it is likely that the access succeeds or a SC_METHOD to be
woken up because the event has been notified. These event

Page 3 of 17
functions enable an interrupt driven approach to using the non
blocking access functions. However, in the general case even if
the relevant event has been notified, we still need to check the
return value of the access function – for example, a number of
threads may have been notified that a fifo is no longer full but
only the first to wake up is guaranteed to have room before it is
full again.
2.2.4 Bidirectional Blocking Interface
template<REQ, RSP>
class tlm_transport_if : public sc_interface
{
public:
virtual RSP transport(const REQ&) = 0;
};
The bidirectional blocking interface is used to model transactions
where there is a tight one to one, non pipelined binding between
the request going in and the response coming out. This is
typically true when modeling from a software programmers point
of view, when for example a read can be described as an address
going in and the read data coming back.
The signature of the transport function can be seen as a merger
between the blocking get and put functions. This is by design,
since then we can produce implementations of tlm_transport_if
which simply call the put(.) and get(.) of two unidirectional
interfaces.
2.3 TLM Channels
One or more of the interfaces described above can be
implemented in any channel that a user cares to design, or directly
in the target using sc_export. However, two channels seem to be
useful in a large number of modeling contexts, so they are
included as part of the core proposal.
2.3.1 tlm_fifo<T>
The tlm_fifo<T> templated class implements all the
unidirectional interfaces described above. The implementation of
the fifo is based on the implementation of sc_fifo. In particular, it
addresses many ( but not all ) of the issues related to non
determinism by using the request_update / update mechanism.
Externally, the effect of this is that a transaction put into the
tlm_fifo is not available for getting until the next delta cycle. In
addition to the functionality provided by sc_fifo, tlm_fifo can be
zero
or infinite sized, and implements the fifo interface extensions
discussed in 4.3.1 below.
2.3.2 tlm_req_rsp_channel<REQ,RSP>
The tlm_req_rsp_channel<REQ,RSP> class consists of two fifos,
one for the request going from initiator to target and the other for
the response being moved from target to initiator. To provide
direct access to these fifos, it exports the put request and get
response interfaces to the initiator and the get request and put
response interfaces to the target.
As well as directly exporting these four fifo interfaces,
tlm_req_rsp_channel<REQ,RSP> implements three interfaces.
The first two combine the unidirectional requests and responses
into convenient master and slave interfaces :
template < typename REQ , typename RSP >
class tlm_master_if :
public virtual tlm_extended_put_if< REQ > ,
public virtual tlm_extended_get_if< RSP > {};
template < typename REQ , typename RSP >
class tlm_slave_if :
public virtual tlm_extended_put_if< RSP > ,
public virtual tlm_extended_get_if< REQ > {};
};
In addition to this, it implements tlm_transport_if<REQ,RSP> as
follows :
RSP transport( const REQ &req ) {
RSP rsp;
mutex.lock();
request_fifo.put( req );
response_fifo.get( rsp );
mutex.unlock();
return rsp;
}
This simple function provides a key link between the bidirectional
and sequential world as represented by the transport function and
the timed, unidirectional world as represented by tlm_fifo. We
will explain this in detail in the transactor ( 3.4 ) and arbiter ( 4.2 )
examples below.
2.4 Summary of the Core TLM Proposal
The ten methods split into five classes described in Section 2.2
form the basis of the OSCI TLM proposal. On the basis of this
simple transport mechanism, we can build models of software and
hardware, generic routers and arbiters, pipelined and non
pipelined buses, and packet based protocols. We can model at
various different levels of timing and data abstraction and we can
also provide channels to connect one abstraction level to another.
Because they are based on the interfaces to sc_fifo, they are easily
understood, safe and efficient.
Users can and should design their own channels implementing
some or all of these interfaces, or they can implement them
directly in the target using sc_export. The transport function in
particular will often be directly implemented in a target when
used to provide fast programmers view models for software
prototyping.
In addition to the core interfaces, we have defined two standard
channels, tlm_fifo<T> and tlm_req_rsp_channel<REQ,RSP>.

Page 4 of 17
These two channels can be used to model a wide variety of timed
systems, with the tlm_req_rsp_channel class providing an easy to
use bridge between the untimed and timed domains.
3. Modeling a simple peripheral bus at
various levels of abstraction
In this section, we will describe how to take an abstract single
master / single slave model down through various levels of
abstraction to an rtl only implementation. This ordering will be
familiar to readers who are from a software background and want
to understand how to incorporate real time hardware behaviour
into their TLM models. We also discuss how to build a modeling
architecture so that a meaningful interface can be presented to
application experts while the underlying protocols can be
accurately modeled. Hardware designers may find it easier to read
this section backwards, starting with the rtl and abstracting to
reach the programmers view model.
3.1 A Programmers View Architecture
In many organizations, there are two distinct groups of engineers.
In fact, one of the primary goals of TLM is to provide a
mechanism that allows these two groups of people to exchange
models. The first group understands the application domain very
well, but is not particularly expert in C++ nor interested in the
finer details of the TLM transport layer or the signal level
protocol used to communicate between modules. The second
group does not necessarily understand the application domain
well but does understand the underlying protocols and the C++
techniques needed to model them. Because of this divide in
expertise and interests, it is often useful ( but by no means
compulsory ) to define a protocol specific boundary between
these two groups of engineers.
Figure 1 : Modeling Architecture
This interface is sometimes called the convenience interface. It
will typically consist of methods that make sense to users of the
protocol in question : for example, read, write, burst read and
burst write. A user will use initiator ports that supply these
interfaces, and define target modules which inherit from the these
interfaces. The infrastructure team will implement the protocol
layer for the users. This consists of the request and response
classes that encapsulate the protocol, an initiator port that
translates from the convenience functions to calls to RSP
transport( const &REQ ) in the port, and a slave base class that
Master
initiator_port
sc_port
Slave
slave_base
sc_export
read()
write()
transport()
User
Layer
Protocol
Layer
Transport
Layer
tlm
interface
convenience
interface
tlm
interface
convenience
interface

Page 5 of 17
implements RSP transport( const REQ & ) in the slave. The
infrastructure team then publishes the initiator port and slave base
class to the users, who are then protected from the transport layer
completely. In effect, we have a three layer protocol stack.
In all the subsequent examples, we use this architecture when we
are modeling at the PV level. The consequence of this is that we
can reuse the master code shown below while we refine the slave
from an abstract implementation down to rtl.
void master::run()
{
DATA_TYPE d;
for( ADDRESS_TYPE a = 0; a < 20; a++ )
{
initiator_port.write( a , a + 50 );
}
for( ADDRESS_TYPE a = 0; a < 20; a++ )
{
initiator_port.read( a , d );
}
}
In order to achieve this level of reuse and usability at the user
level, the implementation team has to define an initiator port, and
slave base class and protocol that allows these two classes to
communicate.
3.1.1 The Protocol
At this abstract modeling level, the request and response classes
used to define the protocol have no signal level implementation,
they simply describe the information going in to the slave in the
request and the information coming out of the slave in the
response.
template< typename ADDRESS , typename DATA >
class basic_request
{
public:
basic_request_type type;
ADDRESS a;
DATA d;
};
template< typename DATA >
class basic_response
{
public:
basic_request_type type;
basic_status status;
DATA d;
};
3.1.2 The Initiator Port
On the master side, infrastructure team supplies an initiator port
which translates from the convenience layer to the transport layer.
basic_status read( const ADDRESS &a , DATA &d ) {
basic_request<ADDRESS,DATA> req;
basic_response<DATA> rsp;
req.type = READ;
req.a = a;
rsp = (*this)->transport( req );
d = rsp.d;
return rsp.status;
}
The write method is implemented in a similar fashion.
3.1.3 Slave Base Class
In the slave base class, we translate back from the transport layer
to the convenience layer.
basic_response<DATA>
transport( const basic_request<ADDRESS,DATA>
&request ) {
basic_response<DATA> response;
switch( request.type ) {
case READ :
response.status = read( request.a ,
response.d );
break;
case WRITE:
response.status = write( request.a ,
request.d );
break;
}
return response;
}
The read and write functions are pure virtual in the slave base
class, and are supplied by the user’s implementation which
inherits from the slave base class.
3.1.4 Only Request and Response Classes are
Compulsory
It is worth re-emphasizing that this modeling architecture is not
compulsory. In this case, the infrastructure team only supplies the
protocol itself and not the initiator port and slave base class. The
consequence of this is that each master and each slave may have
to do the translation to and from the underlying protocol
described in the preceding two sections. While the examples
below have been coded using a convenience layer, they could
have been implemented directly on top of the transport layer.

Citations
More filters
Journal ArticleDOI

High-Level Synthesis for FPGAs: From Prototyping to Deployment

TL;DR: AutoESL's AutoPilot HLS tool coupled with domain-specific system-level implementation platforms developed by Xilinx are used as an example to demonstrate the effectiveness of state-of-art C-to-FPGA synthesis solutions targeting multiple application domains.

Quo Vadis, SLD? Reasoning About the Trends and Challenges of System Level Design Recognizing common requirements for co-design of hardware and software in diverse systems may lead to productivity gains, lower costs and first-pass design success.

TL;DR: In this paper, the authors present the challenges faced by industry in system level design and propose a design methodology, platform-based design (PBD), that has the potential of addres- sing these challenges in a unified way.
Journal ArticleDOI

CADP 2011: a toolbox for the construction and analysis of distributed processes

TL;DR: The theoretical principles and the modular architecture of CADP are described, which has inspired several other recent model checkers, and the main features of the latest release, CADP 2011, are reviewed.
Journal ArticleDOI

Quo Vadis, SLD? Reasoning About the Trends and Challenges of System Level Design

TL;DR: A design methodology, platform-based design (PBD), is proposed that has the potential of addressing system level design challenges in a unified way and a tool environment is presented, Metropolis, that supports PBD and can be used to integrate available tools and methods.
Proceedings ArticleDOI

Overview of the MPSoC design challenge

TL;DR: The design challenges faced by MPSoC designers at all levels are reviewed, and the requirements for design tools that may ameliorate many of these issues are focused on.
References
More filters
Book ChapterDOI

A Tool for Checking ANSI-C Programs

TL;DR: The tool supports almost all ANSI-C language features, including pointer constructs, dynamic memory allocation, recursion, and the float and double data types, and is integrated into a graphical user interface.
Journal ArticleDOI

Proving the Correctness of Multiprocess Programs

TL;DR: The inductive assertion method is generalized to permit formal, machine-verifiable proofs of correctness for multiprocess programs, represented by ordinary flowcharts, and no special synchronization mechanisms are assumed.
Book

Surviving the SOC Revolution: A Guide to Platform-Based Design

TL;DR: This work focuses on the development of an Integration Platform for System-on-Chip Design (SOC) and the design of software design in SOCs.
Book ChapterDOI

The ESTEREL Synchronous Programming Language and its Mathematical Semantics

TL;DR: Closures are presently employed to prevent external contaminants such as dust and liquids from entering bearing housings at the region of clearance between the shaft and the housing through the use of mated, washer-like surfaces.
Proceedings ArticleDOI

An asynchronous NOC architecture providing low latency service and its multi-level design framework

TL;DR: The proposed NOC protocol and its asynchronous implementation are presented as well as the multi-level modeling approach using SystemC language and transaction-level-modeling, which shows that the asynchronous NOC can offer 5 Gbytes/s throughput in a 0.13 /spl mu/m CMOS technology.
Frequently Asked Questions (10)
Q1. What contributions have the authors mentioned in the paper "Transaction level modeling in systemc" ?

In the introduction, the authors describe the motivation for proposing a Transaction Level Modeling standard, focusing on the main use cases and the increase in productivity such a standard will bring. In Section 2, the authors describe the core tlm proposal in detail. In order to do this the authors briefly describe and use some extensions to the core proposals. In the second Appendix, the authors briefly discuss some guidelines for using the TLM proposal in a concurrent SystemC environment in an efficient and safe way. Code for all the examples contained in this paper is available in the OSCI TLM kit available at www. 

The bidirectional blocking interface is used to model transactions where there is a tight one to one, non pipelined binding between the request going in and the response coming out. 

A commonly accepted industry standard for TLM would help to increase the productivity of software engineers, architects, implementation and verification engineers. 

A further advantage of using interfaces based on sc_fifo is that future simulators may be able to perform well known static scheduling optimizations on models which use them. 

Can be called fromBlocking Possibly SC_THREAD onlyNon Blocking No SC_METHOD or SC_THREADSome common transactions are clearly bidirectional, for example a read across a bus. 

In addition to the functionality provided by sc_fifo, tlm_fifo can be zero or infinite sized, and implements the fifo interface extensions discussed in 4.3.1 below. 

On the basis of this simple transport mechanism, the authors can build models of software and hardware, generic routers and arbiters, pipelined and non pipelined buses, and packet based protocols. 

the improvement in productivity promised by such a standard can only be achieved if the standard meets a number of criteria :• 

The authors need some value free terminology, since “read” and “write” in the current sc_fifo interfaces are very loaded terms in the context of TLM• 

To provide direct access to these fifos, it exports the put request and get response interfaces to the initiator and the get request and put response interfaces to the target.