cpe626-SystemC

advertisement
CPE 626
The SystemC Language
Aleksandar Milenkovic
E-mail:
Web:
milenka@ece.uah.edu
http://www.ece.uah.edu/~milenka
Outline




Motivation for SystemC
What is SystemC?
Modules
Processes
A. Milenkovic
2
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
 Parts of the model to be implemented in
hardware are given to Verilog/VHDL coders
 Verilog or VHDL specification written
 Models simulated together to test equivalence
 Verilog/VHDL model synthesized
A. Milenkovic
3
Designing Big Digital Systems
 Current conditions




Every system company was doing this differently
Every system company used its own simulation library
System designers don’t know Verilog or VHDL
Verilog or VHDL coders don’t understand system design
 Problems with standard methodology:
 Manual conversion from C to HDL
o Error prone and time consuming
 Disconnect between system model and HDL model
o C model becomes out of date as changes are made
only to the HDL model
 System testing
o Tests used for C model cannot be run against HDL model =>
they have to be converted to the HDL environment
A. Milenkovic
4
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
A. Milenkovic
5
SystemC Design Methodology
 Refinement methodology
 Design is slowly refined
in small sections to add necessary
hardware and timing constructs
 Written in a single language
 higher productivity due to
modeling at a higher level
 testbenches can be reused
saving time
 Future releases will have constructs to model RTOS
A. Milenkovic
6
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
A. Milenkovic
7
What Is SystemC?
 Language definition is publicly available
 Libraries are freely distributed
 Compiler is an expensive commercial product
 See www.systemc.org for more information
A. Milenkovic
8
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)
A. Milenkovic
9
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
A. Milenkovic
10
Modules
SC_MODULE(mymod) {
// struct mymod : sc_module {
/* port definitions */
/* signal definitions */
/* clock definitions */
/* storage and state variables */
/* process definitions */
SC_CTOR(mymod) {
/* Instances of processes and modules */
}
};
A. Milenkovic
11
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
SC_MODULE(mymod) {
 and any C++ or
sc_in<bool> load, read;
SystemC type
sc_inout<int> data;
sc_out<bool> full;
/* rest of the module */
};
A. Milenkovic
12
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
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
*/
}
};
A. Milenkovic
13
Instances of Modules
 Each instance is a pointer to an object in the module
Connect instance’s
ports to signals
SC_MODULE(mod1) { … };
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);
}
};
A. Milenkovic
14
Positional Connection
// filter.h
#include "systemc.h“ // systemC classes
#include "mult.h“
// decl. of mult
#include "coeff.h“
// decl. of coeff
#include "sample.h“ // decl. of sample
SC_MODULE(filter) {
sample *s1;
// pointer declarations
coeff *c1;
mult *m1;
// signal declarations
sc_signal<sc_uint<32> > q, s, c;
SC_CTOR(filter) { // constructor
s1 = new sample ("s1"); // create obj.
(*s1)(q,s); // signal mapping
c1 = new coeff ("c1");
(*c1)(c);
m1 = new mult ("m1");
(*m1)(s,c,q);
}
}
A. Milenkovic
15
Named Connection
#include "systemc.h“ // systemC classes
#include "mult.h“
// decl. of mult
#include "coeff.h“
// decl. of coeff
#include "sample.h“ // decl. of sample
SC_MODULE(filter) {
sample *s1;
coeff *c1;
mult *m1;
sc_signal<sc_uint<32> > q, s, c;
SC_CTOR(filter) {
s1 = new sample ("s1");
s1->din(q); // din of s1 to signal q
s1->dout(s); // dout to signal s
c1 = new coeff ("c1");
c1->out(c); // out of c1 to signal c
m1 = new mult ("m1");
m1->a(s); // a of m1 to signal s
m1->b(c); // b of m1 to signal c
m1->q(q); // q of m1 to signal c
}
}
A. Milenkovic
16
Internal Data Storage
 Local variables to store data within a module
 May be of any legal C++, SystemC, or user-defined type
 Not visible outside the module unless it is made explicitly
