48
ipblock design in GEZEL Patrick Schaumont Virginia Tech Dept. of Electrical and Computer Engineering September 2010

ipblock design in GEZEL

  • Upload
    chavi

  • View
    42

  • Download
    0

Embed Size (px)

DESCRIPTION

ipblock design in GEZEL. Patrick Schaumont Virginia Tech Dept. of Electrical and Computer Engineering September 2010. What are ipblock?. An ipblock is a black-box simulation entity for GEZEL. Name. Interface. ipblock M(in address : ns(5); in wr,rd   : ns(1); - PowerPoint PPT Presentation

Citation preview

Page 1: ipblock design in GEZEL

ipblock design in GEZEL

Patrick Schaumont

Virginia TechDept. of Electrical and Computer Engineering

September 2010

Page 2: ipblock design in GEZEL

2

What are ipblock?

• An ipblock is a black-box simulation entity for GEZEL

ipblock M(in address : ns(5); in wr,rd   : ns(1); in idata   : ns(8); out odata   : ns(8)) { iptype "ram"; ipparm "wl=8"; ipparm "size=32"; }

InterfaceName

Type

Parameters

Page 3: ipblock design in GEZEL

3

Applications of ipblock

• Capture functionality not available as FSMD• FSMD does not exist: memory modules• FSMD unavailable: IP, complex modules, ..

• Interfaces to other simulation engines• Instruction-set simulators: ARM, 8051• Other languages/environments: SystemC,...

• Extensions of GEZEL simulation capabilities• Collect signal statistics• Debug facility

Page 4: ipblock design in GEZEL

4

Who develops ipblock?

GEZEL Designers GEZEL Users

ipblock

with generic use design-specific

Page 5: ipblock design in GEZEL

5

How are ipblock implemented?

aipblock

ipblock

GEZEL class lib(data types,

symbol table, ...)C++

ld.sofdlsim/gplatform

dynamic-link librarystatically linked

EXE

Page 6: ipblock design in GEZEL

6

Operational Principle

• ipblock are cycle-based simulation models• A cycle-based simulation has two phases

per cycle: evaluate and (state) update

R1 R2 R3logic L1 logic L2

Page 7: ipblock design in GEZEL

7

Operational Principle

• ipblock are cycle-based simulation models• A cycle-based simulation has two phases

per cycle: evaluate and (state) update

R1

R2

R3

logic L1

logic L2

R1

R2

R3

Cycle N Cycle N + 1

Evaluate: next_R1 = ... next_R2 = Logic_L1(R1); next_R3 = Logic_L2(R2);

Update: R1 = next_R1; R2 = next_R2; R3 = next_R3;

Page 8: ipblock design in GEZEL

8

Operational Principle

• ipblock are cycle-based simulation models• A cycle-based simulation has two phases

per cycle: evaluate and (state) update• Evaluate and update can be called only once

per cycle

R1 R3logic L1 logic L2

GEZEL ensures that all Evaluate( ) are properly sorted:Logic_L1(R1) will be called BEFORE Logic L2(L1_output)

Page 9: ipblock design in GEZEL

9

Operational Principle

• ipblock are cycle-based simulation models• A cycle-based simulation has two phases

per cycle: evaluate and (state) update• Evaluate and update are called only once

per cycle

logic L1 logic L1 logic L2

If the execution order for Evaluate( ) cannot be determined,the simulator terminates ('combinatorial loop')

Page 10: ipblock design in GEZEL

10

Combinational ipblock

• By default, have a single evaluate function, called once per clock cycle

ipblock

ipblockipblock

fsmd

OK

Not OK

Page 11: ipblock design in GEZEL

11

Simple ipblock: combinational

ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock";}

GEZEL

C++

void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}

class myblock : public aipblock { public: void run();};

+

Page 12: ipblock design in GEZEL

12

Simple ipblock: combinational

ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock";}

GEZEL

C++

void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}

class myblock : public aipblock { public: void run();};

ioval[0]

ioval[1]

ioval[2]

a

b

c

Page 13: ipblock design in GEZEL

13

Simple ipblock: combinational

ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock";}

GEZEL

C++

void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}

class myblock : public aipblock { public: void run();};

• run() is called once per clock cycle• When called, input ioval[ ] reflects proper value

for that clock cycle• When called, output ioval[ ] must be assigned

proper value for that clock cycle

Page 14: ipblock design in GEZEL

14

Adding parameters

ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval";}

GEZEL

C++

void myblock::run() { ioval[2]->assignulong(ioval[0]->toulong() + ioval[1]->toulong());}

