Sunteți pe pagina 1din 16

Dr.

Zhonghai Lu
KTH Royal Institute of Technology

C++ Basics

SystemC
Introduction
and Get
Started

Modules
and
Processes

Concurrency
and Time

Channels
and
Interfaces

Transaction
Level
Modeling

KTH IL2452 System Design Languages

SystemC
Data Types
and
Debugging

SystemC
Summary

Aim

Understand communication concepts in SystemC


and know how to use it for design

Content

Primitive channels and interfaces


How to use primitive channels?
How to design my own channels?
Ports (used by modules to access channels)
Hierarchical channels
How to design and use my own hierarchical
channels?
KTH IL2452 System Design Languages

Concept

for communication
Channel categories
Primitive channels
Hierarchical channels

KTH IL2452 System Design Languages

In SystemC, channels model communication enabling


the ESL design concepts.
Separate communication from computation while
offering interface.
Refine communication while keeping the interfaces
untouched.
Fast simulation using function calls for communication.

An example
CPU

ASIC

Abstract Bus
MEM

KTH IL2452 System Design Languages

Arbiter

I/O

An interface is declared as a set of methods (pure virtual


functions), like APIs (Application Programming Interfaces) for
hardware and software.
An interface is an abstract base class of the channel.
A channel implements an interface.
A module calls interface methods via a port. Note that, within in
a module, accessing a channel can be done without using ports.
The port definition specifies the type of interface required by the
module in order to access the channel.
Interface

KTH IL2452 System Design Languages

Primitive

channels

Implement one or more interfaces


Derived from sc_prim_channel
Have access to the update phase of the scheduler

Examples

sc_signal<>, sc_signal_resolved<>
sc_buffer<>
sc_fifo<>
sc_mutex, sc_semaphore

To

understand the built-in primitive


channels, we need to know their associated
events and ports altogether.
7

KTH IL2452 System Design Languages

Primitive channel

Event

Port

sc_signal<T>
sc_buffer<T>

change in value
write()

sc_in, sc_out, sc_inout

sc_fifo<T>

write() or read()

sc_fifo_in, sc_fifo_out

sc_mutex
sc_semaphore

sc_signal vs. sc_buffer

sc_buffer is derived from sc_signal, and thus shares all the


same methods and specialized port types.
They differ in what constitutes an event. For sc_signal, an
event is a change in the value of the signal; With sc_buffer,
every call to the write() method causes an event, whether or
not the value of the sc_buffer changes.
sc_signal for modeling hardware wire or bus
(sc_signal_resolved), sc_buffer for modeling data flow where
each new input data will be sampled irrespective of if it is the
same or different from the previous sample.
KTH IL2452 System Design Languages

Primitive channel

Event

Port

sc_signal<T>
sc_buffer<T>

change in value
write()

sc_in, sc_out, sc_inout

sc_fifo<T>

write() or read()

sc_fifo_in, sc_fifo_out

sc_mutex
sc_semaphore

sc_fifo

is a first-in-first-out buffer, widely


used in untimed functional modeling.
sc_mutex vs. sc_semaphore
Used to synchronzize accesses to shared
resources.
Sc_mutex is for a single shared resource while
sc_semaphore is more general, used for multiple
shared resources.
Modeling operating systems and software.

KTH IL2452 System Design Languages

Template class

Interface methods

Bounded FIFO with a


default depth 16,
minimum depth 1
Infinite FIFO defined in
tlm::tlm_fifo
Nonblocking read and
write
Blocking read and
write

Specialized ports for


accessing SC_FIFO,
without using ->
operator

sc_fifo<T> fifo(fifo, 5)

bool fifo.nb_read(T&); //false if empty


bool fifo.nb_write(const T&); //false if full
void fifo.read(T&); //wait if empty
void fifo.write(const T&); //wait if full
sc_fifo_out<int> fifo_out; //for write
sc_fifo_in<int> fifo_in; //for read

sc_fifo_in<T> is equivalent to sc_port<sc_fifo_in_if<T>, 0> >


KTH IL2452 System Design Languages

10

SC_MODULE (Producer) {
sc_fifo_out<int> fifo_out;
.
fifo_out.write(data);
.
};

Top

SC_MODULE (Consumer) {
sc_fifo_in<int> fifo_in;
.
fifo_in.read(data);
Specialized port
.
};

. operator

sc_fifo
Producer

Consumer