// count.h
#include "systemc.h"
SC_MODULE(count) {
sc_in<bool> load;
sc_in<int> din; // input port
sc_in<bool> clock; // input port
sc_out<int> dout; // output port
int count_val; // internal data storage
void count_up();
SC_CTOR(count) {
SC_METHOD(count_up); //Method process
sensitive_pos << clock;
}
};
A. Milenkovic
// count.cc
#include "count.h"
void count::count_up() {
if (load) {
count_val = din;
} else {
// could be count_val++
count_val = count_val + 1;
}
dout = count_val;
}
17
Processes
 Only thing in SystemC that actually does anything
 Functions identified to the SystemC kernel and
called whenever signals these processes are sensitive to
change value
 Statements are executed sequentially
until the end of the process occurs,
or the process is suspended using wait function
 Very much like normal C++ methods
+ Registered with the SystemC kernel
 Like Verilog’s initial blocks
A. Milenkovic
18
Processes (cont’d)
 Processes are not hierarchical
 no process can call another process directly
 can call other methods and functions that are not processes
 Have sensitivity lists
 signals that cause the process to be invoked,
whenever the value of a signal in this list changes
 Processes cause other processes to execute
by assigning new values to signals in the sensitivity lists of
the processes
 To trigger a process, a signal in the sensitivity list
of the process must have an event occur
A. Milenkovic
19
Three Types of Processes
Determines how the process is called and executed
 METHOD
 Models combinational logic
 THREAD
 Models testbenches
 CTHREAD
 Models synchronous FSMs
A. Milenkovic
20
METHOD Processes
 Triggered in response to changes on inputs
 Cannot store control state between invocations
 Designed to model blocks of combinational logic
A. Milenkovic
21
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) {
SC_METHOD(inverter);
sensitive(in);
}
};
A. Milenkovic
Instance of this
process created
and made sensitive
to an input
22
METHOD Processes
 Invoked once every time input “in” changes
 Should not save state between invocations
 Runs to completion: should not contain infinite loops
 Not preempted
void onemethod::inverter() {
bool internal;
internal = in;
out = ~internal;
}
A. Milenkovic
Read a value from the port
Write a value to an
output port
23
THREAD Processes
 Triggered in response to changes on inputs
 Can suspend itself and be reactivated
 Method calls wait() function that suspends process execution
 Scheduler runs it again when an event occurs
on one of the signals the process is sensitive to
 Designed to model just about anything
A. Milenkovic
24
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
}
};
A. Milenkovic
25
THREAD Processes
 Reawakened whenever an input changes
 State saved between invocations
 Infinite loops should contain a wait()
void onemethod::toggler() {
bool last = false;
for (;;) {
last = in; out = last; wait();
last = ~in; out = last; wait();
}
}
A. Milenkovic
Relinquish control
until the next
change of a signal
on the sensitivity
list for this process
26
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
A. Milenkovic
27
CTHREAD Processes
SC_MODULE(onemethod) {
sc_in_clk clock;
sc_in<bool> trigger, in;
sc_out<bool> out;
Instance of this
process created and
relevant clock edge
assigned
void toggler();
SC_CTOR(onemethod) {
SC_CTHREAD(toggler, clock.pos());
}
};
A. Milenkovic
28
CTHREAD Processes
 Reawakened at the edge of the clock
 State saved between invocations
 Infinite loops should contain a wait()
