Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
335 Kevin 1
#include "Gate_XOR.h"
2
 
3
Gate_XOR::Gate_XOR(int gateID, gType type, int numInputs, int gateLevel)
4
    : Gate_BASE(gateID, type, numInputs, gateLevel)
5
{
6
    textRect = QRectF(BORDER_OFFSET * 2.2, BORDER_OFFSET, xSize - BORDER_OFFSET * 3, ySize - BORDER_OFFSET * 2);
7
}
8
 
9
void Gate_XOR::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
10
{
11
    Q_UNUSED(widget);
12
    Q_UNUSED(option);
13
 
14
#ifdef _DEBUG
15
    painter->save();
16
    painter->setPen((auxSelected) ? debugSelectedPen : debugPen);
17
    painter->setBrush(debugBrush);
18
    painter->drawRect(0, 0, xSize, ySize);
19
    painter->drawRect(textRect);
20
    if (numInputs < 2) {
21
        painter->setPen(debugErrorPen);
22
        painter->drawLine(0, 0, xSize, ySize);
23
        painter->drawLine(xSize, 0, 0, ySize);
24
    }
25
    painter->restore();
26
#endif
27
 
28
    if (auxSelected) painter->setPen(highlightedPen);
29
    else painter->setPen(defaultPen);
30
    painter->setBrush(defaultBrush);
31
 
32
    // Draw circles indicating I/O points
33
    for (int i = 0; i < numInputs; i++) {
34
        painter->drawEllipse(inputPoints[i], INPUT_CIRCLE_SIZE, INPUT_CIRCLE_SIZE);
35
    }
36
    painter->drawEllipse(outputPoint, INPUT_CIRCLE_SIZE, INPUT_CIRCLE_SIZE);
37
 
38
    // Draw gate outline
39
    QRectF leftArcBox = QRectF(0, BORDER_OFFSET, BORDER_OFFSET + (numInputs * BORDER_OFFSET / 2), ySize - BORDER_OFFSET * 2);
40
    leftArcBox.translate(BORDER_OFFSET - (BORDER_OFFSET + (numInputs * BORDER_OFFSET / 2)) / 2, 0);
41
    painter->drawArc(leftArcBox, -90 * 16, 180 * 16);
42
 
43
    QRectF leftArcBox2 = QRectF(0, BORDER_OFFSET, BORDER_OFFSET + (numInputs * BORDER_OFFSET / 2), ySize - BORDER_OFFSET * 2);
44
    leftArcBox2.translate(BORDER_OFFSET * 2 - (BORDER_OFFSET + (numInputs * BORDER_OFFSET / 2)) / 2, 0);
45
    painter->drawArc(leftArcBox2, -90 * 16, 180 * 16);
46
 
47
    QRectF rightArcBox = QRectF(0, BORDER_OFFSET, 2 * (xSize - (BORDER_OFFSET * 2)) - BORDER_OFFSET * 2, ySize - (BORDER_OFFSET * 2));
48
    rightArcBox.translate(-xSize + BORDER_OFFSET * 5, 0);
49
    painter->drawArc(rightArcBox, 0, 90 * 16);
50
    painter->drawArc(rightArcBox, -90 * 16, 90 * 16);
51
 
52
    // Draw I/O lines
53
    int a = leftArcBox.width() / 2;
54
    int b = leftArcBox.height() / 2;
55
    QPointF arcCenter = leftArcBox.center();
56
    for (int i = 0; i < numInputs; i++) {
57
        float xPt = sqrt((1 - pow(inputPoints[i].y() - arcCenter.y(), 2) / (b * b)) * (a * a)) + arcCenter.x();
58
        painter->drawLine(inputPoints[i], QPointF(xPt, inputPoints[i].y()));
59
    }
60
    painter->drawLine(outputPoint, QPointF(outputPoint.x() - BORDER_OFFSET, outputPoint.y()));
61
 
62
    // Draw text showing gate ID
63
    painter->setPen(defaultPen);
64
    painter->setFont(defaultFont);
65
    painter->drawText(textRect, Qt::AlignCenter, QString::number(gateID));
66
 
67
    // If enqueued, draw circle around gate ID
68
    if (enqueued) {
69
        painter->drawEllipse(textRect.center(), ENQUEUED_CIRCLE_WIDTH, ENQUEUED_CIRCLE_WIDTH);
70
    }
71
}
72
 
73
void Gate_XOR::simulateToOutput()
74
{
75
    // Save initial values to compare to later
76
    logicValue initValue = outputValue;
77
    logicValue initFaultyValue = outputFaultyValue;
78
 
79
    // Compute new output values
80
    bool undefined = false, undefinedFaulty = false;
81
    bool allOnes = true, allOnesFaulty = true;
82
    bool allZeros = true, allZerosFaulty = true;
83
    for (int i = 0; i < numInputs; i++) {
84
        if (inputValues[i] == logicValue_X) undefined = true;
85
        if (inputValues[i] == logicValue_0) allOnes = false;
86
        if (inputValues[i] == logicValue_1) allZeros = false;
87
 
88
        if (inputFaultyValues[i] == logicValue_X) undefinedFaulty = true;
89
        if (inputFaultyValues[i] == logicValue_0) allOnesFaulty = false;
90
        if (inputFaultyValues[i] == logicValue_1) allZerosFaulty = false;
91
    }
92
 
93
    if (!allOnes && !allZeros) outputValue = logicValue_1;
94
    else if ((allOnes || allZeros) && !undefined) outputValue = logicValue_0;
95
    else outputValue = logicValue_X;
96
 
97
    if (!allOnesFaulty && !allZerosFaulty) outputFaultyValue = logicValue_1;
98
    else if ((allOnesFaulty || allZerosFaulty) && !undefinedFaulty) outputFaultyValue = logicValue_0;
99
    else outputFaultyValue = logicValue_X;
100
 
101
    // If outputs have changed, queue the connected gate for simulation
102
    if (outputValue != initValue || outputFaultyValue != initFaultyValue)
103
        emit enqueueSim(this);
104
 
105
    // Update connected wire values
106
    for (int i = 0; i < gateOutputWires.size(); i++) {
107
        gateOutputWires[i]->setValue(outputValue, outputFaultyValue, false);
108
    }
109
}