![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
sdf
Dependencies: AvailableMemory mbed-rtos mbed
SDF.h
- Committer:
- y7jin
- Date:
- 2014-04-03
- Revision:
- 0:1c8f2727e9f5
File content as of revision 0:1c8f2727e9f5:
#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; void makeSchedule(); void printSchedule()const; void setInput(RingBuffer *data); void setOutput(RingBuffer *buf); void execute(int numOfRepetions); int getChecksum()const{return gout->getChecksum();} }; #endif