/** * Return the buffer size of a given channel (i.e, a given port and a given channel number). The * default value is 1. If the port is an output port, then the buffer size is obtained from the * inside receiver. If it is an input port, then it is obtained from the specified port. * * @param port The given port. * @param channelNumber The given channel number. * @return The buffer size of the given channel. * @exception IllegalActionException If the channel number is out of range or if the port is * neither an input nor an output. */ public int getBufferSize(IOPort port, int channelNumber) throws IllegalActionException { Receiver[][] receivers = null; if (port.isInput()) { receivers = port.getReceivers(); } else if (port.isOutput()) { receivers = port.getInsideReceivers(); } // else { // throw new IllegalActionException(port, // "Port is neither an input nor an output."); // } // try { int size = 0; for (int copy = 0; copy < receivers[channelNumber].length; copy++) { int copySize = ((SDFReceiver) receivers[channelNumber][copy]).getCapacity(); if (copySize > size) { size = copySize; } // When an output port of a composite actor is directly // connected to an input port of the same composite actor, // calling getCapacity() will return 0. Therefore we use // the rate to determine the buffer size. if (port.isOutput()) { copySize = DFUtilities.getRate(port); if (copySize > size) { size = copySize; } } } return size; // } // catch (ArrayIndexOutOfBoundsException ex) { // throw new IllegalActionException(port, "Channel out of bounds: " // + channelNumber); // } }
/** * Generate code for the firing of refinements. * * @param code The string buffer that the generated code is appended to. * @exception IllegalActionException If the helper associated with an actor throws it while * generating fire code for the actor. */ protected void _generateRefinementCode(StringBuffer code) throws IllegalActionException { ptolemy.domains.fsm.kernel.FSMDirector director = (ptolemy.domains.fsm.kernel.FSMDirector) getComponent(); ptolemy.domains.fsm.kernel.FSMActor controller = director.getController(); FSMActor controllerHelper = (FSMActor) _getHelper(controller); int depth = 1; code.append(_getIndentPrefix(depth)); code.append( "switch (" + controllerHelper.processCode("$actorSymbol(currentState)") + ") {" + _eol); Iterator states = controller.entityList().iterator(); int stateCount = 0; depth++; while (states.hasNext()) { code.append(_getIndentPrefix(depth)); code.append("case " + stateCount + ":" + _eol); stateCount++; depth++; State state = (State) states.next(); Actor[] actors = state.getRefinement(); if (actors != null) { for (int i = 0; i < actors.length; i++) { CodeGeneratorHelper actorHelper = (CodeGeneratorHelper) _getHelper((NamedObj) actors[i]); // fire the actor // code.append(actorHelper.generateFireCode()); code.append(_getActorName(actors[i]) + "();" + _eol); // update buffer offset after firing each actor once int[][] rates = actorHelper.getRates(); Iterator ports = ((Entity) actors[i]).portList().iterator(); int portNumber = 0; while (ports.hasNext()) { IOPort port = (IOPort) ports.next(); if (rates != null) { code.append( "switch (" + actorHelper.processCode("$actorSymbol(" + "currentConfiguration)") + ") {" + _eol); for (int k = 0; k < rates.length; k++) { code.append("case " + k + ":" + _eol); if (rates[k] != null) { int rate = rates[k][portNumber]; if (port.isInput()) { _updatePortOffset(port, code, rate); } else { _updateConnectedPortsOffset(port, code, rate); } code.append("break;" + _eol); } } code.append("}" + _eol); } else { int rate = DFUtilities.getRate(port); if (port.isInput()) { _updatePortOffset(port, code, rate); } else { _updateConnectedPortsOffset(port, code, rate); } } portNumber++; } } } code.append(_getIndentPrefix(depth)); code.append("break;" + _eol); // end of case statement depth--; } depth--; code.append(_getIndentPrefix(depth)); code.append("}" + _eol); // end of switch statement }
/** * Check to see if variables are needed to represent read and write offsets for the given port. * * @return Code that declares the read and write offset variables. * @exception IllegalActionException If getting the rate or reading parameters throws it. */ protected String _createOffsetVariablesIfNeeded() throws IllegalActionException { StringBuffer code = new StringBuffer(); CompositeActor container = (CompositeActor) getComponent().getContainer(); boolean inline = ((BooleanToken) _codeGenerator.inline.getToken()).booleanValue(); StringBuffer tempCode = new StringBuffer(); Iterator outputPorts = container.outputPortList().iterator(); while (outputPorts.hasNext()) { IOPort outputPort = (IOPort) outputPorts.next(); for (int i = 0; i < outputPort.getWidthInside(); i++) { int readTokens = 0; int writeTokens = 0; // If each actor firing is inlined in the code, then read // and write positions in the buffer must return to the // previous values after one iteration of the container actor // in order to avoid using read and write offset variables. if (inline) { readTokens = DFUtilities.getRate(outputPort); writeTokens = readTokens; // If each actor firing is wrapped in a function, then read // and write positions in the buffer must return to the // previous values after one firing of this actor or one // firing of the actor that produces tokens consumed by the // inside receiver of this actor in order to avoid using // read and write offset variables. } else { readTokens = DFUtilities.getRate(outputPort); Iterator sourcePorts = outputPort.insideSourcePortList().iterator(); label1: while (sourcePorts.hasNext()) { IOPort sourcePort = (IOPort) sourcePorts.next(); CodeGeneratorHelper helper = (CodeGeneratorHelper) _getHelper(sourcePort.getContainer()); int width; if (sourcePort.isInput()) { width = sourcePort.getWidthInside(); } else { width = sourcePort.getWidth(); } for (int j = 0; j < width; j++) { Iterator channels = helper.getSinkChannels(sourcePort, j).iterator(); while (channels.hasNext()) { Channel channel = (Channel) channels.next(); if (channel.port == outputPort && channel.channelNumber == i) { writeTokens = DFUtilities.getRate(sourcePort); break label1; } } } } } tempCode.append(_createOffsetVariablesIfNeeded(outputPort, i, readTokens, writeTokens)); } } if (tempCode.length() > 0) { code.append("\n" + _codeGenerator.comment(container.getName() + "'s offset variables")); code.append(tempCode); } Iterator actors = container.deepEntityList().iterator(); while (actors.hasNext()) { StringBuffer tempCode2 = new StringBuffer(); Actor actor = (Actor) actors.next(); Iterator inputPorts = actor.inputPortList().iterator(); while (inputPorts.hasNext()) { IOPort inputPort = (IOPort) inputPorts.next(); for (int i = 0; i < inputPort.getWidth(); i++) { int readTokens = 0; int writeTokens = 0; // If each actor firing is inlined in the code, // then read and write positions in the buffer // must return to the previous values after one // iteration of the container actor in order to // avoid using read and write offset variables. if (inline) { Variable firings = (Variable) ((NamedObj) actor).getAttribute("firingsPerIteration"); int firingsPerIteration = ((IntToken) firings.getToken()).intValue(); readTokens = DFUtilities.getRate(inputPort) * firingsPerIteration; writeTokens = readTokens; // If each actor firing is wrapped in a // function, then read and write positions in // the buffer must return to the previous // values after one firing of this actor or // one firing of the actor that produces // tokens consumed by this actor in order to // avoid using read and write offset // variables. } else { readTokens = DFUtilities.getRate(inputPort); Iterator sourcePorts = inputPort.sourcePortList().iterator(); label2: while (sourcePorts.hasNext()) { IOPort sourcePort = (IOPort) sourcePorts.next(); CodeGeneratorHelper helper = (CodeGeneratorHelper) _getHelper(sourcePort.getContainer()); int width; if (sourcePort.isInput()) { width = sourcePort.getWidthInside(); } else { width = sourcePort.getWidth(); } for (int j = 0; j < width; j++) { Iterator channels = helper.getSinkChannels(sourcePort, j).iterator(); while (channels.hasNext()) { Channel channel = (Channel) channels.next(); if (channel.port == inputPort && channel.channelNumber == i) { writeTokens = DFUtilities.getRate(sourcePort); break label2; } } } } } tempCode2.append(_createOffsetVariablesIfNeeded(inputPort, i, readTokens, writeTokens)); } } if (tempCode2.length() > 0) { code.append("\n" + _codeGenerator.comment(actor.getName() + "'s offset variables")); code.append(tempCode2); } } return code.toString(); }