0% found this document useful (0 votes)
152 views

Introduction To Systemc: - Systemc Language Reference Manual

SystemC is a C++ library and language extension that allows modeling and simulation of hardware at different levels of abstraction. It builds on C++ to provide constructs for modeling concurrent hardware such as modules, ports, signals, and processes. Modules contain ports, signals, and processes. Processes include method processes for combinational logic, thread processes for sequential logic, and cthread processes for clocked logic. Ports define module interfaces while signals allow communication between modules.

Uploaded by

KONDA ROHITH
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)
152 views

Introduction To Systemc: - Systemc Language Reference Manual

SystemC is a C++ library and language extension that allows modeling and simulation of hardware at different levels of abstraction. It builds on C++ to provide constructs for modeling concurrent hardware such as modules, ports, signals, and processes. Modules contain ports, signals, and processes. Processes include method processes for combinational logic, thread processes for sequential logic, and cthread processes for clocked logic. Ports define module interfaces while signals allow communication between modules.

Uploaded by

KONDA ROHITH
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/ 59

Introduction to

SystemC
Reference:
• SystemC: From the Ground Up 2nd edition by David C.
Black
• SystemC Language Reference Manual
Standard Methodology for ICs
• System-level designers write a C or C++ model
• Written in a stylized, hardware-like form
• Sometimes refined to be more 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
Idea of SystemC
• C and C++ are being used as ad-hoc modeling
languages
• Why not formalize their use?
• Why not interpret them as hardware specification
languages just as Verilog and VHDL were?
• SystemC developed at Synopsys to do just this
What Is SystemC?
• A subset of C++ that models/specifies
synchronous digital hardware

• A collection of simulation libraries that can be


used to run a SystemC program

• A compiler that translates the “synthesis subset”


of SystemC into a netlist
Why we need SystemC
• SystemC is a system design and modeling language.
• Evolved to meet a system designer’s requirements for designing and integrating
today’s complex electronic systems very quickly while assuring that the final system
will meet performance expectations.
• Thorough functional (and architectural) verification is required to avoid expensive
and sometimes catastrophic failures in the device.
• Concurrent and multidisciplinary approach to the design of complex systems is
electronic system-level design or ESL.
• ESL happens by modeling systems at higher levels of abstraction
• Portions of the system model are subsequently iterated and refined, as needed.
• A set of techniques has evolved called Transaction-Level Modeling or TLM to
aide with this task.
• ESL and TLM impose a set of requirements on a language that is different than
the requirements for hardware description languages (HDLs) or the
requirements for traditional software languages like C, C++, or Java
• The increasingly shortened time to market requirements
• Verify the design in early time
• The growing complexity
• Integration of developed devices
SystemC
• Strictly speaking, SystemC is not a language. SystemC is a
class library within a well established language, C++.
• SystemC is not a panacea that will solve every design
productivity issue.
• In addition, SystemC provides a common language for
software and hardware, C++.
Needed tools

• SystemC latest library package v2.3.1

• Linux platform

• GCC compiler

• GTKWave – Waveform tool

• some text editor


Quick Overview
• A SystemC program consists of module definitions plus a 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)


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
SystemC program structure:
SC_MODULE(<module name>)
{..........
............//this part is described next
...........
};
• Every module should have a constructor 'SC_CTOR' with the same name as that of
the module. The above module with the constructor looks like :

SC_MODULE(<module name>)
{..........
   ............//these steps are described next
   SC_CTOR(<module name>)
   {...........
   ............//these steps are described next
   }
};
SC_MODULE(<module name>)
{
sc_in<datatype> port1; Note that the constructor itself
calls the process which means that
sc_out<datatype> port2; • all the processes are executed
when ever an object of the
module is instantiated or
• the value of any of the signal or
SC_CTOR(<module name>) port in the sensitivity list
{ changes.

SC_METHOD(<process name>);
sensitive << <sensitivity list>;

};
Modules
SC_MODULE(mymod) {
/* port definitions */
/* signal definitions */
/* clock definitions */
/* storage and state variables */
/* process definitions */
SC_CTOR(mymod) {
/* Instances of processes and 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
SC_MODULE(mymod) {
sc_in<bool> load, read;
sc_inout<int> data;
sc_out<bool> full;

/* rest of the module */


};
Signals
• Convey information between modules within a
module
• Directionless: module ports define direction of
data transfer
• Type may be any C++ or 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 */
}
};
Processes
• Only thing in SystemC that actually does
anything

