0,0 → 1,209 |
#include "Circuit.h" |
|
Circuit::Circuit() |
{ |
numGates = 0; |
numFFs = 0; |
numInputs = 0; |
numOutputs = 0; |
circuitLoaded = false; |
|
sim = new Simulator(this); |
connect(sim, SIGNAL(updateStatus(QString)), this, SIGNAL(updateStatus(QString))); |
} |
|
/** |
* Reads a circuit (lev) file into local data structure |
*/ |
int Circuit::readGates(QString name) |
{ |
QFile inputFile(name); |
|
// Check to make sure file exists before reading |
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { |
lastError = "Unable to open circuit (.lev) file!"; |
return 1; |
} |
|
// Open file as stream and begin reading |
QTextStream fileStream(&inputFile); |
|
int numLines, junk; |
int gateID, gateType, gateLevel, gateInputs, gateOutputs; |
int input, output; |
QMap<int, QList<int> > tmpInputs; |
QMap<int, QList<int> > tmpOutputs; |
|
fileStream >> numLines; |
fileStream >> junk; |
for (int i = 0; i < numLines - 1; i++) { |
// Read the first four values and create the gate |
fileStream >> gateID; |
fileStream >> gateType; |
fileStream >> gateLevel; |
fileStream >> gateInputs; |
|
// Initialize an instance of the specified gate |
Gate_BASE *gate; |
switch ((gType)gateType) { |
case gate_UNKNOWN: |
break; |
case gate_INPUT: |
numGates++; |
numInputs++; |
gate = new Gate_INPUT(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_OUTPUT: |
numGates++; |
numOutputs++; |
gate = new Gate_OUTPUT(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_BUFFER: |
numGates++; |
gate = new Gate_BUFFER(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_AND: |
numGates++; |
gate = new Gate_AND(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_NAND: |
numGates++; |
gate = new Gate_NAND(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_OR: |
numGates++; |
gate = new Gate_OR(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_NOR: |
numGates++; |
gate = new Gate_NOR(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_XOR: |
numGates++; |
gate = new Gate_XOR(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_XNOR: |
numGates++; |
gate = new Gate_XNOR(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_NOT: |
numGates++; |
gate = new Gate_NOT(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
case gate_DFF: |
numGates++; |
numFFs++; |
gate = new Gate_DFF(gateID, (gType)gateType, gateInputs, gateLevel); |
break; |
} |
|
// Link gate to simulator |
connect(gate, SIGNAL(enqueueSim(Gate_BASE*)), sim, SLOT(enqueueGate(Gate_BASE*))); |
|
// Store the gate into persistent storage |
gateIndex[gateID] = gate; |
|
// Seperately map gates to levels |
gatesPerLevel[gateLevel].append(gate); |
|
// Read and save the inputs to this gate |
for (int j = 0; j < gateInputs; j++) { |
fileStream >> input; |
tmpInputs[gateID].append(input); |
} |
// Ignore the repeated values |
for (int j = 0; j < gateInputs; j++) { |
fileStream >> junk; |
} |
|
// Read and save the outputs from this gate |
fileStream >> gateOutputs; |
for (int j = 0; j < gateOutputs; j++) { |
fileStream >> output; |
tmpOutputs[gateID].append(output); |
} |
|
// Ignore the rest of the line |
fileStream.readLine(); |
} |
|
// Once all the gates are allocated, we can go back and properly save fanin/fanouts |
// (allows for easier reference and path tracing) |
for (int i = 1; i <= numGates; i++) { |
Gate_BASE *tmp = gateIndex[i]; |
for (int j = 0; j < tmpInputs[i].size(); j++) { |
tmp->fanInGates.append(gateIndex[tmpInputs[i][j]]); |
} |
for (int j = 0; j < tmpOutputs[i].size(); j++) { |
tmp->fanOutGates.append(gateIndex[tmpOutputs[i][j]]); |
} |
} |
|
circuitLoaded = true; |
|
return 0; |
} |
|
/** |
* Reads a vector (vec) file into local data structure |
*/ |
int Circuit::readVectors(QString name) |
{ |
QFile inputFile(name); |
|
// Check to make sure file exists before reading |
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { |
lastError = "Unable to open vector (.vec) file!"; |
return 1; |
} |
|
return 0; |
} |
|
/** |
* Reads a circuit faults (eqf) file into local data structure |
*/ |
int Circuit::readFaults(QString name) |
{ |
QFile inputFile(name); |
|
// Check to make sure file exists before reading |
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { |
lastError = "Unable to open fault (.eqf) file!"; |
return 1; |
} |
|
return 0; |
} |
|
/** |
* Returns the last error generated from this class |
*/ |
QString Circuit::getLastError() |
{ |
return lastError; |
} |
|
/** |
* Resets all gate and wire values to unknown 'X' |
*/ |
void Circuit::reset() |
{ |
if (circuitLoaded) { |
QList<int> keys = gateIndex.keys(); |
for (int i = 0; i < gateIndex.size(); i++) { |
gateIndex[keys[i]]->reset(); |
} |
} |
} |
|
/** |
* Brings up the circuit simulator control widget |
*/ |
void Circuit::showSimController() |
{ |
simController = new SimController(); |
connect(simController, SIGNAL(singleStep()), sim, SLOT(singleStep())); |
connect(simController, SIGNAL(autoStep()), sim, SLOT(autoStep())); |
simController->show(); |
} |