diff options
-rw-r--r-- | GateAnd.cpp | 19 | ||||
-rw-r--r-- | GateAnd.h | 1 | ||||
-rw-r--r-- | GateOr.cpp | 23 | ||||
-rw-r--r-- | GateOr.h | 19 | ||||
-rw-r--r-- | Node.cpp | 15 | ||||
-rw-r--r-- | Node.h | 8 | ||||
-rw-r--r-- | NodeInput.cpp | 8 | ||||
-rw-r--r-- | NodeInput.h | 11 | ||||
-rw-r--r-- | NodeOutput.h | 1 | ||||
-rw-r--r-- | docs/class-diag.puml | 4 | ||||
-rw-r--r-- | makefile | 2 |
11 files changed, 83 insertions, 28 deletions
diff --git a/GateAnd.cpp b/GateAnd.cpp index 987d5e4..e51df30 100644 --- a/GateAnd.cpp +++ b/GateAnd.cpp @@ -1,11 +1,8 @@ #include "GateAnd.h" -#include "Exception.h" GateAnd GateAnd::instance(GateAnd::type); SignalLevel GateAnd::level() { - if (this->inputs.size() < 1) throw CircuitException("AndGate input size error"); - for (int i = 0; i < this->inputs.size(); i++){ SignalLevel l = this->inputs[i]->getLevel(); @@ -15,22 +12,6 @@ SignalLevel GateAnd::level() { return HIGH; } -// Concrete Nodes: -void GateAnd::sim() { - SignalLevel new_out = this->level(); - - if (new_out == UNDEFINED) return; - - printf("io size: %lu\n", this->inputs.size()); - // TODO: fix segfault somewhere below - - - - if (this->output->getLevel() == new_out) return; - - this->output->setLevel(new_out); -} - GateAnd::GateAnd(const GateAnd * prototype) : Node() { } GateAnd * GateAnd::clone() const { @@ -7,7 +7,6 @@ public: GateAnd() = default; GateAnd(const GateAnd * prototype); ~GateAnd() = default; - virtual void sim(); virtual GateAnd * clone() const; private: diff --git a/GateOr.cpp b/GateOr.cpp new file mode 100644 index 0000000..db1e04a --- /dev/null +++ b/GateOr.cpp @@ -0,0 +1,23 @@ +#include "GateOr.h" + +GateOr GateOr::instance(GateOr::type); + +SignalLevel GateOr::level() { + if (this->inputs.size() < 1) throw CircuitException("Or-gate input size error"); + + SignalLevel new_level = LOW; + for (int i = 0; i < this->inputs.size(); i++){ + SignalLevel l = this->inputs[i]->getLevel(); + + if (l == UNDEFINED) return UNDEFINED; + if (l == HIGH) new_level = HIGH; + } + return new_level; +} + +GateOr::GateOr(const GateOr * prototype) : Node() { } + +GateOr * GateOr::clone() const { + return new GateOr(this); +} + diff --git a/GateOr.h b/GateOr.h new file mode 100644 index 0000000..de694be --- /dev/null +++ b/GateOr.h @@ -0,0 +1,19 @@ +#pragma once + +#include "Node.h" + +class GateOr : public Node { +public: + GateOr() = default; + GateOr(const GateOr * prototype); + ~GateOr() = default; + virtual GateOr * clone() const; + +private: + SignalLevel level(); + + using Node::Node; + constexpr static const char * type = "or"; + static GateOr instance; +}; + @@ -19,6 +19,21 @@ void Node::setOutput(Net * net){ this->output = net; } +void Node::sim() { + size_t input_size = this->inputs.size(); + if (this->min_inputs >= 0 && input_size < min_inputs) + throw CircuitException("Too few inputs"); + if (this->max_inputs >= 0 && input_size > max_inputs) + throw CircuitException("Too many inputs"); + + SignalLevel new_out = this->level(); + + if (new_out == UNDEFINED) return; + if (this->output->getLevel() == new_out) return; + + this->output->setLevel(new_out); +} + void Node::update(){ prutprint("updated"); this->sim(); @@ -5,6 +5,7 @@ #include "Observer.h" #include "Net.h" +#include "Exception.h" using std::string; using std::vector; @@ -19,7 +20,8 @@ public: void update(); virtual void addInput(Net *); virtual void setOutput(Net *); - virtual void sim() = 0; + virtual void sim(); + virtual SignalLevel level() = 0; protected: Node(const char * type); @@ -28,5 +30,9 @@ protected: vector<Net *> inputs; Net * output; + +private: + int min_inputs = -1; + int max_inputs = -1; }; diff --git a/NodeInput.cpp b/NodeInput.cpp index 618ed31..fafbd3b 100644 --- a/NodeInput.cpp +++ b/NodeInput.cpp @@ -5,10 +5,12 @@ NodeInputLow NodeInputLow::instance(NodeInputLow::type); NodeInputHigh NodeInputHigh::instance(NodeInputHigh::type); +NodeInput::NodeInput(const char * type) : Node(type) { }; + void NodeInput::sim() { if (this->output == nullptr) return; // std::cout << this->level << " bar\n"; - this->output->setLevel(this->level); + this->output->setLevel(this->input); } NodeInput::NodeInput(const NodeInput * prototype) : Node() { } @@ -17,6 +19,10 @@ NodeInput * NodeInput::clone() const { return new NodeInput(this); } +SignalLevel NodeInput::level() { + return UNDEFINED; +}; + // NodeInputLow::NodeInputLow(const NodeInputLow * prototype) : NodeInput() { } // // INPUT_HIGH diff --git a/NodeInput.h b/NodeInput.h index e6206b9..23a5e14 100644 --- a/NodeInput.h +++ b/NodeInput.h @@ -8,11 +8,14 @@ public: NodeInput(const NodeInput * prototype); ~NodeInput() = default; virtual void sim(); + SignalLevel level(); virtual NodeInput * clone() const; protected: - using Node::Node; - SignalLevel level = UNDEFINED; + NodeInput(const char * type); + +private: + SignalLevel input = UNDEFINED; }; // Input LOW and HIGH unicorns: @@ -30,7 +33,7 @@ private: constexpr static const char * type = "input_low"; static NodeInputLow instance; - SignalLevel level = LOW; + SignalLevel input = LOW; }; class NodeInputHigh : public NodeInput { @@ -39,5 +42,5 @@ private: constexpr static const char * type = "input_high"; static NodeInputHigh instance; - SignalLevel level = HIGH; + SignalLevel input = HIGH; }; diff --git a/NodeOutput.h b/NodeOutput.h index 2e92bf0..3b60335 100644 --- a/NodeOutput.h +++ b/NodeOutput.h @@ -7,6 +7,7 @@ public: NodeOutput(const NodeOutput * prototype); ~NodeOutput() = default; virtual void sim(); + SignalLevel level() { return UNDEFINED; }; virtual NodeOutput * clone() const; private: diff --git a/docs/class-diag.puml b/docs/class-diag.puml index 4d9f489..971de54 100644 --- a/docs/class-diag.puml +++ b/docs/class-diag.puml @@ -61,8 +61,8 @@ Net -- SignalLevel Node -- SignalLevel Node <|-[dashed]-- GateAnd -Node <|-[dashed]-- GateNand -Node <|-[dashed]-- GateNor +GateAnd <|-- GateNand +GateOr <|-- GateNor Node <|-[dashed]-- GateNot Node <|-[dashed]-- GateOr Node <|-[dashed]-- GateXor @@ -20,3 +20,5 @@ clean: compile_commands.json: compiledb make -Bn + +_Bj: ; $(MAKE) -C . -Bj |