001/* BusDisassembler - split input bus channels onto output port channels 002 003 Copyright (c) 2002-2014 The Regents of the University of California and 004 Research in Motion Limited. 005 All rights reserved. 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the above 009 copyright notice and the following two paragraphs appear in all copies 010 of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA OR RESEARCH IN MOTION 013 LIMITED BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 014 INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS 015 SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA 016 OR RESEARCH IN MOTION LIMITED HAVE BEEN ADVISED OF THE POSSIBILITY OF 017 SUCH DAMAGE. 018 019 THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION LIMITED 020 SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 021 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 022 PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" 023 BASIS, AND THE UNIVERSITY OF CALIFORNIA AND RESEARCH IN MOTION 024 LIMITED HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 025 ENHANCEMENTS, OR MODIFICATIONS. 026 PT_COPYRIGHT_VERSION_2 027 COPYRIGHTENDKEY 028 029 */ 030package ptolemy.actor.lib; 031 032import java.util.Iterator; 033 034import ptolemy.actor.TypedAtomicActor; 035import ptolemy.actor.TypedIOPort; 036import ptolemy.data.Token; 037import ptolemy.kernel.CompositeEntity; 038import ptolemy.kernel.util.IllegalActionException; 039import ptolemy.kernel.util.NameDuplicationException; 040 041/////////////////////////////////////////////////////////////////// 042//// BusDisassembler 043 044/** 045 Split the input bus relation into individual (possibly bus) output port 046 relations. If the width of the first output port is W1, it receives the 047 tokens from the first W1 channels of the input bus, the next output port 048 receives its width worth share from subsequent channels of the input bus 049 until either the input bus channels or all output port channels are 050 exhausted.<p> 051 052 Note: The width of a single relation (e.g. connected to an output port) 053 may be controlled by adding a <em>width</em> parameter with an IntToken value 054 representing the desired relation width.<p> 055 056 @author Zoltan Kemenczy 057 @version $Id$ 058 @since Ptolemy II 2.1 059 @Pt.ProposedRating Red (zkemenczy) 060 @Pt.AcceptedRating Red (cxh) 061 @see ptolemy.actor.IORelation 062 */ 063public class BusDisassembler extends TypedAtomicActor { 064 /** Construct a BusDisassembler with the given container and name. 065 * @param container The container. 066 * @param name The name of this actor. 067 * @exception IllegalActionException If this actor cannot be contained 068 * by the proposed container. 069 * @exception NameDuplicationException If the container already has an 070 * actor with this name. 071 */ 072 public BusDisassembler(CompositeEntity container, String name) 073 throws NameDuplicationException, IllegalActionException { 074 super(container, name); 075 input = new TypedIOPort(this, "input", true, false); 076 input.setMultiport(true); 077 _attachText("_iconDescription", 078 "<svg>\n" + "<rect x=\"0\" y=\"0\" width=\"6\" " 079 + "height=\"40\" style=\"fill:black\"/>\n" 080 + "</svg>\n"); 081 } 082 083 /////////////////////////////////////////////////////////////////// 084 //// ports and parameters //// 085 086 /** The input port. */ 087 public TypedIOPort input; 088 089 /////////////////////////////////////////////////////////////////// 090 //// public methods //// 091 @Override 092 public void fire() throws IllegalActionException { 093 super.fire(); 094 int inputWidth = input.getWidth(); 095 Iterator<TypedIOPort> outputPorts = outputPortList().iterator(); 096 TypedIOPort outputPort = outputPorts.hasNext() ? outputPorts.next() 097 : null; 098 int outputWidth = outputPort != null ? outputPort.getWidth() : 0; 099 int j = 0; 100 101 for (int i = 0; i < inputWidth; i++) { 102 if (input.hasToken(i)) { 103 Token t = input.get(i); 104 105 if (outputPort != null) { 106 outputPort.send(j, t); 107 } 108 } 109 110 if (outputPort != null) { 111 if (j < outputWidth - 1) { 112 j++; 113 } else { 114 outputPort = outputPorts.hasNext() ? outputPorts.next() 115 : null; 116 outputWidth = outputPort != null ? outputPort.getWidth() 117 : 0; 118 j = 0; 119 } 120 } 121 } 122 } 123 124 @Override 125 public void preinitialize() throws IllegalActionException { 126 super.preinitialize(); 127 128 if (inputPortList().size() > 1) { 129 throw new IllegalActionException(this, 130 "can have only one input port."); 131 } 132 } 133}