void V3SvrBoolector::add_RED_XOR_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (BV_RED_XOR == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); // Build RED_XOR I/O Relation const V3NetId in1 = _ntk->getInputNetId(out, 0); assert (validNetId(in1)); BtorExp* const exp1 = getVerifyData(in1, depth); assert (exp1); // Set BtorExp* _ntkData[index].push_back(boolector_redxor(_Solver, exp1)); assert (getVerifyData(out, depth)); }
void V3SvrBoolector::add_FF_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (V3_FF == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); const uint32_t width = _ntk->getNetWidth(out); assert (width); if (_freeBound) { // Set BtorExp* _ntkData[index].push_back(boolector_var(_Solver, width, NULL)); } else if (depth) { // Build FF I/O Relation const V3NetId in1 = _ntk->getInputNetId(out, 0); assert (validNetId(in1)); BtorExp* const exp1 = getVerifyData(in1, depth - 1); assert (exp1); // Set BtorExp* _ntkData[index].push_back(boolector_copy(_Solver, exp1)); } else { // Set BtorExp* _ntkData[index].push_back(boolector_var(_Solver, width, NULL)); BtorExp* const exp = _ntkData[index].back(); assert (exp); // Build FF Initial State const V3NetId in1 = _ntk->getInputNetId(out, 1); assert (validNetId(in1)); const V3BvNtk* const ntk = dynamic_cast<const V3BvNtk*>(_ntk); if (ntk) { if (BV_CONST == ntk->getGateType(in1)) { const V3BitVecX* const value = ntk->getInputConstValue(in1); assert (value); assert (width == value->size()); char* bv_value = new char[width + 1]; bv_value[width] = '\0'; for (uint32_t i = 0, j = width - 1; i < width; ++i, --j) bv_value[j] = (*value)[i]; BtorExp* const init_exp = boolector_const(_Solver, bv_value); assert (init_exp); _init.push_back(boolector_eq(_Solver, exp, init_exp)); delete[] bv_value; boolector_release(_Solver, init_exp); } else { // Build Initial Circuit BtorExp* const exp1 = getVerifyData(in1, 0); assert (exp1); _init.push_back(boolector_eq(_Solver, exp, exp1)); } } else { if (AIG_FALSE == _ntk->getGateType(in1)) _init.push_back(!isV3NetInverted(in1) ? boolector_not(_Solver, exp) : boolector_copy(_Solver, exp)); else { // Build Initial Circuit BtorExp* const exp1 = getVerifyData(in1, 0); assert (exp1); _init.push_back(boolector_eq(_Solver, exp, exp1)); } } } assert (getVerifyData(out, depth)); }
void V3SvrBoolector::add_AND_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (!getVerifyData(out, depth)); assert ((AIG_NODE == _ntk->getGateType(out)) || (BV_AND == _ntk->getGateType(out))); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); // Build AND I/O Relation const V3NetId in1 = _ntk->getInputNetId(out, 0); assert (validNetId(in1)); const V3NetId in2 = _ntk->getInputNetId(out, 1); assert (validNetId(in2)); BtorExp* const exp1 = getVerifyData(in1, depth); assert (exp1); BtorExp* const exp2 = getVerifyData(in2, depth); assert (exp2); // Set BtorExp* _ntkData[index].push_back(boolector_and(_Solver, exp1, exp2)); assert (getVerifyData(out, depth)); }
void V3SvrBoolector::add_SLICE_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (BV_SLICE == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); // Build SLICE I/O Relation const V3NetId in1 = _ntk->getInputNetId(out, 0); assert (validNetId(in1)); BtorExp* const exp1 = getVerifyData(in1, depth); assert (exp1); const V3BvNtk* const ntk = dynamic_cast<const V3BvNtk*>(_ntk); assert (ntk); const uint32_t msb = ntk->getInputSliceBit(out, true); const uint32_t lsb = ntk->getInputSliceBit(out, false); // Set BtorExp* if (msb >= lsb) _ntkData[index].push_back(boolector_slice(_Solver, exp1, msb, lsb)); assert (getVerifyData(out, depth)); }
void V3SvrBoolector::add_MUX_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (BV_MUX == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); // Build MUX I/O Relation const V3NetId fIn = _ntk->getInputNetId(out, 0); assert (validNetId(fIn)); const V3NetId tIn = _ntk->getInputNetId(out, 1); assert (validNetId(tIn)); const V3NetId sIn = _ntk->getInputNetId(out, 2); assert (validNetId(sIn)); BtorExp* const fExp = getVerifyData(fIn, depth); assert (fExp); BtorExp* const tExp = getVerifyData(tIn, depth); assert (tExp); BtorExp* const sExp = getVerifyData(sIn, depth); assert (sExp); // Set BtorExp* _ntkData[index].push_back(boolector_cond(_Solver, sExp, tExp, fExp)); assert (getVerifyData(out, depth)); }
void V3SvrBoolector::assertProperty(const V3NetId& id, const bool& invert, const uint32_t& depth) { assert (validNetId(id)); assert (1 == _ntk->getNetWidth(id)); BtorExp* const exp = getVerifyData(id, depth); assert (exp); if (!invert) boolector_assert(_Solver, exp); else boolector_assert(_Solver, boolector_not(_Solver, exp)); }
// Helper Functions for Ntk Construction Validation Check const bool V3Ntk::reportInvertingNet(const V3NetId& id) const { assert (validNetId(id)); if (isV3NetInverted(id)) Msg(MSG_ERR) << "Unexpected Inverting Net = " << id.id << endl; else return false; return true; }
// Gate Formula to Solver Functions void V3SvrBoolector::add_FALSE_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (AIG_FALSE == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); // Set BtorExp* _ntkData[index].push_back(boolector_const(_Solver, "0")); assert (getVerifyData(out, depth)); }
void V3SvrBoolector::add_PI_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (V3_PI == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); // Set BtorExp* _ntkData[index].push_back(boolector_var(_Solver, _ntk->getNetWidth(out), NULL)); assert (getVerifyData(out, depth)); }
void V3Ntk::createGate(const V3GateType& type, const V3NetId& id) { // Check Validation assert (validNetId(id)); assert (type < V3_XD); assert (type > V3_PI); assert (dynamic_cast<const V3BvNtk*>(this) || type <= AIG_FALSE); assert (!(dynamic_cast<const V3BvNtk*>(this)) || (type <= V3_MODULE || type > AIG_FALSE)); //assert (!reportMultipleDrivenNet(type, id)); //assert (!reportUnexpectedFaninSize(type, id)); // Set Gate Type _typeMisc[id.id].type = type; }
const bool V3Ntk::reportUnexpectedFaninSize(const V3GateType& type, const V3NetId& id) const { assert (type < V3_XD); assert (validNetId(id)); if (((isV3ReducedType(type) || BV_CONST == type || V3_PIO == type) && (getInputNetSize(id) != 1)) || ((isV3PairType(type) || AIG_NODE == type || V3_FF == type || BV_SLICE == type) && (getInputNetSize(id) != 2)) || ((BV_MUX == type) && (getInputNetSize(id) != 3)) || ((V3_MODULE == type) && (getInputNetSize(id) != 1))) Msg(MSG_ERR) << "Expecting Fanin Size is One while " << getInputNetSize(id) << " is Found @ " << id.id << " for Gate Type = " << V3GateTypeStr[type] << endl; else return false; return true; }
const bool V3Ntk::reportMultipleDrivenNet(const V3GateType& type, const V3NetId& id) const { assert (type < V3_GATE_TOTAL); assert (validNetId(id)); if (V3_PI != getGateType(id)) Msg(MSG_ERR) << "Multiple-Driven @ " << id.id << "(" << V3GateTypeStr[type] << ")" << ", Exist " << V3GateTypeStr[getGateType(id)] << endl; else if (_globalClk.id == id.id) Msg(MSG_ERR) << "Clock Signal \"" << _globalClk.id << "\" Cannot be Driven, found @ " << id.id << "(" << V3GateTypeStr[type] << ")" << endl; else return false; return true; }
void V3SvrBoolector::add_CONST_Formula(const V3NetId& out, const uint32_t& depth) { // Check Output Validation assert (validNetId(out)); assert (BV_CONST == _ntk->getGateType(out)); assert (!getVerifyData(out, depth)); const uint32_t index = getV3NetIndex(out); assert (depth == _ntkData[index].size()); const uint32_t width = _ntk->getNetWidth(out); assert (width); // Build CONST I/O Relation const V3BvNtk* const ntk = dynamic_cast<const V3BvNtk*>(_ntk); assert (ntk); const V3BitVecX* const value = ntk->getInputConstValue(out); assert (value); assert (width == value->size()); char* bv_value = new char[width + 1]; bv_value[width] = '\0'; for (uint32_t i = 0, j = width - 1; i < width; ++i, --j) bv_value[j] = (*value)[i]; // Set BtorExp* _ntkData[index].push_back(boolector_const(_Solver, bv_value)); assert (getVerifyData(out, depth)); }
// Ntk Structure Functions const uint32_t V3Ntk::getNetWidth(const V3NetId& id) const { assert (validNetId(id)); return 1; }
const V3BitVecX V3BvNtk::getInputConstValue(const V3NetId& id) const { assert (validNetId(id)); assert (BV_CONST == getGateType(id)); return id.cp ? ~getConstValue(_inputData[id.id][0].value) : getConstValue(_inputData[id.id][0].value); }
// Ntk Structure Functions const uint32_t V3BvNtk::getNetWidth(const V3NetId& id) const { assert (validNetId(id)); return _netWidth[id.id]; }
// Ntk Reconstruction Functions void V3BvNtk::resetNetWidth(const V3NetId& id, const uint32_t& width) { assert (validNetId(id)); assert (V3_PI == getGateType(id)); assert (width); _netWidth[id.id] = width; }
void V3Ntk::createOutput(const V3NetId& id) { assert (validNetId(id)); _IOList[1].push_back(id); }
void V3Ntk::createClock(const V3NetId& id) { assert (validNetId(id)); assert (V3_PI == getGateType(id)); assert (V3NetUD == _globalClk); _globalClk = id; }
void V3Ntk::setInput(const V3NetId& id, const V3InputVec& inputs) { assert (validNetId(id)); //assert (V3_PI == getGateType(id)); V3InputVec& fanInVec = _inputData[id.id]; assert (!fanInVec.size()); for (uint32_t i = 0; i < inputs.size(); ++i) fanInVec.push_back(inputs[i]); }
void V3Ntk::createConst(const V3NetId& id) { assert (validNetId(id)); assert (!isV3NetInverted(id)); createGate(dynamic_cast<const V3BvNtk*>(this) ? BV_CONST : AIG_FALSE, id); _ConstList.push_back(id); }
void V3Ntk::replaceOutput(const uint32_t& index, const V3NetId& id) { assert (index < getOutputSize()); assert (validNetId(id)); _IOList[1][index] = id; }
void V3Ntk::createInout(const V3NetId& id) { assert (validNetId(id)); assert (!isV3NetInverted(id)); createGate(V3_PIO, id); _IOList[2].push_back(id); }
// Boolector Functions BtorExp* const V3SvrBoolector::getVerifyData(const V3NetId& id, const uint32_t& depth) const { assert (validNetId(id)); if (depth >= _ntkData[id.id].size()) return 0; else return (id.cp ? boolector_not(_Solver, _ntkData[id.id][depth]) : _ntkData[id.id][depth]); }
const uint32_t V3BvNtk::getInputSliceBit(const V3NetId& id, const bool& msb) const { assert (validNetId(id)); assert (BV_SLICE == getGateType(id)); const V3BusId busId = _inputData[id.id][1].value; assert (busId < _V3BusIdVec.size()); return msb ? _V3BusIdVec[busId].bus[0] : _V3BusIdVec[busId].bus[1]; }
void V3Ntk::createLatch(const V3NetId& id) { assert (validNetId(id)); assert (!isV3NetInverted(id)); createGate(V3_FF, id); _FFList.push_back(id); }
void V3Ntk::createInput(const V3NetId& id) { assert (validNetId(id)); assert (!isV3NetInverted(id)); assert (!reportMultipleDrivenNet(V3_PI, id)); _IOList[0].push_back(id); }