public Simulator(SpdStaticStreamGraph ssg, JoinerSimulator joinerSimulator) { this.ssg = ssg; this.joinerSimulator = joinerSimulator; this.toplevel = ssg.getTopLevel(); this.layout = ((SpdStreamGraph) ssg.getStreamGraph()).getLayout(); this.rawChip = ((SpdStreamGraph) ssg.getStreamGraph()).getRawChip(); }
/** * @return true if we need switch code for this graph, otherwise we can just use the dynamic * network because there are no overlapping routes and no splitters or joiners */ public static boolean needSimulator(SpdStaticStreamGraph ssg) { // check if there are any overlapping routes... if (((SpdStreamGraph) ssg.getStreamGraph()).getLayout().getIntermediateTiles().size() > 0) return true; // check if there are any splitters... Iterator it = ssg.getFlatNodes().iterator(); while (it.hasNext()) { FlatNode node = (FlatNode) it.next(); if (node.isJoiner() || node.isSplitter()) return true; } // all's good! return false; }
/** consume the data and return the number of items produced * */ protected int fireMe( FlatNode fire, SimulationCounter counters, HashMap<FlatNode, Integer> executionCounts) { if (fire.contents instanceof SIRFilter) { // decrement the schedule execution counter decrementExecutionCounts(fire, executionCounts, counters); // consume the date from the buffer counters.decrementBufferCount(fire, consumedItems(fire, counters, executionCounts)); // for a steady state execution return the normal push int ret = ((SIRFilter) fire.contents).getPushInt(); // if the filter is a two stage, and it has not fired // return the initPush() unless the initWork does nothing if (initSimulation && !counters.hasFired(fire) && fire.contents instanceof SIRTwoStageFilter) ret = ((SIRTwoStageFilter) fire.contents).getInitPushInt(); else if (!initSimulation && KjcOptions.ratematch) { // we are ratematching so produce all the data on the one firing. ret *= ssg.getMult(fire, false); } // now this node has fired counters.setFired(fire); return ret; } else if (fire.contents instanceof SIRJoiner) { return fireJoiner(fire, counters, executionCounts); } Utils.fail("Trying to fire a non-filter or joiner"); return -1; }
/** * return how many items a node consumes (pop's) for one firing given the current state of the * simulation * */ protected int consumedItems( FlatNode fire, SimulationCounter counters, HashMap<FlatNode, Integer> executionCounts) { // if this is the first time a two stage fires consume initpop if (initSimulation && !counters.hasFired(fire) && fire.contents instanceof SIRTwoStageFilter) return ((SIRTwoStageFilter) fire.contents).getInitPopInt(); else if (!initSimulation && KjcOptions.ratematch && fire.contents instanceof SIRFilter) { // we are ratematching on the filter // it consumes for the entire steady state return ((SIRFilter) fire.contents).getPopInt() * ssg.getMult(fire, false); } // otherwise just consume pop return ((SIRFilter) fire.contents).getPopInt(); }
/** * given a node * * <pre>fire</pre> * * and the current state of the simulation, return how many items are necessary for the node to * fire. */ protected int itemsNeededToFire( FlatNode fire, SimulationCounter counters, HashMap<FlatNode, Integer> executionCounts) { // if this is the first time a two stage initpeek is needed to execute if (initSimulation && !counters.hasFired(fire) && fire.contents instanceof SIRTwoStageFilter) { return ((SIRTwoStageFilter) fire.contents).getInitPeekInt(); } else if (!initSimulation && KjcOptions.ratematch && fire.contents instanceof SIRFilter) { // we are ratematching filters return (((SIRFilter) fire.contents).getPopInt() * ssg.getMult(fire, false) + (((SIRFilter) fire.contents).getPeekInt() - ((SIRFilter) fire.contents).getPopInt())); } // otherwise peek items are needed return ((SIRFilter) fire.contents).getPeekInt(); }