• Procedural code with the ability to suspend and


resume

• Like Verilog’s initial blocks


Three Types of Processes
• Method processes (SC_METHOD) – similar to Verilog

always block

• Thread processes (SC_THREAD) – similar to Verilog

initial block

• CThread processes (SC_CTHREAD) – similar to

SC_THREAD but sensitive to a particular clock edge


METHOD Processes
• Triggered in response to changes on inputs

• Cannot store control state between invocations

• Designed to model blocks of combinational


logic
METHOD Processes
Process is simply a
method of this class
SC_MODULE(onemethod) {
sc_in<bool> in;
sc_out<bool> out;
void inverter();
SC_CTOR(onemethod) { Instance of this process
created
SC_METHOD(inverter);
sensitive <<in; and made sensitive to an
input
}
};
METHOD Processes
• Invoked once every time input “in” changes
• Should not save state between invocations
• Runs to completion: should not contain infinite
loops

void inverter() {
bool internal; Read a value from the port
internal = in;
out = ~internal; Write a value to an output
port
}
THREAD Processes
• Triggered in response to changes on inputs

• Can suspend itself and be reactivated


• Method calls wait to relinquish control
• Scheduler runs it again later

• Designed to model just about anything


THREAD Processes
Process is simply a
method of this class
SC_MODULE(onemethod) {
sc_in<bool> in;
sc_out<bool> out;
void toggler();
SC_CTOR(onemethod) { Instance of this process
created
SC_THREAD(toggler);
sensitive << in; alternate sensitivity list
} notation

};
THREAD Processes
• Reawakened whenever an input changes
• State saved between invocations
• Infinite loops should contain a wait()
Relinquish control until
void toggler() { the next change of a
bool last = false; signal on the
for (;;) { sensitivity list for this
last = in; out = last; wait(); process
last = ~in; out = last; wait();
}
}
CTHREAD Processes
• Triggered in response to a single clock edge

• Can suspend itself and be reactivated


• Method calls wait to relinquish control
• Scheduler runs it again later

• Designed to model clocked digital hardware


CTHREAD Processes
Instance of this process
SC_MODULE(onemethod) { created and relevant
sc_in_clk clock; clock edge assigned
sc_in<bool> trigger, in;
sc_out<bool> out;
void toggler();
SC_CTOR(onemethod) {
SC_CTHREAD(toggler, clock.pos());
}
};
CTHREAD Processes
• Reawakened at the edge of the clock
• State saved between invocations Relinquish control until
• Infinite loops should contain a wait()
the next clock cycle in
which the trigger input
void toggler() { is 1
bool last = false;
for (;;) {
wait_until(trigger.delayed() == true);
last = in; out = last; wait();
last = ~in; out = last; wait(); Relinquish control until
} the next clock cycle
}
Ports and Signals
• Types of ports and signals:

• All natives C/C++ types


• All SystemC types
• User defined types

• How to declare

• IN : sc_in<port_type>
• OUT : sc_out<port_type>
• Bi-Directional : sc_inout<port_type>
Ports and Signals
• How to read and write a port ?

• Methods read( ); and write( );

• Examples:

• in_tmp = in.read( ); //reads the port in to in_tmp

• out.write(out_temp); //writes out_temp in the out port


Ports and Signals
• Ports of a module are the external interfaces
that pass information to and from a module

• In SystemC one port can be IN, OUT or INOUT

• Signals are used to connect module ports


allowing modules to communicate

• Very similar to ports and signals in VHDL


