SystemC-n-BehaviorCoding_Fall2021_Section4_SystemC
SystemC-n-BehaviorCoding_Fall2021_Section4_SystemC
Contents
Section 4
SystemC 2.3, IEEE 1666-2011
Class Objectives
Not “English as
Second Language”
Drag picture to plac
Chapter 1
SystemC Overview
+ 7
SystemC Overview
SystemC Overview
SystemC Highlights
▶ Modules: component
▶ Processes: functions, SC_THREAD & SC_METHOD
▶ Ports: I/O ports
▶ Signals: wires
▶ Rich set of port and signal types
▶ Rich set of data types
▶ Clocks
C, C++ Done
System-level Modeling
Verilog/VHDL
Simulation &
Refine
Analysis
Simulation
Results
Synthesis
Primitive Channels
Signal, Mutex, Semaphore, FIFO, etc.
Event-Driven Simulation
Events, Processes
SystemC Myth I
+ 16
Methodology
SystemC Myth II
▶ It
is a language to unify the design environment,
SW and HW. A unified design environment.
▶ Well, this is a dream in the academy. In industry,
this is a long way to go and as of today,
SystemC is not the answer. Notice, SystemC is
an HDL, it itself does not support software
performance measure mechanism.
▶ Will the day that a unified design language be
realized? We just don’t know. But new
developments called Model Based Design and
Software Defined Hardware are in discussion.
+ 17
Note 2
Note 3
System-Level Language
Not “English as
Second Language”
Drag picture to plac
Chapter 2
Module, Port, Signal & Blockingness
+ 21
Modules
Module Structure
Derived from class sc_module:
class my_module : public sc_module { … };
A more commonly used way:
SC_MODULE (module_name) {
// ports, sc_export, data members, member functions
// processes, etc.
SC_CTOR(module_name) { // constructur
// body of constructor
// process registration, sensitivity lists
// module instantiations, port binding etc.
}
}; // do not forget this final ;
SC_MODULE is a macro:
#define SC_MODULE(user_module_name) \
struct user_module_name : sc_module
+ 23
Ports
Signal (1)
Is
a un-directional wire when connects
to ports
Theflow of data is determined by the
ports a signal connects to
Example:
Signal (2)
Non-blocking descriptor
Example:
Blocking
// a == 3, b == 4, c == 5
b = a; // b is now 3
c = b; // c is now 3
a = c; // a is 3, again
+ 29
Non-blocking
// a == 3, b == 4, c == 5
b = a; // b is still 4
c = b; // c is still 5
a = c; // a is still 3
wait();
// b is updated as 3
// c is updated as 4
// a is updated as 5
+ 30
Blocking example
Non-blocking exampe
Note
Named Mapping
#include “systemc.h”
#include “mult.h”
#include “coeff.h”
#include “sample.h”
c1
SC_MODULE(filter) {
sample *s1;
coeff *c1;
mult *m1;
sc_signal<sc_uint<32> > q, s, c;
s1 m1
SC_CTOR(filter) {
s1 = new sample(“s1”);
s1->din ( q );
s1->dout ( s );
c1 = new coeff(“c1”);
c1->out ( c );
m1 = new mult(“m1”);
m1->a ( s );
m1->b ( c );
m1->q ( q );
}
};
+ 34
#include “systemc.h”
#include “mult.h”
#include “coeff.h”
c1
#include “sample.h”
SC_MODULE(filter) {
sample *s1;
coeff *c1;
mult *m1; s1 m1
sc_signal<sc_uint<32> > q, s, c;
SC_CTOR(filter) {
s1 = new sample(“s1”);
(*s1) ( q,s ); // 2.2 illegal
c1 = new coeff(“c1”);
(*c1) ( c ); // 2.2 illegal
m1 = new mult(“m1”);
(*m1) ( s, c, q ); // 2.2 illegal
}
};
+ 35
Module Example
#include “systemc.h”
SC_MODULE(timer) {
sc_in<bool> start; // ports
sc_out<bool> timeout;
sc_in<bool> clock;
SC_CTOR(timer) { // constructor
SC_THREAD(runtimer);
sensitive << clock.pos() // sensitivity list
<< start;
count = 0;
}
}; // do not forget the final semi-column
§ sensitive_pos and sensitive_neg are deprecated in 2.2
+ 37
A Module Implementation
// timer.cpp
#include “timer.h”
void timer::runtimer() {
while(1) {
if (start.read()) {
cout << “Timer: timer start detected “ << endl;
count = 5;
timeout.write(0);
} else {
if (count == 0) {
timeout.write(1);
} else {
count--;
timeout.write(0);
}
}
wait();
}
}
+ 38
Clock
Synopsis
class sc_clock : public sc_signal_in_if<bool>,
public sc_module
{
public:
sc_clock();
explicit sc_clock( sc_module_name name_ );
sc_clock( sc_module_name name_,
const sc_time& period_,
double duty_cycle_ = 0.5,
const sc_time& start_time_ = SC_ZERO_TIME,
bool pos_edge_first = true);
…
};
Example:
sc_time clkPrd(20, SC_NS), clkDly(2, SC_NS);
sc_clock clock1(“clock1”, clkPrd, 0.50, clkDly, true);
+
A Simple Example
39
+ 40
Specification
Data
M S
Application/ Data Data Application/
Stimuli
transmit receiver Sink
S M
Acknowledge
+ 41
C/C++ Model
frame data; //global data frame storage for Channel
void transmit(void) { //transmits frames to Channel
int framenum; // sequence number for framces
frams s; // Local frame
packet buffer; // Buffer to hold intermediate data
event_t event; // Event to trigger actions in transmit
SystemC Model
timer
Data
M S
Acknowledge
+ 44
// noisybus.h // noisybus.cpp
#include “packet.h” #include “noisybus.h”
void noisybus::receive_data() {
SC_MODULE (noisybus) {
int i;
sc_in<packet_type> tpackin;
packin = tpackin;
sc_in<packet_type> rpackin; cout << “Noisybus: Received packet seq no. = “ << packin.seq <<
sc_out<packet_type> tpackout; endl;
sc_out<packet_type> rpackout; i = rand();
packout = packin;
packet_type packin; cout << “Noisybus: Random number = “ << i << endl;
if ((i > 1000) && (i < 5000)) {
packet_type packout;
packout.seq = 0;
packet_type ackin;
}
packet_type ackout; rpackout = packout;
}
void receive_data();
void send_ack(); void noisybus::send_ack() {
// Constructor int i;
SC_CTOR(noisybus) { ackin = rpackin;
SC_METHOD(receive_data); cout << “Noisybus: Received Ack for packet = “ << ackin.seq <<
endl;
sensitive << tpackin; i = rand();
ackout = ackin;
SC_METHOD(send_ack); if ((i > 10) && (i < 500)) {
sensitive << rpackin; ackout.seq = 0;
} }
}; tpackout = ackout;
}
+ 47
// receiver.h // receiver.cpp
#include “packet.h” #include “receiver.h”
SC_MODULE(receiver) {
void receiver::receive_data() {
sc_in<packet_type> rpackin;
sc_out<packet_type> rpackout; packin = rpackin;
sc_out<long> dout; if (packin == packold) return;
sc_in<bool> rclk; cout << “Receiver: got packet no. = “ <<
packin.seq << endl;
int framenum; if (packin.seq == framenum) {
packet_type packin, packold; dout = packin.info;
packet_type s; framenum++;
int retry; retry++;
s.retry = retry;
void receive_data();
s.seq = framenum – 1;
//Constructor rpackout = s;
SC_CTOR(receiver) { }
SC_METHOD(receive_data); packold = packin;
sensitive << rclk.pos(); }
framenum = 1;
retry = 1;
}
};
+ 48
// timer.h // timer.cpp
#include “systemc.h” #include “timer.h”
// display.h // display.cpp
#include “packet.h” #include “display.h”
sc_close_vcd_trace_file(tf);
return(0);
}
+
Drag picture to placeholder or click ico
51
Not “English as
Second Language”
Drag picture to plac
Chapter 3
Processes, Interface & Channel
+ 52
Basics
Basics – Cont.
Method
SC_METHOD
Method is just SystemC ways of saying
function, or subroutine. Therefore, it inherits
the behavior of a function.
A process is called to execute and returns the
execution back to the calling mechanism
when completed.
A locally declared variable is not permanent.
Meaning, the value of a local variable is no
longer valid after the end of a method.
+ 55
Thread
SC_THREAD
Clocked Thread
SC_CTHREAD
Clocked thread is a special case of a thread process. A
clocked thread is only sensitive to one edge of a clock
cycle (positive or negative).
Clocked thread is used to clearly describe reset
behavior by using
reset_signal_is()
async_reset_signal_is()
The use of wait() is the same as in SC_THREAD.
+ 57
void ram_proc();
#include “ram.h”
void RAM::ram_proc() {
for (int i = 0; i < size; i++)
memory[i] = 0x0;
while(true) {
wait();
unsigned int haddr = addr.read();
assert(haddr < size);
if (rw) {
data = memory[haddr];
} else {
memory[haddr] = data.read();
}
}
}
#endif
+
SC_HAS_PROCESS Example (3)
main.cpp
#include “ram.h”
Dynamic Process
sc_main()
64
+ 65
Simulating Parallelism
250 ps 250 ps 250 ps
a a a
b b b
1.Input to b is 1.Inputs to mult are 1.Input to signal c is
changed changed changed
2.Triggered signal b to 2.Triggered mult to 2.Triggered signal c to
compute the change compute the change compute the change
3.Input to a is 3.Inputs to signals a, b 3.Inputs to signals a, b
changed and c are not and mult are not
4.Triggered signal a to changed changed
compute the change 4.No execution to a, b 4.No execution to a, b
5.Inputs to mult and and c and mult
signal c are not
changed
6.No execution to mult
and c
+ 66
Execution Semantics
Simulation Semantics
Initialization Phase
Synchronization – Bus
Arbitration
evaluate
evaluate AArequests
checks BBBreads
requests
checks evaluate
evaluate
busgrant from
busgrant
memory
update update
A YESNO B
request_update
request_update read
checkGrant
grant-ID
evaluate
B update
C
Cycle:
0
1
read write
memory
evaluate update
D
+ 70
Simulation Functions
Time
Time Resolution
Time Unit
Events
Events – Cont.
Event – Cont.
A, B & C: Processes
B D: Channel
D
A
C
Event – Cont.
a.cancel(); // Error!
b.cancel(); // Canceled!
c.cancel(); // Canceled!
+ 80
81
+ 82
Interface
Aninterface defines the set of access
functions (methods) of a channel. It
specifies the name, parameters and
return type of functions but does not
have the implementation details.
sc_fifo_in_if
sc_fifo_out_if
sc_mutex_if
sc_semaphore_if
sc_signal_in_if
sc_signal_inout_if
+ 83
Channel
A channel implements the interface functions. Channel
provides the communication between methods or
within a module provides the communication between
processes.
Channel may implement one or more interfaces
Different channels may implement the same interface
in different ways
sc_buffer
sc_fifo
sc_mutex
sc_semaphore
sc_signal
sc_signal_resolved
sc_signal_rv
+
Drag picture to placeholder or click ico
84
Not “English as
Second Language”
Drag picture to plac
Chapter 4
Data Types
+ 85
sc_bit
sc_bit operators
Bitwise & (and) | (or) ^ (xor) ~ (not)
Assignment = &= |= ^=
Equality == !=
a = a & b; a &= b;
a = a | b; a |= b;
+ 86
sc_logic
Assignment = &= |= ^=
Equality == !=
x = ‘1’; x = ‘Z’;
x ^= y; x != y;
+ 87
sc_bv
Arbitrary sized 2 value vector type
Fixed precision integer operators
Bitwise ~ & | ^ >> <<
Assignment = &= |= ^=
Equality == !=
Bit Select [x]
Part Select range()
Concatenation (,)
Reduction and_reduce() or_reduce() xor_reduce()
sc_bv<64> databus;
sc_logic result;
result = databus.or_reduce();
// or_reduce returns the result of ORing all bits in databus
// and_reduce(), or_reduce() and xor_reduce() return bool value
+ 90
sc_lv
sc_lv<16> bus1;
bus1 = “ZZZZZZZZZZZZZZZZ”;
// this string like assignment also works for sc_bv
+
Drag picture to placeholder or click ico
91
Not “English as
Second Language”
Drag picture to plac
Chapter 5
Fixed Point Types
+ 92
Quantization Mode
How to handle the situation when the result of
an operation generates more precision in the
LSB than is available as specified by wl and
iwl. For example, a division, 1/3.
Quantization Mode Name
Round to plus infinity SC_RND
Round to zero SC_RND_ZERO
Round to minus infinity SC_RND_MIN_INF
Round to infinity SC_RND_INF
Convergent round SC_RND_CONV
Truncate SC_TRN
Truncate to zero SC_TRN_ZERO
+ 94
SC_RND
Round the value to the closest representable number
by adding the MSB of the removed bits to the
remaining bits. ( 二進位之四捨五入 )
01001.010[10100] → 01001.011
+ 95
SC_RND Examples
sc_fixed<4, 2> x;
sc_fixed<3, 2, SC_RND> y;
x = 1.25; // 1.25 = 01.01
y = x; // 01.0[1] → 01.1 = 1.5
SC_RND_ZERO
Performs SC_RND if the two nearest representable
numbers are not an equal distance apart, otherwise
round to zero is performed.
x.x is not of equal distance. .xx or xx. Are of equal
distance
When round to zero, for a positive number redundant
bits are deleted, and for a negative number SC_RND is
performed.
+ 97
SC_RND_MIN_INF
Performs SC_RND if the two nearest
representable numbers are not an equal
distance apart, otherwise round to minus
infinity is performed.
Minus infinity: omitting the redundant bits on
the LSB side.
+ 98
SC_RND_INF
Performs SC_RND if the two nearest representable
numbers are not an equal distance apart, otherwise
round to plus infinity is performed.
Plus infinity: for positive numbers perform SC_RND. For
negative numbers eliminate the redundant bits.
+ 99
SC_RND_CONV
Performs SC_RND if the two nearest representable
numbers are not an equal distance apart, otherwise
checks the LSB of the remaining bits. If the LSB is 1
then round towards plus infinity. If the LSB is 0 then
round towards minus infinity.
sc_fixed<4, 2> x;
sc_fixed<3, 2, SC_RND> y;
x = .75; // .75 = 00.11
y = x; // 01.0 = 1
+ 100
SC_TRN
Default mode. The redundant bits are always deleted.
Other ways of saying is it always rounds towards minus
infinity.
+ 101
SC_TRN_ZERO
Performs truncate to positive numbers.
Performs SC_RND to negative numbers.
+ 102
Overflow Mode
Overflow: when the result of an operation generated more
bits on the MSB side than are available for representation.
Overflow mode is specified by the o_mode and n_bits
parameters to a fixed point data type, it has two major
modes, saturate and wrap-around.
MIN is the smallest negative number that can be
represented.
MAX is the largest positive number that can be represented.
Overflow Mode Name
Saturate SC_SAT
Saturate to zero SC_SAT_ZERO
Symmetrical saturate SC_SAT_SYM
Wrap-around SC_WRAP
Sign magnitude wrap-around SC_WRAP_SM
+ 103
SC_SAT
Convertsthe value to MAX for an overflow and
MIN for an underflow.
+ 104
SC_SAT Examples
sc_fixed<4,4> x;
sc_fixed<3,3,SC_TRN,SC_SAT> y;
x = 6; // 0110, with a sign bit
y = x; // 011 = 3, remember the sign bit
x= -5; // 1011
y = x; // 100 = -4
+ 105
SC_SAT_ZERO
Sets the result to 0 for any value that is outside the
representable range of the fixed point data type.
+ 106
SC_SAT_SYM
In 2’s complement notation there is one more
negative representation than positive. Sometimes it is
desirable to have the same positive and negative
numbers of representations. SC_SAT_SYM generates
MAX and negative overflow generates –MAX for signed
numbers.
+ 107
Wrap-around
SC_WRAP, nbits = 0
The default overflow mode.
Any MSB bits outside the range of the target type are
deleted.
+ 109
SC_WRAP_SM, n_bits = 0
Deletes any MSB bits that are outside the result work
length.
Sign bit is set to the value of the LSB of deleted bits.
+ 111
Need to
#include <sysc/datatypes/fx/sc_fixed.h> // for sc_fixed
#include <sysc/datatypes/fx/sc_ufixed.h> // for sc_ufixed
using namespace sc_dt;
Templated & static signed/unsigned fixed point data types
Declaration Syntax:
sc_fixed <wl, iwl [,q_mode [, o_mode [, n_bits]]]>
var_name([init_val][,cast_switch]);
cast_switch : SC_ON, SC_OFF
Examples
sc_ufixed<16, 1, SC_RND_CONV, SC_SAT_SYM, 1> a(1.5);
+ 113
Need to
#include <sysc/datatypes/fx/sc_fixed.h> // within sc_fixed
#include <sysc/datatypes/fx/sc_ufixed.h> // within sc_ufixed
using namespace sc_dt;
Mantissa limited to 53 bits. Templated & static signed/unsigned
fixed point data types
Declaration Syntax:
sc_fixed_fast <wl, iwl [,q_mode [, o_mode [, n_bits]]]>
var_name([init_val][,cast_switch]);
cast_switch : SC_ON, SC_OFF
Examples
sc_ufixed<16, 1, SC_RND_CONV, SC_SAT_SYM, 1> a(1.5);
+ 114
sc_fixed<10,2> my_var;
if (my_var.is_zero())
...
Conversion To String
Available formats
SC_F - Fixed Notation (is the default)
SC_E - Scientific Notation
sc_fixed<10,5> my_var;
cout << my_var.to_string(SC_BIN, SC_E);
Type Casting
123