Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
335 Kevin 1
#include "Circuit.h"
2
 
3
Circuit::Circuit()
4
{
5
    numGates = 0;
6
    numFFs = 0;
7
    numInputs = 0;
8
    numOutputs = 0;
9
    circuitLoaded = false;
10
 
11
    sim = new Simulator(this);
12
    connect(sim, SIGNAL(updateStatus(QString)), this, SIGNAL(updateStatus(QString)));
13
}
14
 
15
/**
16
 * Reads a circuit (lev) file into local data structure
17
 */
18
int Circuit::readGates(QString name)
19
{
20
    QFile inputFile(name);
21
 
22
    // Check to make sure file exists before reading
23
    if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
24
        lastError = "Unable to open circuit (.lev) file!";
25
        return 1;
26
    }
27
 
28
    // Open file as stream and begin reading
29
    QTextStream fileStream(&inputFile);
30
 
31
    int numLines, junk;
32
    int gateID, gateType, gateLevel, gateInputs, gateOutputs;
33
    int input, output;
34
    QMap<int, QList<int> > tmpInputs;
35
    QMap<int, QList<int> > tmpOutputs;
36
 
37
    fileStream >> numLines;
38
    fileStream >> junk;
39
    for (int i = 0; i < numLines - 1; i++) {
40
        // Read the first four values and create the gate
41
        fileStream >> gateID;
42
        fileStream >> gateType;
43
        fileStream >> gateLevel;
44
        fileStream >> gateInputs;
45
 
46
        // Initialize an instance of the specified gate
47
        Gate_BASE *gate;
48
        switch ((gType)gateType) {
49
            case gate_UNKNOWN:
50
                break;
51
            case gate_INPUT:
52
                numGates++;
53
                numInputs++;
54
                gate = new Gate_INPUT(gateID, (gType)gateType, gateInputs, gateLevel);
55
                break;
56
            case gate_OUTPUT:
57
                numGates++;
58
                numOutputs++;
59
                gate = new Gate_OUTPUT(gateID, (gType)gateType, gateInputs, gateLevel);
60
                break;
61
            case gate_BUFFER:
62
                numGates++;
63
                gate = new Gate_BUFFER(gateID, (gType)gateType, gateInputs, gateLevel);
64
                break;
65
            case gate_AND:
66
                numGates++;
67
                gate = new Gate_AND(gateID, (gType)gateType, gateInputs, gateLevel);
68
                break;
69
            case gate_NAND:
70
                numGates++;
71
                gate = new Gate_NAND(gateID, (gType)gateType, gateInputs, gateLevel);
72
                break;
73
            case gate_OR:
74
                numGates++;
75
                gate = new Gate_OR(gateID, (gType)gateType, gateInputs, gateLevel);
76
                break;
77
            case gate_NOR:
78
                numGates++;
79
                gate = new Gate_NOR(gateID, (gType)gateType, gateInputs, gateLevel);
80
                break;
81
            case gate_XOR:
82
                numGates++;
83
                gate = new Gate_XOR(gateID, (gType)gateType, gateInputs, gateLevel);
84
                break;
85
            case gate_XNOR:
86
                numGates++;
87
                gate = new Gate_XNOR(gateID, (gType)gateType, gateInputs, gateLevel);
88
                break;
89
            case gate_NOT:
90
                numGates++;
91
                gate = new Gate_NOT(gateID, (gType)gateType, gateInputs, gateLevel);
92
                break;
93
            case gate_DFF:
94
                numGates++;
95
                numFFs++;
96
                gate = new Gate_DFF(gateID, (gType)gateType, gateInputs, gateLevel);
97
                break;
98
        }
99
 
100
        // Link gate to simulator
101
        connect(gate, SIGNAL(enqueueSim(Gate_BASE*)), sim, SLOT(enqueueGate(Gate_BASE*)));
102
 
103
        // Store the gate into persistent storage
104
        gateIndex[gateID] = gate;
105
 
106
        // Seperately map gates to levels
107
        gatesPerLevel[gateLevel].append(gate);
108
 
109
        // Read and save the inputs to this gate
110
        for (int j = 0; j < gateInputs; j++) {
111
            fileStream >> input;
112
            tmpInputs[gateID].append(input);
113
        }
114
        // Ignore the repeated values
115
        for (int j = 0; j < gateInputs; j++) {
116
            fileStream >> junk;
117
        }
118
 
119
        // Read and save the outputs from this gate
120
        fileStream >> gateOutputs;
121
        for (int j = 0; j < gateOutputs; j++) {
122
            fileStream >> output;
123
            tmpOutputs[gateID].append(output);
124
        }
125
 
126
        // Ignore the rest of the line
127
        fileStream.readLine();
128
    }
129
 
130
    // Once all the gates are allocated, we can go back and properly save fanin/fanouts
131
    // (allows for easier reference and path tracing)
132
    for (int i = 1; i <= numGates; i++) {
133
        Gate_BASE *tmp = gateIndex[i];
134
        for (int j = 0; j < tmpInputs[i].size(); j++) {
135
            tmp->fanInGates.append(gateIndex[tmpInputs[i][j]]);
136
        }
137
        for (int j = 0; j < tmpOutputs[i].size(); j++) {
138
            tmp->fanOutGates.append(gateIndex[tmpOutputs[i][j]]);
139
        }
140
    }
141
 
142
    circuitLoaded = true;
143
 
144
    return 0;
145
}
146
 
147
/**
148
 * Reads a vector (vec) file into local data structure
149
 */
150
int Circuit::readVectors(QString name)
151
{
152
    QFile inputFile(name);
153
 
154
    // Check to make sure file exists before reading
155
    if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
156
        lastError = "Unable to open vector (.vec) file!";
157
        return 1;
158
    }
159
 
160
    return 0;
161
}
162
 
163
/**
164
 * Reads a circuit faults (eqf) file into local data structure
165
 */
166
int Circuit::readFaults(QString name)
167
{
168
    QFile inputFile(name);
169
 
170
    // Check to make sure file exists before reading
171
    if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
172
        lastError = "Unable to open fault (.eqf) file!";
173
        return 1;
174
    }
175
 
176
    return 0;
177
}
178
 
179
/**
180
 * Returns the last error generated from this class
181
 */
182
QString Circuit::getLastError()
183
{
184
    return lastError;
185
}
186
 
187
/**
188
 * Resets all gate and wire values to unknown 'X'
189
 */
190
void Circuit::reset()
191
{
192
    if (circuitLoaded) {
193
        QList<int> keys = gateIndex.keys();
194
        for (int i = 0; i < gateIndex.size(); i++) {
195
            gateIndex[keys[i]]->reset();
196
        }
197
    }
198
}
199
 
200
/**
201
 * Brings up the circuit simulator control widget
202
 */
203
void Circuit::showSimController()
204
{
205
    simController = new SimController();
206
    connect(simController, SIGNAL(singleStep()), sim, SLOT(singleStep()));
207
    connect(simController, SIGNAL(autoStep()), sim, SLOT(autoStep()));
208
    simController->show();
209
}