Global training solutions for engineers creating the world's electronics

SystemC Syntax Summary

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.

back to top

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'Newtonsoft.Json.Linq.JValue' does not contain a definition for 'macroAlias'
   at CallSite.Target(Closure , CallSite , Object )
   at AspNetCore.Views_Partials_grid_editors_macro.ExecuteAsync() in C:\home\site\wwwroot\Views\Partials\grid\editors\macro.cshtml:line 0
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page, ViewContext context)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page, ViewContext context, Boolean invokeViewStarts)
   at Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.RenderPartialCoreAsync(String partialViewName, Object model, ViewDataDictionary viewData, TextWriter writer)
   at Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.PartialAsync(String partialViewName, Object model, ViewDataDictionary viewData)
   at AspNetCore.Views_Partials_grid_editors_base.ExecuteAsync() in C:\home\site\wwwroot\Views\Partials\grid\editors\base.cshtml:line 11