Title: Modules and Processes in SystemC
1Modules and Processes in SystemC
- A Presentation by
- Najmeh Fakhraie
- Mozhgan Nazarian-Naeini
- Hardware-Software Codesign
- Spring 2006
SystemC
2The Nightmares of Citation
SystemC
3References
- An Introduction to SystemC 1.0 Bernard
Niemann, Fraunhoffer Institute for Integrated
Circuits - SystemC Tutorial John Moondanos, Strategic CAD
labs, Intel Corp. GSRC Visiting Fellow, UC
Berkeley - SystemC 2.0.1 Language Reference Manual
- SystemC Tutorial Anonymous Author
- Compositional Approach to SystemC Design
Semantics of SystemC R.K Shyamasundar, IBM
Research Lab - Doulos SystemC Tutorial
- The NEW YORKER Cartoon Bank
SystemC
4Modules in SystemC
- A module is the basic structural building block
in SystemC. Modules may contain - Ports
- Data Members
- Channel
- Processes
- Member functions not registered as processes
- Instances of other modules
- A new type of module is created by deriving from
the container class sc_module - Publicly deriving from class sc_module.
- Or alternatively, a module can be created with
use of the SC_MODULE macro.
SystemC
5Modules in SystemC
- An example for the former would be
- And an example for the latter
class my_module public sc_module ....
SC_MODULE(my_module) ....
SystemC
6Module Constructor
- Every module can have a module constructor
- Accepts one argument which is the module name
- Will be thoroughly explained in the upcoming
sections
7Modules Instantiation
- Instantiation develops hierarchy through out the
design - Declaration
- SC_MODULE(ex2)
-
- . . .
- ex1 ex1_instance
-
- SC_CTOR(ex2) ex1_instance(ex1_anyname)
-
- //body
-
-
SystemC
8Modules Instantiation
- Pointer
- SC_MODULE(ex2)
-
- . . .
- ex1 ex1_instance
-
- SC_CTOR(ex2)
-
- ex1_instance new ex1(ex1_anyname)
- //body
-
-
SystemC
9Module Destructor
SC_MODULE(ex2) ex2() delete
ex1_instance
SystemC
10 Processes in SystemC
- An argument that begs the question
- Processes are small pieces of code that run
concurrently with other processes. - All high-level system level design (SLD) tools
use an underlying model of a network of
processes. - Functionality is described in processes.
Processes must be contained within a module. - They are registered as processes with the SystemC
kernel, using a process declaration in the module
constructor. - Processes accept no arguments and produce no
output -
SystemC
11XOR Using Four NAND Gates
SystemC
12Step One Modeling the NAND Gate
- A NAND Gate is a combination circuit. Its output
is purely a function of its input. - Use the simplest kind of SystemC process to model
it SC_METHOD. - SC_METHODs are simply C functions. Therefore,
the SystemC class library must make them behave
like processes, in particular - The SystemC class library contains a simulation
kernel a piece of code that models the passing
of time, and calls functions to calculate their
outputs whenever their inputs change. - The function must be declared an SC_METHOD and
made sensitive to its inputs.
SystemC
13NAND Gate
include "systemc.h" SC_MODULE(nand2)
//declare nand2 sc_module sc_inltboolgt A,
B //input signal ports sc_outltboolgt
F //output signal ports void
do_nand2() //a C function
F.write( !(A.read() B.read()) )
SC_CTOR(nand2) SC_METHOD(do_nand2)
//register do_nand2 with kernel
sensitive ltlt A ltlt B //sensitivity
list
SystemC
14What just happened?
- SC_MODULE
- Hierarchy in SystemC is created by using a class
sc_module. sc_module may be used directly, or may
be hidden using the macro SC_MODULE. The
example SC_MODULE above creates an sc_module
class object called nand2. - Ports
- SystemC numerous predefined ports such as
sc_inltgt, sc_outltgt, sc_inoutltgt. The language also
allows the definition of user defined ports
through the use of the sc_portltgt class.
sc_portltsc_signal_in_ifltboolgt, 1gt clk
SystemC
15The NAND Function
- do_nand2
- The function that does the work is declared. The
input and output ports include methods read( )
and write( ) to allow reading and writing to the
ports. A and B are read, the NAND function is
calculated and the result is written to F using
the write( ) method. - We could get away without writing the read( ) and
write( ) methods by using operators F !( A
B)
SystemC
16Constructor for sc_module Instance nand2
- SystemC provides a shorthand way of writing the
constructor using a macro SC_CTOR. This
constructor does the following - Create hierarchy (none in this case)
- Register functions as processes with the
simulation kernel - Declare sensitivity list for processes
- Accepts one argument only, which is the module
name - In this example, the constructor declares that
do_nand2 is an SC_METHOD, and says that any event
on ports A and B must make the kernel run the
function (calculate a new value for F).
SystemC
17XOR Gate
include "systemc.h" inclue "nand2.h" SC_MODULE(
xor2) sc_inltboolgt A, B sc_outltboolgt F
nand2 n1, n2, n3, n4 sc_signalltboolgt S1, S2,
S3 SC_CTOR(xor2) n1("N1"), n2("N2"),
n3("N3"), n4("N4") n1.A(A) n1.B(B)
n1.F(S1)
SystemC
18XOR Gate (continued)
n2 ltlt A ltlt S1 ltlt S2 n3(S1) n3(B)
n3(S3) n4.A(S2) n4.B(S3)
n4.F(F)
SystemC
19What just Happened II?
- Header Files
- Note the inclusion of nand2.h. This allows access
to the module containing the NAND gate. - Ports
- It is permitted to reuse the names A, B and F as
this a different level of the hierarchy. - Declaring Intermediate Wires
- They are declared using sc_signal. sc_signal is a
class with a template parameter specifying the
type of data the signal can hold bool in this
example. It is a primitive, built-in channel with
the SystemC library.
SystemC
20XOR Constructor
- Must have four instances of nand2. After the
port declarations, they are declared. And a label
must be declared for each instance. - The four labels, N1, N2, N3 and N4 are passed to
the constructors of the instances of nand2 by
using an initializer list on the constructor of
xor2. - Lastly, the ports are wired up. This can be done
using parentheses () or ltlt and gtgt. - Using ltlt and gtgt only allows the ports and
signals to be listed by position (n2). - Using () allows either by position (n3) or by
name (n1 and n4).
SystemC
21More on Modules
- They map functionality of HW/SW blocks
- The basic building block of every system
- Can contain a whole hierarchy of sub-modules and
provide private variable/signals. - Modules can interface to each other via
ports/interfaces/channels - Module functionality is achieved by means of
processes
SystemC
22Module Hierarchy
SystemC
23Ports, Interfaces, Channels
- Data transmitted and held via channels
- Interfaces provide the operations that the
channel provides - Ports standardize interaction of modules with
the external world - At elaboration time, ports are BOUNDED to
channels via interfaces
SystemC
24Interfaces
- An interface consists of a set of operations
(their prototype), not of their implementation
which is a burden on the channels. - There are two basic interfaces derived from
sc_interface class - sc_signal_in_ifltTgt
- provides a virtual functional read( ) returning
a reference to T - sc_signal_inout_ifltTgt
- provides a virtual functional write( ) taking a
reference to T - an out interface is identical to an inout
interface
SystemC
25Ports
- They provide communication functions to modules
- Derived from SystemC class sc_portltgt
- On the outside, they connect to channels by
means of interfaces - Typical channel (in RTL mode) sc_signal
- Specialized classes were derived sc_inltclass
Tgt, sc_outltclass Tgt, sc_inoutltclassTgt, which are
ports connected to N 1 interfaces of type
sc_signal_in_ifltclass Tgt - The interface sc_signal_in_ifltgt defines the
restricted set of available messages that can be
send to the port clk. For instance, the
functions read() or default_event() are defined
by this class.
SystemC
26Channels
- SystemCs communication medium
- This feature of SystemC differentiates it from
other HDLs such as Verilog - Provides abstraction at the interface level of
components and thus achieves greater design
modeling flexibilities - By definition, modules are interconnected via
channels and ports. - In turn, channels and ports communication via a
common interface - Implementation of interfaces functions
SystemC
27Channels
- Communication among modules and among processes
within a module - Any channel must
- be derived from sc_channel class
- be derived from one or more classes derived from
sc_interface - provide implementations for all pure virtual
functions defined in its parents interfaces
SystemC
28Fifo Example
SystemC
29FIFO Declaration of Interfaces
class write_if public sc_interface public
virtual void write(char) 0 virtual void
reset() 0 class read_if public
sc_interface public virtual void
read(char) 0 virtual int num_available()
0
SystemC
30FIFO Declaration of Channel
void write(char c) if (fifo_full())
wait(read_event) data ltyou calculategt c
num_elements write_event.notify() void
read(char c) if (fifo_empty())
wait(write_event) c datafirst
--num_elements first ...
read_event.notify()
class fifo public sc_channel, public
write_if, public read_if private int
max_elements10 char datamax_elements
int num_elements, first sc_event
write_event, read_event bool
fifo_empty() bool fifo_full()
public fifo() num_elements(0),
first(0)
SystemC
31FIFO Declaration of Channel
void reset() num_elements first
0 int num_available() return
num_elements // end of class
declarations
SystemC
32FIFO Producer Consumer
SC_MODULE(producer) public
sc_portltwrite_ifgt out SC_CTOR(producer)
SC_THREAD(main) void main()
char c while (true)
out.write(c) if() out.reset()
SC_MODULE(consumer) public
sc_portltread_ifgt in SC_CTOR(consumer)
SC_THREAD(main) void main()
char c while (true)
in.read(c) coutltlt in.num_available()
SystemC
33FIFO Completed
SC_MODULE(top) public fifo afifo
producer pproducer consumer pconsumer
SC_CTOR(top) pproducernew
producer(Producer) pproducer-gtout(afifo)
pconsumernew consumer(Consumer)
pconsumer-gtin(afifo)
SystemC
34More on Processes
- They provide module functionality
- Implemented as member functions of the module
and declared to be SystemC process in SC_CTOR - Three kinds of process available
- SC_METHOD
- SC_THREAD
- SC_CTHREAD
- These macros are needed because a member
function is not necessarily a process. The macros
operate specifics registrations with the
scheduler - All these processes in the design run
concurrently - Code inside of each process is sequential
SystemC
35SC_METHOD
- Sensitive to any changes on input ports (i.e.,
it is sensitive to a set of signals, on its
sensitivity list. It can be sensitive to any
change on a signal e.g., the positive or
negative edge of a Boolean signal). - Usually used to model purely combinational logic
(i.e., NORs, NANDs, MUX) - Cannot be suspended. All the function code is
executed every time the SC_METHOD is invoked
(whenever any of the inputs it is sensitive to
change). - Instructions are executed in order.
- Does not remember internal state among
invocations (unless explicitly kept in member
variables)
SystemC
36Defining the Sensitivity List of a Process
- sensitive with the ( ) operator
- Takes a single port or signal as argument
- sensitive(sig1) sensitive(sig2)
sensitive(sig3) - sensitive with the stream notation
- Takes an arbitrary number of arguments
- sensitive ltlt sig1 ltlt sig2 ltlt sig3
- sensitive_pos with either ( ) or ltlt operator
- Defines sensitivity to positive edge of Boolean
signal or clock - sensitive_pos ltlt clk
- sensitive_neg with either ( ) or ltlt operator
- Defines sensitivity to negative edge of Boolean
signal or clock - sensitive_neg ltlt clk
SystemC
37SC_THREAD
- Still has a sensitivity list and may be
sensitive to any change on a signal. - It is reactivated whenever any of the inputs it
is sensitive to changes. Once it is reactivated - Instructions are executed infinitely fast (in
terms of internal simulation time) until the next
occurrence of a wait( ) statement. - Instructions are executed in order.
- The next time the process is reactivated, the
execution will continue after the wait( )
statement. - wait( ) suspends execution of the process until
the process is invoked again
SystemC
38SC_THREAD
- Akin to a Verilog initial block
- Executes only once during simulation and then
suspends - Designers commonly use an infinite loop inside
an SC_THREAD to prevent it from ever exiting
before the end of the simulation - Adds the ability to be suspended to SC_METHOD
processes by means of wait() calls (and
derivatives) - Remembers its internal state among invocations
(i.e., execution resumes from where it was left) - Very useful for clocked systems, memory
elements, multi-cycle behavior
SystemC
39An Example of SC_THREAD
void do_count() while(true)
if(reset) value 0 else if (count)
value q.write(value)
wait()
SystemC
40Thread Processes wait( ) Function
- wait( ) may be used in both SC_THREAD and
SC_CTHREAD processes but not in SC_METHOD process
block - wait( ) suspends execution of the process until
the process is invoked again - wait(ltpos_intgt) may be used to wait for a
certain number of cycles (SC_CTHREAD only) - In Synchronous process (SC_CTHREAD)
- Statements before the wait( ) are executed in
one cycle - Statements after the wait( ) executed in the
next cycle - In Asynchronous process (SC_THREAD)
- Statements before the wait( ) are executed in
the last event - Statements after the wait( ) are executed in the
next event
SystemC
41Another Example
SC_MODULE(my_module) sc_inltboolgt id
sc_inltboolgt clock sc_inltsc_uintlt3gt gt in_a
sc_inltsc_uintlt3gt gt in_b sc_outltsc_uintlt3gt gt
out_c void my_thread() SC_CTOR(my_module)
SC_THREAD(my_thread) sensitive ltlt
clock.pos()
//my_module.cpp void my_module my_thread()
while(true) if (id.read())
out_c.write(in_a.read()) else
out_c.write(in_b.read()) wait()
SystemC
42SC_CTHREAD
- Will be deprecated in future releases
- Almost identical to SC_THREAD, but implements
clocked threads - Sensitive only to one edge of one and only one
clock - It is not triggered if inputs other than the
clock change - Models the behavior of unregistered inputs and
registered outputs - Useful for high level simulations, where the
clock is used as the only synchronization device - Adds wait_until( ) and watching( ) semantics for
easy deployment
SystemC
43SC_CTHREAD
- Once invoked
- The statements execute until a wait( ) statement
is encountered. - At the wait( ) statement, the process execution
is suspended - At the next execution, process execution starts
from the statement after the wait( ) statement - Local variables defined in the process function
are saved each time the process is suspended
SystemC
44Counter in SystemC
SystemC
45Counter in SystemC
SC_MODULE(countsub) sc_inltdoublegt in1
sc_inltdoublegt in2 sc_outltdoublegt sum
sc_outltdoublegt diff sc_inltboolgt clk void
addsub() //Constructor SC_CTOR(addsub)
//Declare addsub as SC_METHOD
SC_METHOD(addsub) dont_intialize()
//make it sensitive to positive clock
sensitive_pos ltlt clk
//Definition of addsub method void
countsubaddsub() double a double b a
in1.read() b in2.read()
sum.write(ab) diff.write(a-b)
SystemC
46The End
SystemC