From 26d816db72ae45eab6cdaade74738a4f35798e89 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Tue, 19 Mar 2024 13:47:36 -0700 Subject: [PATCH] odb dft: creating dbScanList and also supporting dbBTerm as chain si and so Signed-off-by: Felipe Garay --- src/odb/include/odb/db.h | 37 +++-- src/odb/include/odb/dbObject.h | 1 + src/odb/src/codeGenerator/schema.json | 6 + .../schema/scan/dbScanChain.json | 11 +- .../codeGenerator/schema/scan/dbScanInst.json | 7 +- .../codeGenerator/schema/scan/dbScanList.json | 7 + src/odb/src/db/CMakeLists.txt | 1 + src/odb/src/db/dbObject.cpp | 1 + src/odb/src/db/dbScanChain.cpp | 130 +++++++++++----- src/odb/src/db/dbScanChain.h | 23 ++- src/odb/src/db/dbScanInst.cpp | 60 +++----- src/odb/src/db/dbScanInst.h | 2 +- src/odb/src/db/dbScanList.cpp | 142 ++++++++++++++++++ src/odb/src/db/dbScanList.h | 70 +++++++++ src/odb/test/cpp/scan/TestScanChain.cpp | 65 +++++++- 15 files changed, 455 insertions(+), 108 deletions(-) create mode 100644 src/odb/src/codeGenerator/schema/scan/dbScanList.json create mode 100644 src/odb/src/db/dbScanList.cpp create mode 100644 src/odb/src/db/dbScanList.h diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 854a8286ff1..2770ae45f21 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -144,6 +144,7 @@ class dbPowerDomain; class dbPowerSwitch; class dbScanChain; class dbScanInst; +class dbScanList; class dbScanPartition; class dbScanPin; class dbTechLayer; @@ -7660,7 +7661,7 @@ class dbScanChain : public dbObject public: dbSet getScanPartitions() const; - dbSet getScanInsts() const; + dbSet getScanLists() const; // User Code Begin dbScanChain const std::string& getName() const; @@ -7668,16 +7669,23 @@ class dbScanChain : public dbObject void setName(std::string_view name); void setScanIn(dbBTerm* scan_in); - dbBTerm* getScanIn() const; + void setScanIn(dbITerm* scan_in); + std::variant getScanIn() const; void setScanOut(dbBTerm* scan_out); - dbBTerm* getScanOut() const; + void setScanOut(dbITerm* scan_out); + std::variant getScanOut() const; void setScanEnable(dbBTerm* scan_enable); - dbBTerm* getScanEnable() const; + void setScanEnable(dbITerm* scan_enable); + std::variant getScanEnable() const; - const std::string& getTestMode() const; - void setTestMode(std::string_view test_mode); + void setTestMode(dbBTerm* test_mode); + void setTestMode(dbITerm* test_mode); + std::variant getTestMode() const; + + void setTestModeName(const std::string& test_mode_name); + const std::string& getTestModeName() const; static dbScanChain* create(dbDft* dft); // User Code End dbScanChain @@ -7714,14 +7722,23 @@ class dbScanInst : public dbObject void setAccessPins(const AccessPins& access_pins); AccessPins getAccessPins() const; - std::vector getInsts() const; + dbInst* getInst() const; - static dbScanInst* create(dbScanChain* scan_chain, dbInst* inst); - static dbScanInst* create(dbScanChain* scan_chain, - const std::vector& insts); + static dbScanInst* create(dbScanList* scan_list, dbInst* inst); // User Code End dbScanInst }; +class dbScanList : public dbObject +{ + public: + dbSet getScanInsts() const; + + // User Code Begin dbScanList + dbScanInst* add(dbInst* inst); + static dbScanList* create(dbScanChain* scan_chain); + // User Code End dbScanList +}; + class dbScanPartition : public dbObject { public: diff --git a/src/odb/include/odb/dbObject.h b/src/odb/include/odb/dbObject.h index 75472028193..bbd3049ee9e 100644 --- a/src/odb/include/odb/dbObject.h +++ b/src/odb/include/odb/dbObject.h @@ -103,6 +103,7 @@ enum dbObjectType dbPowerSwitchObj, dbScanChainObj, dbScanInstObj, + dbScanListObj, dbScanPartitionObj, dbScanPinObj, dbTechLayerObj, diff --git a/src/odb/src/codeGenerator/schema.json b/src/odb/src/codeGenerator/schema.json index 91f54db8ca4..5be9695b2eb 100644 --- a/src/odb/src/codeGenerator/schema.json +++ b/src/odb/src/codeGenerator/schema.json @@ -198,6 +198,12 @@ }, { "first": "dbScanChain", + "second": "dbScanList", + "type": "1_n", + "tbl_name": "scan_lists_" + }, + { + "first": "dbScanList", "second": "dbScanInst", "type": "1_n", "tbl_name": "scan_insts_" diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanChain.json b/src/odb/src/codeGenerator/schema/scan/dbScanChain.json index ca7d34513b8..ca565760b0b 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanChain.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanChain.json @@ -9,21 +9,26 @@ }, { "name": "scan_in_", - "type": "dbId", + "type": "dbId", "flags": ["private"] }, { "name": "scan_out_", - "type": "dbId", + "type": "dbId", "flags": ["private"] }, { "name": "scan_enable_", - "type": "dbId", + "type": "dbId", "flags": ["private"] }, { "name": "test_mode_", + "type": "dbId", + "flags": ["private"] + }, + { + "name": "test_mode_name_", "type": "std::string", "flags": ["private"] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json index 72bc050e213..6c40cb43334 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json @@ -18,8 +18,8 @@ "flags": ["private"] }, { - "name": "insts_", - "type": "dbVector>", + "name": "inst_", + "type": "dbId", "flags": ["private"] }, { @@ -68,6 +68,7 @@ "cpp_includes": [ "dbScanPin.h", "dbDft.h", - "dbScanChain.h" + "dbScanChain.h", + "dbScanList.h" ] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanList.json b/src/odb/src/codeGenerator/schema/scan/dbScanList.json new file mode 100644 index 00000000000..7c259d554a1 --- /dev/null +++ b/src/odb/src/codeGenerator/schema/scan/dbScanList.json @@ -0,0 +1,7 @@ +{ + "name": "dbScanList", + "type": "dbObject", + "cpp_includes": [ + "dbScanChain.h" + ] +} diff --git a/src/odb/src/db/CMakeLists.txt b/src/odb/src/db/CMakeLists.txt index 1393a5f1a49..a8f8ff2c8f8 100644 --- a/src/odb/src/db/CMakeLists.txt +++ b/src/odb/src/db/CMakeLists.txt @@ -104,6 +104,7 @@ add_library(db dbPowerSwitch.cpp dbScanChain.cpp dbScanInst.cpp + dbScanList.cpp dbScanPartition.cpp dbScanPin.cpp dbTechLayer.cpp diff --git a/src/odb/src/db/dbObject.cpp b/src/odb/src/db/dbObject.cpp index 69160386ba6..6a7ec79e018 100644 --- a/src/odb/src/db/dbObject.cpp +++ b/src/odb/src/db/dbObject.cpp @@ -107,6 +107,7 @@ static const char* name_tbl[] = {"dbDatabase", "dbPowerSwitch", "dbScanChain", "dbScanInst", + "dbScanList", "dbScanPartition", "dbScanPin", "dbTechLayer", diff --git a/src/odb/src/db/dbScanChain.cpp b/src/odb/src/db/dbScanChain.cpp index 26719d3a158..f69eb808322 100644 --- a/src/odb/src/db/dbScanChain.cpp +++ b/src/odb/src/db/dbScanChain.cpp @@ -39,6 +39,7 @@ #include "dbDft.h" #include "dbDiff.hpp" #include "dbScanInst.h" +#include "dbScanList.h" #include "dbScanPartition.h" #include "dbScanPin.h" #include "dbSet.h" @@ -64,10 +65,13 @@ bool _dbScanChain::operator==(const _dbScanChain& rhs) const if (test_mode_ != rhs.test_mode_) { return false; } + if (test_mode_name_ != rhs.test_mode_name_) { + return false; + } if (*scan_partitions_ != *rhs.scan_partitions_) { return false; } - if (*scan_insts_ != *rhs.scan_insts_) { + if (*scan_lists_ != *rhs.scan_lists_) { return false; } @@ -89,8 +93,9 @@ void _dbScanChain::differences(dbDiff& diff, DIFF_FIELD(scan_out_); DIFF_FIELD(scan_enable_); DIFF_FIELD(test_mode_); + DIFF_FIELD(test_mode_name_); DIFF_TABLE(scan_partitions_); - DIFF_TABLE(scan_insts_); + DIFF_TABLE(scan_lists_); DIFF_END } @@ -102,8 +107,9 @@ void _dbScanChain::out(dbDiff& diff, char side, const char* field) const DIFF_OUT_FIELD(scan_out_); DIFF_OUT_FIELD(scan_enable_); DIFF_OUT_FIELD(test_mode_); + DIFF_OUT_FIELD(test_mode_name_); DIFF_OUT_TABLE(scan_partitions_); - DIFF_OUT_TABLE(scan_insts_); + DIFF_OUT_TABLE(scan_lists_); DIFF_END } @@ -115,8 +121,8 @@ _dbScanChain::_dbScanChain(_dbDatabase* db) this, (GetObjTbl_t) &_dbScanChain::getObjectTable, dbScanPartitionObj); - scan_insts_ = new dbTable<_dbScanInst>( - db, this, (GetObjTbl_t) &_dbScanChain::getObjectTable, dbScanInstObj); + scan_lists_ = new dbTable<_dbScanList>( + db, this, (GetObjTbl_t) &_dbScanChain::getObjectTable, dbScanListObj); } _dbScanChain::_dbScanChain(_dbDatabase* db, const _dbScanChain& r) @@ -126,9 +132,10 @@ _dbScanChain::_dbScanChain(_dbDatabase* db, const _dbScanChain& r) scan_out_ = r.scan_out_; scan_enable_ = r.scan_enable_; test_mode_ = r.test_mode_; + test_mode_name_ = r.test_mode_name_; scan_partitions_ = new dbTable<_dbScanPartition>(db, this, *r.scan_partitions_); - scan_insts_ = new dbTable<_dbScanInst>(db, this, *r.scan_insts_); + scan_lists_ = new dbTable<_dbScanList>(db, this, *r.scan_lists_); } dbIStream& operator>>(dbIStream& stream, _dbScanChain& obj) @@ -138,8 +145,9 @@ dbIStream& operator>>(dbIStream& stream, _dbScanChain& obj) stream >> obj.scan_out_; stream >> obj.scan_enable_; stream >> obj.test_mode_; + stream >> obj.test_mode_name_; stream >> *obj.scan_partitions_; - stream >> *obj.scan_insts_; + stream >> *obj.scan_lists_; return stream; } @@ -150,8 +158,9 @@ dbOStream& operator<<(dbOStream& stream, const _dbScanChain& obj) stream << obj.scan_out_; stream << obj.scan_enable_; stream << obj.test_mode_; + stream << obj.test_mode_name_; stream << *obj.scan_partitions_; - stream << *obj.scan_insts_; + stream << *obj.scan_lists_; return stream; } @@ -160,8 +169,8 @@ dbObjectTable* _dbScanChain::getObjectTable(dbObjectType type) switch (type) { case dbScanPartitionObj: return scan_partitions_; - case dbScanInstObj: - return scan_insts_; + case dbScanListObj: + return scan_lists_; default: break; } @@ -171,7 +180,7 @@ dbObjectTable* _dbScanChain::getObjectTable(dbObjectType type) _dbScanChain::~_dbScanChain() { delete scan_partitions_; - delete scan_insts_; + delete scan_lists_; } //////////////////////////////////////////////////////////////////// @@ -186,10 +195,10 @@ dbSet dbScanChain::getScanPartitions() const return dbSet(obj, obj->scan_partitions_); } -dbSet dbScanChain::getScanInsts() const +dbSet dbScanChain::getScanLists() const { _dbScanChain* obj = (_dbScanChain*) this; - return dbSet(obj, obj->scan_insts_); + return dbSet(obj, obj->scan_lists_); } // User Code Begin dbScanChainPublicMethods @@ -206,67 +215,108 @@ void dbScanChain::setName(std::string_view name) scan_chain->name_ = name; } -dbBTerm* _dbScanChain::getPin(_dbScanChain* scan_chain, - dbId _dbScanChain::*field) +std::variant _dbScanChain::getPin( + dbId scan_pin_id) { - _dbDft* dft = (_dbDft*) scan_chain->getOwner(); - _dbBlock* block = (_dbBlock*) dft->getOwner(); + _dbDft* dft = (_dbDft*) getOwner(); + return ((dbScanPin*) dft->scan_pins_->getPtr((dbId<_dbScanPin>) scan_pin_id)) + ->getPin(); +} - return (dbBTerm*) block->_bterm_tbl->getPtr( - (dbId<_dbBTerm>) (scan_chain->*field)); +void _dbScanChain::setPin(dbId _dbScanChain::*field, dbBTerm* pin) +{ + dbDft* dft = (dbDft*) getOwner(); + this->*field = dbScanPin::create(dft, pin); } -void _dbScanChain::setPin(_dbScanChain* scan_chain, - dbId _dbScanChain::*field, - dbBTerm* pin) +void _dbScanChain::setPin(dbId _dbScanChain::*field, dbITerm* pin) { - _dbBTerm* bterm = (_dbBTerm*) pin; - scan_chain->*field = bterm->getId(); + dbDft* dft = (dbDft*) getOwner(); + this->*field = dbScanPin::create(dft, pin); } void dbScanChain::setScanIn(dbBTerm* scan_in) { - _dbScanChain::setPin((_dbScanChain*) this, &_dbScanChain::scan_in_, scan_in); + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::scan_in_, scan_in); } -dbBTerm* dbScanChain::getScanIn() const +void dbScanChain::setScanIn(dbITerm* scan_in) { - return _dbScanChain::getPin((_dbScanChain*) this, &_dbScanChain::scan_in_); + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::scan_in_, scan_in); +} + +std::variant dbScanChain::getScanIn() const +{ + _dbScanChain* obj = (_dbScanChain*) this; + return obj->getPin(obj->scan_in_); } void dbScanChain::setScanOut(dbBTerm* scan_out) { - _dbScanChain::setPin( - (_dbScanChain*) this, &_dbScanChain::scan_out_, scan_out); + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::scan_out_, scan_out); +} + +void dbScanChain::setScanOut(dbITerm* scan_out) +{ + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::scan_out_, scan_out); } -dbBTerm* dbScanChain::getScanOut() const +std::variant dbScanChain::getScanOut() const { - return _dbScanChain::getPin((_dbScanChain*) this, &_dbScanChain::scan_out_); + _dbScanChain* obj = (_dbScanChain*) this; + return obj->getPin(obj->scan_out_); } void dbScanChain::setScanEnable(dbBTerm* scan_enable) { - _dbScanChain::setPin( - (_dbScanChain*) this, &_dbScanChain::scan_enable_, scan_enable); + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::scan_enable_, scan_enable); +} + +void dbScanChain::setScanEnable(dbITerm* scan_enable) +{ + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::scan_enable_, scan_enable); } -dbBTerm* dbScanChain::getScanEnable() const +std::variant dbScanChain::getScanEnable() const { - return _dbScanChain::getPin((_dbScanChain*) this, - &_dbScanChain::scan_enable_); + _dbScanChain* obj = (_dbScanChain*) this; + return obj->getPin(obj->scan_enable_); +} + +void dbScanChain::setTestMode(dbBTerm* test_mode) +{ + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::test_mode_, test_mode); +} + +void dbScanChain::setTestMode(dbITerm* test_mode) +{ + _dbScanChain* obj = (_dbScanChain*) this; + obj->setPin(&_dbScanChain::test_mode_, test_mode); +} + +std::variant dbScanChain::getTestMode() const +{ + _dbScanChain* obj = (_dbScanChain*) this; + return obj->getPin(obj->test_mode_); } -void dbScanChain::setTestMode(std::string_view test_mode) +void dbScanChain::setTestModeName(const std::string& test_mode_name) { _dbScanChain* scan_chain = (_dbScanChain*) this; - scan_chain->test_mode_ = test_mode; + scan_chain->test_mode_name_ = test_mode_name; } -const std::string& dbScanChain::getTestMode() const +const std::string& dbScanChain::getTestModeName() const { _dbScanChain* scan_chain = (_dbScanChain*) this; - return scan_chain->test_mode_; + return scan_chain->test_mode_name_; } dbScanChain* dbScanChain::create(dbDft* dft) diff --git a/src/odb/src/db/dbScanChain.h b/src/odb/src/db/dbScanChain.h index 9f4a5f96a12..a9f83b628f4 100644 --- a/src/odb/src/db/dbScanChain.h +++ b/src/odb/src/db/dbScanChain.h @@ -47,8 +47,8 @@ class dbScanPartition; class _dbScanPartition; template class dbTable; -class _dbScanInst; -class dbBTerm; +class _dbScanList; +class dbScanPin; class _dbScanChain : public _dbObject { @@ -67,22 +67,21 @@ class _dbScanChain : public _dbObject void out(dbDiff& diff, char side, const char* field) const; dbObjectTable* getObjectTable(dbObjectType type); // User Code Begin Methods - static dbBTerm* getPin(_dbScanChain* scan_chain, - dbId _dbScanChain::*field); - static void setPin(_dbScanChain* scan_chain, - dbId _dbScanChain::*field, - dbBTerm* pin); + std::variant getPin(dbId scan_pin_id); + void setPin(dbId _dbScanChain::*field, dbBTerm* pin); + void setPin(dbId _dbScanChain::*field, dbITerm* pin); // User Code End Methods std::string name_; - dbId scan_in_; - dbId scan_out_; - dbId scan_enable_; - std::string test_mode_; + dbId scan_in_; + dbId scan_out_; + dbId scan_enable_; + dbId test_mode_; + std::string test_mode_name_; dbTable<_dbScanPartition>* scan_partitions_; - dbTable<_dbScanInst>* scan_insts_; + dbTable<_dbScanList>* scan_lists_; }; dbIStream& operator>>(dbIStream& stream, _dbScanChain& obj); dbOStream& operator<<(dbOStream& stream, const _dbScanChain& obj); diff --git a/src/odb/src/db/dbScanInst.cpp b/src/odb/src/db/dbScanInst.cpp index 759a1c9bb43..36e6254b7e8 100644 --- a/src/odb/src/db/dbScanInst.cpp +++ b/src/odb/src/db/dbScanInst.cpp @@ -38,6 +38,7 @@ #include "dbDft.h" #include "dbDiff.hpp" #include "dbScanChain.h" +#include "dbScanList.h" #include "dbScanPin.h" #include "dbTable.h" #include "dbTable.hpp" @@ -52,6 +53,9 @@ bool _dbScanInst::operator==(const _dbScanInst& rhs) const if (scan_enable_ != rhs.scan_enable_) { return false; } + if (inst_ != rhs.inst_) { + return false; + } if (scan_clock_ != rhs.scan_clock_) { return false; } @@ -74,6 +78,7 @@ void _dbScanInst::differences(dbDiff& diff, DIFF_BEGIN DIFF_FIELD(bits_); DIFF_FIELD(scan_enable_); + DIFF_FIELD(inst_); DIFF_FIELD(scan_clock_); DIFF_FIELD(clock_edge_); DIFF_END @@ -84,6 +89,7 @@ void _dbScanInst::out(dbDiff& diff, char side, const char* field) const DIFF_OUT_BEGIN DIFF_OUT_FIELD(bits_); DIFF_OUT_FIELD(scan_enable_); + DIFF_OUT_FIELD(inst_); DIFF_OUT_FIELD(scan_clock_); DIFF_OUT_FIELD(clock_edge_); @@ -98,6 +104,7 @@ _dbScanInst::_dbScanInst(_dbDatabase* db, const _dbScanInst& r) { bits_ = r.bits_; scan_enable_ = r.scan_enable_; + inst_ = r.inst_; scan_clock_ = r.scan_clock_; clock_edge_ = r.clock_edge_; } @@ -107,7 +114,7 @@ dbIStream& operator>>(dbIStream& stream, _dbScanInst& obj) stream >> obj.bits_; stream >> obj.access_pins_; stream >> obj.scan_enable_; - stream >> obj.insts_; + stream >> obj.inst_; stream >> obj.scan_clock_; stream >> obj.clock_edge_; return stream; @@ -118,7 +125,7 @@ dbOStream& operator<<(dbOStream& stream, const _dbScanInst& obj) stream << obj.bits_; stream << obj.access_pins_; stream << obj.scan_enable_; - stream << obj.insts_; + stream << obj.inst_; stream << obj.scan_clock_; stream << obj.clock_edge_; return stream; @@ -178,7 +185,8 @@ void dbScanInst::setScanEnable(dbBTerm* scan_enable) void dbScanInst::setScanEnable(dbITerm* scan_enable) { _dbScanInst* scan_inst = (_dbScanInst*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); scan_inst->scan_enable_ = dbScanPin::create(dft, scan_enable); } @@ -186,7 +194,8 @@ void dbScanInst::setScanEnable(dbITerm* scan_enable) std::variant dbScanInst::getScanEnable() const { _dbScanInst* scan_inst = (_dbScanInst*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); _dbDft* dft = (_dbDft*) scan_chain->getOwner(); const dbScanPin* scan_enable = (dbScanPin*) dft->scan_pins_->getPtr( (dbId<_dbScanPin>) scan_inst->scan_enable_); @@ -206,7 +215,8 @@ std::string_view getName(odb::dbITerm* iterm) void dbScanInst::setAccessPins(const AccessPins& access_pins) { _dbScanInst* scan_inst = (_dbScanInst*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); std::visit( @@ -227,7 +237,8 @@ dbScanInst::AccessPins dbScanInst::getAccessPins() const { AccessPins access_pins; _dbScanInst* scan_inst = (_dbScanInst*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); _dbDft* dft = (_dbDft*) scan_chain->getOwner(); const auto& [scan_in_id, scan_out_id] = scan_inst->access_pins_; @@ -243,45 +254,22 @@ dbScanInst::AccessPins dbScanInst::getAccessPins() const return access_pins; } -std::vector dbScanInst::getInsts() const +dbInst* dbScanInst::getInst() const { _dbScanInst* scan_inst = (_dbScanInst*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); _dbDft* dft = (_dbDft*) scan_chain->getOwner(); _dbBlock* block = (_dbBlock*) dft->getOwner(); - std::vector insts; - - for (const dbId& id : scan_inst->insts_) { - insts.push_back((dbInst*) block->_inst_tbl->getPtr((dbId<_dbInst>) id)); - } - - return insts; + return (dbInst*) block->_inst_tbl->getPtr((dbId<_dbInst>) scan_inst->inst_); } -dbScanInst* dbScanInst::create(dbScanChain* scan_chain, dbInst* inst) +dbScanInst* dbScanInst::create(dbScanList* scan_list, dbInst* inst) { - _dbScanChain* obj = (_dbScanChain*) scan_chain; - _dbInst* _inst = (_dbInst*) inst; - - _dbScanInst* scan_inst = (_dbScanInst*) obj->scan_insts_->create(); - scan_inst->insts_.reserve(1); - scan_inst->insts_.push_back(_inst->getId()); - - return (dbScanInst*) scan_inst; -} - -dbScanInst* dbScanInst::create(dbScanChain* scan_chain, - const std::vector& insts) -{ - _dbScanChain* obj = (_dbScanChain*) scan_chain; - + _dbScanList* obj = (_dbScanList*) scan_list; _dbScanInst* scan_inst = (_dbScanInst*) obj->scan_insts_->create(); - scan_inst->insts_.reserve(insts.size()); - - for (const dbInst* inst : insts) { - scan_inst->insts_.push_back(inst->getId()); - } + scan_inst->inst_ = ((_dbInst*)inst)->getId(); return (dbScanInst*) scan_inst; } diff --git a/src/odb/src/db/dbScanInst.h b/src/odb/src/db/dbScanInst.h index 81411abf7ad..adb6c5f088c 100644 --- a/src/odb/src/db/dbScanInst.h +++ b/src/odb/src/db/dbScanInst.h @@ -66,7 +66,7 @@ class _dbScanInst : public _dbObject uint bits_; std::pair, dbId> access_pins_; dbId scan_enable_; - dbVector> insts_; + dbId inst_; std::string scan_clock_; uint clock_edge_; }; diff --git a/src/odb/src/db/dbScanList.cpp b/src/odb/src/db/dbScanList.cpp new file mode 100644 index 00000000000..c4d7250ff78 --- /dev/null +++ b/src/odb/src/db/dbScanList.cpp @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////// +// BSD 3-Clause License +// +// Copyright (c) 2022, The Regents of the University of California +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// Generator Code Begin Cpp +#include "dbScanList.h" + +#include "db.h" +#include "dbDatabase.h" +#include "dbDiff.hpp" +#include "dbScanChain.h" +#include "dbScanInst.h" +#include "dbSet.h" +#include "dbTable.h" +#include "dbTable.hpp" +namespace odb { +template class dbTable<_dbScanList>; + +bool _dbScanList::operator==(const _dbScanList& rhs) const +{ + if (*scan_insts_ != *rhs.scan_insts_) { + return false; + } + + return true; +} + +bool _dbScanList::operator<(const _dbScanList& rhs) const +{ + return true; +} + +void _dbScanList::differences(dbDiff& diff, + const char* field, + const _dbScanList& rhs) const +{ + DIFF_BEGIN + DIFF_TABLE(scan_insts_); + DIFF_END +} + +void _dbScanList::out(dbDiff& diff, char side, const char* field) const +{ + DIFF_OUT_BEGIN + DIFF_OUT_TABLE(scan_insts_); + + DIFF_END +} + +_dbScanList::_dbScanList(_dbDatabase* db) +{ + scan_insts_ = new dbTable<_dbScanInst>( + db, this, (GetObjTbl_t) &_dbScanList::getObjectTable, dbScanInstObj); +} + +_dbScanList::_dbScanList(_dbDatabase* db, const _dbScanList& r) +{ + scan_insts_ = new dbTable<_dbScanInst>(db, this, *r.scan_insts_); +} + +dbIStream& operator>>(dbIStream& stream, _dbScanList& obj) +{ + stream >> *obj.scan_insts_; + return stream; +} + +dbOStream& operator<<(dbOStream& stream, const _dbScanList& obj) +{ + stream << *obj.scan_insts_; + return stream; +} + +dbObjectTable* _dbScanList::getObjectTable(dbObjectType type) +{ + switch (type) { + case dbScanInstObj: + return scan_insts_; + default: + break; + } + return getTable()->getObjectTable(type); +} + +_dbScanList::~_dbScanList() +{ + delete scan_insts_; +} + +//////////////////////////////////////////////////////////////////// +// +// dbScanList - Methods +// +//////////////////////////////////////////////////////////////////// + +dbSet dbScanList::getScanInsts() const +{ + _dbScanList* obj = (_dbScanList*) this; + return dbSet(obj, obj->scan_insts_); +} + +// User Code Begin dbScanListPublicMethods +dbScanInst* dbScanList::add(dbInst* inst) +{ + return dbScanInst::create(this, inst); +} + +dbScanList* dbScanList::create(dbScanChain* scan_chain) +{ + _dbScanChain* obj = (_dbScanChain*) scan_chain; + return (dbScanList*)obj->scan_lists_->create(); +} +// User Code End dbScanListPublicMethods +} // namespace odb +// Generator Code End Cpp diff --git a/src/odb/src/db/dbScanList.h b/src/odb/src/db/dbScanList.h new file mode 100644 index 00000000000..1d5a064aa8f --- /dev/null +++ b/src/odb/src/db/dbScanList.h @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////////// +// BSD 3-Clause License +// +// Copyright (c) 2022, The Regents of the University of California +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +// Generator Code Begin Header +#pragma once + +#include "dbCore.h" +#include "odb.h" + +namespace odb { +class dbIStream; +class dbOStream; +class dbDiff; +class _dbDatabase; +class _dbScanInst; +template +class dbTable; + +class _dbScanList : public _dbObject +{ + public: + _dbScanList(_dbDatabase*, const _dbScanList& r); + _dbScanList(_dbDatabase*); + + ~_dbScanList(); + + bool operator==(const _dbScanList& rhs) const; + bool operator!=(const _dbScanList& rhs) const { return !operator==(rhs); } + bool operator<(const _dbScanList& rhs) const; + void differences(dbDiff& diff, + const char* field, + const _dbScanList& rhs) const; + void out(dbDiff& diff, char side, const char* field) const; + dbObjectTable* getObjectTable(dbObjectType type); + + dbTable<_dbScanInst>* scan_insts_; +}; +dbIStream& operator>>(dbIStream& stream, _dbScanList& obj); +dbOStream& operator<<(dbOStream& stream, const _dbScanList& obj); +} // namespace odb +// Generator Code End Header \ No newline at end of file diff --git a/src/odb/test/cpp/scan/TestScanChain.cpp b/src/odb/test/cpp/scan/TestScanChain.cpp index 30d048d7de0..f111b106ad5 100644 --- a/src/odb/test/cpp/scan/TestScanChain.cpp +++ b/src/odb/test/cpp/scan/TestScanChain.cpp @@ -121,7 +121,9 @@ TEST_F(TestScanChain, CreateScanChain) dbScanChain* scan_chain = dbScanChain::create(dft_); - dbScanInst* scan_inst = dbScanInst::create(scan_chain, inst); + dbScanList* scan_list = dbScanList::create(scan_chain); + + dbScanInst* scan_inst = scan_list->add(inst); scan_inst->setBits(1234); scan_inst->setAccessPins({.scan_in = iterm, .scan_out = bterm}); @@ -135,16 +137,21 @@ TEST_F(TestScanChain, CreateScanChain) dbScanChain* scan_chain2 = *scan_chains2.begin(); - odb::dbSet scan_insts2 = scan_chain2->getScanInsts(); + odb::dbSet scan_lists2 = scan_chain2->getScanLists(); + EXPECT_THAT(scan_lists2.size(), 1); + + odb::dbSet scan_insts2 = scan_lists2.begin()->getScanInsts(); EXPECT_THAT(scan_insts2.size(), 1); } TEST_F(TestScanChain, CreateScanChainWithPartition) { dbScanChain* scan_chain = dbScanChain::create(dft_); + dbScanList* scan_list = dbScanList::create(scan_chain); + for (dbInst* inst : instances_) { - dbScanInst* scan_inst = dbScanInst::create(scan_chain, inst); + dbScanInst* scan_inst = scan_list->add(inst); scan_inst->setBits(1); dbITerm* iterm = inst->findITerm("a"); dbITerm* iterm2 = inst->findITerm("o"); @@ -203,6 +210,58 @@ TEST_F(TestScanChain, CreateScanChainWithPartition) EXPECT_THAT(GetName(partition22->getStart()), "a"); EXPECT_THAT(GetName(partition22->getStop()), "IN3"); + + // check the created instances + dbSet scan_lists2 = scan_chains2.begin()->getScanLists(); + dbSet scan_insts2 = scan_lists2.begin()->getScanInsts(); + + int i = 0; + for (dbScanInst* scan_inst: scan_insts2) { + const dbScanInst::AccessPins& access_pins = scan_inst->getAccessPins(); + EXPECT_THAT(GetName(access_pins.scan_in), "a"); + EXPECT_THAT(GetName(access_pins.scan_out), "o"); + EXPECT_THAT(instances_[i]->getName(), scan_inst->getInst()->getName()); + ++i; + } +} + + +TEST_F(TestScanChain, CreateScanChainWithMultipleScanLists) +{ + dbScanChain* scan_chain = dbScanChain::create(dft_); + dbScanList* scan_list1 = dbScanList::create(scan_chain); + dbScanList* scan_list2 = dbScanList::create(scan_chain); + + scan_list1->add(instances_[0]); + scan_list2->add(instances_[1]); + scan_list2->add(instances_[2]); + + dbDatabase* db2 = writeReadDb(); + + dbBlock* block2 = db2->getChip()->getBlock(); + dbDft* dft2 = block2->getDft(); + + dbSet scan_chains2 = dft2->getScanChains(); + EXPECT_THAT(scan_chains2.size(), 1); + // check the created instances + dbSet scan_lists2 = scan_chains2.begin()->getScanLists(); + EXPECT_THAT(scan_lists2.size(), 2); + + int i = 0; + for (dbScanList* scan_list: scan_lists2) { + for (dbScanInst* scan_inst: scan_list->getScanInsts()) { + EXPECT_THAT(scan_inst->getInst()->getName(), instances_[i]->getName()); + ++i; + } + } + + auto it = scan_lists2.begin(); + dbScanList* scan_list21 = *it; + ++it; + dbScanList* scan_list22 = *it; + + EXPECT_THAT(scan_list21->getScanInsts().size(), 1); + EXPECT_THAT(scan_list22->getScanInsts().size(), 2); } } // namespace