Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: AvailableMemory mbed-rtos mbed
Fork of helloaabbc by
SDF.h
- Committer:
- mbed36372
- Date:
- 2014-04-04
- Revision:
- 1:55e99f6e2aa5
- Parent:
- 0:1c8f2727e9f5
File content as of revision 1:55e99f6e2aa5:
#ifndef _SDF_H
#define _SDF_H
#include "mbed.h"
#include "RationalNum.h"
#include "RingBuffer.h"
#include "Parser.h"
#include <queue>
#include <vector>
using namespace std;
enum NodeType {I, O, A, S, M, D, U, C, F};
class FIFO;
/*base class for all kinds of node in SDF*/
class SDFNode{
protected:
int id;
NodeType type;
public:
virtual int getId()const=0;
virtual NodeType getType()const=0;
virtual void execute()=0;
virtual void display()const=0;
};
/*input node*/
class INode : public SDFNode{
private:
/*input data, inode reads data from a ring buffer*/
RingBuffer *input;
/*edges (fifos) going outward from this node*/
vector<FIFO*> outbounds;
public:
INode(int k=-1,RingBuffer *in=NULL){id=k;input=in;type=I;}
~INode(){input=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
virtual void execute();
virtual void display()const;
void setInput(RingBuffer *buf);
void addOutbound(FIFO* fifo){outbounds.push_back(fifo);}
};
/*output node*/
class ONode : public SDFNode{
private:
/*edge coming into this node*/
FIFO *inbound;
/*ring buffer where to write output*/
RingBuffer *output;
/*checksum of all output samples*/
int checksum;
public:
ONode(int k=-1,RingBuffer *out=NULL):checksum(0){id=k;output=out;type=O;}
~ONode(){inbound=NULL;output=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
virtual void execute();
virtual void display()const;
virtual void setInbound(FIFO* fifo){inbound=fifo;}
void setOutput(RingBuffer *buf);
int getChecksum()const{return checksum;}
};
class ANode : public SDFNode{
private:
/*two edges coming into this node, representing the two operands in an addition: op1+op2*/
FIFO *op1, *op2;
/*edges going outward from this node*/
vector<FIFO*> outbounds;
public:
ANode(int k=-1){id=k;type=A;}
~ANode(){op1=op2=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
virtual void execute();
virtual void display()const;
void addOutbound(FIFO* fifo){outbounds.push_back(fifo);}
void setInbound(FIFO *in1, FIFO *in2){op1=in1;op2=in2;}
};
class SNode : public SDFNode{
private:
/*two edges coming into this node, representing the two operands in an subtraction: op1-op2*/
FIFO *op1, *op2;
/*edges going outward from this node*/
vector<FIFO*> outbounds;
public:
SNode(int k=-1){id=k;type=S;}
~SNode(){op1=op2=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
virtual void execute();
virtual void display()const;
void addOutbound(FIFO *fifo){outbounds.push_back(fifo);}
void setInbound(FIFO *in1, FIFO *in2){op1=in1; op2=in2;}
};
class MNode : public SDFNode{
private:
/*edge providing input data for this node*/
FIFO *inbound;
/*coefficients needed by the multiplier: as specified in the document, op*c/d */
int c,d;
/*edges going outward from this node*/
vector<FIFO*> outbounds;
public:
MNode(int k=-1, int i=1, int j=1){id=k;c=i;d=j;type=M;}
~MNode(){inbound=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
virtual void execute();
virtual void display()const;
void setInbound(FIFO *fifo){inbound=fifo;}
void addOutbound(FIFO *fifo){outbounds.push_back(fifo);}
};
class DNode : public SDFNode{
private:
/*number of samples to read at a time from input edge*/
int numOfSamples;
/*edge providing input to this node*/
FIFO *inbound;
/*edges going outward from this node*/
vector<FIFO*> outbounds;
public:
DNode(int k=-1, int n=0){id=k;numOfSamples=n;type=D;}
~DNode(){inbound=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
int getNumOfSamples()const{return numOfSamples;}
virtual void execute();
virtual void display()const;
void setInbound(FIFO *fifo){inbound=fifo;}
void addOutbound(FIFO *fifo){outbounds.push_back(fifo);}
};
class UNode : public SDFNode{
private:
/*number of samples to duplicate*/
int numOfCopies;
/*edge providing input to this node*/
FIFO *inbound;
/*edges going outward from this node*/
vector<FIFO*> outbounds;
public:
UNode(int k=-1, int n=0){id=k;numOfCopies=n;type=U;}
~UNode(){inbound=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
int getNumOfCopies()const{return numOfCopies;}
virtual void execute();
virtual void display()const;
void setInbound(FIFO *fifo){inbound=fifo;}
void addOutbound(FIFO *fifo){outbounds.push_back(fifo);}
};
class CNode : public SDFNode{
private:
/*constant value this node provides*/
const int constant;
/*edges going outward from this node*/
vector<FIFO*> outbounds;
public:
CNode(int k=-1, int c=0):constant(c){id=k;}
~CNode(){}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
virtual void execute();
virtual void display()const;
void addOutbound(FIFO *fifo){outbounds.push_back(fifo);}
};
class FNode : public SDFNode{
private:
/*edge providing input to this node*/
FIFO *inbound;
/*edges going outward from this node*/
vector<FIFO*> outbounds;
public:
FNode(int k=-1){id=k;type=F;}
~FNode(){inbound=NULL;}
virtual int getId()const{return id;}
virtual NodeType getType()const{return type;}
virtual void execute();
virtual void display()const;
void setInbound(FIFO *fifo){inbound=fifo;}
void addOutbound(FIFO *fifo){outbounds.push_back(fifo);}
};
/*each edge is represented by a First-in-First-out queue, producer puts data into the queue, consumer removes data from the queue*/
class FIFO{
private:
/*id of the fifo*/
int id;
/*queue holding data*/
queue<int> fifo;
/*src is producer node, dst is consumer node*/
SDFNode *src, *dst;
public:
int getData();
void putData(int d);
SDFNode *getSrc()const{return src;}
SDFNode *getDst()const{return dst;}
void setSrc(SDFNode *s){src=s;}
void setDst(SDFNode *d){dst=d;}
void display()const;
int getId()const{return id;}
int getSize()const{return fifo.size();}
FIFO(int k=-1):id(k),src(NULL),dst(NULL){}
~FIFO(){src=dst=NULL;}
};
/*compressed topology matrix*/
class TMatrixRow{
private:
/*srcNode is the id of the producer node, dstNode is the id of the consumer node*/
int srcNode, dstNode;
/*tokensProduced is the number of tokens produced by producer, tokensConsumed is the number of tokens consumed by consumer*/
int tokensProduced, tokensConsumed;
public:
TMatrixRow(int sn=-1, int pt=-1, int dn=-1, int ct=-1):srcNode(sn),dstNode(dn),tokensProduced(pt),tokensConsumed(ct){}
void setValue(int sn, int pt, int dn, int ct){srcNode=sn;tokensProduced=pt;dstNode=dn;tokensConsumed=ct;}
int getSrc()const{return srcNode;}
int getDst()const{return dstNode;}
int getTokensConsumed()const{return tokensConsumed;}
int getTokensProduced()const{return tokensProduced;}
};
/*synchronous data flow*/
class SDFG{
private:
/*input node, each sdf has one and only one input node*/
INode *gin;
/*output node, each sdf has one and only one output node*/
ONode *gout;
/*list of nodes (including gin and gout)*/
vector<SDFNode*> nodes;
/*list of FIFOs*/
vector<FIFO*> fifos;
/*topology matrix corresponding to this sdf*/
TMatrixRow topologyMatrix[256];
/*number of nodes in sdf, equals nodes.size()*/
int numOfNodes;
/*number of FIFOs in sdf, equals fifos.size()*/
int numOfFIFOs;
/*if hasSchedule() method has ever been called, this variable is intended to avoid recalculating hasSchedule() again*/
bool scheduleTested;
/*mark if this sdf is schedulable; together with scheduleTested variable, we can avoid recalculating hasSchedule()*/
bool schedulable;
/*schedule, for example, 1,2,4,3... means firing node 1 first, then 2, then 4, then 3*/
vector<int> schedule;
/*a vector storing the number of times each node has to fire in ONE schedule, e.g. numOfFiringRequired[0] is the
number of times node 0 has to fire in the schedule, numOfFiringRequired[1] is the number of times node 1 has to
fire in the schedule*/
vector<int> numOfFiringRequired;
/*mark if a schedule has been found*/
bool scheduleFound;
public:
SDFG():gin(NULL),gout(NULL),numOfNodes(0),numOfFIFOs(0),scheduleTested(false),schedulable(false), scheduleFound(false){}
SDFG(char*, RingBuffer*, RingBuffer*);
~SDFG();
INode *getInput()const{return this->gin;}
ONode *getOutput()const{return this->gout;}
void addNode(SDFNode *node);
//get the fifo with a specific id, if the fifo does not exist, create one and insert into fifos.
FIFO* getFIFO(int id);
vector<SDFNode *> getNodes()const{return this->nodes;}
SDFNode *getNodeAt(int i)const{return (i<this->nodes.size())? this->nodes[i]:NULL;}
//get fifo at a position i in fifos vector, actually in our case, fifos is sorted vector indicating i is also the id of the fifo
FIFO *getFIFOAt(int i)const{return (i<this->fifos.size()) ? this->fifos[i]:NULL;}
vector<FIFO *> getFIFOs()const{return this->fifos;}
int getNumOfNodes()const{return this->numOfNodes;}
void setNumOfNodes(int k){numOfNodes=k;}
int getNumOfFIFOs()const{return this->numOfFIFOs;}
void setNumOfFIFOs(int k){numOfFIFOs=k;}
//create node of specific kind
void getINode(int nodeId, int params[], int count);
void getONode(int nodeId, int params[], int count);
void getANode(int nodeId, int params[], int count);
void getSNode(int nodeId, int params[], int count);
void getMNode(int nodeId, int params[], int count);
void getDNode(int nodeId, int params[], int count);
void getUNode(int nodeId, int params[], int count);
void getCNode(int nodeId, int params[], int count);
void getFNode(int nodeId, int params[], int count);
void addDelay(int params[], int count);
//build compressed topology matrix, compressing the columns
void buildTopologyMatrix();
void printTopologyMatrix()const;
/*calling sequence: hasSchedule<makeSchedule<execute*/
bool hasSchedule();
vector<int> getNumOfFiringRequired()const{return numOfFiringRequired;}
void printNumOfFiringRequired()const;
vector<int> makeSchedule();
void printSchedule()const;
void setInput(RingBuffer *data);
void setOutput(RingBuffer *buf);
void execute(int numOfRepetions);
int getChecksum()const{return gout->getChecksum();}
};
#endif
