ECEN 468 Advanced Logic Design - Computer...
Transcript of ECEN 468 Advanced Logic Design - Computer...
Lecture 9 : SystemC Dynamic Processes and Design Hierarchy
ECEN 468 Advanced Digital System Design
ECEN 468 Lecture 9
SC_HAS_PROCESS
If you want to use C/C++ constructor style instead of SC_CTOR, and the module has processeso Use “SC_HAS_PROCESS(module_name)” together with the
constructor
When do you need this?o The constructor needs arguments besides module nameo The constructor implementation needs to be placed in .cpp file instead
of within module declaration
ECEN 468 Lecture 9 2
Constructor with Multiple Arguments
ECEN 468 Lecture 9 3
//File: module_name.h
SC_MODULE(module_name) {SC_HAS_PROCESS(module_name);module_name(sc_module_name instname[, arg1…]) :
sc_module(instname) [, other_initializers] {//constructor body
}
};
Another Example of SC_HAS_PROCESS
ECEN 468 Lecture 9 4
//File: module_name.h
SC_MODULE(module_name) {module_name(sc_module_name instname[, arg1…]);
… …
};
//File: module_name.cpp
SC_HAS_PROCESS(module_name);module_name::module_name(sc_module_name instname[, arg1…])
: sc_module(instname) [, other_initializers] {//constructor body
}
};
Two Coding Styles
ECEN 468 Lecture 9 5
//File: *.h
SC_MODULE(mod_nm) {channel instances
submodule instances
SC_CTOR() {…}processes
};
//File: *.cpp
mod_nm::process() {
… …
}
//File: *.h
SC_MODULE(mod_nm) {channel instances
submodule instances
mod_nm();
processes
};
//File: *.cppSC_HAS_PROCESS(mod_nm);mod_nm::mod_nm() {
constructor }mod_nm::process() {… …}
More flexible
Separation
SystemC Time Resolution
All objects of sc_time use a global time resolutionDefault 1 picosecond
ECEN 468 Lecture 9 6
sc_time sc_get_time_resolution();sc_set_time_resolution(double, sc_time_unit);//Change only once
//before creating objects of sc_time and simulation
Dynamic vs. Static Processes
Static processeso SC_THREAD and SC_METHODo Established in the elaboration phase
Need for dynamic processeso Design verification
Chapter 7, “SystemC: From the Ground Up”
ECEN 468 Lecture 9 7
sc_spawn
Use a pre-processor macroo #define SC_INCLUDE_DYNAMIC_PROCESSES
Or, compile with optiono -DSC_INCLUDE_DYNAMIC_PROCESSES
Spawned processo Either a module member function or a global functiono May have up to 8 arguments and a return valueo Thread process by default
Invoke spawned process using sc_spawn and sc_bind
ECEN 468 Lecture 9 8
Example of sc_spawn
ECEN 468 Lecture 9 9
class imodule: public sc_module {
public: sc_signal clock_sig;
SC_HAS_PROCESS(imodule); imodule(sc_module_name nm):sc_module(nm) { SC_THREAD(run); }void spawned_th(bool value) {
cout << "spawned with value: " << value << endl; } void run() {
sc_spawn( sc_bind(&imodule::spawned_th, this, true) ); while(true) {
clock_sig.write(SC_LOGIC_0); wait(10, SC_NS); clock_sig.write(SC_LOGIC_1); wait(10, SC_NS); }
}
};
Another Example of sc_spawn
ECEN 468 Lecture 9 10
int global_th(const bool& din, int& dout) { cout << "spawned: " << din << ", " << dout << endl; if (din) { dout++; return 0; } else return 1; }
class imodule: public sc_module {
public: sc_signal clock_sig;
SC_HAS_PROCESS(imodule); imodule(sc_module_name nm):sc_module(nm) { SC_THREAD(run); } void run() { int return_v, int_arg = 9; bool bool_arg = true;
sc_spawn( &return_v, sc_bind(&global_th,sc_cref(bool_arg), sc_ref(int_arg) ) );
while(true) { clock_sig.write(0); wait(10, SC_NS);clock_sig.write(1); wait(10, SC_NS); }
}
}; //By default, arguments are passed by value
Handle of Spawned Process
sc_spawn() returns a handle of the spawned process It can monitor the termination of the process
ECEN 468 Lecture 9 11
sc_process_handle h = sc_spawn(sc_bind(&spawned_thread));… …
wait(h.terminated_event());
Process Control Method
ECEN 468 Lecture 9 12
void sc_process_handle::suspend();void sc_process_handle::resume();
//Ignore sensitivity while disabled
void sc_process_handle::disable();void sc_process_handle::enable();
void sc_process_handle::kill();
//Asynchronously restart a process
void sc_process_handle::reset();… …
SC_FORK and SC_JOIN
ECEN 468 Lecture 9 13
DataStream d1, d2;SC_FORKsc_spawn( sc_bind(&dut::AXI_xmt, this, sc_ref(d1)), “p1” )
, sc_spawn( sc_bind(&dut::PCI_rcv, this, sc_ref(d1)), “p2” ), sc_spawn( sc_bind(&dut::USB2, this, sc_ref(d1)), “p3” ), sc_spawn( sc_bind(&dut::HT1_xmt, this, sc_ref(d2)), “p4” ), sc_spawn( sc_bind(&dut::HT2_rcv, this, sc_ref(d2)), “p5” )SC_JOIN
p1
p3
p4
p2
p5
AXI
USB2
HT1
DUTPCI
HT2
Process name
Another Example of SC_FORK and SC_JOIN
ECEN 468 Lecture 9 14
SC_MODULE(Fork) {sc_fifo<double> wheel_L, wheel_R;SC_CTOR(Fork) { … }void fork_thread();bool road_thread(sc_fifo<double>& which);
void Fork::fork_thread() { bool l_up, r_up;
SC_FORKsc_spawn(&l_up, sc_bind(&Fork::road_thread, this, sc_ref(wheel_L)), “lf”), sc_spawn(&r_up, sc_bind(&Fork::road_thread, this, sc_ref(wheel_R)), “rt”)
SC_JOIN}
Process name
Design Hierarchy
ECEN 468 Lecture 9 15
sc_maincar_i
engine_ifuelmix_i
exhaust_i
cylinder_i
body_iwheel_left
wheel_right
Chapter 10, “SystemC: From the Ground Up”
How To Instantiate Submodule?
Direct top-level (sc_main) Indirect top-level Direct submodule header-only Direct submodule Indirect submodule header-only Indirect submodule
ECEN 468 Lecture 9 16
Direct Top-Level
ECEN 468 Lecture 9 17
// File: main.cpp
#include <systemc>
#include “Car.h”
int sc_main(int argc, char* argv[]) {Car car_i(“car_i”);
sc_start();return 0;
}
Indirect Top-Level
ECEN 468 Lecture 9 18
// File: main.cpp
#include <systemc>
#include “Car.h”
int sc_main(int argc, char* argv[]) {Car* car_iptr; //Pointer to Car
car_iptr = new Car(“car_i”);
sc_start();delete car_iptr;
return 0;
}
Direct Submodule Header-Only
ECEN 468 Lecture 9 19
// File: Car.h
#include “Body.h”
#include “Engine.h”
SC_MODULE(Car) {Body body_i;
Engine engine_i;
SC_CTOR(Car) : body_i(“body_i”) //initialization, engine_i(“engine_i”) {
… …
}
};
Direct Submodule
ECEN 468 Lecture 9 20
// File: Car.h
#include “Body.h”
#include “Engine.h”
SC_MODULE(Car) {Body body_i;
Engine engine_i;
Car(sc_module_name nm);
};
// File: Car.cpp
#include <systemc>
#include “Car.h”
//Constructor
SC_HAS_PROCESS(Car);Car::Car(sc_module_name nm) :
sc_module(nm), body_i(“body_i”)
, engine_i(“engine_i”) {
… …
}
Indirect Submodule Header-Only
ECEN 468 Lecture 9 21
// File: Body.h
#include “Wheel.h”
SC_MODULE(Body) {Wheel* wheel_left_iptr;
Wheel* wheel_right_iptr;;
SC_CTOR(Body) {wheel_left_iptr = new Wheel(“wheel_left_i”);
wheel_right_iptr = new Wheel(“wheel_right_i”);
… …
}
};
Indirect Submodule
ECEN 468 Lecture 9 22
// File: Engine.h
class FuelMix;
class Exhaust;
class Cylinder;
SC_MODULE(Engin) {FuelMix* fuelmix_ip;
Exhaust* exhaust_ip;
Cylinder* cylinder_ip;
Engine(
sc_module_name nm);
};
// File: Engin.cpp#include <systemc>#include “FuelMix.h”#include “Exhaust.h”#include “Cylinder.h”SC_HAS_PROCESS(Engine);Car::Car(sc_module_name nm) :sc_module(nm) {fuelmix_ip=new FuelMix(“Fi”);exhaust_ip=new Exhaust(“Ei”);cylinder_ip =
new Cylinder(“Ci”);… …
}
Comparison
Level Allocation Pros ConsMain Direct Least code
Main Indirect Dynamically configurable Involves pointers
Module Direct header only All in one file, easier to understand
Module Indirect header only All in one file, dynamically configurable
Involves pointers
Module Direct with separate compilation
Hides implementation
Module Indirect with separate compilation
Hides submodule headers and implementation, dynamically configurable
Involve pointers
ECEN 468 Lecture 9 23