//andgate.h //driver.h
#include "systemc.h" #include "systemc.h"
SC_MODULE(andgate) SC_MODULE(driver)
{
{ sc_out<bool> a1,b1,c1;
sc_in<bool> a1;
void inputs(){
sc_in<bool> b1;
a1.write(false);
sc_in<bool> c1;
sc_out<bool> d1;
b1.write(false);
void compute_and() c1.write(false); wait(5,SC_NS);
{ a1.write(true);
d1.write(a1.read() && b1.read) && (c1. b1.write(true);
read());
c1.write(true); wait(5,SC_NS); }
}
SC_CTOR(driver){
SC_CTOR(andgate)
SC_THREAD(inputs);
{
SC_METHOD(compute_and); sensitive <<a1 <<b1 <<c1;
sensitive <<a1 <<b1 <<c1; }
}}; };
//monitor.h //main program – main.
#include "systemc.h" #include "systemc.h"
SC_MODULE(monitor){ #include "andgate.h"
sc_in<bool> a1,b1,c1,d1; #include "driver.h"
void mon(){ #include "monitor.h"
cout << "Inputs: "<<a1 <<b1 <<c1 << " Output: " int sc_main( int argc, char* argv[] ){
<<d1 <<endl; }
sc_signal <bool> a1,b1,c1,d1;
SC_CTOR(monitor)
{ andgate agate("andgate");
SC_METHOD(mon);
driver drive("driver");
sensitive <<a1 <<b1 <<c1;
monitor mon("monitor");
}};
//Waveform agate.a1(a1); agate.b1(b1);
sc_trace_file *Tf; agate.c1(c1); agate.d1(d1);
Tf = sc_create_vcd_trace_file("traces");
sc_trace(Tf, a1, "a1"); sc_trace(Tf, b1, "b1"); drive.a1(a1); drive.b1(b1);
sc_trace(Tf, c1, "c1"); sc_trace(Tf, d1, "d1"); drive.c1(c1); mon.a1(a1);
sc_start(30,SC_NS);
sc_close_vcd_trace_file(Tf); mon.b1(b1); mon.c1(c1);
return 0; } mon.d1(d1);
Compile and Run using
Cadence
csh

source /cad/cshrc

irun –sysc main.cpp –lrt –sctop

sc_main +gui
Clocks
• Special object
• How to create ?
sc_clock clock_name (
“clock_label”, period, duty_ratio, offset, initial_value );

• Clock connection
f1.clk( clk_signal ); //where f1 is a module

Clock example:
Data Types
• SystemC supports:
• C/C++ native types
• SystemC types

• SystemC types
• Types for systems modelling
• 2 values (‘0’,’1’)
• 4 values (‘0’,’1’,’Z’,’X’)
• Arbitrary size integer (Signed/Unsigned)
• Fixed point types
Native C++ Data Types
SystemC types
Type Description

sc_logic Simple bit with 4 values(0/1/X/Z)


sc_int Signed Integer from 1-64 bits
sc_uint Unsigned Integer from 1-64 bits
sc_bigint Arbitrary size signed integer
sc_biguint Arbitrary size unsigned integer
sc_bv Arbitrary size 2-values vector
sc_lv Arbitrary size 4-values vector
sc_fixed templated signed fixed point
sc_ufixed templated unsigned fixed point
sc_fix untemplated signed fixed point
sc_ufix untemplated unsigned fixed point
SC_LOGIC type
• More general than bool, 4 values :
• (‘0’ (false), ‘1’ (true), ‘X’ (undefined) , ‘Z’(high-impedance) )

• Declaration
• sc_logic my_logic;

• Assignment like bool


• my_logic = ‘0’;
• my_logic = ‘Z’;

• Simulation time bigger than bool


Fixed precision integers
• Used when arithmetic operations need fixed size arithmetic
operands

• INT can be converted in UINT and vice-versa

• “int” in C++
• The size depends on the machine
• Faster in the simulation

• 1-64 bits integer in SystemC


• sc_int<n> -- signed integer with n-bits
• sc_uint<n> -- unsigned integer with n-bits
Arbitrary precision integers

• Integer bigger than 64 bits


• sc_bigint<n>
• sc_biguint<n>

• More precision, slow simulation

• Can be used together with:


• Integer C++
• sc_int, sc_uint
Other SystemC types
• Bit vector
• sc_bv<n>
• 2-value vector (0/1)
• Not used in arithmetics operations
• Faster simulation than sc_lv

• Logic Vector
• sc_lv<n>
• Vector to the sc_logic type

• Assignment operator (“=“)


• my_vector = “XZ01”
String Input and Output

• SystemC data types may be converted to a standard C++ string using the
data type’s to_string method
Operators for SystemC Data Types
Example
• sc_bv<5> positions = "01101";
• sc_bv<6> mask = "100111";
• sc_bv<5> active = positions & mask;// 00101
• sc_bv<1> all = active.and_reduce(); //
SC_LOGIC_0
• positions.range(3,2) = "00";// 00001
• positions[2] = active[0] ^ flag;
Exercises
1. Write a program to read data from a file using the unified string
representation and store in an array of sc_uint<W>. Output the
values as SC_DEC and SC_HEX_SM.

