00001
00025 #ifndef TWOINPUTGATE_H_
00026 #define TWOINPUTGATE_H_
00027
00028
00029 #include <string>
00030
00031 #include <cassert>
00032
00033 #include "Event.h"
00034 #include "LogicGate.h"
00035 #include "LogicFunctions.h"
00036 #include "LogicUpdate.h"
00037 #include "BaseTwoInputGate.h"
00038
00042 class TwoInputGate: public LogicGate, public BaseTwoInputGate {
00043
00044 private:
00045
00051 const TwoInputFunc& func;
00052
00053 public:
00064 TwoInputGate(size_t id, const TwoInputFunc& func, const std::string& outputName, const std::string& input1Name, const std::string& input2Name,
00065 const SimTime& delay)
00066 : LogicGate (id, 1, 2, delay), BaseTwoInputGate (outputName, input1Name, input2Name), func (func) {}
00067
00068 TwoInputGate (const TwoInputGate& that)
00069 : LogicGate (that), BaseTwoInputGate (that), func(that.func) {}
00070
00071 virtual TwoInputGate* clone () const {
00072 return new TwoInputGate (*this);
00073 }
00074
00075
00076
00077
00078
00079 protected:
00080
00084 virtual LogicVal evalOutput () const {
00085 return func (getInput1Val (), getInput2Val ());
00086 }
00087
00095 virtual void execEvent (Graph& graph, GNode& myNode, const EventTy& event) {
00096
00097 if (event.getType() == EventTy::NULL_EVENT) {
00098
00099
00100 sendEventsToFanout(graph, myNode, event, EventTy::NULL_EVENT, LogicUpdate ());
00101
00102 } else {
00103
00104 const LogicUpdate& lu = event.getAction();
00105
00106 if (input1Name == (lu.getNetName())) {
00107 input1Val = lu.getNetVal();
00108
00109 } else if (input2Name == (lu.getNetName())) {
00110 input2Val = lu.getNetVal();
00111
00112 } else {
00113 LogicGate::netNameMismatch(lu);
00114 }
00115
00116
00117
00118
00119 LogicVal newOutput = evalOutput();
00120 this->outputVal = newOutput;
00121
00122 LogicUpdate drvFanout(outputName, newOutput);
00123
00124 sendEventsToFanout(graph, myNode, event, EventTy::REGULAR_EVENT, drvFanout);
00125
00126 }
00127
00128 }
00129
00130
00131
00132
00133 public:
00140 virtual bool hasInputName(const std::string& net) const {
00141 return BaseTwoInputGate::hasInputName (net);
00142 }
00143
00150 virtual bool hasOutputName(const std::string& net) const {
00151 return BaseTwoInputGate::hasOutputName (net);
00152 }
00153
00159 virtual const std::string& getOutputName() const {
00160 return BaseTwoInputGate::getOutputName ();
00161 }
00162
00172 virtual size_t getInputIndex(const std::string& net) const {
00173 if (this->input2Name == (net)) {
00174 return 1;
00175
00176 } else if (this->input1Name == (net)) {
00177 return 0;
00178
00179 } else {
00180 abort ();
00181 return -1;
00182 }
00183 }
00184
00188 virtual const std::string getGateName () const {
00189 return func.toString ();
00190 }
00191
00192
00193 virtual const std::string toString() const {
00194 std::ostringstream ss;
00195 ss << AbstractSimObject::toString () << getGateName () << ": " << BaseTwoInputGate::toString ()
00196 << " delay = " << BaseLogicGate::getDelay ();
00197 return ss.str ();
00198 }
00199 };
00200
00201 #endif