skeleton for lab1

Dependencies:   AvailableMemory mbed-rtos mbed

Fork of helloaabbc by 32314 mbed

Committer:
mbed36372
Date:
Fri Apr 04 21:31:22 2014 +0000
Revision:
1:55e99f6e2aa5
Parent:
0:1c8f2727e9f5
SP14_lab1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
y7jin 0:1c8f2727e9f5 1 #include "SDF.h"
y7jin 0:1c8f2727e9f5 2
y7jin 0:1c8f2727e9f5 3 /*set the input to a ring buffer pointed to by buf, the input node will read input from this ring buffer*/
y7jin 0:1c8f2727e9f5 4 void INode::setInput(RingBuffer *buf){
y7jin 0:1c8f2727e9f5 5 input=buf;
y7jin 0:1c8f2727e9f5 6 }
y7jin 0:1c8f2727e9f5 7
y7jin 0:1c8f2727e9f5 8 /*each time inode executes, reading one sample from input ring buffer, and put this data onto all the outgoing edges*/
y7jin 0:1c8f2727e9f5 9 void INode::execute(){
y7jin 0:1c8f2727e9f5 10 int inputSample = input->next();
y7jin 0:1c8f2727e9f5 11 for(int i=0; i<(int)outbounds.size(); i++){
y7jin 0:1c8f2727e9f5 12 outbounds[i]->putData(inputSample);
y7jin 0:1c8f2727e9f5 13 }
y7jin 0:1c8f2727e9f5 14 }
y7jin 0:1c8f2727e9f5 15
y7jin 0:1c8f2727e9f5 16 /*display function*/
y7jin 0:1c8f2727e9f5 17 void INode::display()const{
y7jin 0:1c8f2727e9f5 18 printf("INode id=%d type=%d ", id, type);
y7jin 0:1c8f2727e9f5 19 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 20 printf("\r\n");
y7jin 0:1c8f2727e9f5 21 }
y7jin 0:1c8f2727e9f5 22
y7jin 0:1c8f2727e9f5 23 /*set the output to a ring buffer pointed to by buf, the output node will write output samples into this buf*/
y7jin 0:1c8f2727e9f5 24 void ONode::setOutput(RingBuffer *buf){
y7jin 0:1c8f2727e9f5 25 output=buf;
y7jin 0:1c8f2727e9f5 26 }
y7jin 0:1c8f2727e9f5 27
y7jin 0:1c8f2727e9f5 28 /*each time onode executes, reading one sample from inbound FIFO and write this sample to ring buffer; also compute checksum*/
y7jin 0:1c8f2727e9f5 29 void ONode::execute(){
y7jin 0:1c8f2727e9f5 30 int sampleOut=inbound->getData();
y7jin 0:1c8f2727e9f5 31 checksum ^= sampleOut;
y7jin 0:1c8f2727e9f5 32 output->insert(sampleOut);
y7jin 0:1c8f2727e9f5 33 }
y7jin 0:1c8f2727e9f5 34
y7jin 0:1c8f2727e9f5 35 /*display function*/
y7jin 0:1c8f2727e9f5 36 void ONode::display()const{
y7jin 0:1c8f2727e9f5 37 printf("ONode id=%d type=%d %d\r\n", id, type, inbound->getId());
y7jin 0:1c8f2727e9f5 38 }
y7jin 0:1c8f2727e9f5 39
y7jin 0:1c8f2727e9f5 40 /*each time anode executes, reading operand1 from one inbound FIFO op1, reading operand2 from the other inbound FIFO op2,
y7jin 0:1c8f2727e9f5 41 compute the sum of the two and put this result onto all the outbound FIFOs*/
y7jin 0:1c8f2727e9f5 42 void ANode::execute(){
y7jin 0:1c8f2727e9f5 43 int a = op1->getData(), b = op2->getData();
y7jin 0:1c8f2727e9f5 44 for(int i=0; i<(int)outbounds.size(); i++){
y7jin 0:1c8f2727e9f5 45 outbounds[i]->putData(a+b);
y7jin 0:1c8f2727e9f5 46 }
y7jin 0:1c8f2727e9f5 47 }
y7jin 0:1c8f2727e9f5 48
y7jin 0:1c8f2727e9f5 49 /*display function*/
y7jin 0:1c8f2727e9f5 50 void ANode::display()const{
y7jin 0:1c8f2727e9f5 51 printf("ANode id=%d type=%d %d %d ", id, type, op1->getId(), op2->getId());
y7jin 0:1c8f2727e9f5 52 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 53 printf("\r\n");
y7jin 0:1c8f2727e9f5 54 }
y7jin 0:1c8f2727e9f5 55
y7jin 0:1c8f2727e9f5 56 /*each time anode executes, reading operand1 from one inbound FIFO op1, reading operand2 from the other inbound FIFO op2,
y7jin 0:1c8f2727e9f5 57 compute the difference of the two and put this result onto all the outbound FIFOs*/
y7jin 0:1c8f2727e9f5 58 void SNode::execute(){
y7jin 0:1c8f2727e9f5 59 int a = op1->getData(), b = op2->getData();
y7jin 0:1c8f2727e9f5 60 for(int i=0; i<(int)outbounds.size(); i++){
y7jin 0:1c8f2727e9f5 61 outbounds[i]->putData(a-b);
y7jin 0:1c8f2727e9f5 62 }
y7jin 0:1c8f2727e9f5 63 }
y7jin 0:1c8f2727e9f5 64
y7jin 0:1c8f2727e9f5 65 /*display function*/
y7jin 0:1c8f2727e9f5 66 void SNode::display()const{
y7jin 0:1c8f2727e9f5 67 printf("SNode id=%d type=%d %d %d ", id, type, op1->getId(), op2->getId());
y7jin 0:1c8f2727e9f5 68 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 69 printf("\r\n");
y7jin 0:1c8f2727e9f5 70 }
y7jin 0:1c8f2727e9f5 71
y7jin 0:1c8f2727e9f5 72 /*each time mnode executes, reading a sample from inbound FIFO, multiply it by c and divide by d, put the result onto all
y7jin 0:1c8f2727e9f5 73 the outbound FIFOs*/
y7jin 0:1c8f2727e9f5 74 void MNode::execute(){
y7jin 0:1c8f2727e9f5 75 int a = inbound->getData();
y7jin 0:1c8f2727e9f5 76 for(int i=0; i<(int)outbounds.size(); i++){
y7jin 0:1c8f2727e9f5 77 outbounds[i]->putData(a*c/d);
y7jin 0:1c8f2727e9f5 78 }
y7jin 0:1c8f2727e9f5 79 }
y7jin 0:1c8f2727e9f5 80
y7jin 0:1c8f2727e9f5 81 /*display function*/
y7jin 0:1c8f2727e9f5 82 void MNode::display()const{
y7jin 0:1c8f2727e9f5 83 printf("MNode id=%d type=%d c=%d d=%d %d ", id, type, c, d, inbound->getId());
y7jin 0:1c8f2727e9f5 84 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 85 printf("\r\n");
y7jin 0:1c8f2727e9f5 86 }
y7jin 0:1c8f2727e9f5 87
y7jin 0:1c8f2727e9f5 88 /*each time dnode executes, read numOfSamples samples from inbound FIFO, put the first sample (sample 0) onto all the outbound FIFOs*/
y7jin 0:1c8f2727e9f5 89 void DNode::execute(){
y7jin 0:1c8f2727e9f5 90 for(int i=0; i<numOfSamples; i++){
y7jin 0:1c8f2727e9f5 91 int d = inbound->getData();
y7jin 0:1c8f2727e9f5 92 if(i==0){
y7jin 0:1c8f2727e9f5 93 for(int j=0; j<(int)outbounds.size(); j++)outbounds[j]->putData(d);
y7jin 0:1c8f2727e9f5 94 }
y7jin 0:1c8f2727e9f5 95 }
y7jin 0:1c8f2727e9f5 96 }
y7jin 0:1c8f2727e9f5 97
y7jin 0:1c8f2727e9f5 98 /*display function*/
y7jin 0:1c8f2727e9f5 99 void DNode::display()const{
y7jin 0:1c8f2727e9f5 100 printf("DNode id=%d type=%d n=%d %d ", id, type, numOfSamples, inbound->getId());
y7jin 0:1c8f2727e9f5 101 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 102 printf("\r\n");
y7jin 0:1c8f2727e9f5 103 }
y7jin 0:1c8f2727e9f5 104
y7jin 0:1c8f2727e9f5 105 /*each time unode executes, read a sample from inbound FIFO, duplicate numOfCopies copies, put all those copies onto outbound FIFOs*/
y7jin 0:1c8f2727e9f5 106 void UNode::execute(){
y7jin 0:1c8f2727e9f5 107 int a = inbound->getData();
y7jin 0:1c8f2727e9f5 108 for(int i=0; i<(int)outbounds.size(); i++){
y7jin 0:1c8f2727e9f5 109 for(int j=0; j<numOfCopies; j++){outbounds[i]->putData(a);}
y7jin 0:1c8f2727e9f5 110 }
y7jin 0:1c8f2727e9f5 111 }
y7jin 0:1c8f2727e9f5 112
y7jin 0:1c8f2727e9f5 113 /*display function*/
y7jin 0:1c8f2727e9f5 114 void UNode::display()const{
y7jin 0:1c8f2727e9f5 115 printf("UNode id=%d type=%d n=%d %d ", id, type, numOfCopies, inbound->getId());
y7jin 0:1c8f2727e9f5 116 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 117 printf("\r\n");
y7jin 0:1c8f2727e9f5 118 }
y7jin 0:1c8f2727e9f5 119
y7jin 0:1c8f2727e9f5 120 /*each time cnode executes, put the constant onto outbound FIFOs*/
y7jin 0:1c8f2727e9f5 121 void CNode::execute(){
y7jin 0:1c8f2727e9f5 122 for(int i=0; i<outbounds.size(); i++){
y7jin 0:1c8f2727e9f5 123 outbounds[i]->putData(constant);
y7jin 0:1c8f2727e9f5 124 }
y7jin 0:1c8f2727e9f5 125 }
y7jin 0:1c8f2727e9f5 126
y7jin 0:1c8f2727e9f5 127 /*display function*/
y7jin 0:1c8f2727e9f5 128 void CNode::display()const{
y7jin 0:1c8f2727e9f5 129 printf("CNode id=%d type=%d constant=%d ", id, type, constant);
y7jin 0:1c8f2727e9f5 130 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 131 printf("\r\n");
y7jin 0:1c8f2727e9f5 132 }
y7jin 0:1c8f2727e9f5 133
y7jin 0:1c8f2727e9f5 134 /*each time fnode executes, read a sample from inbound FIFO, and put this sample onto outbound FIFOs*/
y7jin 0:1c8f2727e9f5 135 void FNode::execute(){
y7jin 0:1c8f2727e9f5 136 int a = inbound->getData();
y7jin 0:1c8f2727e9f5 137 for(int i=0; i<(int)outbounds.size(); i++){
y7jin 0:1c8f2727e9f5 138 outbounds[i]->putData(a);
y7jin 0:1c8f2727e9f5 139 }
y7jin 0:1c8f2727e9f5 140 }
y7jin 0:1c8f2727e9f5 141
y7jin 0:1c8f2727e9f5 142 /*display function*/
y7jin 0:1c8f2727e9f5 143 void FNode::display()const{
y7jin 0:1c8f2727e9f5 144 printf("FNode id=%d type=%d %d ", id, type, inbound->getId());
y7jin 0:1c8f2727e9f5 145 for(int i=0; i<outbounds.size(); i++)printf("%d ", outbounds[i]->getId());
y7jin 0:1c8f2727e9f5 146 printf("\r\n");
y7jin 0:1c8f2727e9f5 147 }
y7jin 0:1c8f2727e9f5 148
y7jin 0:1c8f2727e9f5 149 /*intended for the consumer to use, read one sample from the FIFO, and remove that data*/
y7jin 0:1c8f2727e9f5 150 int FIFO::getData(){
y7jin 0:1c8f2727e9f5 151 if(this->fifo.empty()){
y7jin 0:1c8f2727e9f5 152 error("trying to read from empty FIFO: id=%d...\r\n", this->id);
y7jin 0:1c8f2727e9f5 153 exit(1);
y7jin 0:1c8f2727e9f5 154 }
y7jin 0:1c8f2727e9f5 155 int ret = this->fifo.front();
y7jin 0:1c8f2727e9f5 156 this->fifo.pop();
y7jin 0:1c8f2727e9f5 157 return ret;
y7jin 0:1c8f2727e9f5 158 }
y7jin 0:1c8f2727e9f5 159
y7jin 0:1c8f2727e9f5 160 /*intended for the producer to use, put one sample into the FIFO*/
y7jin 0:1c8f2727e9f5 161 void FIFO::putData(int d){
y7jin 0:1c8f2727e9f5 162 this->fifo.push(d);
y7jin 0:1c8f2727e9f5 163 }
y7jin 0:1c8f2727e9f5 164
y7jin 0:1c8f2727e9f5 165 /*display function*/
y7jin 0:1c8f2727e9f5 166 void FIFO::display()const{
y7jin 0:1c8f2727e9f5 167 printf("FIFO id=%d src=%d dst=%d numOfMarkings=%d\r\n", id, src->getId(), dst->getId(), fifo.size());
y7jin 0:1c8f2727e9f5 168 }
y7jin 0:1c8f2727e9f5 169
y7jin 0:1c8f2727e9f5 170 SDFG::SDFG(char* path, RingBuffer* input, RingBuffer* output):
y7jin 0:1c8f2727e9f5 171 gin(NULL),gout(NULL),numOfNodes(0),numOfFIFOs(0),scheduleTested(false),schedulable(false), scheduleFound(false)
y7jin 0:1c8f2727e9f5 172 {
y7jin 0:1c8f2727e9f5 173 Parser::parseSDFG(path,this);
y7jin 0:1c8f2727e9f5 174 if(!hasSchedule()){
y7jin 0:1c8f2727e9f5 175 error("ERROR: CANNOT SCHEDULE\r\n");
y7jin 0:1c8f2727e9f5 176 exit(1);
y7jin 0:1c8f2727e9f5 177 }
y7jin 0:1c8f2727e9f5 178 setInput(input);
y7jin 0:1c8f2727e9f5 179 setOutput(output);
mbed36372 1:55e99f6e2aa5 180 schedule=makeSchedule();
y7jin 0:1c8f2727e9f5 181 }
y7jin 0:1c8f2727e9f5 182
y7jin 0:1c8f2727e9f5 183 /*destructor, reclaim all the space allocated for nodes and FIFOs*/
y7jin 0:1c8f2727e9f5 184 SDFG::~SDFG(){
y7jin 0:1c8f2727e9f5 185 for(int i=0; i<nodes.size(); i++)delete nodes[i];
y7jin 0:1c8f2727e9f5 186 for(int i=0; i<fifos.size(); i++)delete fifos[i];
y7jin 0:1c8f2727e9f5 187 }
y7jin 0:1c8f2727e9f5 188
y7jin 0:1c8f2727e9f5 189 /*add a node into the nodes vector, keep the nodes whose id's are arranged in ascending order in the nodes vector;
y7jin 0:1c8f2727e9f5 190 basically an insertion-sort*/
y7jin 0:1c8f2727e9f5 191 void SDFG::addNode(SDFNode *node){
y7jin 0:1c8f2727e9f5 192 if(!node)return;
y7jin 0:1c8f2727e9f5 193 int i=0;
y7jin 0:1c8f2727e9f5 194 while(i<nodes.size()&&nodes[i]->getId()<node->getId())i++;
y7jin 0:1c8f2727e9f5 195 if(i<nodes.size()&&nodes[i]->getId()==node->getId())return;
y7jin 0:1c8f2727e9f5 196 else if(i>=nodes.size())nodes.push_back(node);
y7jin 0:1c8f2727e9f5 197 else{
y7jin 0:1c8f2727e9f5 198 nodes.push_back(NULL);
y7jin 0:1c8f2727e9f5 199 for(int j=nodes.size()-1;j>i;j--)nodes[j]=nodes[j-1];
y7jin 0:1c8f2727e9f5 200 nodes[i]=node;
y7jin 0:1c8f2727e9f5 201 }
y7jin 0:1c8f2727e9f5 202 }
y7jin 0:1c8f2727e9f5 203
y7jin 0:1c8f2727e9f5 204 /*given an id, if a FIFO with that id exists, return that FIFO; otherwise create a new FIFO, insert the FIFO into
y7jin 0:1c8f2727e9f5 205 vector fifos, and return that FIFO; also an insertion-sort implementation*/
y7jin 0:1c8f2727e9f5 206 FIFO* SDFG::getFIFO(int id){
y7jin 0:1c8f2727e9f5 207 int i=0;
y7jin 0:1c8f2727e9f5 208 FIFO *fifo=NULL;
y7jin 0:1c8f2727e9f5 209 while(i<fifos.size()&&fifos[i]->getId()<id)i++;
y7jin 0:1c8f2727e9f5 210 if(i<fifos.size() && fifos[i]->getId()==id)return fifos[i];
y7jin 0:1c8f2727e9f5 211 else if(i>=fifos.size()){
y7jin 0:1c8f2727e9f5 212 fifo=new FIFO(id);
y7jin 0:1c8f2727e9f5 213 fifos.push_back(fifo);
y7jin 0:1c8f2727e9f5 214 }else{
y7jin 0:1c8f2727e9f5 215 fifo=new FIFO(id);
y7jin 0:1c8f2727e9f5 216 fifos.push_back(NULL);
y7jin 0:1c8f2727e9f5 217 for(int j=fifos.size()-1;j>i;j--)fifos[j]=fifos[j-1];
y7jin 0:1c8f2727e9f5 218 fifos[i]=fifo;
y7jin 0:1c8f2727e9f5 219 }
y7jin 0:1c8f2727e9f5 220 return fifo;
y7jin 0:1c8f2727e9f5 221 }
y7jin 0:1c8f2727e9f5 222
y7jin 0:1c8f2727e9f5 223 /*invoked when parsing sdfgconf.txt. When reading a line starting with I, invoke this method to create a new INode; refer
y7jin 0:1c8f2727e9f5 224 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 225 void SDFG::getINode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 226 gin = new INode(nodeId,NULL);
y7jin 0:1c8f2727e9f5 227 addNode(gin);
y7jin 0:1c8f2727e9f5 228 for(int i=0;i<count;i++){
y7jin 0:1c8f2727e9f5 229 FIFO *fifo=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 230 gin->addOutbound(fifo);
y7jin 0:1c8f2727e9f5 231 fifo->setSrc(gin);
y7jin 0:1c8f2727e9f5 232 }
y7jin 0:1c8f2727e9f5 233 }
y7jin 0:1c8f2727e9f5 234
y7jin 0:1c8f2727e9f5 235 /*invoked when parsing sdfgconf.txt. When reading a line starting with O, invoke this method to create a new ONode; refer
y7jin 0:1c8f2727e9f5 236 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 237 void SDFG::getONode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 238 gout = new ONode(nodeId,NULL);
y7jin 0:1c8f2727e9f5 239 addNode(gout);
y7jin 0:1c8f2727e9f5 240 for(int i=0;i<count;i++){
y7jin 0:1c8f2727e9f5 241 FIFO *fifo=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 242 gout->setInbound(fifo);
y7jin 0:1c8f2727e9f5 243 fifo->setDst(gout);
y7jin 0:1c8f2727e9f5 244 }
y7jin 0:1c8f2727e9f5 245 }
y7jin 0:1c8f2727e9f5 246
y7jin 0:1c8f2727e9f5 247 /*invoked when parsing sdfgconf.txt. When reading a line starting with A, invoke this method to create a new ANode; refer
y7jin 0:1c8f2727e9f5 248 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 249 void SDFG::getANode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 250 ANode *anode = new ANode(nodeId);
y7jin 0:1c8f2727e9f5 251 addNode(anode);
y7jin 0:1c8f2727e9f5 252 FIFO *in1=NULL, *in2=NULL;
y7jin 0:1c8f2727e9f5 253 for(int i=0; i<count; i++){
y7jin 0:1c8f2727e9f5 254 if(i==0){
y7jin 0:1c8f2727e9f5 255 in1 = getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 256 in1->setDst(anode);
y7jin 0:1c8f2727e9f5 257 }else if(i==1){
y7jin 0:1c8f2727e9f5 258 in2 = getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 259 in2->setDst(anode);
y7jin 0:1c8f2727e9f5 260 anode->setInbound(in1, in2);
y7jin 0:1c8f2727e9f5 261 }else{
y7jin 0:1c8f2727e9f5 262 FIFO *out = getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 263 out->setSrc(anode);
y7jin 0:1c8f2727e9f5 264 anode->addOutbound(out);
y7jin 0:1c8f2727e9f5 265 }
y7jin 0:1c8f2727e9f5 266 }
y7jin 0:1c8f2727e9f5 267 }
y7jin 0:1c8f2727e9f5 268
y7jin 0:1c8f2727e9f5 269
y7jin 0:1c8f2727e9f5 270 /*invoked when parsing sdfgconf.txt. When reading a line starting with S, invoke this method to create a new SNode; refer
y7jin 0:1c8f2727e9f5 271 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 272 void SDFG::getSNode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 273 SNode *snode = new SNode(nodeId);
y7jin 0:1c8f2727e9f5 274 addNode(snode);
y7jin 0:1c8f2727e9f5 275 FIFO *in1=NULL, *in2=NULL;
y7jin 0:1c8f2727e9f5 276 for(int i=0; i<count; i++){
y7jin 0:1c8f2727e9f5 277 if(i==0){
y7jin 0:1c8f2727e9f5 278 in1=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 279 in1->setDst(snode);
y7jin 0:1c8f2727e9f5 280 }else if(i==1){
y7jin 0:1c8f2727e9f5 281 in2=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 282 in2->setDst(snode);
y7jin 0:1c8f2727e9f5 283 snode->setInbound(in1,in2);
y7jin 0:1c8f2727e9f5 284 }else{
y7jin 0:1c8f2727e9f5 285 FIFO *out = getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 286 out->setSrc(snode);
y7jin 0:1c8f2727e9f5 287 snode->addOutbound(out);
y7jin 0:1c8f2727e9f5 288 }
y7jin 0:1c8f2727e9f5 289 }
y7jin 0:1c8f2727e9f5 290 }
y7jin 0:1c8f2727e9f5 291
y7jin 0:1c8f2727e9f5 292 /*invoked when parsing sdfgconf.txt. When reading a line starting with M, invoke this method to create a new MNode; refer
y7jin 0:1c8f2727e9f5 293 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 294 void SDFG::getMNode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 295 MNode *mnode = new MNode(nodeId, params[0], params[1]);
y7jin 0:1c8f2727e9f5 296 addNode(mnode);
y7jin 0:1c8f2727e9f5 297 for(int i=2; i<count; i++){
y7jin 0:1c8f2727e9f5 298 if(i==2){
y7jin 0:1c8f2727e9f5 299 FIFO *in=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 300 in->setDst(mnode);
y7jin 0:1c8f2727e9f5 301 mnode->setInbound(in);
y7jin 0:1c8f2727e9f5 302 }else{
y7jin 0:1c8f2727e9f5 303 FIFO *out=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 304 out->setSrc(mnode);
y7jin 0:1c8f2727e9f5 305 mnode->addOutbound(out);
y7jin 0:1c8f2727e9f5 306 }
y7jin 0:1c8f2727e9f5 307 }
y7jin 0:1c8f2727e9f5 308 }
y7jin 0:1c8f2727e9f5 309
y7jin 0:1c8f2727e9f5 310 /*invoked when parsing sdfgconf.txt. When reading a line starting with D, invoke this method to create a new DNode; refer
y7jin 0:1c8f2727e9f5 311 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 312 void SDFG::getDNode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 313 DNode *dnode=new DNode(nodeId, params[0]);
y7jin 0:1c8f2727e9f5 314 addNode(dnode);
y7jin 0:1c8f2727e9f5 315 for(int i=1; i<count; i++){
y7jin 0:1c8f2727e9f5 316 if(i==1){
y7jin 0:1c8f2727e9f5 317 FIFO *in=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 318 in->setDst(dnode);
y7jin 0:1c8f2727e9f5 319 dnode->setInbound(in);
y7jin 0:1c8f2727e9f5 320 }else{
y7jin 0:1c8f2727e9f5 321 FIFO *out=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 322 out->setSrc(dnode);
y7jin 0:1c8f2727e9f5 323 dnode->addOutbound(out);
y7jin 0:1c8f2727e9f5 324 }
y7jin 0:1c8f2727e9f5 325 }
y7jin 0:1c8f2727e9f5 326 }
y7jin 0:1c8f2727e9f5 327
y7jin 0:1c8f2727e9f5 328 /*invoked when parsing sdfgconf.txt. When reading a line starting with U, invoke this method to create a new UNode; refer
y7jin 0:1c8f2727e9f5 329 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 330 void SDFG::getUNode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 331 UNode *unode = new UNode(nodeId, params[0]);
y7jin 0:1c8f2727e9f5 332 addNode(unode);
y7jin 0:1c8f2727e9f5 333 for(int i=1; i<count; i++){
y7jin 0:1c8f2727e9f5 334 if(i==1){
y7jin 0:1c8f2727e9f5 335 FIFO *in=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 336 in->setDst(unode);
y7jin 0:1c8f2727e9f5 337 unode->setInbound(in);
y7jin 0:1c8f2727e9f5 338 }else{
y7jin 0:1c8f2727e9f5 339 FIFO *out=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 340 out->setSrc(unode);
y7jin 0:1c8f2727e9f5 341 unode->addOutbound(out);
y7jin 0:1c8f2727e9f5 342 }
y7jin 0:1c8f2727e9f5 343 }
y7jin 0:1c8f2727e9f5 344 }
y7jin 0:1c8f2727e9f5 345
y7jin 0:1c8f2727e9f5 346 /*invoked when parsing sdfgconf.txt. When reading a line starting with C, invoke this method to create a new CNode; refer
y7jin 0:1c8f2727e9f5 347 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 348 void SDFG::getCNode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 349 CNode *cnode=new CNode(nodeId, params[0]);
y7jin 0:1c8f2727e9f5 350 addNode(cnode);
y7jin 0:1c8f2727e9f5 351 for(int i=1; i<count; i++){
y7jin 0:1c8f2727e9f5 352 FIFO *out=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 353 out->setSrc(cnode);
y7jin 0:1c8f2727e9f5 354 cnode->addOutbound(out);
y7jin 0:1c8f2727e9f5 355 }
y7jin 0:1c8f2727e9f5 356 }
y7jin 0:1c8f2727e9f5 357
y7jin 0:1c8f2727e9f5 358 /*invoked when parsing sdfgconf.txt. When reading a line starting with F, invoke this method to create a new FNode; refer
y7jin 0:1c8f2727e9f5 359 to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 360 void SDFG::getFNode(int nodeId, int params[], int count){
y7jin 0:1c8f2727e9f5 361 FNode *fnode=new FNode(nodeId);
y7jin 0:1c8f2727e9f5 362 addNode(fnode);
y7jin 0:1c8f2727e9f5 363 for(int i=0; i<count; i++){
y7jin 0:1c8f2727e9f5 364 if(i==0){
y7jin 0:1c8f2727e9f5 365 FIFO *in=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 366 in->setDst(fnode);
y7jin 0:1c8f2727e9f5 367 fnode->setInbound(in);
y7jin 0:1c8f2727e9f5 368 }else{
y7jin 0:1c8f2727e9f5 369 FIFO *out=getFIFO(params[i]);
y7jin 0:1c8f2727e9f5 370 out->setSrc(fnode);
y7jin 0:1c8f2727e9f5 371 fnode->addOutbound(out);
y7jin 0:1c8f2727e9f5 372 }
y7jin 0:1c8f2727e9f5 373 }
y7jin 0:1c8f2727e9f5 374 }
y7jin 0:1c8f2727e9f5 375
y7jin 0:1c8f2727e9f5 376 /*invoked when parsing sdfgconf.txt. When reading a line starting with E, invoke this method to add delay to a specific edge,
y7jin 0:1c8f2727e9f5 377 namely put initial data into the FIFO associated with the edge; refer to the document regarding what each element in params array means*/
y7jin 0:1c8f2727e9f5 378 void SDFG::addDelay(int params[], int count){
y7jin 0:1c8f2727e9f5 379 FIFO *fifo=getFIFOAt(params[0]);
y7jin 0:1c8f2727e9f5 380 if(!fifo){
y7jin 0:1c8f2727e9f5 381 error("trying to add delay to a nonexisting edge\r\n");
y7jin 0:1c8f2727e9f5 382 exit(1);
y7jin 0:1c8f2727e9f5 383 }
y7jin 0:1c8f2727e9f5 384 for(int i=0; i<params[1]; i++){
y7jin 0:1c8f2727e9f5 385 fifo->putData(params[i+2]);
y7jin 0:1c8f2727e9f5 386 }
y7jin 0:1c8f2727e9f5 387 }
y7jin 0:1c8f2727e9f5 388
y7jin 0:1c8f2727e9f5 389 /*Each row in topology matrix corresponds to a FIFO; on a row-by-row basis, if node is the producer (src) of a FIFO, then set
y7jin 0:1c8f2727e9f5 390 tokenProduced to be the number of tokens the producer produces; the same for consumer; the number of tokens produced or consumed
y7jin 0:1c8f2727e9f5 391 can be found in the specification*/
y7jin 0:1c8f2727e9f5 392 void SDFG::buildTopologyMatrix(){
y7jin 0:1c8f2727e9f5 393 SDFNode *src=NULL, *dst=NULL;
y7jin 0:1c8f2727e9f5 394 int tokenProduced=0, tokenConsumed=0;
y7jin 0:1c8f2727e9f5 395 for(int i=0; i<fifos.size(); i++){
y7jin 0:1c8f2727e9f5 396 tokenConsumed=tokenProduced=1;
y7jin 0:1c8f2727e9f5 397 src=fifos[i]->getSrc();
y7jin 0:1c8f2727e9f5 398 dst=fifos[i]->getDst();
y7jin 0:1c8f2727e9f5 399 if(src->getType()==U){
y7jin 0:1c8f2727e9f5 400 UNode *unode=(UNode*) src;
y7jin 0:1c8f2727e9f5 401 tokenProduced=unode->getNumOfCopies();
y7jin 0:1c8f2727e9f5 402 }
y7jin 0:1c8f2727e9f5 403 if(dst->getType()==D){
y7jin 0:1c8f2727e9f5 404 DNode *dnode=(DNode*) dst;
y7jin 0:1c8f2727e9f5 405 tokenConsumed=dnode->getNumOfSamples();
y7jin 0:1c8f2727e9f5 406 }
y7jin 0:1c8f2727e9f5 407 topologyMatrix[i].setValue(src->getId(), tokenProduced, dst->getId(), tokenConsumed);
y7jin 0:1c8f2727e9f5 408 }
y7jin 0:1c8f2727e9f5 409 }
y7jin 0:1c8f2727e9f5 410
y7jin 0:1c8f2727e9f5 411 /*print the full topology matrix*/
y7jin 0:1c8f2727e9f5 412 void SDFG::printTopologyMatrix()const{
y7jin 0:1c8f2727e9f5 413 for(int i=0; i<fifos.size(); i++){
y7jin 0:1c8f2727e9f5 414 for(int j=0; j<nodes.size(); j++){
y7jin 0:1c8f2727e9f5 415 if(topologyMatrix[i].getSrc()==nodes[j]->getId())printf("%d ", topologyMatrix[i].getTokensProduced());
y7jin 0:1c8f2727e9f5 416 else if(topologyMatrix[i].getDst()==nodes[j]->getId())printf("%d ", 0-topologyMatrix[i].getTokensConsumed());
y7jin 0:1c8f2727e9f5 417 else printf("0 ");
y7jin 0:1c8f2727e9f5 418 }
y7jin 0:1c8f2727e9f5 419 printf("\r\n");
y7jin 0:1c8f2727e9f5 420 }
y7jin 0:1c8f2727e9f5 421 }
y7jin 0:1c8f2727e9f5 422
y7jin 0:1c8f2727e9f5 423 /*test if the SDF has a schedule by solving the equation group; RationalNum is a class used to represent rational numbers,
y7jin 0:1c8f2727e9f5 424 useful in producing integer solutions to equation groups*/
y7jin 0:1c8f2727e9f5 425 bool SDFG::hasSchedule(){
y7jin 0:1c8f2727e9f5 426 /*if this function has been called before, just return the recorded result*/
y7jin 0:1c8f2727e9f5 427 if(scheduleTested)return schedulable;
y7jin 0:1c8f2727e9f5 428 /*solution to the equation group, at most 256 variables, each variable corresponds to a node in SDF*/
y7jin 0:1c8f2727e9f5 429 vector<RationalNum> solution(256);
y7jin 0:1c8f2727e9f5 430 /*count keeps track of the number of variables in the equation group whose value has been found*/
y7jin 0:1c8f2727e9f5 431 int count=0;
y7jin 0:1c8f2727e9f5 432 /*initial values for the variables, initialize them to be -1 to flag that their values have not been found*/
y7jin 0:1c8f2727e9f5 433 for(int i=0; i<256; i++)solution[i]=RationalNum(-1);
y7jin 0:1c8f2727e9f5 434 /*set the value of first variable to 1, this is OK since the solution to the equation group is not unique*/
y7jin 0:1c8f2727e9f5 435 solution[0]=RationalNum(1);
y7jin 0:1c8f2727e9f5 436 count++;
y7jin 0:1c8f2727e9f5 437 /*repeat for each equation until the values of all variables have been found*/
y7jin 0:1c8f2727e9f5 438 do{
y7jin 0:1c8f2727e9f5 439 for(int i=0; i<numOfFIFOs; i++){
y7jin 0:1c8f2727e9f5 440 /*node1 and node2 correspond to the src and dst of the FIFO, we use them to index into the solution vector*/
y7jin 0:1c8f2727e9f5 441 int node1,node2;
y7jin 0:1c8f2727e9f5 442 node1=topologyMatrix[i].getSrc();
y7jin 0:1c8f2727e9f5 443 node2=topologyMatrix[i].getDst();
y7jin 0:1c8f2727e9f5 444 /*we have found the values for neither of them, there is nothing more we can do for now, so just skip and proceed*/
y7jin 0:1c8f2727e9f5 445 if(solution[node1]<0&&solution[node2]<0)continue;
y7jin 0:1c8f2727e9f5 446 /*we have found the values for both of them, then we plug in their values into this equation to see if the solution
y7jin 0:1c8f2727e9f5 447 satisfies this equation*/
y7jin 0:1c8f2727e9f5 448 else if(solution[node1]>=0&&solution[node2]>=0){
y7jin 0:1c8f2727e9f5 449 /*values which we already found do not satisfy this current equation, meaning there is conflict, namely there is no
y7jin 0:1c8f2727e9f5 450 schedule for this SDF*/
y7jin 0:1c8f2727e9f5 451 if(solution[node1]*topologyMatrix[i].getTokensProduced()!=solution[node2]*topologyMatrix[i].getTokensConsumed()){
y7jin 0:1c8f2727e9f5 452 scheduleTested=true;
y7jin 0:1c8f2727e9f5 453 schedulable=false;
y7jin 0:1c8f2727e9f5 454 return false;
y7jin 0:1c8f2727e9f5 455 }
y7jin 0:1c8f2727e9f5 456 }
y7jin 0:1c8f2727e9f5 457 /*node1's value is not found, but node2's value is found, then use node2 to solve node1*/
y7jin 0:1c8f2727e9f5 458 else if(solution[node1]<0 && solution[node2]>=0){
y7jin 0:1c8f2727e9f5 459 RationalNum r(topologyMatrix[i].getTokensConsumed(), topologyMatrix[i].getTokensProduced());
y7jin 0:1c8f2727e9f5 460 solution[node1]=r*solution[node2];
y7jin 0:1c8f2727e9f5 461 /*we have found the value for one more variable, thus we should update count*/
y7jin 0:1c8f2727e9f5 462 count++;
y7jin 0:1c8f2727e9f5 463 }
y7jin 0:1c8f2727e9f5 464 /*node2's value is not found, but node1's value is found, then use node1 to solve node2*/
y7jin 0:1c8f2727e9f5 465 else if(solution[node1]>=0 && solution[node2]<0){
y7jin 0:1c8f2727e9f5 466 RationalNum r(topologyMatrix[i].getTokensProduced(), topologyMatrix[i].getTokensConsumed());
y7jin 0:1c8f2727e9f5 467 solution[node2]=r*solution[node1];
y7jin 0:1c8f2727e9f5 468 /*we have found the value for one more variable, thus we should update count*/
y7jin 0:1c8f2727e9f5 469 count++;
y7jin 0:1c8f2727e9f5 470 }
y7jin 0:1c8f2727e9f5 471 }
y7jin 0:1c8f2727e9f5 472 }while(count<numOfNodes);
y7jin 0:1c8f2727e9f5 473 /*adding all the elements in solution vector together; perform this process simply to make their denominators the same*/
y7jin 0:1c8f2727e9f5 474 RationalNum temp(0);
y7jin 0:1c8f2727e9f5 475 for(int i=0; i<numOfNodes; i++)temp=temp+solution[i];
y7jin 0:1c8f2727e9f5 476 /*for each element in solution, multiply by the common denominator found just now; in this way, we can acquire a set of integer
y7jin 0:1c8f2727e9f5 477 solution to the original equations group, this solution represents how many times a node has to run in a schedule, if there
y7jin 0:1c8f2727e9f5 478 exists one; then store the values in numOfFiringRequired vector*/
y7jin 0:1c8f2727e9f5 479 for(int i=0; i<numOfNodes; i++){
y7jin 0:1c8f2727e9f5 480 solution[i]=solution[i]*temp.getDenominator();
y7jin 0:1c8f2727e9f5 481 numOfFiringRequired.push_back(solution[i].getNumerator());
y7jin 0:1c8f2727e9f5 482 }
y7jin 0:1c8f2727e9f5 483 /*if we are here, we have found a schedule*/
y7jin 0:1c8f2727e9f5 484 scheduleTested=true;
y7jin 0:1c8f2727e9f5 485 schedulable=true;
y7jin 0:1c8f2727e9f5 486 return true;
y7jin 0:1c8f2727e9f5 487 }
y7jin 0:1c8f2727e9f5 488
y7jin 0:1c8f2727e9f5 489 /*print number of times each node is required to fire in one schedule*/
y7jin 0:1c8f2727e9f5 490 void SDFG::printNumOfFiringRequired()const{
y7jin 0:1c8f2727e9f5 491 for(int i=0; i<numOfFiringRequired.size(); i++){
y7jin 0:1c8f2727e9f5 492 printf("node %d will fire %d time(s)\r\n", i, numOfFiringRequired[i]);
y7jin 0:1c8f2727e9f5 493 }
y7jin 0:1c8f2727e9f5 494 }
y7jin 0:1c8f2727e9f5 495
mbed36372 1:55e99f6e2aa5 496 /*
mbed36372 1:55e99f6e2aa5 497 * Compute a schedule according to numOfFiringRequired;
mbed36372 1:55e99f6e2aa5 498 * each time find a node which can fire and fire it; update the tokens on each FIFO,
mbed36372 1:55e99f6e2aa5 499 * repeat this process until all the nodes have fired the required number of times, which means a complete schedule has finished
mbed36372 1:55e99f6e2aa5 500 * As it is a function in the class SDFG, we could use all the data structures in SDFG,
mbed36372 1:55e99f6e2aa5 501 * These may includes fifos, nodes, topologyMatrix
mbed36372 1:55e99f6e2aa5 502 */
mbed36372 1:55e99f6e2aa5 503 vector<int> SDFG::makeSchedule(){
mbed36372 1:55e99f6e2aa5 504 vector<int> vSchedule;
mbed36372 1:55e99f6e2aa5 505 // TODO HERE!!!
mbed36372 1:55e99f6e2aa5 506
mbed36372 1:55e99f6e2aa5 507 return vSchedule;
y7jin 0:1c8f2727e9f5 508 }
y7jin 0:1c8f2727e9f5 509
y7jin 0:1c8f2727e9f5 510 /*display schedule*/
y7jin 0:1c8f2727e9f5 511 void SDFG::printSchedule()const{
y7jin 0:1c8f2727e9f5 512 for(int i=0; i<schedule.size(); i++){
y7jin 0:1c8f2727e9f5 513 printf("fire node %d ", schedule[i]);
y7jin 0:1c8f2727e9f5 514 nodes[schedule[i]]->display();
y7jin 0:1c8f2727e9f5 515 }
y7jin 0:1c8f2727e9f5 516 }
y7jin 0:1c8f2727e9f5 517
y7jin 0:1c8f2727e9f5 518 /*set the input of the SDF to a ring buffer buf*/
y7jin 0:1c8f2727e9f5 519 void SDFG::setInput(RingBuffer *buf){
y7jin 0:1c8f2727e9f5 520 gin->setInput(buf);
y7jin 0:1c8f2727e9f5 521 }
y7jin 0:1c8f2727e9f5 522
y7jin 0:1c8f2727e9f5 523 /*set the output of the SDF to a ring buffer buf*/
y7jin 0:1c8f2727e9f5 524 void SDFG::setOutput(RingBuffer *buf){
y7jin 0:1c8f2727e9f5 525 gout->setOutput(buf);
y7jin 0:1c8f2727e9f5 526 }
y7jin 0:1c8f2727e9f5 527
y7jin 0:1c8f2727e9f5 528 /*execute the SDF according to the computed schedule, firing each node for required number of times, repeat this process for
y7jin 0:1c8f2727e9f5 529 numOfRepetitions iterations*/
y7jin 0:1c8f2727e9f5 530 void SDFG::execute(int numOfRepetitions){
y7jin 0:1c8f2727e9f5 531 for(int i=0; i<numOfRepetitions; i++){
y7jin 0:1c8f2727e9f5 532 for(int j=0; j<schedule.size(); j++){
y7jin 0:1c8f2727e9f5 533 getNodeAt(schedule[j])->execute();
y7jin 0:1c8f2727e9f5 534 }
y7jin 0:1c8f2727e9f5 535 }
y7jin 0:1c8f2727e9f5 536 }