2. Write a program to generate 10 random values and compute the


squares of these values. Do the math using each of the following
data types: short, int, unsigned, long, sc_int<8>, sc_uint<19>,
sc_bigint<8>, sc_bigint<100>. Be certain to generate numbers
distributed over the entire range of possibilities.

3. Write a module from scratch using what you know. The output
should count down from 3 to 1 and display the corresponding
words “Ready”, “Set”, “Go” with each count. Compile and run.
A Notion of Time
• Wall-clock time, processor time, and simulated time
• The simulation’s wall-clock time is the time from the
start of execution to completion, including time
waiting on other system activities and applications
• The simulation’s processor time is the actual time
spent executing the simulation, which will always be
less than the simulation’s wall-clock time
• The simulated time is the time being modeled by
the simulation
• sc_time - represented by a minimum of a 64-bit
unsigned integer
• used by the simulation kernel to track simulated
time and to specify delays and timeouts.
A Notion of Time
• SC_FS, SC_PS, SC_NS, SC_US, SC_MS,SC_SEC
• All objects of sc_time use a single (global) time
resolution that has a default of 1 picosecond
• sc_time_stamp ()
• cout << " The time is now “ << sc_time_stamp()
• The time is now 0 ns
• sc_start() - used to start simulation
• sc_start(60.0,SC_SEC); // Limit sim to one minute
• wait(sc_time) – delays in SC_THREAD processes
//fsm.h detect 101 overlapping sequence case 1:
#include "systemc.h" if (in.read()){
SC_MODULE(fsm){ next_state = 1;out=0;}
sc_in<bool> rst,in,clk; else{
sc_out<bool> out; next_state = 2;out=0;}
sc_uint<2> state,next_state; break;
void update_state(){ case 2:
if (rst.read() == true){ if (in.read()){
state = 0; next_state = 1;out=1;}
} else { else{
state = next_state; next_state = 0;out=0;}
}} break;
void ns_logic(){ default:
// Determine next state and output {
switch(state) { next_state = 0;out=0;}
case 0: break;
if (in.read()) { }
next_state = 1;out=0;} }
else {
next_state = 0; out=0;} break;
SC_CTOR(fsm){
SC_METHOD(update_state); rst.write(false);
sensitive << clk.pos()<<rst; in.write(true);
SC_METHOD(ns_logic); wait();
sensitive <<clk.pos()<<in<<rst; in.write(false);
wait();
}}; in.write(true);
wait();
#include "systemc.h" in.write(false);
SC_MODULE(driver) wait();
{ }
sc_out<bool>rst,in;
sc_in<bool>clk; SC_CTOR(driver)
void inputs() {
{ SC_THREAD(inputs);
rst.write(false); sensitive << clk.pos();
in.write(true); }
wait(); };
rst.write(true);
in.write(true);
wait();
#include "systemc.h"

SC_MODULE(monitor)
{
sc_in<bool> rst, in,out;
sc_in<bool> clk;

void mon()
{
while (true){
cout << sc_time_stamp();
cout << " rst "<<rst.read();
cout << " clk "<<clk.read();
cout << " in "<<in.read();
cout << " out "<<out.read() <<endl;
wait();
}}

SC_CTOR(monitor)
{
SC_THREAD(mon);
sensitive << clk.pos();
}};
#include "systemc.h" mon.rst(rst);
#include "driver.h" mon.in(in);
#include "monitor.h" mon.out(out);
#include "fsm.h" mon.clk(clk);

int sc_main(int argc, char* argv[]) //Waveform


{ sc_trace_file *Tf;
sc_signal <bool> rst,in,out; Tf = sc_create_vcd_trace_file("traces");
sc_clock clk("TestClock",10,SC_NS,0.5);
sc_trace(Tf, rst, "rst");
fsm f_sm("state_machine"); sc_trace(Tf, in, "in1");
driver drive("driver"); sc_trace(Tf, clk, "clk");
monitor mon("monitor"); sc_trace(Tf, out, "out");
sc_trace(Tf, f_sm.state, "state");
f_sm.rst(rst);
f_sm.in(in); sc_start(100,SC_NS);
f_sm.clk(clk);
f_sm.out(out); sc_close_vcd_trace_file(Tf);

drive.rst(rst); return 0;
drive.in(in); }
drive.clk(clk);
Basic Channels
• Primitive Channels
• sc_mutex, sc_semaphore, and sc_fifo<T>
• sc_mutex - Mutex is short for mutually exclusive text
• A program object that lets multiple program threads share a common
resource, such as file access, without colliding
• A mutex will be in one of two exclusive states: unlocked or locked.
• Only one process can lock a given mutex at one time.
• A mutex can only be unlocked by the particular process that
locked the mutex, but may be locked subsequently by a different
process.
• sc_mutex class comes with pre-defined methods as below.
• int lock() : Lock the mutex if it is free, else wait till mutex gets free.
• int unlock() : Unlock the mutex
• int trylock() : Check if mutex is free, if free then lock it else return -1.
Example of sc_mutex used in bus class Used with an SC_METHOD process, access
might look like this

