cpe 626 the systemc language
Post on 01-Jan-2016
53 Views
Preview:
DESCRIPTION
TRANSCRIPT
CPE 626 The SystemC Language
Aleksandar MilenkovicE-mail: milenka@ece.uah.edu
Web: http://www.ece.uah.edu/~milenka
A. Milenkovic 2
Outline
Motivation for SystemC What is SystemC? Modules Processes
A. Milenkovic 3
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 4
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 modelo 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 5
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 6
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 7
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 8
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 9
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 10
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 11
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 12
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
SC_MODULE(mymod) {
sc_in<bool> load, read;
sc_inout<int> data;
sc_out<bool> full;
/* rest of the module */
};
A. Milenkovic 13
Signals
Convey information between modules within a module
Directionless: module ports define direction of data transfer
Type may be any C++ or built-in typeSC_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 14
Instances of Modules
Each instance is a pointer to an object in the moduleConnect 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 15
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 16
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 17
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;
}
};
// 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;
}
A. Milenkovic 18
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 19
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 20
Three Types of Processes
METHOD Models combinational logic
THREAD Models testbenches
CTHREAD Models synchronous FSMs
Determines how the process is called and executed
A. Milenkovic 21
METHOD Processes
Triggered in response to changes on inputs
Cannot store control state between invocations
Designed to model blocks of combinational logic
A. Milenkovic 22
METHOD Processes
Process is simply a method of this class
Instance of this process created
and made sensitive to an input
SC_MODULE(onemethod) { sc_in<bool> in; sc_out<bool> out;
void inverter();
SC_CTOR(onemethod) {
SC_METHOD(inverter); sensitive(in);
}};
A. Milenkovic 23
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
Read a value from the port
Write a value to an output port
void onemethod::inverter() { bool internal; internal = in; out = ~internal;}
A. Milenkovic 24
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 25
THREAD Processes
Process is simply a method of this class
Instance of this process created
alternate sensitivity list notation
SC_MODULE(onemethod) { sc_in<bool> in; sc_out<bool> out;
void toggler();
SC_CTOR(onemethod) {
SC_THREAD(toggler); sensitive << in; }
};
A. Milenkovic 26
THREAD Processes
Reawakened whenever an input changes
State saved between invocations
Infinite loops should contain a wait()
Relinquish control until the next change of a signal on the sensitivity list for this process
void onemethod::toggler() { bool last = false; for (;;) { last = in; out = last; wait(); last = ~in; out = last; wait(); }}
A. Milenkovic 27
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 28
CTHREAD Processes
Instance of this process created and relevant clock edge assigned
SC_MODULE(onemethod) { sc_in_clk clock; sc_in<bool> trigger, in; sc_out<bool> out;
void toggler();
SC_CTOR(onemethod) {
SC_CTHREAD(toggler, clock.pos()); }
};
A. Milenkovic 29
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
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(); }}
A. Milenkovic 30
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 31
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 &SensitizeMethod
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 32
Watching
SC_THREAD and SC_CTHREAD processes typicallyhave 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 33
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 34
Local Watching
Allows us to specify exactly which section of the process is watching which signal, and where event handlers are locatedW_BEGIN// put the watching declarations herewatching(...);watching(...);W_DO// This is where the process functionality goes...W_ESCAPE// This is where the handlers // for the watched events goif (..) {...}W_END
A. Milenkovic 35
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 36
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 37
Integers, Floating-point, Fixed-point
Integer
Fixed-point
Floating-point
2
Decimal (“binary”) point
A. Milenkovic 38
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 39
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 40
Rounding
What happens when your result doesn’t land exactly on a representable number?
Rounding mode makes the choice
A. Milenkovic 41
SC_RND
Round up at 0.5 What you expect?
A. Milenkovic 42
SC_RND_ZERO
Round toward zero Less error accumulation
A. Milenkovic 43
SC_TRN
Truncate Easiest to implement
A. Milenkovic 44
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 45
SC_SAT
Saturate Sometimes desired
A. Milenkovic 46
SC_SAT_ZERO
Set to zero Odd behavior
A. Milenkovic 47
SC_WRAP
Wraparound
Easiest to implement
A. Milenkovic 48
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 49
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 50
Clocks
sc_clock clock1(“myclock”, 20, 0.5, 2, false);
20
2
0.5 of 20
Initial value is false
Time Zero
A. Milenkovic 51
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 52
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 53
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 54
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 55
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 56
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 57
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 58
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 59
Conclusions
C++ dialect for modeling digital systems Provides a simple form of concurrency
Cooperative multitasking
Modules Instances of other modules Processes
A. Milenkovic 60
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 61
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 62
An Example Process
// dff.h
#include "systemc.h"
SC_MODULE(dff) {
sc_in<bool> din; // data input
sc_in<bool> clock; // clock input
sc_out<bool> dout; // data output
void doit(); // 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;
}
};
// dff.cc
#include "dff.h"
void dff::doit() {
dout = din;
}
Determines how the process is called and executed
top related