2013-12-13 04:31:47 +00:00
|
|
|
/*
|
|
|
|
* File: StateCalculator.cpp
|
|
|
|
* Author: Christopher
|
|
|
|
*
|
|
|
|
* Created on December 12, 2013, 8:29 PM
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "StateCalculator.h"
|
|
|
|
#include "Circuit.h"
|
|
|
|
#include "trans.h"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Recalculate segment states (on/off), based on the fact that the segments
|
2013-12-15 17:49:18 +00:00
|
|
|
* in segs have just changed state. Keep track of which other segments are
|
2013-12-13 04:31:47 +00:00
|
|
|
* affected, and repeat the process on those segments. Repeat until no more
|
|
|
|
* segments change state.
|
|
|
|
*/
|
|
|
|
#define SANE (100)
|
|
|
|
|
2013-12-15 17:49:18 +00:00
|
|
|
void StateCalculator::recalc(const SegmentSet& segs) {
|
2013-12-13 04:31:47 +00:00
|
|
|
int sanity(0);
|
|
|
|
|
2013-12-15 17:49:18 +00:00
|
|
|
SegmentSet changed(segs);
|
2013-12-14 04:06:13 +00:00
|
|
|
while (!changed.empty()) {
|
2013-12-13 04:31:47 +00:00
|
|
|
if (++sanity >= SANE) {
|
|
|
|
throw "ERROR: reached maximum iteration limit while recalculating CPU state";
|
|
|
|
}
|
|
|
|
|
2013-12-14 06:04:55 +00:00
|
|
|
StateCalculator c;
|
2013-12-14 04:06:13 +00:00
|
|
|
for (auto s : changed) {
|
|
|
|
c.recalcNode(s);
|
2013-12-13 04:31:47 +00:00
|
|
|
}
|
2013-12-14 23:10:32 +00:00
|
|
|
changed = c.segs;
|
2013-12-13 04:31:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2013-12-15 17:49:18 +00:00
|
|
|
* Gets group of segments currently electrically connected to seg,
|
2013-12-13 04:31:47 +00:00
|
|
|
* gets what their group value is (or should be), goes through all
|
|
|
|
* those segments and sets their "on" value. For all connected gates,
|
|
|
|
* turn on/off, and indicate that the segments connected to those
|
|
|
|
* transistors' source and drain legs have changed, by adding them
|
2013-12-15 17:49:18 +00:00
|
|
|
* to this->segs.
|
2013-12-13 04:31:47 +00:00
|
|
|
*/
|
|
|
|
void StateCalculator::recalcNode(Segment* seg) {
|
2013-12-14 06:04:55 +00:00
|
|
|
if (!(seg->vss || seg->vcc)) {
|
|
|
|
Circuit c(seg);
|
2013-12-14 04:06:13 +00:00
|
|
|
for (auto s : c) {
|
|
|
|
setSeg(s, c.getValue());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-12-13 04:31:47 +00:00
|
|
|
|
2013-12-14 04:06:13 +00:00
|
|
|
void StateCalculator::setSeg(Segment* s, const bool on) {
|
|
|
|
if (s->on != on) {
|
|
|
|
s->on = on;
|
|
|
|
for (auto t : s->gates) {
|
|
|
|
setTrans(t, on);
|
2013-12-13 04:31:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StateCalculator::setTrans(Trans* t, const bool on) {
|
|
|
|
if (t->on != on) {
|
|
|
|
t->on = on;
|
2013-12-15 17:49:18 +00:00
|
|
|
this->segs.insert(t->c1);
|
|
|
|
this->segs.insert(t->c2);
|
2013-12-13 04:31:47 +00:00
|
|
|
}
|
|
|
|
}
|