Ipblock design in gezel
This presentation is the property of its rightful owner.
Sponsored Links
1 / 48

ipblock design in GEZEL PowerPoint PPT Presentation


  • 104 Views
  • Uploaded on
  • Presentation posted in: General

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);

Download Presentation

ipblock design in GEZEL

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Ipblock design in gezel

ipblock design in GEZEL

Patrick Schaumont

Virginia Tech

Dept. of Electrical and Computer Engineering

September 2010


What are ipblock

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);

in idata   : ns(8);

out odata   : ns(8)) {

iptype "ram";

ipparm "wl=8";

ipparm "size=32";

}

Type

Parameters


Applications of ipblock

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


Who develops ipblock

Who develops ipblock?

GEZEL Designers

GEZEL Users

ipblock

with generic use

design-specific


How are ipblock implemented

How are ipblock implemented?

aipblock

GEZEL class lib

(data types,

symbol table, ...)

C++

ipblock

statically linked

dynamic-link library

ld.so

EXE

fdlsim/gplatform


Operational principle

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


Operational principle1

Operational Principle

  • ipblock are cycle-based simulation models

  • A cycle-based simulation has two phases per cycle: evaluate and (state) update

R1

R1

logic L1

Evaluate:

next_R1 = ...

next_R2 = Logic_L1(R1);

next_R3 = Logic_L2(R2);

Update:

R1 = next_R1;

R2 = next_R2;

R3 = next_R3;

R2

R2

logic L2

R3

R3

Cycle N + 1

Cycle N


Operational principle2

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

R3

logic L1

logic L2

GEZEL ensures that all Evaluate( ) are properly sorted:

Logic_L1(R1) will be called BEFORE Logic L2(L1_output)


Operational principle3

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')


Combinational ipblock

Combinational ipblock

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

fsmd

OK

ipblock

Not OK

ipblock

ipblock


Simple ipblock combinational

Simple ipblock: combinational

GEZEL

ipblock ablock(in a, b : ns(8); out c : ns(8)) {

iptype "myblock";

}

C++

class myblock : public aipblock {

public:

void run();

};

void myblock::run() {

ioval[2]->assignulong(ioval[0]->toulong() +

ioval[1]->toulong());

}

+


Simple ipblock combinational1

Simple ipblock: combinational

GEZEL

ipblock ablock(in a, b : ns(8); out c : ns(8)) {

iptype "myblock";

}

a

ioval[0]

C++

b

ioval[1]

c

ioval[2]

class myblock : public aipblock {

public:

void run();

};

void myblock::run() {

ioval[2]->assignulong(ioval[0]->toulong() +

ioval[1]->toulong());

}


Simple ipblock combinational2

Simple ipblock: combinational

GEZEL

ipblock ablock(in a, b : ns(8); out c : ns(8)) {

iptype "myblock";

}

C++

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

void myblock::run() {

ioval[2]->assignulong(ioval[0]->toulong() +

ioval[1]->toulong());

}


Adding parameters

Adding parameters

GEZEL

ipblock ablock(in a, b : ns(8); out c : ns(8)) {

iptype "myblock";

ipparm "thisparam=thatval";

}

C++

class myblock : public aipblock {

public:

void run();

void setparam(char *);

};

call constructor

for each 'ipparm'

call setparam

void myblock::run() {

ioval[2]->assignulong(ioval[0]->toulong() +

ioval[1]->toulong());

}

void myblock::setparam(char *n) {

// ...

}

for each cycle

call run


Terminal check function

Terminal-check function

GEZEL

ipblock ablock(in a, b : ns(8); out c : ns(8)) {

iptype "myblock";

ipparm "thisparam=thatval";

}

  • ipblock use positional port matching

  • checkterminal verifies that ioval[0] is an input name "a", ioval[1] is input "b", ...

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;

}


Terminal check function1

Terminal-check function

GEZEL

ipblock ablock(in a, b : ns(8); out c : ns(8)) {

iptype "myblock";

ipparm "thisparam=thatval";

}

call constructor

C++

class myblock : public aipblock {

public:

void run();

void setparam(char *);

void checkterminal(..);

};

for each 'ipparm'

call setparam

for each i/o port

call checkterminal

for each cycle

call run


Completing the c

Completing the C++

myblock.h

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

#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

Called by the dynamic-link facility,

Function name depends on class name!

simulator control

(see part 2)


Completing the c1

Completing the C++

myblock.cxx

Called by dynamic-link facility

#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 implementation

for combinational modules


Compilation simulation example

Compilation-Simulation Example

Compile:

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

Create dynamic-link library