SC_MODULE (Top) {
Producer p;
Consumer c;
sc_fifo<int> fifo;
SC_CTOR(Top): p(p), c(c), fifo(fifo,5){
p.fifo_out(fifo);
c.fifo_in(fifo);
.
};
KTH IL2452 System Design Languages

Step1:

11

Declare an abstract interface class

derived from sc_interface


Virtual inheritance to allow multiple inheritance
Pure virtual functions because it is mandatory for
users to supply the implementation

Example: Queue
class queue_write_if : virtual public sc_interface {
public: virtual void write (int c) = 0;};
class queue_read_if : virtual public sc_interface {
public: virtual int read () = 0;};
class queue_if : public queue_write_if, public queue_read_if { };
KTH IL2452 System Design Languages

12

Declare the queue class as


our own channel

#include queue_if.h

The interface class is


declared but does nothing.
It is the channels
responsibility to override
the pure virtual methods
and describe functionality.
Derived from sc_object.

Since the queue channel is


neither a hierarchical nor a
primitive channel, it is
recommended that such
channels are at least derived
from sc_object so that they
own attributes such as a
hierarchical name and a
position in the module
hierarchy.
sc_object is the base class for
all objects in the module
hierarchy.

class Queue : public queue_if, public sc_object {


public:
Queue(char *_nm, int _size): sc_object(_nm),
size(_size) {
data = new int[size];
w=r=n=0;
}

private:
int* data;
int size, w, r, n;
};

13

KTH IL2452 System Design Languages

Class sc_object is
the base class for
all objects in the
module hierarchy.

sc_module
+kind
get_child_objects

w: write pointer
r: read pointer
n: number of data
in the queue

void write(int c);


int read();

sc_object
+name
+kind
get_child_objects
get_parent_objects

sc_prim_channel
+kind

KTH IL2452 System Design Languages

sc_port_base

sc_process*

+kind

+kind
+get_child_objects

14

Define interface methods

With the same interface


declaration, definitions
may be different.

#include queue_if.h
void Queue :: write(int c) {
if (n < size) {
n++;
data[w++] = c;
if (w == size) w = 0;
}
};
int Queue::read(){
int c = 0;
if (n > 0) {
n--;
c = data[r++];
if (r == size) r = 0;
}
return c;
}
15

KTH IL2452 System Design Languages

We

write a module to
test the functionality
of the channel.

use port-less channel


access, i.e. access the
channel without
declaring ports.

Port-less channel access

KTH IL2452 System Design Languages

class Test : public sc_module {


public:
Queue queue;
SC_CTOR(Test): queue(queue, 10){
SC_THREAD(testing);
}
void testing(){
for(int i=0; i<10; i++)
queue.write(i);
for(int i=0; i<10; i++)
std::cout << queue.read();
}
};

16

Class sc_port, a class template with three parameters, is


the base class for all ports in SystemC.

Interface type
The max. number of channels to which the port may be bound
(0 means no limit, default is 1).
Port binding policy (optional) with respect to unbounded ports.
sc_port<my_interface, N, policy> if1, if2, ;

Port definitions can use the class sc_port directly or use a


port specialization, which is a class dervied from sc_port,
for example, sc_in, sc_fifo_in.

template <class T>


class sc_in : public sc_port<sc_signal_in_if<T>, 1> { };
template<class T>
class sc_fifo_in : public sc_port<sc_fifo_in_if<T>, 0> { };

17

KTH IL2452 System Design Languages

Channel: interface + implementation


Module uses ports to access the channel interface
Required interface: sif
Module

Offered interface: sif

Process

channel

sc_port<sif> port;
port->method();

Inherit sc_module if
hierarchical channel

struct channel: sif, sc_object {


void method() { }
};

struct sif: virtual sc_interface {


virtual void method() = 0;};

The port is declared with interface sif, so a process may call the method method()
through the port.
Note that the port is typed using the name of the interface, not the channel. Thus, any
channel that implements the interface sif may be bound to the port.
KTH IL2452 System Design Languages

18

Define interface-typed ports


Define a process to call an interface method
Through the typed port out, call the write() method offered by
a queue_write_if. Which channel (queue) to use is decided by
the Port-to-Channel binding.

queue_write_if queue_read_if

Top
Producer

Consumer
queue

SC_MODULE(Producer){
public:
sc_port<queue_write_if> out;
void write_chan();

void Producer :: write_chan(){


for(int i=0; i<10; i++)
out -> write(i);
}

SC_CTOR(Producer){
SC_THREAD(write_chan); }
};

Interface method call (IMC)


Overloaded operator ->
19

KTH IL2452 System Design Languages

The syntax for binding sc_port instances to channels is the


same as we would use for one of the standard signal ports,
like binding sc_in, sc_out ports to sc_signals.
queue_write_if queue_read_if

Top
Producer

Consumer
out

queue

SC_MODULE(Top){
Queue queue;
Producer producer;
Consumer consumer;
SC_CTROR(Top):queue(queue, 5){
producer.out(queue);
consumer.in(queue);
}

in
Channel instance
Module instance

Port to channel binding

};
KTH IL2452 System Design Languages

20

Besides

functional methods, one can add


debug facilities to an interface.

For example, add a dump() method that writes


out the content of the queue at a time instance.

class queue_debug_if : virtual public sc_interface {


public:
virtual void dump const() = 0;
};
class Queue : public queue_if, public queue_debug_if, public sc_object {
public:
void write(int c);
int read();
void dump() const;
};
KTH IL2452 System Design Languages

21

Different

from primitive channels,


hierarchical channels are modules which may
have ports and sub-modules.
Used to model complex communication, such
as network on chip.
The distinction between module and channel
becomes fuzzy because of hierarchial
channels, but any channel must have well
defined interfaces.

KTH IL2452 System Design Languages

22

Define the channel interface


Implement the channel
Port creation: Create ports (interface-typed) at
the user module

1.
2.
3.

eg. sc_port<queue_write_if> out;


The user module uses the interface method call
eg. out->write(i);

Port-to-Channel binding: Bind ports of the user


module to the channel instance

4.

Example: A stack channel

Define a write and a read interface, using


nonblocking method.
KTH IL2452 System Design Languages

23

Define

a write and a read interface, using


nonblocking method.
#ifndef STACK_IF_H
#define STACK_IF_H
#include <systemc>
class stack_write_if : virtual public sc_interface {
public:
virtual bool nb_write(char) = 0; //write a character
virtual void reset()=0;
//empty the stack
};
class stack_read_if : virtual public sc_interface {
public:
virtual bool nb_read(char&) = 0; //read a character
};
#endif
KTH IL2452 System Design Languages

24

The

stack channel implements the methods.

#ifndef STACK.H
#define STACK.H
#include <systemc>
#include stack.h
class stack : pubic sc_module, public stack_read_if, stack_write_if {
private:
char data[100];
int top; //top of the stack
public:
stack(sc_module_nm nm) : sc_module(nm), top(0){ }
bool nb_write(char c) {
if (top<100) { data[top++] = c; return true;}
return false; }
void reset(){ top = 0;}
bool nb_read(char& c){
if (top > 0) { c = data[--top]; return true;}
return false;}
};
#endif
KTH IL2452 System Design Languages

25

To use the stack, it must be instantiated. We use


again a producer and a consumer.

#ifndef PRODUCER.H
#define PRODUCER.H
#include <systemc>
#include stack_if.h
class producer : pubic sc_module {
public:
sc_port<stack_write_if> out; //declare a port that interfaces to the stack
sc_in<bool> clock;
void write_stack(){
int i=0; char* TestString=Hello world;
while true {
wait(); //wait for clock edge
if (out->nb_write(TestString[i]) //write to the stack via the port calling nb_write() method
cout << Write stack << TestString[i] << at << sc_time_stamp() <<endl;
i=(i+1)%32;}}
SC_CTOR(producer){
SC_THREAD(write_stack);
sensitive << clock.pos(); }
#endif
KTH IL2452 System Design Languages

26

#include systemc.h
#include producer.h
#include consumer.h
#include stack.h
int sc_main(int argc, char* argv[]){
sc_clock ClkFast(ClkFast, 100, SC_NS);
sc_clock ClkSlow(ClkSlow, 50, SC_NS);
stack Stack1(Stack 1);
producer P1(Producer 1);
P1.out(Stack1);
P1.clock(ClkFast);
consumer C1(Consumer 1);
C1.in(Stack1);
C1.clock(ClkSlow);
sc_start(5000, SC_NS);
return 0;
}

KTH IL2452 System Design Languages

Processes

27

communicate with channels

Channels inside the module: directly calling the


channel methods (port-less access)
Channels outside the module: indirectly calling
via port(s) of the module

Create Interface-typed port


Use interface method call

KTH IL2452 System Design Languages

28

SystemC concepts in C++

Interfaces

Channels

Class implementation of interfaces

Ports

Abstract class

Template class sc_port<IF>


Specialized ports: sc_in<>, sc_out<>, sc_fifo_in<>, sc_fifo_out<>

Channels

Primitive channels: sc_signal, sc_fifo, sc_buffer.


Hierarchical channels are essentially modules but with interfaces
We can follow well-defined steps to build own channels with
appropriate interfaces.

Homework:
Try the example of creating own channel Queue.
KTH IL2452 System Design Languages

29

TLM

whitepaper Transaction Level Modeling


in SystemC by Rose, Swan et al.
Download TLM-1.0 package for TLM
examples.

KTH IL2452 System Design Languages

30

www.systemc.org,

www.accelera.org

www.doulos.com
SystemC:

From the Ground Up by D. C. Black,


J. Donovan, B. Bunton, and A. Keist.
System Design with SystemC by T. Grtker, S.
Liao, G. Martin, and S. Swan
Others

KTH IL2452 System Design Languages

31

S-ar putea să vă placă și