wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
ElementSimState.cpp
Go to the documentation of this file.
1// Copyright 2015 - 2026, GIBIS-UNIFESP and the wiRedPanda contributors
2// SPDX-License-Identifier: GPL-3.0-or-later
3
5
7#include "App/Wiring/Port.h"
8
9void ElementSimState::reset(const QVector<OutputPort *> &outputPorts)
10{
11 // Reset each output slot to the port's power-on default so that the next
12 // BeWavedDolphin sweep starts from a known, reproducible state.
13 // Subclasses with internal edge-detection variables (flip-flops) override
14 // GraphicElement::resetSimState() to also clear those fields.
15 for (int i = 0; i < m_outputs.size(); ++i) {
16 const Status def = (i < outputPorts.size())
17 ? outputPorts.at(i)->defaultValue()
18 : Status::Inactive;
19 m_outputs[i] = (def == Status::Unknown) ? Status::Inactive : def;
20 }
21 m_outputChanged = true;
22}
23
24void ElementSimState::connectPredecessor(int inputIndex, GraphicElement *source, int outputPort)
25{
26 if (inputIndex >= m_connections.size()) {
27 return;
28 }
29 m_connections[inputIndex] = {source, outputPort};
30}
31
32void ElementSimState::initVectors(int inputCount, int outputCount, const QVector<OutputPort *> &outputPorts)
33{
34 m_connections.fill({}, inputCount);
35 m_inputs.fill(Status::Inactive, inputCount);
36 m_outputs.resize(outputCount);
37 m_staged.resize(outputCount);
38 m_deferCommit = false;
39 // Initialize outputs from port default statuses when they're explicitly set
40 // (e.g., flip-flop Q'=Active), otherwise default to Inactive.
41 // Using Inactive (not Unknown) ensures gate-level feedback loops can settle.
42 for (int i = 0; i < outputCount; ++i) {
43 if (i < outputPorts.size()) {
44 const Status def = outputPorts.at(i)->defaultValue();
45 m_outputs[i] = (def == Status::Unknown) ? Status::Inactive : def;
46 } else {
47 m_outputs[i] = Status::Inactive;
48 }
49 }
50 m_outputChanged = false;
51}
52
53bool ElementSimState::updateInputs(bool allowUnknown, const QVector<InputPort *> &inputPorts)
54{
55 for (int index = 0; index < m_connections.size(); ++index) {
56 auto *pred = m_connections.at(index).sourceElement;
57 Status val;
58 if (pred) {
59 val = pred->outputValue(m_connections.at(index).sourceOutputIndex);
60 } else {
61 if (index < inputPorts.size() && inputPorts.at(index)->connections().size() > 1) {
62 val = Status::Error; // multi-driver bus conflict
63 } else {
64 // Unconnected input: use port's default status (replaces global GND/VCC).
65 val = (index < inputPorts.size()) ? inputPorts.at(index)->defaultValue() : Status::Unknown;
66 }
67 }
68
69 // allowUnknown: only fail for truly unconnected inputs that return Unknown.
70 // !allowUnknown: fail for any Unknown or Error value.
71 const bool shouldFail = allowUnknown ? (val == Status::Unknown && !pred)
72 : (val == Status::Unknown || val == Status::Error);
73 if (shouldFail) {
74 for (auto &out : m_outputs) {
75 if (out != Status::Unknown) {
76 m_outputChanged = true;
77 }
78 out = Status::Unknown;
79 }
80 return false;
81 }
82 m_inputs[index] = val;
83 }
84 return true;
85}
86
87int ElementSimState::decodeSelectValue(int offset, int count) const
88{
89 int selectValue = 0;
90 for (int i = 0; i < count; i++) {
91 if (m_inputs.at(offset + i) == Status::Active) {
92 selectValue |= (1 << i);
93 }
94 }
95 return selectValue;
96}
Per-element simulation runtime state (input/output values and the connection graph).
Enums::Status Status
Definition Enums.h:106
Abstract base class for all graphical circuit elements.
Port classes: Port (base), InputPort, and OutputPort.
bool updateInputs(bool allowUnknown, const QVector< InputPort * > &inputPorts)
Snapshots each predecessor's output into the input cache, reading inputPorts for unconnected-input de...
void reset(const QVector< OutputPort * > &outputPorts)
Resets each output slot to its port's power-on default (Unknown coerced to Inactive).
int decodeSelectValue(int offset, int count) const
Decodes count select-line statuses starting at offset into a binary index.
void initVectors(int inputCount, int outputCount, const QVector< OutputPort * > &outputPorts)
Allocates the I/O vectors and seeds outputs from outputPorts default statuses.
void connectPredecessor(int inputIndex, GraphicElement *source, int outputPort)
Records that simulation input inputIndex is driven by source output outputPort.
Abstract base class for all graphical circuit elements in wiRedPanda.