001/* A static integer arithmetic logic unit. 002 003 Copyright (c) 2007-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.actor.lib.tutorial; 029 030import ptolemy.actor.TypedAtomicActor; 031import ptolemy.actor.TypedIOPort; 032import ptolemy.data.IntToken; 033import ptolemy.data.Token; 034import ptolemy.data.expr.StringParameter; 035import ptolemy.data.type.BaseType; 036import ptolemy.kernel.CompositeEntity; 037import ptolemy.kernel.util.IllegalActionException; 038import ptolemy.kernel.util.NameDuplicationException; 039import ptolemy.kernel.util.Workspace; 040 041/////////////////////////////////////////////////////////////////// 042//// StaticALU 043 044/** 045 <p> 046 A static integer arithmetic logic unit. 047 </p> 048 049 @author Man-Kit Leung 050 @version $Id$ 051 @since Ptolemy II 6.0.2 052 @Pt.ProposedRating Red (mankit) 053 @Pt.AcceptedRating Red (mankit) 054 */ 055public class StaticALU extends TypedAtomicActor { 056 /** Construct an actor in the specified container with the specified 057 * name. 058 * @param container The container. 059 * @param name The name of this adder within the container. 060 * @exception IllegalActionException If the actor cannot be contained 061 * by the proposed container. 062 * @exception NameDuplicationException If the name coincides with 063 * an actor already in the container. 064 */ 065 public StaticALU(CompositeEntity container, String name) 066 throws IllegalActionException, NameDuplicationException { 067 super(container, name); 068 A = new TypedIOPort(this, "A", true, false); 069 A.setTypeEquals(BaseType.INT); 070 B = new TypedIOPort(this, "B", true, false); 071 B.setTypeEquals(BaseType.INT); 072 073 operation = new StringParameter(this, "operation"); 074 operation.setExpression("0 : (NOP)"); 075 operation.addChoice("0 : (NOP)"); 076 operation.addChoice("1 : (A + B)"); 077 operation.addChoice("2 : (A - B)"); 078 operation.addChoice("3 : (A * B)"); 079 operation.addChoice("4 : (A / B)"); 080 081 output = new TypedIOPort(this, "output", false, true); 082 output.setTypeEquals(BaseType.INT); 083 084 } 085 086 /////////////////////////////////////////////////////////////////// 087 //// ports and parameters //// 088 089 /** Input port for the first operand. The port type is integer. 090 */ 091 public TypedIOPort A; 092 093 /** Input port for the second operand. The port type is integer. 094 */ 095 public TypedIOPort B; 096 097 /** Input port for the operation code. The port type is integer. 098 * The value of the input tokens should not exceed the number of 099 * operations supported. 100 */ 101 public StringParameter operation; 102 103 /** Output port. The type is inferred from the connections. 104 */ 105 public TypedIOPort output; 106 107 /////////////////////////////////////////////////////////////////// 108 //// public methods //// 109 110 /** Override the base class to set type constraints. 111 * @param workspace The workspace for the new object. 112 * @return A new instance of StaticALU. 113 * @exception CloneNotSupportedException If a derived class contains 114 * an attribute that cannot be cloned. 115 */ 116 @Override 117 public Object clone(Workspace workspace) throws CloneNotSupportedException { 118 StaticALU newObject = (StaticALU) super.clone(workspace); 119 newObject.A.setTypeEquals(BaseType.INT); 120 newObject.B.setTypeEquals(BaseType.INT); 121 return newObject; 122 } 123 124 /** If there is at least one token on each of the input ports, the 125 * first token from each port is consumed. The value of the token 126 * from the operation input port determines which operation will be 127 * perform on the tokens from input port A and B. The opcode is 128 * defined as follow: 129 * 0 - NOP 130 * 1 - Addition (A + B) 131 * 2 - Subtraction (A - B) 132 * 3 - Multiplication (A * B) 133 * 4 - Division (A / B) 134 * @exception IllegalActionException If the input operation code 135 * is not supported. 136 */ 137 @Override 138 public void fire() throws IllegalActionException { 139 super.fire(); 140 Token result = null; 141 142 if (A.hasToken(0) && B.hasToken(0)) { 143 int opcode = Integer 144 .parseInt(operation.getExpression().substring(0, 1)); 145 IntToken tokenA = (IntToken) A.get(0); 146 IntToken tokenB = (IntToken) B.get(0); 147 148 switch (opcode) { 149 case 0: // NOP 150 result = IntToken.ZERO; 151 break; 152 case 1: // addition 153 result = tokenA.add(tokenB); 154 break; 155 case 2: // subtraction 156 result = tokenA.subtract(tokenB); 157 break; 158 case 3: // multiplication 159 result = tokenA.multiply(tokenB); 160 break; 161 case 4: // division 162 result = tokenA.divide(tokenB); 163 break; 164 default: 165 throw new IllegalActionException(this, 166 "Unsupported operation code: " + opcode + ".\n"); 167 } 168 } 169 output.send(0, result); 170 } 171}