skeleton for lab1

Dependencies:   AvailableMemory mbed-rtos mbed

Fork of helloaabbc by 32314 mbed

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