SystemC
M. Barış Uyar
What Is SystemC?
A subset of C++ that models/specifies synchronous digital
hardware
Processes (for concurrency)
Clocks (for time)
Hardware (finite) data types [bit vectors, 4-
4-valued logic, fixed
fixed--point types,
arbitrary precision integers] and infinite data types
Waiting and watching (for reactivity)
Modules, ports, signals (for hierarchy)
SystemC provides
Modelling in a higher level of abstraction
Faster simulation times
Testing the behaviour of the entire chip before production
Allows to make an “Executable Specification”
Synthesis support??!!
Where to use?
1. Modelling in a higher level of abstraction
2. Synthesis
Why not just C++
• Concurrency support is missing
(HW is inherently parallel)
No notion of time (clock, delays)
Communication model is very
different from actual HW model
(signals)
Weak/complex reactivity to events
Missing data types (logic values, bit
vectors, fixed point math)
SystemC
… C++ extensions!
New library (libsystemc.a)
providing additional
functionality
Building upon C++ features
(inheritance!) and data types to
better express HW behavior
“SystemC” HW-modeling
code is actually C++ code and
can be freely mixed with plain
C++
SystemC usage models
Standard Methodology for ICs
System-level designers write a C or C++ model
System-
Written in a stylized, hardware-
hardware-like form
Sometimes refined to be more hardware-
hardware-like
C/C++ model simulated to verify functionality
Model given to Verilog/VHDL coders
Verilog or VHDL specification written
Models simulated together to test equivalence
Verilog/VHDL model synthesized
Designing Big Digital Systems
Every system company was doing this differently
Every system company used its own simulation library
“Throw the model over the wall” approach makes it
easy to introduce errors
Problems:
System designers don’t know Verilog or VHDL
Verilog or VHDL coders don’t understand system
design
Idea of SystemC
C and C++ are being used as ad-ad-hoc modeling
languages
Why not formalize their use?
Why not interpret them as hardware
specification languages just as Verilog and
VHDL were?
Quick Overview
A SystemC program consists of module definitions plus a top- top-
level function that starts the simulation
Modules contain processes (C++ methods) and instances of
other modules
Ports on modules define their interface
Rich set of port data types (hardware modeling, etc.)
Signals in modules convey information between instances
Clocks are special signals that run periodically and can trigger
clocked processes
Rich set of numeric types (fixed and arbitrary precision numbers)
System
Module 1 Module 2
Process A ports
Process C
Process B
channels
Modules
Hierarchical entity
Similar to Verilog’s module
Actually a C++ class definition
Simulation involves
Creating objects of this class
They connect themselves together
Processes in these objects (methods) are called by the
scheduler to perform the simulation
Modules
map functionality of HW/SW blocks
derived from SystemC class sc_module
represent the basic building block of every system
modules can contain a whole hierarchy of sub-modules
and provide private variables/signals
Communication: Modules
can interface to each other via
ports/interfaces/channels
Functionality: achieved by
means of processes
Modules
Ports
Define the interface to each module
Channels through which data is communicated
Port consists of a direction
input sc_in
output sc_out
bidirectional sc_inout
and any C++ or SystemC type
Ports
Signals
Convey information between modules within a
module
Directionless: module ports define direction of
data transfer
Type may be any C++ or built-
built-in type
Signals
SC_MODULE(mymod) {
/* port definitions */
sc_signal<sc_uint<32> > s1, s2;
sc_signal<bool> reset;
/* … */
SC_CTOR(mymod) {
/* Instances of modules that connect to the signals */
}
};
Instances of Modules
Each instance is a pointer to an object in the module
SC_MODULE(mod1) { … }; Connect instance’s
ports to signals
SC_MODULE(mod2) { … };
SC_MODULE(foo) {
mod1* m1;
mod2* m2;
sc_signal<int> a, b, c;
SC_CTOR(foo) {
m1 = new mod1(“i1”); (*m1)(a, b, c);
m2 = new mod2(“i2”); (*m2)(c, b);
}
};
Signal instanciation and binding
Processes
They provide module functionality
Implemented as member functions
Three kinds of processes available:
SC_METHOD
SC_THREAD
SC_CTHREAD
All of the processes in the design run concurrently
Code inside of every process is sequential
METHOD Processes
Sensitive to any change on input ports
Usually used to model purely combinational logic (i.e. NORs, NANDs,
muxes, …)
Cannot be suspended. All of the function code is executed every time the
SC_METHOD is invoked
Does not remember internal state among invocations (unless explicitly kept
in member variables)
Method
Thread Processes
Adds the ability to be suspended to SC_METHOD processes
by means of wait() calls (and derivatives)
Still has a sensitivity list. wait() returns when a change is
detected on a port in the sensitivity list
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
Imposes a heavier load onto the SystemC scheduler (slower
simulations) due to context switches and state tracking
Thread
SystemC Types
SystemC programs may use any C++ type along
with any of the built-
built-in ones for modeling
systems
SystemC Built-
Built-in Types
sc_bit, sc_logic
Two
Two-- and four-
four-valued single bit
sc_int, sc_unint
1 to 64-
64-bit signed and unsigned integers
sc_bigint, sc_biguint
arbitrary (fixed) width signed and unsigned integers
sc_bv, sc_lv
arbitrary width two-
two- and four-
four-valued vectors
sc_fixed, sc_ufixed
signed and unsigned fixed point numbers
Fixed and Floating Point Types
Integers
Precise
Manipulation is fast and cheap
Poor for modeling continuous real-
real-world behavior
Floating--point numbers
Floating
Less precise
Better approximation to real numbers
Good for modeling continuous behavior
Manipulation is slow and expensive
Fixed--point numbers
Fixed
Worst of both worlds
Used in many signal processing applications
Integers, Floating-
Floating-point, Fixed-
Fixed-
point Decimal
point
(“binary”)
Integer
Fixed--point
Fixed
Floating--point
Floating ×2
Using Fixed-
Fixed-Point Numbers
High-level models usually use floating-
High- floating-point for convenience
Fixed--point usually used in hardware implementation because
Fixed
they’re much cheaper
Problem: the behavior of the two are different
How do you make sure your algorithm still works after it’s
been converted from floating-
floating-point to fixed-
fixed-point?
SystemC’s fixed-
fixed-point number classes facilitate simulating
algorithms with fixed-
fixed-point numbers
SystemC’s Fixed-
Fixed-Point Types
sc_fixed<8, 1, SC_RND, SC_SAT> fpn;
8 is the total number of bits in the type
1 is the number of bits to the left of the decimal point
SC_RND defines rounding behavior
SC_SAT defines saturation behavior
Rounding
What happens when your result doesn’t land
exactly on a representable number?
Rounding mode makes the choice
SC_RND
Round up at 0.5
What you expect?
SC_RND_ZERO
Round toward zero
Less error accumulation
SC_TRN
Truncate
Easiest to implement
Overflow
What happens if the result is too positive or too
negative to fit in the result?
Saturation? Wrap-
Wrap-around?
Different behavior appropriate for different
applications
SC_SAT
Saturate
Sometimes desired
SC_SAT_ZERO
Set to zero
Odd behavior
SC_WRAP
Wraparound
Easiest to implement
Layers of HW design
Scope of Layers
Purpose of layers
Low-level layers: Clock management (sc_clock), signal support
(sc_signal),01XZ values (sc_lv), flexible synchronization of
modules(SC_METHOD, SC_THREAD), VHDL-like
scheduling
High-level layers: Powerful object-oriented features (C++
roots), easy synchronization of modules (SC_THREAD,
SC_CTHREAD), reconfigurable sensitivity according to
circumstances (sc_event), high-level abstractions of HW
resources (FIFOs, mutexes,semaphores…)
SystemC Philosophy
Channel binding
RTL Model Example
An 8 bit counter. This counter can be loaded on a clk
rising edge by setting the input load to 1 and placing a
value on input din. The counter can be cleared by setting
input clear high.
A very basic 8 bit shifter. The shifter can be loaded on a
clk rising edge by placing a value on input din and setting
input load to 1. The shifter will shift the data left or right
depending on the value of input LR. If LR is low the shifter
will shift right by one bit, otherwise left by one bit.
Local temporary values are needed because the value of
output ports cannot be read.
Bus Cycle Accurate model
UnTimed Functional
Timed Functional
Synthesis Subset of SystemC
At least two
“Behavioral” Subset
Resource sharing, binding, and allocation done automatically
System determines how many adders you have
Register-transfer-
Register- transfer-level Subset
More like Verilog
You write a “+”, you get an adder
Do People Use SystemC?
Not as many as use Verilog or VHDL
Growing in popularity
People recognize advantage of being able to
share models
Most companies were doing something like it
already
Use someone else’s free libraries? Why not?
Conclusions
C++ dialect for modeling digital systems
Provides a simple form of concurrency
Cooperative multitasking
Modules
Instances of other modules
Processes
Conclusions
Perhaps even more flawed than Verilog
Verilog was a hardware modeling language
forced into specifying hardware
SystemC forces C++, a software specification
language, into modeling and specifying hardware
Will it work? Time will tell.
References
Course slides : Prof. Stephen A. Edwards
Course slides : Federico Angiolini