ECEN 468 Advanced Logic Design - Computer...

Preview:

Citation preview

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

Recommended