Global training solutions for engineers creating the world's electronics products

SystemC Syntax Guide

SystemC Syntax Summary

SystemC Logo

This section contains all the essential syntax necessary to start designing using SystemC.

For a more detailed practical guide to using SystemC, see our SystemC Golden Reference Guide

Modules, Instancing, sc_main

//ModuleName.h - interface file
#include "systemc.h"
#include "SubModulename.h"; // lower-level module
SC_MODULE( ModuleName)
{
  //port declarations
  // member variable declarations
  //internal channels
  //sub-module declaration
  SubModuleName InstName1;
  // see 2nd example below for hierarchy using pointers
  //local methods
  int local_method();
  //process declarations
  void MyProc1();
  void MyProc2();
  void MyProc3();
  //module constructor

  SC_CTOR( ModuleName): InstName1("InstName1")
  {
    InstName1.SubPortName1(SigName1);//named mapping
    InstName1.SubPortName2(SigName2);//named mapping

    //process/local method definition
    SC_METHOD(MyProc1);
      //sensitivity list
    SC_THREAD(MyProc2);
      //sensitivity list
    SC_CTHREAD(MyProc3,ClkName);
  }
};

// Alternative form of module declaration without using SC_MODULE macro
class ModuleName: public sc_module
{
public:
  // declarations
  ...
  //sub-module pointer declaration
  SubModuleName *InstName1;
  //alternative macro to register module constructor:
  SC_HAS_PROCESS(ModuleName);
  //module constructor
  ModuleName(sc_module_name Nm, [other constructor arguments] ): sc_module(Nm), [argument initialisers]
  {
    //module instances
    InstName1 = new SubModuleName("Instlabel");
    InstName1->SubPortName1(SigName1); //named mapping
    InstName1->SubPortName2(SigName2);//named mapping

    //process/local method definition
    SC_METHOD(MyProc1);
      //sensitivity list
    SC_THREAD(MyProc2);
      //sensitivity list
    SC_CTHREAD(MyProc3,ClkName);
  }
};

//ModuleName.cpp - implementation file
#include "systemc.h"
#include "ModuleName.h"
int ModuleName :: local_method()
{  int x;
   // sequential statements...
   return x;
};
void ModuleName :: MyProc1()
{
  // sequential statements...
};
//main.cpp
#include "systemc.h"
#include "ModuleName.h"
int sc_main(int argc, char*argv[])
{
  //signal declaration
   sc_signal <type> P1;
   ...
  //clock declaration
  //module instantiation
   ModuleName MN ("ModNm");
  //module mapping
   MN.port1(P1);
   ...
  // trace file creation

   //run simulation
   //close trace file
  return(0);

}

back to top

Signals

sc_signal< type> ListOfNames;
sc_signal< type> S1("Sig1");  // assign label "Sig1"
resolved signals:
sc_signal_resolved Signal_name1, …;
sc_signal_rv<width> Vector_name1, …;

back to top

Commonly-Used Signal Methods

SigName.read()
SigName.write()
SigName.event()
SigName.value_changed_event()

back to top

Other primitive Channels

//mutex declaration
sc_mutex Mutex1;
sc_mutex Mutex2("Mutex2");

//semaphore declaration
sc_semaphore Semaphore1(5);  //initial value=5

sc_semaphore Semaphore2("Sem2",8);  //initial value=8

//fifo declaration
sc_fifo<type> Fifo1;  //default length = 16
sc_fifo<type> Fifo2("Fifo2",2);  //length = 2

//buffer declaration
sc_buffer<type> B1("Buf1");

back to top

Ports

sc_port<interface_type, N, Policy> P1, P2, ...;
(base class for all port specialization types):

back to top

Port Specializations

Unresolved signal ports:
{sc_in | sc_out  | sc_inout} <type> P1, P2, ...;

Resolved signal ports:
{sc_in_resolved | sc_out_resolved | sc_inout_resolved} P1, P2, ...;

Resolved logic vector ports:
{sc_in_rv | sc_out_rv  | sc_inout_rv} <width> A1,A2, ...;