Relinquish control
until the next clock
cycle in which the
trigger input is 1
void onemethod::toggler() {
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
A. Milenkovic
29
A CTHREAD for Complex Multiply
struct complex_mult : sc_module {
sc_in<int> a, b, c, d;
sc_out<int> x, y;
sc_in_clk
clock;
void do_mult() {
for (;;) {
x = a * c - b * d;
wait();
y = a * d + b * c;
wait();
}
}
SC_CTOR(complex_mult) {
SC_CTHREAD(do_mult, clock.pos());
}
};
A. Milenkovic
30
Put It All Together
Process Type
SC_METHOD
SC_THREAD
SC_CTHREAD
Exec. Trigger
Signal Events
Signal Events
Clock Edge
Exec.
Suspend
NO
YES
YES
Infinite Loop
NO
YES
YES
Suspend /
Resume by
N.A.
wait()
wait()
wait_until()
Construct &
Sensitize
Method
SC_METHOD(call_back);
sensitive(signals);
sensitive_pos(signals);
sensitive_neg(signals);
SC_THREAD(call_back);
sensitive(signals);
sensitive_pos(signals);
sensitive_neg(signals);
SC_CTHREAD(
call_back,
clock.pos());
SC_CTHREAD(
call_back,
clock.neg());
A. Milenkovic
31
Watching
 SC_THREAD and SC_CTHREAD processes typically
have infinite loops that will continuously execute
 Use watching construct to jump out of the loop
 Watching construct will monitor a specified condition
 When condition occurs control is transferred
from the current execution point
to the beginning of the process
A. Milenkovic
32
Watching: An Example
// datagen.h
#include "systemc.h"
SC_MODULE(data_gen) {
sc_in_clk clk;
sc_inout<int> data;
sc_in<bool> reset;
void gen_data();
SC_CTOR(data_gen){
SC_CTHREAD(gen_data, clk.pos());
watching(reset.delayed() == true);
}
};
// datagen.cc
#include "datagen.h"
void gen_data() {
if (reset == true) {
data = 0;
}
while (true) {
data = data + 1;
wait();
data = data + 2;
wait();
data = data + 4;
wait();
}
}
Watching expressions are tested at the wait() or wait_until() calls.
All variables defined locally will lose their value on the control exiting.
A. Milenkovic
33
Local Watching
 Allows us to specify exactly
which section of the process is watching which signal, and
where event handlers are located
W_BEGIN
// put the watching declarations here
watching(...);
watching(...);
W_DO
// This is where the process functionality goes
...
W_ESCAPE
// This is where the handlers
// for the watched events go
if (..) {
...
}
W_END
A. Milenkovic
34
SystemC Types
 SystemC programs may use any C++ type along with any
of the built-in ones for modeling systems
 SystemC Built-in Types
 sc_bit, sc_logic
o Two- and four-valued single bit
 sc_int, sc_unint
o 1 to 64-bit signed and unsigned integers
 sc_bigint, sc_biguint
o arbitrary (fixed) width signed and unsigned integers
 sc_bv, sc_lv
o arbitrary width two- and four-valued vectors
 sc_fixed, sc_ufixed
o signed and unsigned fixed point numbers
A. Milenkovic
35
Fixed and Floating Point Types
 Integers
 Precise
 Manipulation is fast and cheap
 Poor for modeling continuous real-world behavior
 Floating-point numbers




Less precise
Better approximation to real numbers
Good for modeling continuous behavior
Manipulation is slow and expensive
 Fixed-point numbers
 Worst of both worlds
 Used in many signal processing applications
A. Milenkovic
36
Integers, Floating-point, Fixed-point
Decimal (“binary”)
point
 Integer
 Fixed-point
 Floating-point
2
A. Milenkovic
37
Using Fixed-Point Numbers
 High-level models usually use floating-point for convenience
 Fixed-point usually used in hardware implementation
because 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-point to fixed-point?
 SystemC’s fixed-point number classes facilitate simulating
algorithms with fixed-point numbers
A. Milenkovic
38
SystemC’s 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
A. Milenkovic
39
Rounding
 What happens when your result doesn’t land exactly on a
representable number?
 Rounding mode makes the choice
A. Milenkovic
40
SC_RND
 Round up at 0.5
 What you expect?
A. Milenkovic
41
SC_RND_ZERO
 Round toward zero
 Less error accumulation
A. Milenkovic
42
SC_TRN
 Truncate
 Easiest to implement
A. Milenkovic
43
Overflow
 What happens if the result is too positive or too negative to
fit in the result?
 Saturation? Wrap-around?
 Different behavior appropriate for different applications
A. Milenkovic
44
SC_SAT
 Saturate
 Sometimes desired
A. Milenkovic
45
SC_SAT_ZERO
 Set to zero
 Odd behavior
A. Milenkovic
46
SC_WRAP
 Wraparound
 Easiest to implement
A. Milenkovic
47
SystemC Semantics
 Cycle-based simulation semantics
 Resembles Verilog, but does not allow the modeling of
delays
 Designed to simulate quickly and resemble most
synchronous digital logic
A. Milenkovic
48
Clocks
 The only thing in SystemC that has a notion of real time
 Only interesting part is relative sequencing among multiple
clocks
 Triggers SC_CTHREAD processes
 or others if they decided to become sensitive to clocks
A. Milenkovic
49
Clocks
 sc_clock clock1(“myclock”, 20, 0.5, 2, false);
Time Zero
Initial value is false
20
0.5 of 20
2
A. Milenkovic
50
SystemC 1.0 Scheduler
 Assign clocks new values
 Repeat until stable
 Update the outputs of triggered SC_CTHREAD processes
 Run all SC_METHOD and SC_THREAD processes whose inputs
have changed
 Execute all triggered SC_CTHREAD methods. Their outputs
are saved until next time
A. Milenkovic
51
Scheduling
 Clock updates outputs of SC_CTHREADs
 SC_METHODs and SC_THREADs respond to this change
and settle down
 Bodies of SC_CTHREADs compute the next state
Sync.
Async.
Clock
A. Milenkovic
52
Why Clock Outputs?
 Why not allow Mealy-machine-like behavior in FSMs?
 Difficult to build large, fast systems predictably
 Easier when timing worries are per-FSM
 Synthesis tool assumes all inputs arrive at the beginning of
the clock period and do not have to be ready
 Alternative would require knowledge of inter-FSM timing
A. Milenkovic
53
Implementing SystemC
 Main trick is implementing SC_THREAD and SC_CTHREAD’s
ability to call wait()
 Implementations use a lightweight threads package
/* … */
wait();
/* … */
Instructs thread package to save
current processor state (register,
stack, PC, etc.) so this method can
be resumed later
A. Milenkovic
54
Implementing SystemC
 Other trick is wait_until()
wait_until(continue.delayed() == true);
 Expression builds an object that can check the condition
 Instead of context switching back to the process, scheduler
calls this object and only runs the process if the condition
holds
A. Milenkovic
55
Determinism in SystemC
 Easy to write deterministic programs in SystemC
 Don’t share variables among processes
 Communicate through signals
 Don’t try to store state in SC_METHODs
 Possible to introduce nondeterminism
 Share variables among SC_CTHREADs
o They are executed in nondeterministic order
 Hide state in SC_METHODs
o No control over how many times they are invoked
 Use nondeterministic features of C/C++
A. Milenkovic
56
Synthesis Subset of SystemC
 At least two
 “Behavioral” Subset
 Implicit state machines permitted
 Resource sharing, binding, and allocation done automatically
 System determines how many adders you have
 Register-transfer-level Subset
 More like Verilog
 You write a “+”, you get an adder
 State machines must be listed explicitly
A. Milenkovic
57
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?
A. Milenkovic
58
Conclusions
 C++ dialect for modeling digital systems
 Provides a simple form of concurrency
 Cooperative multitasking
 Modules
 Instances of other modules
 Processes
A. Milenkovic
59
Conclusions
 SC_METHOD
 Designed for modeling purely functional behavior
 Sensitive to changes on inputs
 Does not save state between invocations
 SC_THREAD
 Designed to model anything
 Sensitive to changes
 May save variable, control state between invocations
 SC_CTHREAD
 Models clocked digital logic
 Sensitive to clock edges
 May save variable, control state between invocations
A. Milenkovic
60
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.
A. Milenkovic
61
An Example Process
Determines how the process is called and executed
// dff.h
#include "systemc.h"
SC_MODULE(dff) {
sc_in<bool> din;
sc_in<bool> clock;
sc_out<bool> dout;
void doit();
// data input
// clock input
// data output
// dff.cc
#include "dff.h"
void dff::doit() {
dout = din;
}
// method in the module
SC_CTOR(dff) { // constructor
SC_METHOD(doit); // doit type is SC_METHOD
// method will be called whenever a
// positive edge occurs on port clock
sensitive_pos << clock;
}
};
A. Milenkovic
62
Download