sc_module bus{
sc_mutex bus_access; void grab_bus_method() {
… if (bus_access.trylock() == 0) {
void write(int addr, int data) { // access bus
bus_access.lock(); …
// perform write bus_access.unlock();
bus_access.unlock(); }
} }

};
• sc_semaphore
• For some resources, you may want to model
more than one copy or owner.
• Ex: parking spaces in a parking lot
• A multiport memory model
class multiport_RAM {
sc_semaphore read_ports(3);
sc_semaphore write_ports(2);

void read(int addr, int& data) {
read_ports.wait();
// perform read
read_ports.post();
}
void write(int addr, const int& data) {
write_ports.wait();
// perform write
write_ports.post();
}

};//endclass
• sc_fifo
• Predefined primitive channel intended to model the behavior of a fifo, that is,
a first-in first-out buffer. Each fifo has a number of slots for storing values.
• The number of slots is fixed when the object is constructed. Default slots
size is 16.
• sc_fifo has following predefined methods.
• write() : This method write the values passed as an argument into the fifo. If
fifo if full then write() function waits till fifo slot is available
• nb_write() : This method is same as write(), only difference is, when fifo is
full nb_write() does not wait till fifo slot is avaible. Rather it returns false.
• read() : This method returns the least recent written data in fifo. If fifo is
empty, then read() function waits till data is available in fifo.
• nb_read() :This method is same as read(), only difference is, when fifo is
empty, nb_read() does not wait till fifo has some data. Rather it returns false.
• num_available() : This method returns the numbers of data values available
in fifo in current delta time.
• num_free() : This method returns the number of free slots available in fifo in
current delta time.
Example void fifowrite(void) {
int val = 10;
#include "systemc.h"
SC_MODULE(example_fifo) { for (;;) {
// Declare the FIFO wait(2, SC_NS);

sc_fifo<int> packet_fifo; val++;


packet_fifo.write(val);

void fiforead(void) { cout << sc_time_stamp() << ": wrote " << val << " No.

int val; of Free Slots in FIFO " <packet_fifo.num_free()<<endl;

for (;;) { }

wait(3, SC_NS); }

packet_fifo.read(val);
cout << sc_time_stamp() << ": Read " << val <<endl;
//cout << sc_time_stamp()<<"No.of Data in FIFO " SC_CTOR(example_fifo) :
<<packet_fifo.num_available()<<endl; packet_fifo(25)
{
}
SC_THREAD(fifowrite);
} SC_THREAD(fiforead);
}
};
#include "systemc.h"
#include "fifo.h"

int sc_main(int argc, char* argv[]) {

example_fifo ex_fifo ("ex_fifo0");


sc_start(10, SC_NS);
return 0;

}
SystemC Highlights (1)
• Support Hardware-Software Co-Design

• Interface in a C++ environment


• Modules
• Container class includes hierarchical Entity and Processes
• Processes
• Describe functionality, Event sensitivity
• Ports
• Single-directional(in, out), Bi-directional(inout) mode
• Signals
• Resolved, Unresolved signals
• Rich set of port and signal types
• Rich set of data types
• All C/C++ types, 32/64-bit signed/unsigned, fixed-points, MVL, user
defined
SystemC Highlights (2)
• Interface in a C++ environment (continued)
• Clocks
• Special signal, Timekeeper of simulation and Multiple clocks,
with arbitrary phase relationship
• Cycle-based simulation
• High-Speed Cycle-Based simulation kernel
• Multiple abstraction levels
• Untimed from high-level functional model to detailed clock cycle
accuracy RTL model
• Communication Protocols
• Debugging Supports
• Run-Time error check
• Waveform Tracing

You might also like