void myblock::setparam(char *n) { // ...}

class myblock : public aipblock { public: void run(); void setparam(char *);};

call constructor

for each 'ipparm'call setparam

for each cyclecall run

Page 15: ipblock design in GEZEL

15

Terminal-check function

ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval";}

GEZEL

C++

class myblock : public aipblock { public: void run(); void setparam(char *); bool checkterminal(int n, char *tname, iodir d);};

bool myblock::checkterminal(int n, char *tname, iodir d) { switch(n) { case 0 : return (isinput(d) && isname(tname, "a")); break; ... } return false;}

• ipblock use positional port matching• checkterminal verifies that ioval[0] is

an input name "a", ioval[1] is input "b", ...

Page 16: ipblock design in GEZEL

16

Terminal-check function

ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval";}

GEZEL

C++

class myblock : public aipblock { public: void run(); void setparam(char *); void checkterminal(..);};

call constructor

for each 'ipparm'call setparam

for each cyclecall run

for each i/o portcall checkterminal

Page 17: ipblock design in GEZEL

17

Completing the C++

#ifndef myblock_h#define myblock_h

#include "ipblock.h"

extern "C" aipblock *create_myblock(char *instname);

class myblock : public aipblock {

public: myblock(char *name); void setparm(char *); void run(); bool checkterminal(int n, char *tname, aipblock::iodir d); bool cannotSleepTest(); bool needsWakeupTest();};

#endif

myblock.h

Access to GEZEL library functions(aipblock definition, arbitrary-precision data types, ..)

Called by the dynamic-link facility,Function name depends on class name!

simulator control(see part 2)

Page 18: ipblock design in GEZEL

18

Completing the C++

myblock.cxx

#include "myblock.h"

extern "C" aipblock *create_myblock(char *instname) { return new myblock(instname);}

myblock::myblock(char *name) : aipblock(name) {..}

void myblock::setparm(char *_name) {..}

void myblock::run() {..}bool myblock::checkterminal(..) {..}

bool myblock::cannotSleepTest(){ return false;}

bool myblock::needsWakeupTest(){ return true;}

Default implementationfor combinational modules

Called by dynamic-link facility

Page 19: ipblock design in GEZEL

19

Compilation-Simulation Example

g++ -fPIC -O3 -I/opt/gezel-2.2/include/gezel -c myblock.cxx

g++ -shared -O3 \ -Wl,--rpath -Wl,/home/schaum/gezel/devel/build/lib \ myblock.o \ /opt/gezel-2.2/lib/libipconfig.so \ /opt/gezel-2.2/lib/libfdl.so \ -lgmp -ldl -o libmyblock.so

Compile:

Create dynamic-link library

Page 20: ipblock design in GEZEL

20

Compilation-Simulation Example

g++ -fPIC -O3 -I/opt/gezel-2.2/include/gezel -c myblock.cxx

g++ -shared -O3 \ -Wl,--rpath -Wl,/home/schaum/gezel/devel/build/lib \ myblock.o \ /opt/gezel-2.2/lib/libipconfig.so \ /opt/gezel-2.2/lib/libfdl.so \ -lgmp -ldl -o libmyblock.so

Compile:

Create dynamic-link library

position-independent code

.so library

path to gezel lib

gezel lib and predefined ipblocks

arbitrary precisionmath lib

dynamic link lib

Page 21: ipblock design in GEZEL

21

GEZEL File

ipblock ablock(in a, b : ns(8); out c : ns(8)) { iptype "myblock"; ipparm "thisparam=thatval";}

dp top { sig a, b, c : ns(8); reg a1 : ns(8); use ablock(a, b, c); always { a = a1; b = 2; $display("a ", a, " b ", b, " c ",c); a1 = a1 + 1; }}

system S { top;}

Page 22: ipblock design in GEZEL

22

Simulation

> /opt/gezel-2.2/bin/fdlsim ipb.fdl 5

set parm: thisparam=thatvala 0 b 2 c 2a 1 b 2 c 3a 2 b 2 c 4a 3 b 2 c 5a 4 b 2 c 6

1. parse ipb.fdl2. instantiate ipblock 2.1. link dynamic-link lib3. simulate 5 cycles

output:

define all FSM next-state

evaluate output of each dp

call ipblock with no output

update dp registers

Per clock cycle:

Page 23: ipblock design in GEZEL

23

Summary

#ifndef myblock_h#define myblock_h

#include "ipblock.h"

class myblock : public aipblock {

public: myblock(char *name); void setparm(char *); void run(); bool checkterminal(int n, char *tname, aipblock::iodir d); bool cannotSleepTest(); bool needsWakeupTest();};

#endif

Page 24: ipblock design in GEZEL

24

Sleep Cycle Mechanism

#ifndef myblock_h#define myblock_h

#include "ipblock.h"

class myblock : public aipblock {

public: myblock(char *name); void setparm(char *); void run(); bool checkterminal(int n, char *tname, aipblock::iodir d); bool cannotSleepTest(); bool needsWakeupTest();};

#endif

Page 25: ipblock design in GEZEL

25

Sleep Cycle Mechanism

Software(typ 1Mc/s)

Hardware(typ 10K/s)

100K cycles

100 cycles

100 cycles

100K cycles

100K cycles

Page 26: ipblock design in GEZEL

26

Sleep Cycle Mechanism

Software(typ 1Mc/s)

Hardware(typ 10K/s)

100K cycles

100 cycles

100 cycles

100K cycles

100K cycles

Without sleep-cycle:300,200 cycles @ 10K/s

=30.02 seconds

Page 27: ipblock design in GEZEL

27

Sleep Cycle Mechanism

Software(typ 1Mc/s)

Hardware(typ 10K/s)

100K cycles

100 cycles

100 cycles

100K cycles

100K cycles

With sleep-cycle:300K cycles @ 1M/s +

300K cycles (testing_overhead) +200 cycles @ 10K/s

=less than 0.5 seconds!

Page 28: ipblock design in GEZEL

28

Sleep Cycle Mechanism

• GEZEL simulator has two states:• Active:

– each clock cycle, evaluate all datapath outputs (and dependent signals), evaluate all registers, evaluate all ipblock

– perform sleep test

• Passive:– perform wakeup test

Page 29: ipblock design in GEZEL

29

Sleep Cycle Mechanism

• Transition from active to passive

Active

Passive

sleep_test = false

sleep_test = truewakeup_test = true

wakeup_test = false

Page 30: ipblock design in GEZEL

30

Sleep Test

• Sleep test evaluates to false in cycle X if:• Any register changes state during a clock X• Any FSM changes state during clock cycle X• Any ipblock returns true in

aipblock::cannotSleepTest()

• GEZEL simulator will call cannotSleepTest () once per cycle in active mode, default value should be false

• (why is my GEZEL cosimulation so slow?Might be because there is remaining HW activity in idle phases)

Page 31: ipblock design in GEZEL

31

Wakeup Test

• Wakeup test evaluates to true in cycle X if:• Any ipblock returns true in

aipblock::needsWakeupTest()

• GEZEL simulator will call needsWakeupTest () once per cycle in passive mode, default value should be false

• If needsWakeupTest() never returns false, your simulation will never sleep (may be the cause of a slow cosimulation)

• If needsWakeupTest() never returns true, your simulation will never wakeup (may be the cause of a ‘halted’ cosimulation)

Page 32: ipblock design in GEZEL

32

Example: 8051 cosimulation interface

8051 4 bi-directional ports

Three GEZEL ipblock:

ipblock my8051 { iptype "i8051system"; ipparm "exec=driver.ihx"; ipparm "verbose=1"; ipparm "period=1";}

ipblock my8051_datain(out data : ns(8)) { iptype "i8051systemsource"; ipparm "core=my8051"; ipparm "port=P1";}

ipblock my8051_dataout(in data : ns(8)) { iptype "i8051systemsink"; ipparm "core=my8051"; ipparm "port=P2";}

Core

Input port

Output port

Page 33: ipblock design in GEZEL

33

The Core

void i8051system::run() { if (sim.IsRunning()) { period_cnt--; if (period_cnt == 0) { period_cnt = period; sim.ClockTick(); if (! sim.IsRunning())

glbRunningISS--; } }}

bool i8051system::cannotSleepTest() { return false; // the ISS will continue to run in sleep mode // so we can also return 'OK to sleep'}

bool i8051system::needsWakeupTest() { run(); return false;}

Page 34: ipblock design in GEZEL

34

The Input Port

void i8051systemsink::run() { if (hook) { hook->writeRAM(address, ioval[0]->toulong()); }}

bool i8051systemsink::cannotSleepTest() { return false;}

(If you do not specify needsWakeupTest(), default implementation is used, which returns false)

Page 35: ipblock design in GEZEL

35

The Output Port

void i8051systemsource::run() {}

Obviously, it is the 8051 simulator that decides what the value of the output port should be. The 8051 simulator calls a functionexternalwrite(address, data) each time is performs a port write

Page 36: ipblock design in GEZEL

36

The Output Port

void i8051systemsource::run() {}

Obviously, it is the 8051 simulator that decides what the value of the output port should be. The 8051 simulator calls a functionexternalwrite(address, data) each time is performs a port write

void i8051externalwrite(int dev, unsigned char d) { i8051devmap[dev]->ioval[0]->assignulong((long) d); i8051devmap[dev]->touch();}

I8051devmap is an array of output port ipblocks that are

implemented by GEZEL

The result of the externalwrite( ) is that an ipblock output is updated

Page 37: ipblock design in GEZEL

37

The Output Port

void i8051systemsource::run() {}

bool i8051systemsource::needsWakeupTest() { bool v = interfacewritten; interfacewritten = false; return v;}

bool i8051systemsource::cannotSleepTest() { bool v = interfacewritten; interfacewritten = false; return v;}

void i8051systemsource::touch() { interfacewritten = true;}

void i8051externalwrite(int dev, unsigned char d) { i8051devmap[dev]->ioval[0]->assignulong((long) d); i8051devmap[dev]->touch();}

As a result ofthe 8051 WRITING

to the hardware,the cycle-simulation

will wake-up

Page 38: ipblock design in GEZEL

38

Review: One C++ class

#ifndef myblock_h#define myblock_h

#include "ipblock.h"

class myblock : public aipblock {

public: myblock(char *name); void setparm(char *); void run(); bool checkterminal(int n, char *tname, aipblock::iodir d); bool cannotSleepTest(); bool needsWakeupTest();};

#endif

OK!

Page 39: ipblock design in GEZEL

39

Ipblock are combinational

• By default, have a single evaluate function, run( ), called once per clock cycle

ipblock

ipblockipblock

fsmd

OK

Not OK

Page 40: ipblock design in GEZEL

40

Support for sequential IP block

• Define sequential IP block:

a sequential ipblock is an ipblock with an output which is is known and stable at the start of a clock cycle.

• Thus, ‘sequential’ is a property of an output, not an entire ipblock

Page 41: ipblock design in GEZEL

41

Support for Sequential IPblock

• For example, assume you develop a C++ class for this structure:

ipblock

CombFunction

Sequential output

Combinational output

Page 42: ipblock design in GEZEL

42

Support for Sequential IP block

• This will simulate fine !

ipblock

CombFunction

CombFunction

0

Page 43: ipblock design in GEZEL

43

Sequential IP Block in C++

#ifndef myblock_h#define myblock_h

#include "ipblock.h"

class myblock : public aipblock {

public: myblock(char *name); void setparm(char *); void run(); bool checkterminal(int n, char *tname, aipblock::iodir d); bool cannotSleepTest(); bool needsWakeupTest(); void regOutput(); void out_run();};

#endif

Page 44: ipblock design in GEZEL

44

regOutput

• Used in constructor to define an ipblock output as sequential

armsfu2x1::armsfu2x1(char *name) : aipblock(name) { deviceid = 0; hook = 0; myarm = 0; interfacewritten = false; regOutput(0); // d1 and d2 are registered regOutput(1);}

// ipblock mysfu(out d1 : ns(32); out d2 : ns(32);// in q1 : ns(32); in q2 : ns(32)) {// iptype "armsfu2x2";// ipparm "core = mycore"; -- core to hook into// ipparm "device = 0"; -- 2 possible devices per sfu type// }

Page 45: ipblock design in GEZEL

45

regOutput

• Used in constructor to define an ipblock output as sequential

// ipblock mysfu(out d1 : ns(32); out d2 : ns(32);// in q1 : ns(32); in q2 : ns(32)) {// iptype "armsfu2x2";// ipparm "core = mycore"; -- core to hook into// ipparm "device = 0"; -- 2 possible devices per sfu type// }

armsfu2x2Custom

Datapath(combinational)

d1d2

q1q2

OK!

Stable at the start of a clock cycle

Page 46: ipblock design in GEZEL

46

out_run( )

• out_run( ) is called at the start of the clock cycle, before any other run( ) is called, and before any signal or register is evaluated.

• Typically, out_run( ) is used to initialize regOutput outputs to a stable value for that clock cycle.

Page 47: ipblock design in GEZEL

47

Example: accumulator ipblock

ipblock

add

ipblock acc(in d : ns(8); out q : ns(8)) { iptype “accumulator”;}

myacc::myacc(char *name) : aipblock(name) { regOutput(0); accvalue = 0;}

myacc::out_run() { ioval[0]->assignulong(accvalue);}

myacc::run() { accvalue = accvalue + ioval[1]->toulong();}

Page 48: ipblock design in GEZEL

48

Final hints

• ipblock are a powerful extension mechanism for GEZEL• Puts a designer in control of design

environment• Allows to put hardware design in context

• Other neat tool: icg (incremental code generator)• Generates ipblock C++ out of GEZEL code• Useful to speed up simulation (3X – 10X faster)• Useful to compile HW to SW

nice open research problems left here