Clock ports :
(Use {sc_in | sc_out  | sc_inout} <bool>

FIFO ports:
sc_fifo_in<type> FifoPortName1, ...;
sc_fifo_out<type> FifoPortName1, ...;

back to top

Processes

Process definitions
SC_METHOD (M_ProcName);
//or SC_THREAD (M_Proc_Name);
  sensitive(SigName1);
  sensitive(SigName2);
//or
  sensitive << SigName1 << SigName2;
  sensitive << BoolSigName.pos();
  sensitive << BoolSigName.neg();

SC_CTHREAD(CTh_ProcName, BoolSigName.pos());
//or SC_CTHREAD(CTh_ProcName, BoolSigName.neg());

Process implementation
Method process
ModuleName::M_ProcName()
{//when invoked, executes until returns
 //cannot be suspended
 //should not have infinite loop
  next_trigger(event); //specify next dynamic event to trigger process
}

Thread process
ModuleName::Th_ProcName()
{//usually has infinite loop, that continuously executes
  while(true)
  {
   //can be suspended and reactivated
    wait();  //wait for event in static sensitivity list
   //wait on events
    wait(event); //wait on event
    wait(e1 & e2); //wait on events e1 and e2
    wait(e1 | e2 |e3); //wait on event e1 or e2 or e3
    wait(x, SC_NS); // wait for x ns
    wait(0, SC_NS); //wait for 1 delta cycle
    wait(SC_ZERO_TIME); //wait for 1 delta cycle
    wait(N);        // wait for N occurrences of static sensitivity event

   }
};

Clocked thread process
ModuleName::CTh_ProcName()
{//only triggered on one edge of one clock
  while(true)
  {//can be suspended and reactivated
    wait();//or wait(N);
  }
//signals updated when process suspends,
//other SC_CTHREAD processes do not see new value until next active clock event
};

back to top

Timing Control

wait(); //suspends execution for one clock cycle
        //(for SC_CTHREADs), or until an event specified
        // in the sensitivity list (for SC_THREADs)
wait(N);   // suspends execution for N lots of static sensitivity events,
           // where N can be constant, variable

back to top

Time and Clocks

sc_time t(int/double, sc_time_unit);

where sc_time_unit can be: SC_FS, SC_PS, SC_NS, SC_US, SC_MS, SC_SEC

The default time resolution: SC_PS

back to top

Time Methods

sc_set_time_resolution(double, sc_time_unit)
sc_get_time_resolution()

back to top

Clocks

sc_clock ClkName(sc_module_name name, sc_time period, double duty_cycle, sc_time start_time, bool positive_first)

defaults:
sc_clock ClkName("Clk", 1, SC_NS, 0.5, 0, true);

ClkName.posedge()
ClkName.negedge()
ClkName.name()
ClkName.period()
ClkName.duty_cycle()
ClkName.read()
ClkName.signal()
ClkName.first_edge()

back to top

Simulation Control Methods

sc_start(sc_time X);
sc_stop();

back to top

Debugging

//C-style
printf("%s: SigName = %s\n", sc_time_stamp(),
            SigName.to_string());

//C++-style
cout <<"( << sc_time_stamp() << "): SigName=" << SigName
     << endl;

back to top

Tracing

sc_trace_file *F;//declare trace file
F = sc_create_vcd_trace_file("Name");//create file
//set the default vcd time unit to ns
F->sc_set_time_unit(1, SC_NS);

sc_trace(TraceFile, WhatToTrace, "LabelInWaveViewer"); //register for tracing

//run the simulation using sc_start(),

sc_close_vcd_trace_file(F);//close file

back to top

Data Types

sc_logic
Bitwise		&(and)	|(or)	^(xor)	~(not)
Assignment	=	&=	|=	^=
Equality	==	!=

Values: 	sc_logic:	'0', '1', 'X', 'Z'
  also    SC_LOGIC_0, SC_LOGIC_1, SC_LOGIC_X, SC_LOGIC_Z

sc_int, sc_uint, sc_bigint, sc_biguint
Bitwise		~	&	|	^	>>	<<
Arithmetic	+	-	*	/	%
Assignment	=	+=	-=	*=	/=	%=	&=	^=	|=
Equality	==	!=
Relational	<	<=	>	>=
Autoinc/dec	++	--
Bit Select	[x]
Part Select	range()
Concatenate	(,)
to_string	Yes ( sc_int, sc_uint)
to_double	Yes
to_signed	Yes ( sc_int)
to_unsigned	Yes ( sc_uint)

sc_int: 64bit, 2's complement
sc_uint: 64bit unsigned
sc_bigint, sc_biguint: default 512bits

sc_bv, sc_lv
Bitwise		~	&	|	^	>>	<<
Assignment	=	&=	|=	^=
Equality	==	!=
Reduction	and_reduce()	or_reduce()	xor_reduce()
Bit Select	[x]
Part Select	range()
Concatenation	(,)
to_string	Yes

back to top

Fixed Point Types

//wl:total word length,iwl:integer word length
//q_mode: quantisation mode, o_mode: overflow mode
//n_bits: no. of saturated bits
sc_fixed(_fast)(wl, iwl, q_mode, o_mode, n_bits) X;
sc_ufixed(_fast)(wl, iwl, q_mode, o_mode, n_bits) Y;
sc_fix(_fast) X(list of options);//non-static arguments
sc_ufix(_fast) Y(list of options);
//for fast fixed types mantissa is limited to 53bits

Quantisation modes:	SC_RND,
			SC_RND_ZERO,
			SC_RND_MIN_INF,
			SC_RND_INF,
			SC_RND_CONV,
			SC_TRN,
			SC_TRN_ZERO

Overflow modes:		SC_SAT,
			SC_SAT_ZERO,
			SC_SAT_SYM,
			SC_WRAP,
			SC_WRAP_SM

sc_fixed, sc_ufixed, sc_fix, sc_ufix
Bitwise		~ 	&	^	|
Arithmetic	*	/	+	-	<<      >>	++	--
Assignment	=	+=	-=	*=	/=	<<=     &= 	^=   |=
							>>=
Equality  	==	!=
Relational	<	<=	>	>=
Bit Select	[x]
Part Select	range()
to_string()	Yes

Arithmetic shifts preserve the sign bit
Bitwise operators do not work on mixtures of signed and unsigned types.