Compilation simulation example1

Compilation-Simulation Example

position-independent code

Compile:

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

.so library

Create dynamic-link library

path to gezel lib

gezel lib and predefined ipblocks

arbitrary precision

math lib

dynamic link lib


Gezel file

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;

}


Simulation

Simulation

1. parse ipb.fdl

2. instantiate ipblock

2.1. link dynamic-link lib

3. simulate 5 cycles

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

set parm: thisparam=thatval

a 0 b 2 c 2

a 1 b 2 c 3

a 2 b 2 c 4

a 3 b 2 c 5

a 4 b 2 c 6

Per clock cycle:

output:

define all FSM next-state

evaluate output of each dp

call ipblock with no output

update dp registers


Summary

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


Sleep cycle mechanism

Sleep Cycle Mechanism

#ifndefmyblock_h

#define myblock_h

#include "ipblock.h"

classmyblock : publicaipblock {

public:

myblock(char *name);

voidsetparm(char *);

void run();

boolcheckterminal(int n, char *tname, aipblock::iodir d);

boolcannotSleepTest();

boolneedsWakeupTest();

};

#endif


Sleep cycle mechanism1

Sleep Cycle Mechanism

Software

(typ 1Mc/s)

Hardware

(typ 10K/s)

100K cycles

100 cycles

100K cycles

100 cycles

100K cycles


Sleep cycle mechanism2

Sleep Cycle Mechanism

Software

(typ 1Mc/s)

Hardware

(typ 10K/s)

100K cycles

100 cycles

100K cycles

100 cycles

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

=

30.02 seconds

100K cycles


Sleep cycle mechanism3

Sleep Cycle Mechanism

Software

(typ 1Mc/s)

Hardware

(typ 10K/s)

100K cycles

100 cycles

100K cycles

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

200 cycles @ 10K/s

=

less than 0.5 seconds!

100 cycles

100K cycles


Sleep cycle mechanism4

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


Sleep cycle mechanism5

Sleep Cycle Mechanism

  • Transition from active to passive

sleep_test = false

Active

sleep_test = true

wakeup_test = true

Passive

wakeup_test = false


Sleep test

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)


Wakeup test

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)


Example 8051 cosimulation interface

Example: 8051 cosimulation interface

8051

4 bi-directional ports

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

Three GEZEL ipblock:

Input port

Output port


The core

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;

}


The input port

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)


The output port

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


The output port1

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


The output port2

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;

}

As a result ofthe 8051 WRITING

to the hardware,the cycle-simulation

will wake-up

void i8051externalwrite(int dev, unsigned char d) {

i8051devmap[dev]->ioval[0]->assignulong((long) d);

i8051devmap[dev]->touch();

}


Review one c class

Review: One C++ class

#ifndefmyblock_h

#define myblock_h

#include "ipblock.h"

classmyblock : publicaipblock {

public:

myblock(char *name);

voidsetparm(char *);

void run();

boolcheckterminal(int n, char *tname, aipblock::iodir d);

boolcannotSleepTest();

boolneedsWakeupTest();

};

#endif

OK!


Ipblock are combinational

Ipblock are combinational

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

fsmd

OK

ipblock

Not OK

ipblock

ipblock


Support for sequential ip block

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


Support for sequential ipblock

Support for Sequential IPblock

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

ipblock

Sequential output

Comb

Function

Combinational output


Support for sequential ip block1

Support for Sequential IP block

  • This will simulate fine !

ipblock

Comb

Function

Comb

Function

0


Sequential ip block in c

Sequential IP Block in C++

#ifndefmyblock_h

#define myblock_h

#include "ipblock.h"

classmyblock : publicaipblock {

public:

myblock(char *name);

voidsetparm(char *);

void run();

boolcheckterminal(int n, char *tname, aipblock::iodir d);

boolcannotSleepTest();

boolneedsWakeupTest();

voidregOutput();voidout_run();

};

#endif


Regoutput

regOutput

  • Used in constructor to define an ipblock output as sequential

// ipblockmysfu(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

// }

armsfu2x1::armsfu2x1(char *name) : aipblock(name) {

deviceid = 0;

hook = 0;

myarm = 0;

interfacewritten = false;

regOutput(0); // d1 and d2 are registered

regOutput(1);

}


Regoutput1

regOutput

  • Used in constructor to define an ipblock output as sequential

// ipblockmysfu(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

// }

Stable at the start of a clock cycle

d1

d2

Custom

Datapath(combinational)

OK!

armsfu2x2

q1

q2


Out run

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.


Example accumulator ipblock

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();}


Final hints

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


  • Login