skeleton for lab1
Dependencies: AvailableMemory mbed-rtos mbed
Fork of helloaabbc by
SDF.cpp@0:1c8f2727e9f5, 2014-04-03 (annotated)
- Committer:
- y7jin
- Date:
- Thu Apr 03 22:56:32 2014 +0000
- Revision:
- 0:1c8f2727e9f5
- Child:
- 1:55e99f6e2aa5
hello
Who changed what in which revision?
User | Revision | Line number | New 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); |
y7jin | 0:1c8f2727e9f5 | 180 | 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 | |
y7jin | 0:1c8f2727e9f5 | 496 | /*compile a schedule according to numOfFiringRequired; each time find a node which can fire and fire it; update the tokens on each FIFO, |
y7jin | 0:1c8f2727e9f5 | 497 | repeat this process until all the nodes have fired the required number of times, which means a complete schedule has finished*/ |
y7jin | 0:1c8f2727e9f5 | 498 | void SDFG::makeSchedule(){ |
y7jin | 0:1c8f2727e9f5 | 499 | vector<int> buffers(fifos.size()), firingCount(nodes.size()); |
y7jin | 0:1c8f2727e9f5 | 500 | for(int i=0; i<buffers.size(); i++)buffers[i]=fifos[i]->getSize(); |
y7jin | 0:1c8f2727e9f5 | 501 | for(int i=0; i<firingCount.size(); i++)firingCount[i]=0; |
y7jin | 0:1c8f2727e9f5 | 502 | bool finished; |
y7jin | 0:1c8f2727e9f5 | 503 | do{ |
y7jin | 0:1c8f2727e9f5 | 504 | /*check if all nodes have fired the number of times required, as computed in hasSchedule() function*/ |
y7jin | 0:1c8f2727e9f5 | 505 | finished=true; |
y7jin | 0:1c8f2727e9f5 | 506 | for(int i=0; i<firingCount.size(); i++){ |
y7jin | 0:1c8f2727e9f5 | 507 | if(firingCount[i]<numOfFiringRequired[i]){ |
y7jin | 0:1c8f2727e9f5 | 508 | /*this node has not fired that many times, then it has not finished*/ |
y7jin | 0:1c8f2727e9f5 | 509 | finished=false; |
y7jin | 0:1c8f2727e9f5 | 510 | vector<int> tempBuf(buffers); |
y7jin | 0:1c8f2727e9f5 | 511 | bool valid=true; |
y7jin | 0:1c8f2727e9f5 | 512 | /*test if this node can fire, namely if it has all its input data ready on the inbound FIFOs; we are doing matrix multiplication |
y7jin | 0:1c8f2727e9f5 | 513 | with a vector in a compressed form, if the resulting buffer only has non-negative elements, then it means this node can |
y7jin | 0:1c8f2727e9f5 | 514 | fire*/ |
y7jin | 0:1c8f2727e9f5 | 515 | for(int j=0; j<tempBuf.size(); j++){ |
y7jin | 0:1c8f2727e9f5 | 516 | if(topologyMatrix[j].getSrc()==i){ |
y7jin | 0:1c8f2727e9f5 | 517 | tempBuf[j]+=topologyMatrix[j].getTokensProduced(); |
y7jin | 0:1c8f2727e9f5 | 518 | }else if(topologyMatrix[j].getDst()==i){ |
y7jin | 0:1c8f2727e9f5 | 519 | tempBuf[j]-=topologyMatrix[j].getTokensConsumed(); |
y7jin | 0:1c8f2727e9f5 | 520 | if(tempBuf[j]<0){ |
y7jin | 0:1c8f2727e9f5 | 521 | valid=false; |
y7jin | 0:1c8f2727e9f5 | 522 | break; |
y7jin | 0:1c8f2727e9f5 | 523 | } |
y7jin | 0:1c8f2727e9f5 | 524 | } |
y7jin | 0:1c8f2727e9f5 | 525 | } |
y7jin | 0:1c8f2727e9f5 | 526 | if(valid){ |
y7jin | 0:1c8f2727e9f5 | 527 | /*fire this node*/ |
y7jin | 0:1c8f2727e9f5 | 528 | firingCount[i]++; |
y7jin | 0:1c8f2727e9f5 | 529 | schedule.push_back(i); |
y7jin | 0:1c8f2727e9f5 | 530 | for(int j=0; j<tempBuf.size(); j++)buffers[j]=tempBuf[j]; |
y7jin | 0:1c8f2727e9f5 | 531 | } |
y7jin | 0:1c8f2727e9f5 | 532 | } |
y7jin | 0:1c8f2727e9f5 | 533 | } |
y7jin | 0:1c8f2727e9f5 | 534 | }while(!finished); |
y7jin | 0:1c8f2727e9f5 | 535 | } |
y7jin | 0:1c8f2727e9f5 | 536 | |
y7jin | 0:1c8f2727e9f5 | 537 | /*display schedule*/ |
y7jin | 0:1c8f2727e9f5 | 538 | void SDFG::printSchedule()const{ |
y7jin | 0:1c8f2727e9f5 | 539 | for(int i=0; i<schedule.size(); i++){ |
y7jin | 0:1c8f2727e9f5 | 540 | printf("fire node %d ", schedule[i]); |
y7jin | 0:1c8f2727e9f5 | 541 | nodes[schedule[i]]->display(); |
y7jin | 0:1c8f2727e9f5 | 542 | } |
y7jin | 0:1c8f2727e9f5 | 543 | } |
y7jin | 0:1c8f2727e9f5 | 544 | |
y7jin | 0:1c8f2727e9f5 | 545 | /*set the input of the SDF to a ring buffer buf*/ |
y7jin | 0:1c8f2727e9f5 | 546 | void SDFG::setInput(RingBuffer *buf){ |
y7jin | 0:1c8f2727e9f5 | 547 | gin->setInput(buf); |
y7jin | 0:1c8f2727e9f5 | 548 | } |
y7jin | 0:1c8f2727e9f5 | 549 | |
y7jin | 0:1c8f2727e9f5 | 550 | /*set the output of the SDF to a ring buffer buf*/ |
y7jin | 0:1c8f2727e9f5 | 551 | void SDFG::setOutput(RingBuffer *buf){ |
y7jin | 0:1c8f2727e9f5 | 552 | gout->setOutput(buf); |
y7jin | 0:1c8f2727e9f5 | 553 | } |
y7jin | 0:1c8f2727e9f5 | 554 | |
y7jin | 0:1c8f2727e9f5 | 555 | /*execute the SDF according to the computed schedule, firing each node for required number of times, repeat this process for |
y7jin | 0:1c8f2727e9f5 | 556 | numOfRepetitions iterations*/ |
y7jin | 0:1c8f2727e9f5 | 557 | void SDFG::execute(int numOfRepetitions){ |
y7jin | 0:1c8f2727e9f5 | 558 | for(int i=0; i<numOfRepetitions; i++){ |
y7jin | 0:1c8f2727e9f5 | 559 | for(int j=0; j<schedule.size(); j++){ |
y7jin | 0:1c8f2727e9f5 | 560 | getNodeAt(schedule[j])->execute(); |
y7jin | 0:1c8f2727e9f5 | 561 | } |
y7jin | 0:1c8f2727e9f5 | 562 | } |
y7jin | 0:1c8f2727e9f5 | 563 | } |