From dad13d7bfa036dde51ac86d2af84a4d9668a698a Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Fri, 16 Feb 2024 17:56:45 -0800 Subject: [PATCH 01/16] odb: adding support for persistent DFT structures This is a basic set of structs to support scan chains and scan cells in odb. Signed-off-by: Felipe Garay --- src/odb/include/odb/db.h | 104 ++++++++- src/odb/include/odb/dbObject.h | 1 + src/odb/src/codeGenerator/schema.json | 24 ++ .../src/codeGenerator/schema/scan/dbDft.json | 13 ++ .../schema/scan/dbScanChain.json | 40 +--- .../codeGenerator/schema/scan/dbScanInst.json | 58 ++++- .../schema/scan/dbScanPartition.json | 4 +- .../codeGenerator/schema/scan/dbScanPin.json | 12 +- src/odb/src/db/CMakeLists.txt | 1 + src/odb/src/db/dbBlock.cpp | 44 +++- src/odb/src/db/dbBlock.h | 3 + src/odb/src/db/dbDatabase.h | 6 +- src/odb/src/db/dbDft.cpp | 188 ++++++++++++++++ src/odb/src/db/dbDft.h | 74 +++++++ src/odb/src/db/dbObject.cpp | 1 + src/odb/src/db/dbScanChain.cpp | 194 ++++++++++++++-- src/odb/src/db/dbScanChain.h | 35 +-- src/odb/src/db/dbScanInst.cpp | 181 +++++++++++++-- src/odb/src/db/dbScanInst.h | 12 +- src/odb/src/db/dbScanPartition.cpp | 71 +++++- src/odb/src/db/dbScanPartition.h | 2 +- src/odb/src/db/dbScanPin.cpp | 16 +- src/odb/src/db/dbScanPin.h | 4 +- src/odb/test/cpp/CMakeLists.txt | 2 +- src/odb/test/cpp/TestAccessPoint.cpp | 2 +- src/odb/test/cpp/TestJournal.cpp | 2 +- src/odb/test/cpp/TestLef58Properties.cpp | 8 +- src/odb/test/cpp/helper/env.cpp | 11 +- src/odb/test/cpp/helper/env.h | 2 +- src/odb/test/cpp/scan/CMakeLists.txt | 25 +++ src/odb/test/cpp/scan/TestScanChain.cpp | 209 ++++++++++++++++++ src/odb/test/data/design.odb | Bin 206487 -> 217975 bytes 32 files changed, 1221 insertions(+), 128 deletions(-) create mode 100644 src/odb/src/codeGenerator/schema/scan/dbDft.json create mode 100644 src/odb/src/db/dbDft.cpp create mode 100644 src/odb/src/db/dbDft.h create mode 100644 src/odb/test/cpp/scan/CMakeLists.txt create mode 100644 src/odb/test/cpp/scan/TestScanChain.cpp diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 5bd9ca9d05..261fe8445f 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -128,6 +128,7 @@ class dbViaParams; // Generator Code Begin ClassDeclarations class dbAccessPoint; +class dbDft; class dbGCellGrid; class dbGlobalConnect; class dbGroup; @@ -1366,6 +1367,16 @@ class dbBlock : public dbObject /// dbExtControl* getExtControl(); + /// + /// Get the dbDft object for persistent dft structs + /// + dbDft* createDft(); + + /// + /// Get the dbDft object for persistent dft structs + /// + dbDft* getDft() const; + /// /// Get the extraction corner names /// @@ -7084,6 +7095,22 @@ class dbAccessPoint : public dbObject // User Code End dbAccessPoint }; +class dbDft : public dbObject +{ + public: + void setScanInserted(bool scan_inserted); + + bool isScanInserted() const; + + dbSet getScanChains() const; + + // User Code Begin dbDft + dbId CreateScanPin(dbBTerm* bterm); + dbId CreateScanPin(dbITerm* iterm); + dbScanChain* CreateScanChain(); + // User Code End dbDft +}; + class dbGCellGrid : public dbObject { public: @@ -7743,22 +7770,91 @@ class dbPowerSwitch : public dbObject class dbScanChain : public dbObject { public: + dbSet getScanPartitions() const; + + dbSet getScanInsts() const; + + // User Code Begin dbScanChain + std::string_view getName() const; + + void setName(std::string_view name); + + void setScanIn(dbBTerm* scan_in); + dbBTerm* getScanIn() const; + + void setScanOut(dbBTerm* scan_out); + dbBTerm* getScanOut() const; + + void setScanEnable(dbBTerm* scan_enable); + + dbBTerm* getScanEnable() const; + + std::string_view getTestMode() const; + void setTestMode(std::string_view test_mode); + + dbScanPartition* createScanPartition(); + dbScanInst* createScanInst(dbInst* inst); + dbScanInst* createScanInst(const std::vector& insts); + // User Code End dbScanChain }; class dbScanInst : public dbObject { public: - enum class SCAN_INST_TYPE + struct AccessPins { - OneBit, - ShiftRegister, - BlackBox + std::variant scan_in; + std::variant scan_out; }; + enum class ClockEdge + { + Rising, + Falling + }; + + // User Code Begin dbScanInst + void setScanClock(std::string_view scan_clock); + std::string_view getScanClock() const; + + void setClockEdge(ClockEdge clock_edge); + ClockEdge getClockEdge() const; + + void setBits(uint bits); + + uint getBits() const; + + void setScanEnable(dbBTerm* scan_enable); + void setScanEnable(dbITerm* scan_enable); + std::variant getScanEnable() const; + + void setAccessPins(const AccessPins& access_pins); + + AccessPins getAccessPins() const; + + std::vector getInsts() const; + // User Code End dbScanInst }; class dbScanPartition : public dbObject { public: + // User Code Begin dbScanPartition + void setStart(dbBTerm* bterm); + + void setStart(dbITerm* iterm); + + void setStop(dbBTerm* bterm); + + void setStop(dbITerm* iterm); + + std::variant getStart() const; + + std::variant getStop() const; + + std::string_view getName() const; + + void setName(std::string_view name); + // User Code End dbScanPartition }; class dbScanPin : public dbObject diff --git a/src/odb/include/odb/dbObject.h b/src/odb/include/odb/dbObject.h index d65ed98313..8dcf204c43 100644 --- a/src/odb/include/odb/dbObject.h +++ b/src/odb/include/odb/dbObject.h @@ -87,6 +87,7 @@ enum dbObjectType dbBPinObj, // Generator Code Begin DbObjectType dbAccessPointObj, + dbDftObj, dbGCellGridObj, dbGlobalConnectObj, dbGroupObj, diff --git a/src/odb/src/codeGenerator/schema.json b/src/odb/src/codeGenerator/schema.json index 55e7e9e9c1..9f0bafe787 100644 --- a/src/odb/src/codeGenerator/schema.json +++ b/src/odb/src/codeGenerator/schema.json @@ -254,5 +254,29 @@ "tbl_name":"two_wires_forbidden_spc_rules_tbl_", "schema":"db_schema_lef58_two_wires_forbidden_spacing" } + "first": "dbDft", + "second": "dbScanPin", + "type": "1_n", + "tbl_name": "scan_pins_", + "flags": ["no-get"] + }, + { + "first": "dbScanChain", + "second": "dbScanPartition", + "type": "1_n", + "tbl_name": "scan_partitions_" + }, + { + "first": "dbScanChain", + "second": "dbScanInst", + "type": "1_n", + "tbl_name": "scan_insts_" + }, + { + "first": "dbDft", + "second": "dbScanChain", + "type": "1_n", + "tbl_name": "scan_chains_" + } ] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbDft.json b/src/odb/src/codeGenerator/schema/scan/dbDft.json new file mode 100644 index 0000000000..579f852579 --- /dev/null +++ b/src/odb/src/codeGenerator/schema/scan/dbDft.json @@ -0,0 +1,13 @@ +{ + "name": "dbDft", + "type": "dbObject", + "fields": [ + { + "name": "scan_inserted_", + "type": "bool" + } + ], + "h_includes": [ + "dbBlock.h" + ] +} diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanChain.json b/src/odb/src/codeGenerator/schema/scan/dbScanChain.json index caa7f950bb..ca7d34513b 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanChain.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanChain.json @@ -7,50 +7,25 @@ "type": "std::string", "flags": ["private"] }, - { - "name": "length_", - "type": "uint", - "flags": ["private"] - }, - { - "name": "cells_", - "type": "dbVector>", - "flags": ["private"] - }, { "name": "scan_in_", - "type": "dbId", + "type": "dbId", "flags": ["private"] }, { "name": "scan_out_", - "type": "dbId", - "flags": ["private"] - }, - { - "name": "scan_clock_", - "type": "dbId", + "type": "dbId", "flags": ["private"] }, { "name": "scan_enable_", - "type": "dbId", + "type": "dbId", "flags": ["private"] }, { "name": "test_mode_", "type": "std::string", "flags": ["private"] - }, - { - "name": "partitions_", - "type": "dbVector>", - "flags": ["private"] - }, - { - "name": "scan_insts_", - "type": "dbVector>", - "flags": ["private"] } ], "h_includes": [ @@ -58,6 +33,13 @@ "dbScanPin.h" ], "cpp_includes": [ - "dbScanPin.h" + "dbScanPin.h", + "dbScanPartition.h", + "dbScanInst.h", + "dbBlock.h", + "dbDft.h" + ], + "classes": [ + "dbScanPartition" ] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json index 29cc4f0c76..72bc050e21 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json @@ -3,37 +3,71 @@ "type": "dbObject", "fields": [ { - "name": "bits", + "name": "bits_", "type": "uint", "flags": ["private"] }, { - "name": "scanIn", + "name": "access_pins_", + "type": "std::pair, dbId>", + "flags": ["private", "no-template"] + }, + { + "name": "scan_enable_", "type": "dbId", "flags": ["private"] }, { - "name": "scanOut", - "type": "dbId", + "name": "insts_", + "type": "dbVector>", + "flags": ["private"] + }, + { + "name": "scan_clock_", + "type": "std::string", + "flags": ["private"] + }, + { + "name": "clock_edge_", + "type": "uint", "flags": ["private"] } ], "enums": [ { - "name": "SCAN_INST_TYPE", - "public": true, + "name": "ClockEdge", "class": true, "values": [ - "OneBit", - "ShiftRegister", - "BlackBox" - ] + "Rising", + "Falling" + ], + "public": true + } + ], + "structs": [ + { + "name": "AccessPins", + "public": true, + "fields": [ + { + "name": "scan_in", + "type": "std::variant" + }, + { + "name": "scan_out", + "type": "std::variant" + } + ] } ], "h_includes": [ - "dbScanPin.h" + "dbScanPin.h", + "dbInst.h", + "dbVector.h" ], "cpp_includes": [ - "dbScanPin.h" + "dbScanPin.h", + "dbDft.h", + "dbScanChain.h" ] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json b/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json index f06dec160a..16d47805c1 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json @@ -22,6 +22,8 @@ "dbScanPin.h" ], "cpp_includes": [ - "dbScanPin.h" + "dbScanPin.h", + "dbScanChain.h", + "dbDft.h" ] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanPin.json b/src/odb/src/codeGenerator/schema/scan/dbScanPin.json index 2e2aec5fb4..29c4fb83ff 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanPin.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanPin.json @@ -10,7 +10,15 @@ ], "h_includes": [ "dbBTerm.h", - "dbITerm.h", - "dbBlock.h" + "dbITerm.h" + ], + "cpp_includes": [ + "dbBlock.h", + "dbDft.h" + ], + "classes": [ + "dbScanPin", + "dbBTerm", + "dbITerm" ] } diff --git a/src/odb/src/db/CMakeLists.txt b/src/odb/src/db/CMakeLists.txt index ba30f371f5..18c8b7e864 100644 --- a/src/odb/src/db/CMakeLists.txt +++ b/src/odb/src/db/CMakeLists.txt @@ -88,6 +88,7 @@ add_library(db dbGroupGroundNetItr.cpp # Generator Code Begin cpp dbAccessPoint.cpp + dbDft.cpp dbGCellGrid.cpp dbGlobalConnect.cpp dbGroup.cpp diff --git a/src/odb/src/db/dbBlock.cpp b/src/odb/src/db/dbBlock.cpp index 039d50981c..45853580d0 100644 --- a/src/odb/src/db/dbBlock.cpp +++ b/src/odb/src/db/dbBlock.cpp @@ -59,6 +59,7 @@ #include "dbCapNodeItr.h" #include "dbChip.h" #include "dbDatabase.h" +#include "dbDft.h" #include "dbDiff.h" #include "dbDiff.hpp" #include "dbExtControl.h" @@ -333,6 +334,9 @@ _dbBlock::_dbBlock(_dbDatabase* db) _extControl = new dbExtControl(); + _dft_tbl = new dbTable<_dbDft>( + db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbDftObj); + _net_hash.setTable(_net_tbl); _inst_hash.setTable(_inst_tbl); _module_hash.setTable(_module_tbl); @@ -449,7 +453,8 @@ _dbBlock::_dbBlock(_dbDatabase* db, const _dbBlock& block) _maxCCSegId(block._maxCCSegId), _children(block._children), _component_mask_shift(block._component_mask_shift), - _currentCcAdjOrder(block._currentCcAdjOrder) + _currentCcAdjOrder(block._currentCcAdjOrder), + _dft(block._dft) { if (block._name) { _name = strdup(block._name); @@ -547,6 +552,8 @@ _dbBlock::_dbBlock(_dbDatabase* db, const _dbBlock& block) _extControl = new dbExtControl(); + _dft_tbl = new dbTable<_dbDft>(db, this, *block._dft_tbl); + _net_hash.setTable(_net_tbl); _inst_hash.setTable(_inst_tbl); _module_hash.setTable(_module_tbl); @@ -687,6 +694,7 @@ _dbBlock::~_dbBlock() delete _group_ground_net_itr; delete _bpin_itr; delete _prop_itr; + delete _dft_tbl; std::list::iterator _cbitr; while (_callbacks.begin() != _callbacks.end()) { @@ -892,6 +900,10 @@ dbObjectTable* _dbBlock::getObjectTable(dbObjectType type) case dbPropertyObj: return _prop_tbl; + + case dbDftObj: + return _dft_tbl; + default: break; } @@ -999,6 +1011,8 @@ dbOStream& operator<<(dbOStream& stream, const _dbBlock& block) stream << NamedTable("r_seg_tbl", block._r_seg_tbl); stream << NamedTable("cc_seg_tbl", block._cc_seg_tbl); stream << *block._extControl; + stream << block._dft; + stream << *block._dft_tbl; //---------------------------------------------------------- stream out // properties @@ -1129,6 +1143,10 @@ dbIStream& operator>>(dbIStream& stream, _dbBlock& block) stream >> *block._r_seg_tbl; // DKF stream >> *block._cc_seg_tbl; stream >> *block._extControl; + if (db->isSchema(db_schema_add_scan)) { + stream >> block._dft; + stream >> *block._dft_tbl; + } //---------------------------------------------------------- stream in // properties @@ -1416,6 +1434,12 @@ bool _dbBlock::operator==(const _dbBlock& rhs) const if (*_cc_seg_tbl != *rhs._cc_seg_tbl) return false; + if (_dft != rhs._dft) + return false; + + if (*_dft_tbl != *rhs._dft_tbl) + return false; + return true; } @@ -1501,6 +1525,8 @@ void _dbBlock::differences(dbDiff& diff, DIFF_TABLE(_layer_rule_tbl); DIFF_TABLE_NO_DEEP(_prop_tbl); DIFF_NAME_CACHE(_name_cache); + DIFF_FIELD(_dft); + DIFF_TABLE(_dft_tbl); if (*_r_val_tbl != *rhs._r_val_tbl) _r_val_tbl->differences(diff, "_r_val_tbl", *rhs._r_val_tbl); @@ -1597,6 +1623,8 @@ void _dbBlock::out(dbDiff& diff, char side, const char* field) const DIFF_OUT_TABLE(_layer_rule_tbl); DIFF_OUT_TABLE_NO_DEEP(_prop_tbl); DIFF_OUT_NAME_CACHE(_name_cache); + DIFF_OUT_FIELD(_dft); + DIFF_OUT_TABLE(_dft_tbl); _r_val_tbl->out(diff, side, "_r_val_tbl"); _c_val_tbl->out(diff, side, "_c_val_tbl"); @@ -2278,6 +2306,20 @@ dbExtControl* dbBlock::getExtControl() return (block->_extControl); } +dbDft* dbBlock::createDft() +{ + _dbBlock* block = (_dbBlock*) this; + _dbDft* dft = block->_dft_tbl->create(); + block->_dft = dft->getId(); + return (dbDft*) dft; +} + +dbDft* dbBlock::getDft() const +{ + _dbBlock* block = (_dbBlock*) this; + return (dbDft*) block->_dft_tbl->getPtr(block->_dft); +} + void dbBlock::getExtCornerNames(std::list& ecl) { _dbBlock* block = (_dbBlock*) this; diff --git a/src/odb/src/db/dbBlock.h b/src/odb/src/db/dbBlock.h index 294d260192..a22d7d52b4 100644 --- a/src/odb/src/db/dbBlock.h +++ b/src/odb/src/db/dbBlock.h @@ -136,6 +136,7 @@ class dbBlockSearch; class dbBlockCallBackObj; class dbGuideItr; class dbNetTrackItr; +class _dbDft; struct _dbBlockFlags { @@ -195,6 +196,7 @@ class _dbBlock : public _dbObject dbVector> _children; dbVector> _component_mask_shift; uint _currentCcAdjOrder; + dbId<_dbDft> _dft; // NON-PERSISTANT-STREAMED-MEMBERS dbTable<_dbBTerm>* _bterm_tbl; @@ -232,6 +234,7 @@ class _dbBlock : public _dbObject dbTable<_dbGuide>* _guide_tbl; dbTable<_dbNetTrack>* _net_tracks_tbl; _dbNameCache* _name_cache; + dbTable<_dbDft>* _dft_tbl; dbPagedVector* _r_val_tbl; dbPagedVector* _c_val_tbl; diff --git a/src/odb/src/db/dbDatabase.h b/src/odb/src/db/dbDatabase.h index 52cabb4a35..7c9e056bdf 100644 --- a/src/odb/src/db/dbDatabase.h +++ b/src/odb/src/db/dbDatabase.h @@ -69,7 +69,11 @@ namespace odb { // const uint db_schema_major = 0; // Not used... const uint db_schema_initial = 57; -const uint db_schema_minor = 82; // Current revision number + +const uint db_schema_minor = 83; // Current revision number + +// Revision where scan structs are added +const uint db_schema_add_scan = 83; // Revision where _dbTechLayer::two_wires_forbidden_spc_rules_tbl_ was added const uint db_schema_lef58_two_wires_forbidden_spacing = 82; diff --git a/src/odb/src/db/dbDft.cpp b/src/odb/src/db/dbDft.cpp new file mode 100644 index 0000000000..e455e98b2b --- /dev/null +++ b/src/odb/src/db/dbDft.cpp @@ -0,0 +1,188 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 "dbDft.h" + +#include "db.h" +#include "dbDatabase.h" +#include "dbDiff.hpp" +#include "dbScanChain.h" +#include "dbScanPin.h" +#include "dbSet.h" +#include "dbTable.h" +#include "dbTable.hpp" +namespace odb { +template class dbTable<_dbDft>; + +bool _dbDft::operator==(const _dbDft& rhs) const +{ + if (scan_inserted_ != rhs.scan_inserted_) { + return false; + } + if (*scan_pins_ != *rhs.scan_pins_) { + return false; + } + if (*scan_chains_ != *rhs.scan_chains_) { + return false; + } + + return true; +} + +bool _dbDft::operator<(const _dbDft& rhs) const +{ + return true; +} + +void _dbDft::differences(dbDiff& diff, + const char* field, + const _dbDft& rhs) const +{ + DIFF_BEGIN + DIFF_FIELD(scan_inserted_); + DIFF_TABLE(scan_pins_); + DIFF_TABLE(scan_chains_); + DIFF_END +} + +void _dbDft::out(dbDiff& diff, char side, const char* field) const +{ + DIFF_OUT_BEGIN + DIFF_OUT_FIELD(scan_inserted_); + DIFF_OUT_TABLE(scan_pins_); + DIFF_OUT_TABLE(scan_chains_); + + DIFF_END +} + +_dbDft::_dbDft(_dbDatabase* db) +{ + scan_pins_ = new dbTable<_dbScanPin>( + db, this, (GetObjTbl_t) &_dbDft::getObjectTable, dbScanPinObj); + scan_chains_ = new dbTable<_dbScanChain>( + db, this, (GetObjTbl_t) &_dbDft::getObjectTable, dbScanChainObj); +} + +_dbDft::_dbDft(_dbDatabase* db, const _dbDft& r) +{ + scan_inserted_ = r.scan_inserted_; + scan_pins_ = new dbTable<_dbScanPin>(db, this, *r.scan_pins_); + scan_chains_ = new dbTable<_dbScanChain>(db, this, *r.scan_chains_); +} + +dbIStream& operator>>(dbIStream& stream, _dbDft& obj) +{ + stream >> obj.scan_inserted_; + stream >> *obj.scan_pins_; + stream >> *obj.scan_chains_; + return stream; +} + +dbOStream& operator<<(dbOStream& stream, const _dbDft& obj) +{ + stream << obj.scan_inserted_; + stream << *obj.scan_pins_; + stream << *obj.scan_chains_; + return stream; +} + +dbObjectTable* _dbDft::getObjectTable(dbObjectType type) +{ + switch (type) { + case dbScanPinObj: + return scan_pins_; + case dbScanChainObj: + return scan_chains_; + default: + break; + } + return getTable()->getObjectTable(type); +} + +_dbDft::~_dbDft() +{ + delete scan_pins_; + delete scan_chains_; +} + +//////////////////////////////////////////////////////////////////// +// +// dbDft - Methods +// +//////////////////////////////////////////////////////////////////// + +void dbDft::setScanInserted(bool scan_inserted) +{ + _dbDft* obj = (_dbDft*) this; + + obj->scan_inserted_ = scan_inserted; +} + +bool dbDft::isScanInserted() const +{ + _dbDft* obj = (_dbDft*) this; + return obj->scan_inserted_; +} + +dbSet dbDft::getScanChains() const +{ + _dbDft* obj = (_dbDft*) this; + return dbSet(obj, obj->scan_chains_); +} + +// User Code Begin dbDftPublicMethods +dbId dbDft::CreateScanPin(dbBTerm* bterm) +{ + _dbDft* obj = (_dbDft*) this; + _dbScanPin* scan_pin = (_dbScanPin*) obj->scan_pins_->create(); + ((dbScanPin*) scan_pin)->setPin(bterm); + return scan_pin->getId(); +} + +dbId dbDft::CreateScanPin(dbITerm* iterm) +{ + _dbDft* obj = (_dbDft*) this; + _dbScanPin* scan_pin = (_dbScanPin*) obj->scan_pins_->create(); + ((dbScanPin*) scan_pin)->setPin(iterm); + return scan_pin->getId(); +} + +dbScanChain* dbDft::CreateScanChain() +{ + _dbDft* obj = (_dbDft*) this; + return (dbScanChain*) obj->scan_chains_->create(); +} + +// User Code End dbDftPublicMethods +} // namespace odb +// Generator Code End Cpp diff --git a/src/odb/src/db/dbDft.h b/src/odb/src/db/dbDft.h new file mode 100644 index 0000000000..5942a0186e --- /dev/null +++ b/src/odb/src/db/dbDft.h @@ -0,0 +1,74 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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 "dbBlock.h" +#include "dbCore.h" +#include "odb.h" + +namespace odb { +class dbIStream; +class dbOStream; +class dbDiff; +class _dbDatabase; +class _dbScanPin; +template +class dbTable; +class _dbScanChain; + +class _dbDft : public _dbObject +{ + public: + _dbDft(_dbDatabase*, const _dbDft& r); + _dbDft(_dbDatabase*); + + ~_dbDft(); + + bool operator==(const _dbDft& rhs) const; + bool operator!=(const _dbDft& rhs) const { return !operator==(rhs); } + bool operator<(const _dbDft& rhs) const; + void differences(dbDiff& diff, const char* field, const _dbDft& rhs) const; + void out(dbDiff& diff, char side, const char* field) const; + dbObjectTable* getObjectTable(dbObjectType type); + + bool scan_inserted_; + + dbTable<_dbScanPin>* scan_pins_; + + dbTable<_dbScanChain>* scan_chains_; +}; +dbIStream& operator>>(dbIStream& stream, _dbDft& obj); +dbOStream& operator<<(dbOStream& stream, const _dbDft& obj); +} // namespace odb +// Generator Code End Header diff --git a/src/odb/src/db/dbObject.cpp b/src/odb/src/db/dbObject.cpp index ea1a80e60a..87e9af3cef 100644 --- a/src/odb/src/db/dbObject.cpp +++ b/src/odb/src/db/dbObject.cpp @@ -91,6 +91,7 @@ static const char* name_tbl[] = {"dbDatabase", "dbBPin", // Generator Code Begin ObjectNames "dbAccessPoint", + "dbDft", "dbGCellGrid", "dbGlobalConnect", "dbGroup", diff --git a/src/odb/src/db/dbScanChain.cpp b/src/odb/src/db/dbScanChain.cpp index c73a5b6cca..777666200d 100644 --- a/src/odb/src/db/dbScanChain.cpp +++ b/src/odb/src/db/dbScanChain.cpp @@ -34,9 +34,14 @@ #include "dbScanChain.h" #include "db.h" +#include "dbBlock.h" #include "dbDatabase.h" +#include "dbDft.h" #include "dbDiff.hpp" +#include "dbScanInst.h" +#include "dbScanPartition.h" #include "dbScanPin.h" +#include "dbSet.h" #include "dbTable.h" #include "dbTable.hpp" namespace odb { @@ -47,24 +52,24 @@ bool _dbScanChain::operator==(const _dbScanChain& rhs) const if (name_ != rhs.name_) { return false; } - if (length_ != rhs.length_) { - return false; - } if (scan_in_ != rhs.scan_in_) { return false; } if (scan_out_ != rhs.scan_out_) { return false; } - if (scan_clock_ != rhs.scan_clock_) { - return false; - } if (scan_enable_ != rhs.scan_enable_) { return false; } if (test_mode_ != rhs.test_mode_) { return false; } + if (*scan_partitions_ != *rhs.scan_partitions_) { + return false; + } + if (*scan_insts_ != *rhs.scan_insts_) { + return false; + } return true; } @@ -80,12 +85,12 @@ void _dbScanChain::differences(dbDiff& diff, { DIFF_BEGIN DIFF_FIELD(name_); - DIFF_FIELD(length_); DIFF_FIELD(scan_in_); DIFF_FIELD(scan_out_); - DIFF_FIELD(scan_clock_); DIFF_FIELD(scan_enable_); DIFF_FIELD(test_mode_); + DIFF_TABLE(scan_partitions_); + DIFF_TABLE(scan_insts_); DIFF_END } @@ -93,66 +98,209 @@ void _dbScanChain::out(dbDiff& diff, char side, const char* field) const { DIFF_OUT_BEGIN DIFF_OUT_FIELD(name_); - DIFF_OUT_FIELD(length_); DIFF_OUT_FIELD(scan_in_); DIFF_OUT_FIELD(scan_out_); - DIFF_OUT_FIELD(scan_clock_); DIFF_OUT_FIELD(scan_enable_); DIFF_OUT_FIELD(test_mode_); + DIFF_OUT_TABLE(scan_partitions_); + DIFF_OUT_TABLE(scan_insts_); DIFF_END } _dbScanChain::_dbScanChain(_dbDatabase* db) { + scan_partitions_ = new dbTable<_dbScanPartition>( + db, + this, + (GetObjTbl_t) &_dbScanChain::getObjectTable, + dbScanPartitionObj); + scan_insts_ = new dbTable<_dbScanInst>( + db, this, (GetObjTbl_t) &_dbScanChain::getObjectTable, dbScanInstObj); } _dbScanChain::_dbScanChain(_dbDatabase* db, const _dbScanChain& r) { name_ = r.name_; - length_ = r.length_; scan_in_ = r.scan_in_; scan_out_ = r.scan_out_; - scan_clock_ = r.scan_clock_; scan_enable_ = r.scan_enable_; test_mode_ = r.test_mode_; + scan_partitions_ + = new dbTable<_dbScanPartition>(db, this, *r.scan_partitions_); + scan_insts_ = new dbTable<_dbScanInst>(db, this, *r.scan_insts_); } dbIStream& operator>>(dbIStream& stream, _dbScanChain& obj) { stream >> obj.name_; - stream >> obj.length_; - stream >> obj.cells_; stream >> obj.scan_in_; stream >> obj.scan_out_; - stream >> obj.scan_clock_; stream >> obj.scan_enable_; stream >> obj.test_mode_; - stream >> obj.partitions_; - stream >> obj.scan_insts_; + stream >> *obj.scan_partitions_; + stream >> *obj.scan_insts_; return stream; } dbOStream& operator<<(dbOStream& stream, const _dbScanChain& obj) { stream << obj.name_; - stream << obj.length_; - stream << obj.cells_; stream << obj.scan_in_; stream << obj.scan_out_; - stream << obj.scan_clock_; stream << obj.scan_enable_; stream << obj.test_mode_; - stream << obj.partitions_; - stream << obj.scan_insts_; + stream << *obj.scan_partitions_; + stream << *obj.scan_insts_; return stream; } +dbObjectTable* _dbScanChain::getObjectTable(dbObjectType type) +{ + switch (type) { + case dbScanPartitionObj: + return scan_partitions_; + case dbScanInstObj: + return scan_insts_; + default: + break; + } + return getTable()->getObjectTable(type); +} + +_dbScanChain::~_dbScanChain() +{ + delete scan_partitions_; + delete scan_insts_; +} + //////////////////////////////////////////////////////////////////// // // dbScanChain - Methods // //////////////////////////////////////////////////////////////////// +dbSet dbScanChain::getScanPartitions() const +{ + _dbScanChain* obj = (_dbScanChain*) this; + return dbSet(obj, obj->scan_partitions_); +} + +dbSet dbScanChain::getScanInsts() const +{ + _dbScanChain* obj = (_dbScanChain*) this; + return dbSet(obj, obj->scan_insts_); +} + +// User Code Begin dbScanChainPublicMethods + +std::string_view dbScanChain::getName() const +{ + _dbScanChain* scan_chain = (_dbScanChain*) this; + return scan_chain->name_; +} + +void dbScanChain::setName(std::string_view name) +{ + _dbScanChain* scan_chain = (_dbScanChain*) this; + scan_chain->name_ = name; +} + +dbBTerm* _dbScanChain::getPin(_dbScanChain* scan_chain, + dbId _dbScanChain::*field) +{ + _dbDft* dft = (_dbDft*) scan_chain->getOwner(); + _dbBlock* block = (_dbBlock*) dft->getOwner(); + + return (dbBTerm*) block->_bterm_tbl->getPtr( + (dbId<_dbBTerm>) (scan_chain->*field)); +} + +void _dbScanChain::setPin(_dbScanChain* scan_chain, + dbId _dbScanChain::*field, + dbBTerm* pin) +{ + _dbBTerm* bterm = (_dbBTerm*) pin; + scan_chain->*field = bterm->getId(); +} + +void dbScanChain::setScanIn(dbBTerm* scan_in) +{ + _dbScanChain::setPin((_dbScanChain*) this, &_dbScanChain::scan_in_, scan_in); +} + +dbBTerm* dbScanChain::getScanIn() const +{ + return _dbScanChain::getPin((_dbScanChain*) this, &_dbScanChain::scan_in_); +} + +void dbScanChain::setScanOut(dbBTerm* scan_out) +{ + _dbScanChain::setPin( + (_dbScanChain*) this, &_dbScanChain::scan_out_, scan_out); +} + +dbBTerm* dbScanChain::getScanOut() const +{ + return _dbScanChain::getPin((_dbScanChain*) this, &_dbScanChain::scan_out_); +} + +void dbScanChain::setScanEnable(dbBTerm* scan_enable) +{ + _dbScanChain::setPin( + (_dbScanChain*) this, &_dbScanChain::scan_enable_, scan_enable); +} + +dbBTerm* dbScanChain::getScanEnable() const +{ + return _dbScanChain::getPin((_dbScanChain*) this, + &_dbScanChain::scan_enable_); +} + +void dbScanChain::setTestMode(std::string_view test_mode) +{ + _dbScanChain* scan_chain = (_dbScanChain*) this; + scan_chain->test_mode_ = test_mode; +} + +std::string_view dbScanChain::getTestMode() const +{ + _dbScanChain* scan_chain = (_dbScanChain*) this; + return scan_chain->test_mode_; +} + +dbScanPartition* dbScanChain::createScanPartition() +{ + _dbScanChain* scan_chain = (_dbScanChain*) this; + return (dbScanPartition*) (scan_chain->scan_partitions_->create()); +} + +dbScanInst* dbScanChain::createScanInst(dbInst* inst) +{ + _dbScanChain* scan_chain = (_dbScanChain*) this; + _dbInst* _inst = (_dbInst*) inst; + + _dbScanInst* scan_inst = (_dbScanInst*) scan_chain->scan_insts_->create(); + scan_inst->insts_.reserve(1); + scan_inst->insts_.push_back(_inst->getId()); + + return (dbScanInst*) scan_inst; +} + +dbScanInst* dbScanChain::createScanInst(const std::vector& insts) +{ + _dbScanChain* scan_chain = (_dbScanChain*) this; + + _dbScanInst* scan_inst = (_dbScanInst*) scan_chain->scan_insts_->create(); + scan_inst->insts_.reserve(insts.size()); + + for (const dbInst* inst : insts) { + scan_inst->insts_.push_back(inst->getId()); + } + + return (dbScanInst*) scan_inst; +} + +// User Code End dbScanChainPublicMethods } // namespace odb - // Generator Code End Cpp \ No newline at end of file + // Generator Code End Cpp diff --git a/src/odb/src/db/dbScanChain.h b/src/odb/src/db/dbScanChain.h index 41a874f26b..9f4a5f96a1 100644 --- a/src/odb/src/db/dbScanChain.h +++ b/src/odb/src/db/dbScanChain.h @@ -43,10 +43,12 @@ class dbIStream; class dbOStream; class dbDiff; class _dbDatabase; -class dbInst; -class dbScanPin; class dbScanPartition; -class dbScanInst; +class _dbScanPartition; +template +class dbTable; +class _dbScanInst; +class dbBTerm; class _dbScanChain : public _dbObject { @@ -54,7 +56,7 @@ class _dbScanChain : public _dbObject _dbScanChain(_dbDatabase*, const _dbScanChain& r); _dbScanChain(_dbDatabase*); - ~_dbScanChain() = default; + ~_dbScanChain(); bool operator==(const _dbScanChain& rhs) const; bool operator!=(const _dbScanChain& rhs) const { return !operator==(rhs); } @@ -63,19 +65,26 @@ class _dbScanChain : public _dbObject const char* field, const _dbScanChain& rhs) const; 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); + // User Code End Methods std::string name_; - uint length_; - dbVector> cells_; - dbId scan_in_; - dbId scan_out_; - dbId scan_clock_; - dbId scan_enable_; + dbId scan_in_; + dbId scan_out_; + dbId scan_enable_; std::string test_mode_; - dbVector> partitions_; - dbVector> scan_insts_; + + dbTable<_dbScanPartition>* scan_partitions_; + + dbTable<_dbScanInst>* scan_insts_; }; dbIStream& operator>>(dbIStream& stream, _dbScanChain& obj); dbOStream& operator<<(dbOStream& stream, const _dbScanChain& obj); } // namespace odb - // Generator Code End Header \ No newline at end of file + // Generator Code End Header diff --git a/src/odb/src/db/dbScanInst.cpp b/src/odb/src/db/dbScanInst.cpp index 4cbe74b57b..6d433e4dd3 100644 --- a/src/odb/src/db/dbScanInst.cpp +++ b/src/odb/src/db/dbScanInst.cpp @@ -35,7 +35,9 @@ #include "db.h" #include "dbDatabase.h" +#include "dbDft.h" #include "dbDiff.hpp" +#include "dbScanChain.h" #include "dbScanPin.h" #include "dbTable.h" #include "dbTable.hpp" @@ -44,13 +46,16 @@ template class dbTable<_dbScanInst>; bool _dbScanInst::operator==(const _dbScanInst& rhs) const { - if (bits != rhs.bits) { + if (bits_ != rhs.bits_) { return false; } - if (scanIn != rhs.scanIn) { + if (scan_enable_ != rhs.scan_enable_) { return false; } - if (scanOut != rhs.scanOut) { + if (scan_clock_ != rhs.scan_clock_) { + return false; + } + if (clock_edge_ != rhs.clock_edge_) { return false; } @@ -67,18 +72,20 @@ void _dbScanInst::differences(dbDiff& diff, const _dbScanInst& rhs) const { DIFF_BEGIN - DIFF_FIELD(bits); - DIFF_FIELD(scanIn); - DIFF_FIELD(scanOut); + DIFF_FIELD(bits_); + DIFF_FIELD(scan_enable_); + DIFF_FIELD(scan_clock_); + DIFF_FIELD(clock_edge_); DIFF_END } void _dbScanInst::out(dbDiff& diff, char side, const char* field) const { DIFF_OUT_BEGIN - DIFF_OUT_FIELD(bits); - DIFF_OUT_FIELD(scanIn); - DIFF_OUT_FIELD(scanOut); + DIFF_OUT_FIELD(bits_); + DIFF_OUT_FIELD(scan_enable_); + DIFF_OUT_FIELD(scan_clock_); + DIFF_OUT_FIELD(clock_edge_); DIFF_END } @@ -89,24 +96,31 @@ _dbScanInst::_dbScanInst(_dbDatabase* db) _dbScanInst::_dbScanInst(_dbDatabase* db, const _dbScanInst& r) { - bits = r.bits; - scanIn = r.scanIn; - scanOut = r.scanOut; + bits_ = r.bits_; + scan_enable_ = r.scan_enable_; + scan_clock_ = r.scan_clock_; + clock_edge_ = r.clock_edge_; } dbIStream& operator>>(dbIStream& stream, _dbScanInst& obj) { - stream >> obj.bits; - stream >> obj.scanIn; - stream >> obj.scanOut; + stream >> obj.bits_; + stream >> obj.access_pins_; + stream >> obj.scan_enable_; + stream >> obj.insts_; + stream >> obj.scan_clock_; + stream >> obj.clock_edge_; return stream; } dbOStream& operator<<(dbOStream& stream, const _dbScanInst& obj) { - stream << obj.bits; - stream << obj.scanIn; - stream << obj.scanOut; + stream << obj.bits_; + stream << obj.access_pins_; + stream << obj.scan_enable_; + stream << obj.insts_; + stream << obj.scan_clock_; + stream << obj.clock_edge_; return stream; } @@ -116,5 +130,134 @@ dbOStream& operator<<(dbOStream& stream, const _dbScanInst& obj) // //////////////////////////////////////////////////////////////////// +// User Code Begin dbScanInstPublicMethods +void dbScanInst::setScanClock(std::string_view scan_clock) +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + scan_inst->scan_clock_ = scan_clock; +} + +std::string_view dbScanInst::getScanClock() const +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + return scan_inst->scan_clock_; +} + +void dbScanInst::setClockEdge(ClockEdge clock_edge) +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + scan_inst->clock_edge_ = static_cast(clock_edge); +} + +dbScanInst::ClockEdge dbScanInst::getClockEdge() const +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + return static_cast(scan_inst->clock_edge_); +} + +void dbScanInst::setBits(uint bits) +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + scan_inst->bits_ = bits; +} + +uint dbScanInst::getBits() const +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + return scan_inst->bits_; +} + +void dbScanInst::setScanEnable(dbBTerm* scan_enable) +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + dbDft* dft = (dbDft*) scan_chain->getOwner(); + scan_inst->scan_enable_ = dft->CreateScanPin(scan_enable); +} + +void dbScanInst::setScanEnable(dbITerm* scan_enable) +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + dbDft* dft = (dbDft*) scan_chain->getOwner(); + scan_inst->scan_enable_ = dft->CreateScanPin(scan_enable); +} + +std::variant dbScanInst::getScanEnable() const +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + _dbDft* dft = (_dbDft*) scan_chain->getOwner(); + const dbScanPin* scan_enable = (dbScanPin*) dft->scan_pins_->getPtr( + (dbId<_dbScanPin>) scan_inst->scan_enable_); + return scan_enable->getPin(); +} + +std::string_view getName(odb::dbBTerm* bterm) +{ + return bterm->getConstName(); +} + +std::string_view getName(odb::dbITerm* iterm) +{ + return iterm->getMTerm()->getConstName(); +} + +void dbScanInst::setAccessPins(const AccessPins& access_pins) +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + dbDft* dft = (dbDft*) scan_chain->getOwner(); + + std::visit( + [&access_pins, scan_inst, dft](auto&& scan_in_pin) { + const dbId scan_in = dft->CreateScanPin(scan_in_pin); + std::visit( + [scan_inst, dft, &scan_in](auto&& scan_out_pin) { + const dbId scan_out = dft->CreateScanPin(scan_out_pin); + scan_inst->access_pins_ = std::make_pair(scan_in, scan_out); + }, + access_pins.scan_out); + }, + access_pins.scan_in); +} + +dbScanInst::AccessPins dbScanInst::getAccessPins() const +{ + AccessPins access_pins; + _dbScanInst* scan_inst = (_dbScanInst*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); + _dbDft* dft = (_dbDft*) scan_chain->getOwner(); + + const auto& [scan_in_id, scan_out_id] = scan_inst->access_pins_; + + dbScanPin* scan_in + = (dbScanPin*) dft->scan_pins_->getPtr((dbId<_dbScanPin>) scan_in_id); + dbScanPin* scan_out + = (dbScanPin*) dft->scan_pins_->getPtr((dbId<_dbScanPin>) scan_out_id); + + access_pins.scan_in = scan_in->getPin(); + access_pins.scan_out = scan_out->getPin(); + + return access_pins; +} + +std::vector dbScanInst::getInsts() const +{ + _dbScanInst* scan_inst = (_dbScanInst*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->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; +} + +// User Code End dbScanInstPublicMethods } // namespace odb - // Generator Code End Cpp \ No newline at end of file + // Generator Code End Cpp diff --git a/src/odb/src/db/dbScanInst.h b/src/odb/src/db/dbScanInst.h index 1fe94580dc..81411abf7a 100644 --- a/src/odb/src/db/dbScanInst.h +++ b/src/odb/src/db/dbScanInst.h @@ -34,7 +34,9 @@ #pragma once #include "dbCore.h" +#include "dbInst.h" #include "dbScanPin.h" +#include "dbVector.h" #include "odb.h" namespace odb { @@ -43,6 +45,7 @@ class dbOStream; class dbDiff; class _dbDatabase; class dbScanPin; +class dbInst; class _dbScanInst : public _dbObject { @@ -60,9 +63,12 @@ class _dbScanInst : public _dbObject const _dbScanInst& rhs) const; void out(dbDiff& diff, char side, const char* field) const; - uint bits; - dbId scanIn; - dbId scanOut; + uint bits_; + std::pair, dbId> access_pins_; + dbId scan_enable_; + dbVector> insts_; + std::string scan_clock_; + uint clock_edge_; }; dbIStream& operator>>(dbIStream& stream, _dbScanInst& obj); dbOStream& operator<<(dbOStream& stream, const _dbScanInst& obj); diff --git a/src/odb/src/db/dbScanPartition.cpp b/src/odb/src/db/dbScanPartition.cpp index ed2d921a51..776b629e73 100644 --- a/src/odb/src/db/dbScanPartition.cpp +++ b/src/odb/src/db/dbScanPartition.cpp @@ -35,7 +35,9 @@ #include "db.h" #include "dbDatabase.h" +#include "dbDft.h" #include "dbDiff.hpp" +#include "dbScanChain.h" #include "dbScanPin.h" #include "dbTable.h" #include "dbTable.hpp" @@ -116,5 +118,72 @@ dbOStream& operator<<(dbOStream& stream, const _dbScanPartition& obj) // //////////////////////////////////////////////////////////////////// +// User Code Begin dbScanPartitionPublicMethods + +void dbScanPartition::setStart(dbBTerm* bterm) +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); + dbDft* dft = (dbDft*) scan_chain->getOwner(); + scan_partition->start_ = dft->CreateScanPin(bterm); +} + +void dbScanPartition::setStart(dbITerm* iterm) +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); + dbDft* dft = (dbDft*) scan_chain->getOwner(); + scan_partition->start_ = dft->CreateScanPin(iterm); +} + +void dbScanPartition::setStop(dbBTerm* bterm) +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); + dbDft* dft = (dbDft*) scan_chain->getOwner(); + scan_partition->stop_ = dft->CreateScanPin(bterm); +} + +void dbScanPartition::setStop(dbITerm* iterm) +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); + dbDft* dft = (dbDft*) scan_chain->getOwner(); + scan_partition->stop_ = dft->CreateScanPin(iterm); +} + +std::variant dbScanPartition::getStart() const +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); + _dbDft* dft = (_dbDft*) scan_chain->getOwner(); + dbScanPin* scan_pin = (dbScanPin*) dft->scan_pins_->getPtr( + (dbId<_dbScanPin>) scan_partition->start_); + return scan_pin->getPin(); +} + +std::variant dbScanPartition::getStop() const +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); + _dbDft* dft = (_dbDft*) scan_chain->getOwner(); + dbScanPin* scan_pin = (dbScanPin*) dft->scan_pins_->getPtr( + (dbId<_dbScanPin>) scan_partition->stop_); + return scan_pin->getPin(); +} + +std::string_view dbScanPartition::getName() const +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + return scan_partition->name_; +} + +void dbScanPartition::setName(std::string_view name) +{ + _dbScanPartition* scan_partition = (_dbScanPartition*) this; + scan_partition->name_ = name; +} + +// User Code End dbScanPartitionPublicMethods } // namespace odb - // Generator Code End Cpp \ No newline at end of file + // Generator Code End Cpp diff --git a/src/odb/src/db/dbScanPartition.h b/src/odb/src/db/dbScanPartition.h index 17c7bdc8b5..a0832dd681 100644 --- a/src/odb/src/db/dbScanPartition.h +++ b/src/odb/src/db/dbScanPartition.h @@ -70,4 +70,4 @@ class _dbScanPartition : public _dbObject dbIStream& operator>>(dbIStream& stream, _dbScanPartition& obj); dbOStream& operator<<(dbOStream& stream, const _dbScanPartition& obj); } // namespace odb - // Generator Code End Header \ No newline at end of file + // Generator Code End Header diff --git a/src/odb/src/db/dbScanPin.cpp b/src/odb/src/db/dbScanPin.cpp index 51380bd489..4af2489182 100644 --- a/src/odb/src/db/dbScanPin.cpp +++ b/src/odb/src/db/dbScanPin.cpp @@ -34,11 +34,12 @@ #include "dbScanPin.h" #include "db.h" +#include "dbBlock.h" #include "dbDatabase.h" +#include "dbDft.h" #include "dbDiff.hpp" #include "dbTable.h" #include "dbTable.hpp" - // User Code Begin Includes namespace { template @@ -131,15 +132,18 @@ dbOStream& operator<<(dbOStream& stream, const _dbScanPin& obj) std::variant dbScanPin::getPin() const { const _dbScanPin* scan_pin = (_dbScanPin*) this; - const _dbBlock* block = (_dbBlock*) scan_pin->getOwner(); + const _dbDft* dft = (_dbDft*) scan_pin->getOwner(); + const _dbBlock* block = (_dbBlock*) dft->getOwner(); return std::visit( [block](auto&& pin) { using T = std::decay_t; if constexpr (std::is_same_v>) { - return (dbBTerm*) block->_bterm_tbl->getPtr(pin); + return std::variant( + (dbBTerm*) block->_bterm_tbl->getPtr(pin)); } else if constexpr (std::is_same_v>) { - return (dbBTerm*) block->_iterm_tbl->getPtr(pin); + return std::variant( + (dbITerm*) block->_iterm_tbl->getPtr(pin)); } else { static_assert(always_false_v, "non-exhaustive visitor!"); } @@ -150,13 +154,13 @@ std::variant dbScanPin::getPin() const void dbScanPin::setPin(dbBTerm* bterm) { _dbScanPin* scan_pin = (_dbScanPin*) this; - scan_pin->pin_.emplace>(((_dbBTerm*) this)->getId()); + scan_pin->pin_.emplace>(((_dbBTerm*) bterm)->getId()); } void dbScanPin::setPin(dbITerm* iterm) { _dbScanPin* scan_pin = (_dbScanPin*) this; - scan_pin->pin_.emplace>(((_dbITerm*) this)->getId()); + scan_pin->pin_.emplace>(((_dbITerm*) iterm)->getId()); } // User Code End dbScanPinPublicMethods diff --git a/src/odb/src/db/dbScanPin.h b/src/odb/src/db/dbScanPin.h index 84cf20d5b7..3ad6b5e0c5 100644 --- a/src/odb/src/db/dbScanPin.h +++ b/src/odb/src/db/dbScanPin.h @@ -34,7 +34,6 @@ #pragma once #include "dbBTerm.h" -#include "dbBlock.h" #include "dbCore.h" #include "dbITerm.h" #include "odb.h" @@ -47,6 +46,9 @@ class dbIStream; class dbOStream; class dbDiff; class _dbDatabase; +class dbScanPin; +class dbBTerm; +class dbITerm; class _dbScanPin : public _dbObject { diff --git a/src/odb/test/cpp/CMakeLists.txt b/src/odb/test/cpp/CMakeLists.txt index 4be59afa64..577543969c 100644 --- a/src/odb/test/cpp/CMakeLists.txt +++ b/src/odb/test/cpp/CMakeLists.txt @@ -69,5 +69,5 @@ add_dependencies(build_and_test TestMaster OdbGTests ) - add_subdirectory(helper) +add_subdirectory(scan) diff --git a/src/odb/test/cpp/TestAccessPoint.cpp b/src/odb/test/cpp/TestAccessPoint.cpp index 4191ea941d..e1f75a0438 100644 --- a/src/odb/test/cpp/TestAccessPoint.cpp +++ b/src/odb/test/cpp/TestAccessPoint.cpp @@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(test_default) ap->setHighType(dbAccessType::HalfGrid); ap->setAccess(true, dbDirection::DOWN); iterm->setAccessPoint(pin, ap); - std::string path = testTmpPath("/results/TestAccessPointDbRW"); + std::string path = testTmpPath("results", "TestAccessPointDbRW"); std::ofstream write; write.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ios::eofbit); diff --git a/src/odb/test/cpp/TestJournal.cpp b/src/odb/test/cpp/TestJournal.cpp index 23d4f728dd..2bf18d3743 100644 --- a/src/odb/test/cpp/TestJournal.cpp +++ b/src/odb/test/cpp/TestJournal.cpp @@ -24,7 +24,7 @@ struct F_DEFAULT dbDatabase* db; dbLib* lib; dbBlock* block; - std::string journal_path = testTmpPath("/results/db_jounal.eco"); + std::string journal_path = testTmpPath("results", "db_jounal.eco"); }; BOOST_FIXTURE_TEST_CASE(test_write, F_DEFAULT) { diff --git a/src/odb/test/cpp/TestLef58Properties.cpp b/src/odb/test/cpp/TestLef58Properties.cpp index e753998146..3010d34461 100644 --- a/src/odb/test/cpp/TestLef58Properties.cpp +++ b/src/odb/test/cpp/TestLef58Properties.cpp @@ -25,12 +25,12 @@ BOOST_AUTO_TEST_CASE(lef58_class) lefin lefParser(db1, logger, false); const char* libname = "gscl45nm.lef"; - std::string path = testTmpPath("/data/gscl45nm.lef"); + std::string path = testTmpPath("data", "gscl45nm.lef"); lefParser.createTechAndLib("tech", libname, path.c_str()); odb::dbLib* dbLib = db1->findLib(libname); - path = testTmpPath("/data/lef58class_gscl45nm.lef"); + path = testTmpPath("data", "lef58class_gscl45nm.lef"); lefParser.updateLib(dbLib, path.c_str()); odb::dbMaster* endcap = db1->findMaster("ENDCAP_BOTTOMEDGE_NOT_A_REAL_CELL"); @@ -49,11 +49,11 @@ BOOST_AUTO_TEST_CASE(test_default) lefin lefParser(db1, logger, false); const char* libname = "gscl45nm.lef"; - std::string path = testTmpPath("/data/gscl45nm.lef"); + std::string path = testTmpPath("data", "gscl45nm.lef"); lefParser.createTechAndLib("tech", libname, path.c_str()); - path = testTmpPath("/results/TestLef58PropertiesDbRW"); + path = testTmpPath("results", "TestLef58PropertiesDbRW"); std::ofstream write; write.exceptions(std::ifstream::failbit | std::ifstream::badbit diff --git a/src/odb/test/cpp/helper/env.cpp b/src/odb/test/cpp/helper/env.cpp index e221875e20..8dbb51f460 100644 --- a/src/odb/test/cpp/helper/env.cpp +++ b/src/odb/test/cpp/helper/env.cpp @@ -32,17 +32,22 @@ #include "env.h" +#include #include namespace odb { -std::string testTmpPath(const std::string& file) +std::string testTmpPath(const std::string& path, const std::string& file) { const char* base_dir = std::getenv("BASE_DIR"); if (!base_dir) { - throw std::runtime_error("BASE_DIR environment variable not set"); + const char* pwd = std::getenv("PWD"); + if (!pwd) { + throw std::runtime_error("BASE_DIR and PWD environment variables are not set"); + } + return std::string(pwd) + file; } - return std::string(base_dir) + file; + return std::string(base_dir) + "/" + path + "/" + file; } } // namespace odb diff --git a/src/odb/test/cpp/helper/env.h b/src/odb/test/cpp/helper/env.h index 01ae006ec1..71b382ce22 100644 --- a/src/odb/test/cpp/helper/env.h +++ b/src/odb/test/cpp/helper/env.h @@ -35,5 +35,5 @@ #pragma once namespace odb { -std::string testTmpPath(const std::string& file); +std::string testTmpPath(const std::string& path, const std::string& file); } // namespace odb diff --git a/src/odb/test/cpp/scan/CMakeLists.txt b/src/odb/test/cpp/scan/CMakeLists.txt new file mode 100644 index 0000000000..2701a438db --- /dev/null +++ b/src/odb/test/cpp/scan/CMakeLists.txt @@ -0,0 +1,25 @@ +include(openroad) + +set(TEST_LIBS + odb + zutil + lef + defin + defout + lefin + lefout + cdl + ${TCL_LIBRARY} + Boost::boost + utl_lib gtest + gmock + gtest_main + odb_test_helper +) + +add_executable(TestScanChain TestScanChain.cpp) +target_link_libraries(TestScanChain ${TEST_LIBS}) + +gtest_discover_tests(TestScanChain WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_dependencies(build_and_test TestScanChain) diff --git a/src/odb/test/cpp/scan/TestScanChain.cpp b/src/odb/test/cpp/scan/TestScanChain.cpp new file mode 100644 index 0000000000..f6455d67a0 --- /dev/null +++ b/src/odb/test/cpp/scan/TestScanChain.cpp @@ -0,0 +1,209 @@ +/////////////////////////////////////////////////////////////////////////////// +// BSD 3-Clause License +// +// Copyright (c) 2023, Google LLC +// 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. + +#include + +#include "db.h" +#include "env.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "helper.h" + +namespace odb { +namespace { + +constexpr std::string_view kPartition1 = "CHAIN_1_FALLING_1"; +constexpr std::string_view kPartition2 = "CHAIN_1_RISING_1"; + +template +inline constexpr bool always_false_v = false; + +std::string_view GetName(const std::variant& pin) +{ + return std::visit( + [](auto&& pin) { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return pin->getName(); + } else if constexpr (std::is_same_v) { + return pin->getMTerm()->getName(); + } else { + static_assert(always_false_v, "non-exhaustive visitor"); + } + }, + pin); +} + +class TestScanChain : public testing::Test +{ + protected: + TestScanChain() + { + db_ = create2LevetDbWithBTerms(); + block_ = db_->getChip()->getBlock(); + tmp_path_ = testTmpPath("results", "TestScanChain"); + dft_ = block_->createDft(); + + std::vector instances_names = {"i1", "i2", "i3"}; + + for (const auto& name : instances_names) { + instances_.push_back(block_->findInst(name.c_str())); + } + } + + dbDatabase* writeReadDb() + { + writeDb(); + return readDb(); + } + + void writeDb() + { + std::ofstream write; + write.exceptions(std::ifstream::failbit | std::ifstream::badbit + | std::ios::eofbit); + write.open(tmp_path_, std::ios::binary); + db_->write(write); + } + + dbDatabase* readDb() + { + dbDatabase* db = dbDatabase::create(); + std::ifstream read; + read.exceptions(std::ifstream::failbit | std::ifstream::badbit + | std::ios::eofbit); + read.open(tmp_path_, std::ios::binary); + db->read(read); + return db; + } + + dbDatabase* db_; + dbBlock* block_; + std::string tmp_path_; + dbDft* dft_; + std::vector instances_; +}; + +TEST_F(TestScanChain, CreateScanChain) +{ + dbInst* inst = block_->findInst("i1"); + dbITerm* iterm = inst->findITerm("a"); + dbBTerm* bterm = block_->findBTerm("IN1"); + + dbScanChain* scan_chain = dft_->CreateScanChain(); + + dbScanInst* scan_inst = scan_chain->createScanInst(inst); + scan_inst->setBits(1234); + scan_inst->setAccessPins({.scan_in = iterm, .scan_out = bterm}); + + //***************************** + dbDatabase* db2 = writeReadDb(); + dbBlock* block2 = db2->getChip()->getBlock(); + dbDft* dft2 = block2->getDft(); + + odb::dbSet scan_chains2 = dft2->getScanChains(); + EXPECT_THAT(scan_chains2.size(), 1); + + dbScanChain* scan_chain2 = *scan_chains2.begin(); + + odb::dbSet scan_insts2 = scan_chain2->getScanInsts(); + EXPECT_THAT(scan_insts2.size(), 1); +} + +TEST_F(TestScanChain, CreateScanChainWithPartition) +{ + dbScanChain* scan_chain = dft_->CreateScanChain(); + + for (dbInst* inst : instances_) { + dbScanInst* scan_inst = scan_chain->createScanInst(inst); + scan_inst->setBits(1); + dbITerm* iterm = inst->findITerm("a"); + dbITerm* iterm2 = inst->findITerm("o"); + scan_inst->setAccessPins({.scan_in = iterm, .scan_out = iterm2}); + } + + // 2 partitions, one for the first instance and a second one for the second + // instance. The partition 1 start at a bterm (chain scan in) and ends in the + // scan out of the first instance. + // + // The second partition starts at the scan in of the second instance and ends + // in the bterm scan out of the chain. The second partition contains 2 + // elements. + // + // Partition 1: [chain scan_in, i1 scan_out] + // Partition 2: [i2 scan_in, chain scan out] + + dbScanPartition* partition1 = scan_chain->createScanPartition(); + dbScanPartition* partition2 = scan_chain->createScanPartition(); + + dbBTerm* chain_scan_in = block_->findBTerm("IN1"); + dbBTerm* chain_scan_out = block_->findBTerm("IN3"); + + partition1->setStart(chain_scan_in); + partition1->setStop(instances_[0]->findITerm("o")); + partition1->setName(kPartition1); + + partition2->setStart(instances_[1]->findITerm("a")); + partition2->setStop(chain_scan_out); + partition2->setName(kPartition2); + + //***************************** + dbDatabase* db2 = writeReadDb(); + + dbBlock* block2 = db2->getChip()->getBlock(); + dbDft* dft2 = block2->getDft(); + + dbSet scan_chains2 = dft2->getScanChains(); + EXPECT_THAT(scan_chains2.size(), 1); + + dbSet scan_partitions2 + = scan_chains2.begin()->getScanPartitions(); + EXPECT_THAT(scan_partitions2.size(), 2); + + auto iterator = scan_partitions2.begin(); + + dbScanPartition* partition12 = *iterator; + ++iterator; + dbScanPartition* partition22 = *iterator; + + EXPECT_THAT(partition12->getName(), kPartition1); + EXPECT_THAT(partition22->getName(), kPartition2); + + EXPECT_THAT(GetName(partition12->getStart()), "IN1"); + EXPECT_THAT(GetName(partition12->getStop()), "o"); + + EXPECT_THAT(GetName(partition22->getStart()), "a"); + EXPECT_THAT(GetName(partition22->getStop()), "IN3"); +} + +} // namespace +} // namespace odb diff --git a/src/odb/test/data/design.odb b/src/odb/test/data/design.odb index a47c216f63502f38bc5fe3eea16ba06ff7f266a3..65e7d432d53e549476c2fdbbb3cf29e4567fd35d 100644 GIT binary patch delta 12879 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 UJ2gE1wT@2*{lI5OH>1@50_DJ7v;Y7A delta 11718 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 Date: Tue, 20 Feb 2024 17:37:08 -0800 Subject: [PATCH 02/16] odb tests: clang-format Signed-off-by: Felipe Garay --- src/odb/test/cpp/helper/env.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/odb/test/cpp/helper/env.cpp b/src/odb/test/cpp/helper/env.cpp index 8dbb51f460..c055a5068d 100644 --- a/src/odb/test/cpp/helper/env.cpp +++ b/src/odb/test/cpp/helper/env.cpp @@ -43,7 +43,8 @@ std::string testTmpPath(const std::string& path, const std::string& file) if (!base_dir) { const char* pwd = std::getenv("PWD"); if (!pwd) { - throw std::runtime_error("BASE_DIR and PWD environment variables are not set"); + throw std::runtime_error( + "BASE_DIR and PWD environment variables are not set"); } return std::string(pwd) + file; } From 64cbca787d622600da5abc26876f4395f24cb690 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Wed, 21 Feb 2024 12:54:44 -0800 Subject: [PATCH 03/16] odb tests: rollback design.odb to original state Signed-off-by: Felipe Garay --- src/odb/test/data/design.odb | Bin 217975 -> 206487 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/odb/test/data/design.odb b/src/odb/test/data/design.odb index 65e7d432d53e549476c2fdbbb3cf29e4567fd35d..a47c216f63502f38bc5fe3eea16ba06ff7f266a3 100644 GIT binary patch delta 11718 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 UJ2gE1wT@2*{lI5OH>1@50_DJ7v;Y7A From ba80273a37fb7709136e97d607afbf90d6cfbda8 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Thu, 22 Feb 2024 15:28:53 -0800 Subject: [PATCH 04/16] odb: making imposible for 2+ DFT objects to exist in a block Signed-off-by: Felipe Garay --- src/odb/include/odb/db.h | 5 ----- src/odb/src/db/dbBlock.cpp | 13 ++++--------- src/odb/src/db/dbDft.cpp | 7 +++++++ src/odb/src/db/dbDft.h | 3 +++ src/odb/test/cpp/scan/TestScanChain.cpp | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 261fe8445f..07e975a5f7 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -1367,11 +1367,6 @@ class dbBlock : public dbObject /// dbExtControl* getExtControl(); - /// - /// Get the dbDft object for persistent dft structs - /// - dbDft* createDft(); - /// /// Get the dbDft object for persistent dft structs /// diff --git a/src/odb/src/db/dbBlock.cpp b/src/odb/src/db/dbBlock.cpp index 45853580d0..33e4bcf02e 100644 --- a/src/odb/src/db/dbBlock.cpp +++ b/src/odb/src/db/dbBlock.cpp @@ -335,7 +335,10 @@ _dbBlock::_dbBlock(_dbDatabase* db) _extControl = new dbExtControl(); _dft_tbl = new dbTable<_dbDft>( - db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbDftObj); + db, this, (GetObjTbl_t) &_dbBlock::getObjectTable, dbDftObj, 4096, 12); + _dbDft* dft_ptr = _dft_tbl->create(); + dft_ptr->initialize(); + _dft = dft_ptr->getId(); _net_hash.setTable(_net_tbl); _inst_hash.setTable(_inst_tbl); @@ -2306,14 +2309,6 @@ dbExtControl* dbBlock::getExtControl() return (block->_extControl); } -dbDft* dbBlock::createDft() -{ - _dbBlock* block = (_dbBlock*) this; - _dbDft* dft = block->_dft_tbl->create(); - block->_dft = dft->getId(); - return (dbDft*) dft; -} - dbDft* dbBlock::getDft() const { _dbBlock* block = (_dbBlock*) this; diff --git a/src/odb/src/db/dbDft.cpp b/src/odb/src/db/dbDft.cpp index e455e98b2b..22888b929a 100644 --- a/src/odb/src/db/dbDft.cpp +++ b/src/odb/src/db/dbDft.cpp @@ -135,6 +135,13 @@ _dbDft::~_dbDft() delete scan_chains_; } +// User Code Begin PrivateMethods +void _dbDft::initialize() +{ + scan_inserted_ = false; +} +// User Code End PrivateMethods + //////////////////////////////////////////////////////////////////// // // dbDft - Methods diff --git a/src/odb/src/db/dbDft.h b/src/odb/src/db/dbDft.h index 5942a0186e..8fb3d3481c 100644 --- a/src/odb/src/db/dbDft.h +++ b/src/odb/src/db/dbDft.h @@ -61,6 +61,9 @@ class _dbDft : public _dbObject void differences(dbDiff& diff, const char* field, const _dbDft& rhs) const; void out(dbDiff& diff, char side, const char* field) const; dbObjectTable* getObjectTable(dbObjectType type); + // User Code Begin Methods + void initialize(); + // User Code End Methods bool scan_inserted_; diff --git a/src/odb/test/cpp/scan/TestScanChain.cpp b/src/odb/test/cpp/scan/TestScanChain.cpp index f6455d67a0..67fee5b044 100644 --- a/src/odb/test/cpp/scan/TestScanChain.cpp +++ b/src/odb/test/cpp/scan/TestScanChain.cpp @@ -71,7 +71,7 @@ class TestScanChain : public testing::Test db_ = create2LevetDbWithBTerms(); block_ = db_->getChip()->getBlock(); tmp_path_ = testTmpPath("results", "TestScanChain"); - dft_ = block_->createDft(); + dft_ = block_->getDft(); std::vector instances_names = {"i1", "i2", "i3"}; From eaf3282a6e991773273dbdca29d14f21110dd7e3 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Fri, 8 Mar 2024 14:36:21 -0800 Subject: [PATCH 05/16] odb dft: making the code style consistent with the rest of odb Signed-off-by: Felipe Garay --- src/odb/include/odb/db.h | 21 +++++++-------- src/odb/src/db/dbDft.cpp | 24 ----------------- src/odb/src/db/dbScanChain.cpp | 32 +++------------------- src/odb/src/db/dbScanInst.cpp | 36 ++++++++++++++++++++++--- src/odb/src/db/dbScanPartition.cpp | 14 +++++++--- src/odb/src/db/dbScanPin.cpp | 16 +++++++++++ src/odb/test/cpp/scan/TestScanChain.cpp | 12 ++++----- 7 files changed, 76 insertions(+), 79 deletions(-) diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 07e975a5f7..06d391aa5d 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -7098,12 +7098,6 @@ class dbDft : public dbObject bool isScanInserted() const; dbSet getScanChains() const; - - // User Code Begin dbDft - dbId CreateScanPin(dbBTerm* bterm); - dbId CreateScanPin(dbITerm* iterm); - dbScanChain* CreateScanChain(); - // User Code End dbDft }; class dbGCellGrid : public dbObject @@ -7781,15 +7775,12 @@ class dbScanChain : public dbObject dbBTerm* getScanOut() const; void setScanEnable(dbBTerm* scan_enable); - dbBTerm* getScanEnable() const; std::string_view getTestMode() const; void setTestMode(std::string_view test_mode); - dbScanPartition* createScanPartition(); - dbScanInst* createScanInst(dbInst* inst); - dbScanInst* createScanInst(const std::vector& insts); + static dbScanChain* create(dbDft* dft); // User Code End dbScanChain }; @@ -7815,7 +7806,6 @@ class dbScanInst : public dbObject ClockEdge getClockEdge() const; void setBits(uint bits); - uint getBits() const; void setScanEnable(dbBTerm* scan_enable); @@ -7823,10 +7813,13 @@ class dbScanInst : public dbObject std::variant getScanEnable() const; void setAccessPins(const AccessPins& access_pins); - AccessPins getAccessPins() const; std::vector getInsts() const; + + static dbScanInst* create(dbScanChain* scan_chain, dbInst* inst); + static dbScanInst* create(dbScanChain* scan_chain, + const std::vector& insts); // User Code End dbScanInst }; @@ -7849,6 +7842,8 @@ class dbScanPartition : public dbObject std::string_view getName() const; void setName(std::string_view name); + + static dbScanPartition* create(dbScanChain* chain); // User Code End dbScanPartition }; @@ -7859,6 +7854,8 @@ class dbScanPin : public dbObject std::variant getPin() const; void setPin(dbBTerm* bterm); void setPin(dbITerm* iterm); + static dbId create(dbDft* dft, dbBTerm* bterm); + static dbId create(dbDft* dft, dbITerm* iterm); // User Code End dbScanPin }; diff --git a/src/odb/src/db/dbDft.cpp b/src/odb/src/db/dbDft.cpp index 22888b929a..723dd8e41d 100644 --- a/src/odb/src/db/dbDft.cpp +++ b/src/odb/src/db/dbDft.cpp @@ -167,29 +167,5 @@ dbSet dbDft::getScanChains() const return dbSet(obj, obj->scan_chains_); } -// User Code Begin dbDftPublicMethods -dbId dbDft::CreateScanPin(dbBTerm* bterm) -{ - _dbDft* obj = (_dbDft*) this; - _dbScanPin* scan_pin = (_dbScanPin*) obj->scan_pins_->create(); - ((dbScanPin*) scan_pin)->setPin(bterm); - return scan_pin->getId(); -} - -dbId dbDft::CreateScanPin(dbITerm* iterm) -{ - _dbDft* obj = (_dbDft*) this; - _dbScanPin* scan_pin = (_dbScanPin*) obj->scan_pins_->create(); - ((dbScanPin*) scan_pin)->setPin(iterm); - return scan_pin->getId(); -} - -dbScanChain* dbDft::CreateScanChain() -{ - _dbDft* obj = (_dbDft*) this; - return (dbScanChain*) obj->scan_chains_->create(); -} - -// User Code End dbDftPublicMethods } // namespace odb // Generator Code End Cpp diff --git a/src/odb/src/db/dbScanChain.cpp b/src/odb/src/db/dbScanChain.cpp index 777666200d..c332507460 100644 --- a/src/odb/src/db/dbScanChain.cpp +++ b/src/odb/src/db/dbScanChain.cpp @@ -269,36 +269,10 @@ std::string_view dbScanChain::getTestMode() const return scan_chain->test_mode_; } -dbScanPartition* dbScanChain::createScanPartition() +dbScanChain* dbScanChain::create(dbDft* dft) { - _dbScanChain* scan_chain = (_dbScanChain*) this; - return (dbScanPartition*) (scan_chain->scan_partitions_->create()); -} - -dbScanInst* dbScanChain::createScanInst(dbInst* inst) -{ - _dbScanChain* scan_chain = (_dbScanChain*) this; - _dbInst* _inst = (_dbInst*) inst; - - _dbScanInst* scan_inst = (_dbScanInst*) scan_chain->scan_insts_->create(); - scan_inst->insts_.reserve(1); - scan_inst->insts_.push_back(_inst->getId()); - - return (dbScanInst*) scan_inst; -} - -dbScanInst* dbScanChain::createScanInst(const std::vector& insts) -{ - _dbScanChain* scan_chain = (_dbScanChain*) this; - - _dbScanInst* scan_inst = (_dbScanInst*) scan_chain->scan_insts_->create(); - scan_inst->insts_.reserve(insts.size()); - - for (const dbInst* inst : insts) { - scan_inst->insts_.push_back(inst->getId()); - } - - return (dbScanInst*) scan_inst; + _dbDft* obj = (_dbDft*) dft; + return (dbScanChain*) obj->scan_chains_->create(); } // User Code End dbScanChainPublicMethods diff --git a/src/odb/src/db/dbScanInst.cpp b/src/odb/src/db/dbScanInst.cpp index 6d433e4dd3..b8e70b9652 100644 --- a/src/odb/src/db/dbScanInst.cpp +++ b/src/odb/src/db/dbScanInst.cpp @@ -172,7 +172,7 @@ void dbScanInst::setScanEnable(dbBTerm* scan_enable) _dbScanInst* scan_inst = (_dbScanInst*) this; _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_inst->scan_enable_ = dft->CreateScanPin(scan_enable); + scan_inst->scan_enable_ = dbScanPin::create(dft, scan_enable); } void dbScanInst::setScanEnable(dbITerm* scan_enable) @@ -180,7 +180,7 @@ void dbScanInst::setScanEnable(dbITerm* scan_enable) _dbScanInst* scan_inst = (_dbScanInst*) this; _dbScanChain* scan_chain = (_dbScanChain*) scan_inst->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_inst->scan_enable_ = dft->CreateScanPin(scan_enable); + scan_inst->scan_enable_ = dbScanPin::create(dft, scan_enable); } std::variant dbScanInst::getScanEnable() const @@ -211,10 +211,11 @@ void dbScanInst::setAccessPins(const AccessPins& access_pins) std::visit( [&access_pins, scan_inst, dft](auto&& scan_in_pin) { - const dbId scan_in = dft->CreateScanPin(scan_in_pin); + const dbId scan_in = dbScanPin::create(dft, scan_in_pin); std::visit( [scan_inst, dft, &scan_in](auto&& scan_out_pin) { - const dbId scan_out = dft->CreateScanPin(scan_out_pin); + const dbId scan_out + = dbScanPin::create(dft, scan_out_pin); scan_inst->access_pins_ = std::make_pair(scan_in, scan_out); }, access_pins.scan_out); @@ -258,6 +259,33 @@ std::vector dbScanInst::getInsts() const return insts; } +dbScanInst* dbScanInst::create(dbScanChain* scan_chain, 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; + + _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()); + } + + return (dbScanInst*) scan_inst; +} + // User Code End dbScanInstPublicMethods } // namespace odb // Generator Code End Cpp diff --git a/src/odb/src/db/dbScanPartition.cpp b/src/odb/src/db/dbScanPartition.cpp index 776b629e73..2379467082 100644 --- a/src/odb/src/db/dbScanPartition.cpp +++ b/src/odb/src/db/dbScanPartition.cpp @@ -125,7 +125,7 @@ void dbScanPartition::setStart(dbBTerm* bterm) _dbScanPartition* scan_partition = (_dbScanPartition*) this; _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->start_ = dft->CreateScanPin(bterm); + scan_partition->start_ = dbScanPin::create(dft, bterm); } void dbScanPartition::setStart(dbITerm* iterm) @@ -133,7 +133,7 @@ void dbScanPartition::setStart(dbITerm* iterm) _dbScanPartition* scan_partition = (_dbScanPartition*) this; _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->start_ = dft->CreateScanPin(iterm); + scan_partition->start_ = dbScanPin::create(dft, iterm); } void dbScanPartition::setStop(dbBTerm* bterm) @@ -141,7 +141,7 @@ void dbScanPartition::setStop(dbBTerm* bterm) _dbScanPartition* scan_partition = (_dbScanPartition*) this; _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->stop_ = dft->CreateScanPin(bterm); + scan_partition->stop_ = dbScanPin::create(dft, bterm); } void dbScanPartition::setStop(dbITerm* iterm) @@ -149,7 +149,7 @@ void dbScanPartition::setStop(dbITerm* iterm) _dbScanPartition* scan_partition = (_dbScanPartition*) this; _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->stop_ = dft->CreateScanPin(iterm); + scan_partition->stop_ = dbScanPin::create(dft, iterm); } std::variant dbScanPartition::getStart() const @@ -184,6 +184,12 @@ void dbScanPartition::setName(std::string_view name) scan_partition->name_ = name; } +dbScanPartition* dbScanPartition::create(dbScanChain* chain) +{ + _dbScanChain* scan_chain = (_dbScanChain*) chain; + return (dbScanPartition*) (scan_chain->scan_partitions_->create()); +} + // User Code End dbScanPartitionPublicMethods } // namespace odb // Generator Code End Cpp diff --git a/src/odb/src/db/dbScanPin.cpp b/src/odb/src/db/dbScanPin.cpp index 4af2489182..1988da4ef5 100644 --- a/src/odb/src/db/dbScanPin.cpp +++ b/src/odb/src/db/dbScanPin.cpp @@ -163,6 +163,22 @@ void dbScanPin::setPin(dbITerm* iterm) scan_pin->pin_.emplace>(((_dbITerm*) iterm)->getId()); } +dbId dbScanPin::create(dbDft* dft, dbBTerm* bterm) +{ + _dbDft* obj = (_dbDft*) dft; + _dbScanPin* scan_pin = (_dbScanPin*) obj->scan_pins_->create(); + ((dbScanPin*) scan_pin)->setPin(bterm); + return scan_pin->getId(); +} + +dbId dbScanPin::create(dbDft* dft, dbITerm* iterm) +{ + _dbDft* obj = (_dbDft*) dft; + _dbScanPin* scan_pin = (_dbScanPin*) obj->scan_pins_->create(); + ((dbScanPin*) scan_pin)->setPin(iterm); + return scan_pin->getId(); +} + // User Code End dbScanPinPublicMethods } // namespace odb // Generator Code End Cpp diff --git a/src/odb/test/cpp/scan/TestScanChain.cpp b/src/odb/test/cpp/scan/TestScanChain.cpp index 67fee5b044..30d048d7de 100644 --- a/src/odb/test/cpp/scan/TestScanChain.cpp +++ b/src/odb/test/cpp/scan/TestScanChain.cpp @@ -119,9 +119,9 @@ TEST_F(TestScanChain, CreateScanChain) dbITerm* iterm = inst->findITerm("a"); dbBTerm* bterm = block_->findBTerm("IN1"); - dbScanChain* scan_chain = dft_->CreateScanChain(); + dbScanChain* scan_chain = dbScanChain::create(dft_); - dbScanInst* scan_inst = scan_chain->createScanInst(inst); + dbScanInst* scan_inst = dbScanInst::create(scan_chain, inst); scan_inst->setBits(1234); scan_inst->setAccessPins({.scan_in = iterm, .scan_out = bterm}); @@ -141,10 +141,10 @@ TEST_F(TestScanChain, CreateScanChain) TEST_F(TestScanChain, CreateScanChainWithPartition) { - dbScanChain* scan_chain = dft_->CreateScanChain(); + dbScanChain* scan_chain = dbScanChain::create(dft_); for (dbInst* inst : instances_) { - dbScanInst* scan_inst = scan_chain->createScanInst(inst); + dbScanInst* scan_inst = dbScanInst::create(scan_chain, inst); scan_inst->setBits(1); dbITerm* iterm = inst->findITerm("a"); dbITerm* iterm2 = inst->findITerm("o"); @@ -162,8 +162,8 @@ TEST_F(TestScanChain, CreateScanChainWithPartition) // Partition 1: [chain scan_in, i1 scan_out] // Partition 2: [i2 scan_in, chain scan out] - dbScanPartition* partition1 = scan_chain->createScanPartition(); - dbScanPartition* partition2 = scan_chain->createScanPartition(); + dbScanPartition* partition1 = dbScanPartition::create(scan_chain); + dbScanPartition* partition2 = dbScanPartition::create(scan_chain); dbBTerm* chain_scan_in = block_->findBTerm("IN1"); dbBTerm* chain_scan_out = block_->findBTerm("IN3"); From 0a511e47b5d8de19fa2e9881cddb5f7235c8baf3 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Fri, 8 Mar 2024 15:54:12 -0800 Subject: [PATCH 06/16] odb: changing std::string_view with std::string to make it compatible with swig Signed-off-by: Felipe Garay --- src/odb/include/odb/db.h | 8 ++++---- src/odb/src/db/dbScanChain.cpp | 4 ++-- src/odb/src/db/dbScanInst.cpp | 2 +- src/odb/src/db/dbScanPartition.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 06d391aa5d..a4ea427b90 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -7764,7 +7764,7 @@ class dbScanChain : public dbObject dbSet getScanInsts() const; // User Code Begin dbScanChain - std::string_view getName() const; + const std::string& getName() const; void setName(std::string_view name); @@ -7777,7 +7777,7 @@ class dbScanChain : public dbObject void setScanEnable(dbBTerm* scan_enable); dbBTerm* getScanEnable() const; - std::string_view getTestMode() const; + const std::string& getTestMode() const; void setTestMode(std::string_view test_mode); static dbScanChain* create(dbDft* dft); @@ -7800,7 +7800,7 @@ class dbScanInst : public dbObject // User Code Begin dbScanInst void setScanClock(std::string_view scan_clock); - std::string_view getScanClock() const; + const std::string& getScanClock() const; void setClockEdge(ClockEdge clock_edge); ClockEdge getClockEdge() const; @@ -7839,7 +7839,7 @@ class dbScanPartition : public dbObject std::variant getStop() const; - std::string_view getName() const; + const std::string& getName() const; void setName(std::string_view name); diff --git a/src/odb/src/db/dbScanChain.cpp b/src/odb/src/db/dbScanChain.cpp index c332507460..26719d3a15 100644 --- a/src/odb/src/db/dbScanChain.cpp +++ b/src/odb/src/db/dbScanChain.cpp @@ -194,7 +194,7 @@ dbSet dbScanChain::getScanInsts() const // User Code Begin dbScanChainPublicMethods -std::string_view dbScanChain::getName() const +const std::string& dbScanChain::getName() const { _dbScanChain* scan_chain = (_dbScanChain*) this; return scan_chain->name_; @@ -263,7 +263,7 @@ void dbScanChain::setTestMode(std::string_view test_mode) scan_chain->test_mode_ = test_mode; } -std::string_view dbScanChain::getTestMode() const +const std::string& dbScanChain::getTestMode() const { _dbScanChain* scan_chain = (_dbScanChain*) this; return scan_chain->test_mode_; diff --git a/src/odb/src/db/dbScanInst.cpp b/src/odb/src/db/dbScanInst.cpp index b8e70b9652..759a1c9bb4 100644 --- a/src/odb/src/db/dbScanInst.cpp +++ b/src/odb/src/db/dbScanInst.cpp @@ -137,7 +137,7 @@ void dbScanInst::setScanClock(std::string_view scan_clock) scan_inst->scan_clock_ = scan_clock; } -std::string_view dbScanInst::getScanClock() const +const std::string& dbScanInst::getScanClock() const { _dbScanInst* scan_inst = (_dbScanInst*) this; return scan_inst->scan_clock_; diff --git a/src/odb/src/db/dbScanPartition.cpp b/src/odb/src/db/dbScanPartition.cpp index 2379467082..5b651cbc65 100644 --- a/src/odb/src/db/dbScanPartition.cpp +++ b/src/odb/src/db/dbScanPartition.cpp @@ -172,7 +172,7 @@ std::variant dbScanPartition::getStop() const return scan_pin->getPin(); } -std::string_view dbScanPartition::getName() const +const std::string& dbScanPartition::getName() const { _dbScanPartition* scan_partition = (_dbScanPartition*) this; return scan_partition->name_; From 4c723cddcb6453ee4b593c116134213659315b8e Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Tue, 19 Mar 2024 13:47:36 -0700 Subject: [PATCH 07/16] 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 a4ea427b90..01ca94be59 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -147,6 +147,7 @@ class dbPowerDomain; class dbPowerSwitch; class dbScanChain; class dbScanInst; +class dbScanList; class dbScanPartition; class dbScanPin; class dbTechLayer; @@ -7761,7 +7762,7 @@ class dbScanChain : public dbObject public: dbSet getScanPartitions() const; - dbSet getScanInsts() const; + dbSet getScanLists() const; // User Code Begin dbScanChain const std::string& getName() const; @@ -7769,16 +7770,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 @@ -7815,14 +7823,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 8dcf204c43..5eaf51dc5f 100644 --- a/src/odb/include/odb/dbObject.h +++ b/src/odb/include/odb/dbObject.h @@ -106,6 +106,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 9f0bafe787..59c964a634 100644 --- a/src/odb/src/codeGenerator/schema.json +++ b/src/odb/src/codeGenerator/schema.json @@ -268,6 +268,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 ca7d34513b..ca565760b0 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 72bc050e21..6c40cb4333 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 0000000000..7c259d554a --- /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 18c8b7e864..312a9269da 100644 --- a/src/odb/src/db/CMakeLists.txt +++ b/src/odb/src/db/CMakeLists.txt @@ -107,6 +107,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 87e9af3cef..dbf12d7707 100644 --- a/src/odb/src/db/dbObject.cpp +++ b/src/odb/src/db/dbObject.cpp @@ -110,6 +110,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 26719d3a15..f69eb80832 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 9f4a5f96a1..a9f83b628f 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 759a1c9bb4..36e6254b7e 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 81411abf7a..adb6c5f088 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 0000000000..c4d7250ff7 --- /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 0000000000..1d5a064aa8 --- /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 30d048d7de..f111b106ad 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 From 386ca9ff7a322c05934a1cfcfc1d15f065c305cc Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Wed, 20 Mar 2024 15:46:49 -0700 Subject: [PATCH 08/16] odb dft: Updating dbScanInst and dbScanList Signed-off-by: Felipe Garay --- src/odb/src/db/dbScanInst.cpp | 14 +++++++++++++- src/odb/src/db/dbScanInst.h | 1 + src/odb/src/db/dbScanList.cpp | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/odb/src/db/dbScanInst.cpp b/src/odb/src/db/dbScanInst.cpp index 36e6254b7e..9eef6832f4 100644 --- a/src/odb/src/db/dbScanInst.cpp +++ b/src/odb/src/db/dbScanInst.cpp @@ -109,6 +109,12 @@ _dbScanInst::_dbScanInst(_dbDatabase* db, const _dbScanInst& r) clock_edge_ = r.clock_edge_; } +dbIStream& operator>>(dbIStream& stream, dbScanInst::AccessPins& obj) +{ + stream >> obj.scan_in; + stream >> obj.scan_out; + return stream; +} dbIStream& operator>>(dbIStream& stream, _dbScanInst& obj) { stream >> obj.bits_; @@ -120,6 +126,12 @@ dbIStream& operator>>(dbIStream& stream, _dbScanInst& obj) return stream; } +dbOStream& operator<<(dbOStream& stream, const dbScanInst::AccessPins& obj) +{ + stream << obj.scan_in; + stream << obj.scan_out; + return stream; +} dbOStream& operator<<(dbOStream& stream, const _dbScanInst& obj) { stream << obj.bits_; @@ -269,7 +281,7 @@ dbScanInst* dbScanInst::create(dbScanList* scan_list, dbInst* inst) { _dbScanList* obj = (_dbScanList*) scan_list; _dbScanInst* scan_inst = (_dbScanInst*) obj->scan_insts_->create(); - scan_inst->inst_ = ((_dbInst*)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 adb6c5f088..d92697d746 100644 --- a/src/odb/src/db/dbScanInst.h +++ b/src/odb/src/db/dbScanInst.h @@ -33,6 +33,7 @@ // Generator Code Begin Header #pragma once +#include "db.h" #include "dbCore.h" #include "dbInst.h" #include "dbScanPin.h" diff --git a/src/odb/src/db/dbScanList.cpp b/src/odb/src/db/dbScanList.cpp index c4d7250ff7..64ae564b7c 100644 --- a/src/odb/src/db/dbScanList.cpp +++ b/src/odb/src/db/dbScanList.cpp @@ -135,7 +135,7 @@ dbScanInst* dbScanList::add(dbInst* inst) dbScanList* dbScanList::create(dbScanChain* scan_chain) { _dbScanChain* obj = (_dbScanChain*) scan_chain; - return (dbScanList*)obj->scan_lists_->create(); + return (dbScanList*) obj->scan_lists_->create(); } // User Code End dbScanListPublicMethods } // namespace odb From 235f45724e6be67340256a8397bde7901f153e76 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Wed, 20 Mar 2024 16:07:24 -0700 Subject: [PATCH 09/16] odb dft: adding no-serializer-in and no-serializer-out to dbScanInst Signed-off-by: Felipe Garay --- .../src/codeGenerator/schema/scan/dbScanInst.json | 4 ++++ src/odb/src/db/dbScanInst.cpp | 12 ------------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json index 6c40cb4333..eb8c416d02 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json @@ -57,6 +57,10 @@ "name": "scan_out", "type": "std::variant" } + ], + "flags": [ + "no-serializer-in", + "no-serializer-out" ] } ], diff --git a/src/odb/src/db/dbScanInst.cpp b/src/odb/src/db/dbScanInst.cpp index 9eef6832f4..9fb11da729 100644 --- a/src/odb/src/db/dbScanInst.cpp +++ b/src/odb/src/db/dbScanInst.cpp @@ -109,12 +109,6 @@ _dbScanInst::_dbScanInst(_dbDatabase* db, const _dbScanInst& r) clock_edge_ = r.clock_edge_; } -dbIStream& operator>>(dbIStream& stream, dbScanInst::AccessPins& obj) -{ - stream >> obj.scan_in; - stream >> obj.scan_out; - return stream; -} dbIStream& operator>>(dbIStream& stream, _dbScanInst& obj) { stream >> obj.bits_; @@ -126,12 +120,6 @@ dbIStream& operator>>(dbIStream& stream, _dbScanInst& obj) return stream; } -dbOStream& operator<<(dbOStream& stream, const dbScanInst::AccessPins& obj) -{ - stream << obj.scan_in; - stream << obj.scan_out; - return stream; -} dbOStream& operator<<(dbOStream& stream, const _dbScanInst& obj) { stream << obj.bits_; From 71472dde4314ebfb140fb8c2b931b487c2e530a6 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Wed, 20 Mar 2024 16:13:30 -0700 Subject: [PATCH 10/16] odb tests: clang-format Signed-off-by: Felipe Garay --- src/odb/test/cpp/scan/TestScanChain.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/odb/test/cpp/scan/TestScanChain.cpp b/src/odb/test/cpp/scan/TestScanChain.cpp index f111b106ad..ab572a87ab 100644 --- a/src/odb/test/cpp/scan/TestScanChain.cpp +++ b/src/odb/test/cpp/scan/TestScanChain.cpp @@ -149,7 +149,6 @@ TEST_F(TestScanChain, CreateScanChainWithPartition) dbScanChain* scan_chain = dbScanChain::create(dft_); dbScanList* scan_list = dbScanList::create(scan_chain); - for (dbInst* inst : instances_) { dbScanInst* scan_inst = scan_list->add(inst); scan_inst->setBits(1); @@ -216,7 +215,7 @@ TEST_F(TestScanChain, CreateScanChainWithPartition) dbSet scan_insts2 = scan_lists2.begin()->getScanInsts(); int i = 0; - for (dbScanInst* scan_inst: scan_insts2) { + 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"); @@ -225,7 +224,6 @@ TEST_F(TestScanChain, CreateScanChainWithPartition) } } - TEST_F(TestScanChain, CreateScanChainWithMultipleScanLists) { dbScanChain* scan_chain = dbScanChain::create(dft_); @@ -248,8 +246,8 @@ TEST_F(TestScanChain, CreateScanChainWithMultipleScanLists) EXPECT_THAT(scan_lists2.size(), 2); int i = 0; - for (dbScanList* scan_list: scan_lists2) { - for (dbScanInst* scan_inst: scan_list->getScanInsts()) { + for (dbScanList* scan_list : scan_lists2) { + for (dbScanInst* scan_inst : scan_list->getScanInsts()) { EXPECT_THAT(scan_inst->getInst()->getName(), instances_[i]->getName()); ++i; } From bcbf90a5a6987abf37f6dbda11cf755603874f0b Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Wed, 20 Mar 2024 16:31:13 -0700 Subject: [PATCH 11/16] odb dft: re-generating dbScanList.h Signed-off-by: Felipe Garay --- src/odb/src/db/dbScanList.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/odb/src/db/dbScanList.h b/src/odb/src/db/dbScanList.h index 1d5a064aa8..e9bc276dac 100644 --- a/src/odb/src/db/dbScanList.h +++ b/src/odb/src/db/dbScanList.h @@ -36,6 +36,9 @@ #include "dbCore.h" #include "odb.h" +// User Code Begin Includes +// User Code End Includes + namespace odb { class dbIStream; class dbOStream; @@ -44,10 +47,18 @@ class _dbDatabase; class _dbScanInst; template class dbTable; +// User Code Begin Classes +// User Code End Classes + +// User Code Begin Structs +// User Code End Structs class _dbScanList : public _dbObject { public: + // User Code Begin Enums + // User Code End Enums + _dbScanList(_dbDatabase*, const _dbScanList& r); _dbScanList(_dbDatabase*); @@ -61,10 +72,17 @@ class _dbScanList : public _dbObject const _dbScanList& rhs) const; void out(dbDiff& diff, char side, const char* field) const; dbObjectTable* getObjectTable(dbObjectType type); + // User Code Begin Methods + // User Code End Methods dbTable<_dbScanInst>* scan_insts_; + + // User Code Begin Fields + // User Code End Fields }; dbIStream& operator>>(dbIStream& stream, _dbScanList& obj); dbOStream& operator<<(dbOStream& stream, const _dbScanList& obj); +// User Code Begin General +// User Code End General } // namespace odb // Generator Code End Header \ No newline at end of file From b1a68800ef83f955fa09348233009653f27a9d9f Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Thu, 21 Mar 2024 16:45:54 -0700 Subject: [PATCH 12/16] odb dft: updating dbScanList with generated code Signed-off-by: Felipe Garay --- src/odb/src/db/dbScanList.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/odb/src/db/dbScanList.h b/src/odb/src/db/dbScanList.h index e9bc276dac..1d5a064aa8 100644 --- a/src/odb/src/db/dbScanList.h +++ b/src/odb/src/db/dbScanList.h @@ -36,9 +36,6 @@ #include "dbCore.h" #include "odb.h" -// User Code Begin Includes -// User Code End Includes - namespace odb { class dbIStream; class dbOStream; @@ -47,18 +44,10 @@ class _dbDatabase; class _dbScanInst; template class dbTable; -// User Code Begin Classes -// User Code End Classes - -// User Code Begin Structs -// User Code End Structs class _dbScanList : public _dbObject { public: - // User Code Begin Enums - // User Code End Enums - _dbScanList(_dbDatabase*, const _dbScanList& r); _dbScanList(_dbDatabase*); @@ -72,17 +61,10 @@ class _dbScanList : public _dbObject const _dbScanList& rhs) const; void out(dbDiff& diff, char side, const char* field) const; dbObjectTable* getObjectTable(dbObjectType type); - // User Code Begin Methods - // User Code End Methods dbTable<_dbScanInst>* scan_insts_; - - // User Code Begin Fields - // User Code End Fields }; dbIStream& operator>>(dbIStream& stream, _dbScanList& obj); dbOStream& operator<<(dbOStream& stream, const _dbScanList& obj); -// User Code Begin General -// User Code End General } // namespace odb // Generator Code End Header \ No newline at end of file From 0ca67bdf43558aa7be83f34534519f05214eb4f2 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Thu, 21 Mar 2024 19:11:50 -0700 Subject: [PATCH 13/16] odb dft: adding whitespace to prevent PR checks fail Signed-off-by: Felipe Garay --- src/odb/src/db/dbScanList.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odb/src/db/dbScanList.h b/src/odb/src/db/dbScanList.h index 1d5a064aa8..d56637b15e 100644 --- a/src/odb/src/db/dbScanList.h +++ b/src/odb/src/db/dbScanList.h @@ -67,4 +67,4 @@ class _dbScanList : public _dbObject 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 + // Generator Code End Header From 0dfc089c7e398e202efc669f48dbaf28f3199537 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Fri, 22 Mar 2024 11:42:51 -0700 Subject: [PATCH 14/16] odb dft: adding comments to dft methods Signed-off-by: Felipe Garay --- src/odb/include/odb/db.h | 2 ++ src/odb/test/cpp/scan/TestScanChain.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 01ca94be59..4d6716d780 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -7813,6 +7813,8 @@ class dbScanInst : public dbObject void setClockEdge(ClockEdge clock_edge); ClockEdge getClockEdge() const; + // The number of bits that are in this scan inst from the scan in to the scan + // out. For simple flops this is just 1. void setBits(uint bits); uint getBits() const; diff --git a/src/odb/test/cpp/scan/TestScanChain.cpp b/src/odb/test/cpp/scan/TestScanChain.cpp index ab572a87ab..07fb2344f4 100644 --- a/src/odb/test/cpp/scan/TestScanChain.cpp +++ b/src/odb/test/cpp/scan/TestScanChain.cpp @@ -80,6 +80,8 @@ class TestScanChain : public testing::Test } } + // Writes a temporal DB and then tries to read the contents back to check if + // the serialization is working as expected dbDatabase* writeReadDb() { writeDb(); From 64d7d938c02786b78a75949584c5fc28f3bca87d Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Fri, 22 Mar 2024 12:14:41 -0700 Subject: [PATCH 15/16] odb dft: clang-tidy Signed-off-by: Felipe Garay --- src/odb/src/db/dbScanChain.cpp | 2 +- src/odb/src/db/dbScanChain.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/odb/src/db/dbScanChain.cpp b/src/odb/src/db/dbScanChain.cpp index f69eb80832..762988a247 100644 --- a/src/odb/src/db/dbScanChain.cpp +++ b/src/odb/src/db/dbScanChain.cpp @@ -216,7 +216,7 @@ void dbScanChain::setName(std::string_view name) } std::variant _dbScanChain::getPin( - dbId scan_pin_id) + const dbId& scan_pin_id) { _dbDft* dft = (_dbDft*) getOwner(); return ((dbScanPin*) dft->scan_pins_->getPtr((dbId<_dbScanPin>) scan_pin_id)) diff --git a/src/odb/src/db/dbScanChain.h b/src/odb/src/db/dbScanChain.h index a9f83b628f..9cba7dd663 100644 --- a/src/odb/src/db/dbScanChain.h +++ b/src/odb/src/db/dbScanChain.h @@ -67,7 +67,7 @@ class _dbScanChain : public _dbObject void out(dbDiff& diff, char side, const char* field) const; dbObjectTable* getObjectTable(dbObjectType type); // User Code Begin Methods - std::variant getPin(dbId scan_pin_id); + std::variant getPin(const dbId& scan_pin_id); void setPin(dbId _dbScanChain::*field, dbBTerm* pin); void setPin(dbId _dbScanChain::*field, dbITerm* pin); // User Code End Methods From 4bda97719176696b69c0ec083050b77028f88858 Mon Sep 17 00:00:00 2001 From: Felipe Garay Date: Wed, 3 Apr 2024 17:24:28 -0700 Subject: [PATCH 16/16] odb: adding comments to the scan structs Signed-off-by: Felipe Garay --- src/odb/include/odb/db.h | 51 ++++--- src/odb/src/codeGenerator/schema.json | 5 +- .../src/codeGenerator/schema/scan/dbDft.json | 1 + .../schema/scan/dbScanChain.json | 5 + .../codeGenerator/schema/scan/dbScanInst.json | 12 +- .../codeGenerator/schema/scan/dbScanList.json | 9 +- .../schema/scan/dbScanPartition.json | 18 ++- .../codeGenerator/schema/scan/dbScanPin.json | 7 + src/odb/src/codeGenerator/templates/db.h | 5 + src/odb/src/db/dbScanChain.cpp | 20 --- src/odb/src/db/dbScanChain.h | 3 - src/odb/src/db/dbScanInst.cpp | 16 ++- src/odb/src/db/dbScanList.cpp | 5 +- src/odb/src/db/dbScanPartition.cpp | 96 +++++-------- src/odb/src/db/dbScanPartition.h | 11 +- src/odb/test/cpp/scan/TestScanChain.cpp | 126 +++++++----------- 16 files changed, 184 insertions(+), 206 deletions(-) diff --git a/src/odb/include/odb/db.h b/src/odb/include/odb/db.h index 4d6716d780..2547173172 100644 --- a/src/odb/include/odb/db.h +++ b/src/odb/include/odb/db.h @@ -7091,6 +7091,7 @@ class dbAccessPoint : public dbObject // User Code End dbAccessPoint }; +// Top level DFT (Design for Testing) class class dbDft : public dbObject { public: @@ -7757,13 +7758,16 @@ class dbPowerSwitch : public dbObject // User Code End dbPowerSwitch }; +// A scan chain is a collection of dbScanLists that contains dbScanInsts. Here, +// scan_in, scan_out and scan_enable are the top level ports/pins to where this +// scan chain is connected. Each scan chain is also associated with a +// particular test mode and test mode pin that puts the Circuit Under Test (CUT) +// in test. The Scan Enable port/pin puts the scan chain into shifting mode. class dbScanChain : public dbObject { public: dbSet getScanPartitions() const; - dbSet getScanLists() const; - // User Code Begin dbScanChain const std::string& getName() const; @@ -7792,6 +7796,14 @@ class dbScanChain : public dbObject // User Code End dbScanChain }; +// A scan inst is a cell with a scan in, scan out and an optional scan enable. +// If no scan enable is provided, then this is an stateless component (because +// we don't need to enable scan for it) and the number of bits is set to 0. It +// may be possible that two or more dbScanInst contains the same dbInst if the +// dbInst has more than one scan_in/scan_out pair. Examples of those cases are +// multibit cells with external scan or black boxes. In this case, the scan_in, +// scan_out and scan enables are pins in the dbInst. The scan clock is the pin +// that we use to shift patterns in and out of the scan chain. class dbScanInst : public dbObject { public: @@ -7831,6 +7843,11 @@ class dbScanInst : public dbObject // User Code End dbScanInst }; +// A scan list is a collection of dbScanInsts in a particular order that must be +// respected when performing scan reordering and repartitioning. For ScanList +// with two or more elements we say that they are ORDERED. If the ScanList +// contains only one element then they are FLOATING elements that don't have any +// restriccion when optimizing the scan chain. class dbScanList : public dbObject { public: @@ -7838,34 +7855,34 @@ class dbScanList : public dbObject // User Code Begin dbScanList dbScanInst* add(dbInst* inst); - static dbScanList* create(dbScanChain* scan_chain); + static dbScanList* create(dbScanPartition* scan_partition); // User Code End dbScanList }; +// A scan partition is way to split the scan chains into sub chains with +// compatible scan flops (same clock, edge and voltage). The biggest partition +// possible is the whole chain if all the scan flops inside it are compatible +// between them for reordering and repartitioning. The name of this partition is +// not unique, as multiple partitions may have the same same and therefore +// contain the same type of flops. class dbScanPartition : public dbObject { public: - // User Code Begin dbScanPartition - void setStart(dbBTerm* bterm); - - void setStart(dbITerm* iterm); - - void setStop(dbBTerm* bterm); - - void setStop(dbITerm* iterm); - - std::variant getStart() const; - - std::variant getStop() const; + dbSet getScanLists() const; + // User Code Begin dbScanPartition const std::string& getName() const; - - void setName(std::string_view name); + void setName(const std::string& name); static dbScanPartition* create(dbScanChain* chain); // User Code End dbScanPartition }; +// This is a helper class to contain dbBTerms and dbITerms in the same field. We +// need this difference because some pins may need to be conected to top level +// ports or cell's pins. For example: a scan chain may be connected to a top +// level design port (dbBTerm) or to an output/input pin of a cell that is part +// of a decompressor/compressor class dbScanPin : public dbObject { public: diff --git a/src/odb/src/codeGenerator/schema.json b/src/odb/src/codeGenerator/schema.json index 59c964a634..63fa0b5474 100644 --- a/src/odb/src/codeGenerator/schema.json +++ b/src/odb/src/codeGenerator/schema.json @@ -253,7 +253,8 @@ "type":"1_n", "tbl_name":"two_wires_forbidden_spc_rules_tbl_", "schema":"db_schema_lef58_two_wires_forbidden_spacing" - } + }, + { "first": "dbDft", "second": "dbScanPin", "type": "1_n", @@ -267,7 +268,7 @@ "tbl_name": "scan_partitions_" }, { - "first": "dbScanChain", + "first": "dbScanPartition", "second": "dbScanList", "type": "1_n", "tbl_name": "scan_lists_" diff --git a/src/odb/src/codeGenerator/schema/scan/dbDft.json b/src/odb/src/codeGenerator/schema/scan/dbDft.json index 579f852579..ab7fbfe2cc 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbDft.json +++ b/src/odb/src/codeGenerator/schema/scan/dbDft.json @@ -1,6 +1,7 @@ { "name": "dbDft", "type": "dbObject", + "description": ["Top level DFT (Design for Testing) class"], "fields": [ { "name": "scan_inserted_", diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanChain.json b/src/odb/src/codeGenerator/schema/scan/dbScanChain.json index ca565760b0..783c354269 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanChain.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanChain.json @@ -1,6 +1,11 @@ { "name": "dbScanChain", "type": "dbObject", + "description": ["A scan chain is a collection of dbScanLists that contains dbScanInsts. Here,", + "scan_in, scan_out and scan_enable are the top level ports/pins to where this", + "scan chain is connected. Each scan chain is also associated with a particular", + "test mode and test mode pin that puts the Circuit Under Test (CUT) in test. The", + "Scan Enable port/pin puts the scan chain into shifting mode."], "fields": [ { "name": "name_", diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json index eb8c416d02..1e005add7a 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanInst.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanInst.json @@ -1,6 +1,15 @@ { "name": "dbScanInst", "type": "dbObject", + "description": + ["A scan inst is a cell with a scan in, scan out and an optional scan enable. If", + "no scan enable is provided, then this is an stateless component (because we", + "don't need to enable scan for it) and the number of bits is set to 0. It may", + "be possible that two or more dbScanInst contains the same dbInst if the dbInst", + "has more than one scan_in/scan_out pair. Examples of those cases are multibit", + "cells with external scan or black boxes. In this case, the scan_in, scan_out", + "and scan enables are pins in the dbInst. The scan clock is the pin that we use", + "to shift patterns in and out of the scan chain."], "fields": [ { "name": "bits_", @@ -73,6 +82,7 @@ "dbScanPin.h", "dbDft.h", "dbScanChain.h", - "dbScanList.h" + "dbScanList.h", + "dbScanPartition.h" ] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanList.json b/src/odb/src/codeGenerator/schema/scan/dbScanList.json index 7c259d554a..c7dc7371cf 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanList.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanList.json @@ -1,7 +1,14 @@ { "name": "dbScanList", "type": "dbObject", + "description": [ + "A scan list is a collection of dbScanInsts in a particular order that must be", + "respected when performing scan reordering and repartitioning. For ScanList with", + "two or more elements we say that they are ORDERED. If the ScanList contains only", + "one element then they are FLOATING elements that don't have any restriccion when", + "optimizing the scan chain."], "cpp_includes": [ - "dbScanChain.h" + "dbScanChain.h", + "dbScanPartition.h" ] } diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json b/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json index 16d47805c1..964b9654bb 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanPartition.json @@ -1,17 +1,15 @@ { "name": "dbScanPartition", "type": "dbObject", + "description": [ + "A scan partition is way to split the scan chains into sub chains with compatible", + "scan flops (same clock, edge and voltage). The biggest partition possible is the", + "whole chain if all the scan flops inside it are compatible between them for", + "reordering and repartitioning. The name of this partition is not unique, as", + "multiple partitions may have the same same and therefore contain the same type", + "of flops." + ], "fields": [ - { - "name": "start_", - "type": "dbId", - "flags": ["private"] - }, - { - "name": "stop_", - "type": "dbId", - "flags": ["private"] - }, { "name": "name_", "type": "std::string", diff --git a/src/odb/src/codeGenerator/schema/scan/dbScanPin.json b/src/odb/src/codeGenerator/schema/scan/dbScanPin.json index 29c4fb83ff..94e89c6a02 100644 --- a/src/odb/src/codeGenerator/schema/scan/dbScanPin.json +++ b/src/odb/src/codeGenerator/schema/scan/dbScanPin.json @@ -1,6 +1,13 @@ { "name": "dbScanPin", "type": "dbObject", + "description": [ + "This is a helper class to contain dbBTerms and dbITerms in the same field. We", + "need this difference because some pins may need to be conected to top level", + "ports or cell's pins. For example: a scan chain may be connected to a top level", + "design port (dbBTerm) or to an output/input pin of a cell that is part of a", + "decompressor/compressor" + ], "fields": [ { "name": "pin_", diff --git a/src/odb/src/codeGenerator/templates/db.h b/src/odb/src/codeGenerator/templates/db.h index 04ac32e092..2ccb19a823 100644 --- a/src/odb/src/codeGenerator/templates/db.h +++ b/src/odb/src/codeGenerator/templates/db.h @@ -6,6 +6,11 @@ class {{klass.name}}; //Generator Code Begin ClassDefinition {% for klass in schema.classes|sort(attribute='name') %} +{% if klass.description %} + {% for line in klass.description %} + // {{ line }} + {% endfor %} +{% endif %} class {{klass.name}} : public dbObject { public: diff --git a/src/odb/src/db/dbScanChain.cpp b/src/odb/src/db/dbScanChain.cpp index 762988a247..626f2d2fa0 100644 --- a/src/odb/src/db/dbScanChain.cpp +++ b/src/odb/src/db/dbScanChain.cpp @@ -39,7 +39,6 @@ #include "dbDft.h" #include "dbDiff.hpp" #include "dbScanInst.h" -#include "dbScanList.h" #include "dbScanPartition.h" #include "dbScanPin.h" #include "dbSet.h" @@ -71,9 +70,6 @@ bool _dbScanChain::operator==(const _dbScanChain& rhs) const if (*scan_partitions_ != *rhs.scan_partitions_) { return false; } - if (*scan_lists_ != *rhs.scan_lists_) { - return false; - } return true; } @@ -95,7 +91,6 @@ void _dbScanChain::differences(dbDiff& diff, DIFF_FIELD(test_mode_); DIFF_FIELD(test_mode_name_); DIFF_TABLE(scan_partitions_); - DIFF_TABLE(scan_lists_); DIFF_END } @@ -109,7 +104,6 @@ void _dbScanChain::out(dbDiff& diff, char side, const char* field) const DIFF_OUT_FIELD(test_mode_); DIFF_OUT_FIELD(test_mode_name_); DIFF_OUT_TABLE(scan_partitions_); - DIFF_OUT_TABLE(scan_lists_); DIFF_END } @@ -121,8 +115,6 @@ _dbScanChain::_dbScanChain(_dbDatabase* db) this, (GetObjTbl_t) &_dbScanChain::getObjectTable, dbScanPartitionObj); - scan_lists_ = new dbTable<_dbScanList>( - db, this, (GetObjTbl_t) &_dbScanChain::getObjectTable, dbScanListObj); } _dbScanChain::_dbScanChain(_dbDatabase* db, const _dbScanChain& r) @@ -135,7 +127,6 @@ _dbScanChain::_dbScanChain(_dbDatabase* db, const _dbScanChain& r) test_mode_name_ = r.test_mode_name_; scan_partitions_ = new dbTable<_dbScanPartition>(db, this, *r.scan_partitions_); - scan_lists_ = new dbTable<_dbScanList>(db, this, *r.scan_lists_); } dbIStream& operator>>(dbIStream& stream, _dbScanChain& obj) @@ -147,7 +138,6 @@ dbIStream& operator>>(dbIStream& stream, _dbScanChain& obj) stream >> obj.test_mode_; stream >> obj.test_mode_name_; stream >> *obj.scan_partitions_; - stream >> *obj.scan_lists_; return stream; } @@ -160,7 +150,6 @@ dbOStream& operator<<(dbOStream& stream, const _dbScanChain& obj) stream << obj.test_mode_; stream << obj.test_mode_name_; stream << *obj.scan_partitions_; - stream << *obj.scan_lists_; return stream; } @@ -169,8 +158,6 @@ dbObjectTable* _dbScanChain::getObjectTable(dbObjectType type) switch (type) { case dbScanPartitionObj: return scan_partitions_; - case dbScanListObj: - return scan_lists_; default: break; } @@ -180,7 +167,6 @@ dbObjectTable* _dbScanChain::getObjectTable(dbObjectType type) _dbScanChain::~_dbScanChain() { delete scan_partitions_; - delete scan_lists_; } //////////////////////////////////////////////////////////////////// @@ -195,12 +181,6 @@ dbSet dbScanChain::getScanPartitions() const return dbSet(obj, obj->scan_partitions_); } -dbSet dbScanChain::getScanLists() const -{ - _dbScanChain* obj = (_dbScanChain*) this; - return dbSet(obj, obj->scan_lists_); -} - // User Code Begin dbScanChainPublicMethods const std::string& dbScanChain::getName() const diff --git a/src/odb/src/db/dbScanChain.h b/src/odb/src/db/dbScanChain.h index 9cba7dd663..0744efcc07 100644 --- a/src/odb/src/db/dbScanChain.h +++ b/src/odb/src/db/dbScanChain.h @@ -47,7 +47,6 @@ class dbScanPartition; class _dbScanPartition; template class dbTable; -class _dbScanList; class dbScanPin; class _dbScanChain : public _dbObject @@ -80,8 +79,6 @@ class _dbScanChain : public _dbObject std::string test_mode_name_; dbTable<_dbScanPartition>* scan_partitions_; - - 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 9fb11da729..a993a43ebb 100644 --- a/src/odb/src/db/dbScanInst.cpp +++ b/src/odb/src/db/dbScanInst.cpp @@ -39,6 +39,7 @@ #include "dbDiff.hpp" #include "dbScanChain.h" #include "dbScanList.h" +#include "dbScanPartition.h" #include "dbScanPin.h" #include "dbTable.h" #include "dbTable.hpp" @@ -186,7 +187,8 @@ void dbScanInst::setScanEnable(dbITerm* scan_enable) { _dbScanInst* scan_inst = (_dbScanInst*) this; _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); - _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); + _dbScanPartition* scan_partition = (_dbScanPartition*) scan_list->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); scan_inst->scan_enable_ = dbScanPin::create(dft, scan_enable); } @@ -195,7 +197,8 @@ std::variant dbScanInst::getScanEnable() const { _dbScanInst* scan_inst = (_dbScanInst*) this; _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); - _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); + _dbScanPartition* scan_partition = (_dbScanPartition*) scan_list->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); _dbDft* dft = (_dbDft*) scan_chain->getOwner(); const dbScanPin* scan_enable = (dbScanPin*) dft->scan_pins_->getPtr( (dbId<_dbScanPin>) scan_inst->scan_enable_); @@ -216,7 +219,8 @@ void dbScanInst::setAccessPins(const AccessPins& access_pins) { _dbScanInst* scan_inst = (_dbScanInst*) this; _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); - _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); + _dbScanPartition* scan_partition = (_dbScanPartition*) scan_list->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); dbDft* dft = (dbDft*) scan_chain->getOwner(); std::visit( @@ -238,7 +242,8 @@ dbScanInst::AccessPins dbScanInst::getAccessPins() const AccessPins access_pins; _dbScanInst* scan_inst = (_dbScanInst*) this; _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); - _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); + _dbScanPartition* scan_partition = (_dbScanPartition*) scan_list->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); _dbDft* dft = (_dbDft*) scan_chain->getOwner(); const auto& [scan_in_id, scan_out_id] = scan_inst->access_pins_; @@ -258,7 +263,8 @@ dbInst* dbScanInst::getInst() const { _dbScanInst* scan_inst = (_dbScanInst*) this; _dbScanList* scan_list = (_dbScanList*) scan_inst->getOwner(); - _dbScanChain* scan_chain = (_dbScanChain*) scan_list->getOwner(); + _dbScanPartition* scan_partition = (_dbScanPartition*) scan_list->getOwner(); + _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); _dbDft* dft = (_dbDft*) scan_chain->getOwner(); _dbBlock* block = (_dbBlock*) dft->getOwner(); diff --git a/src/odb/src/db/dbScanList.cpp b/src/odb/src/db/dbScanList.cpp index 64ae564b7c..305730c431 100644 --- a/src/odb/src/db/dbScanList.cpp +++ b/src/odb/src/db/dbScanList.cpp @@ -38,6 +38,7 @@ #include "dbDiff.hpp" #include "dbScanChain.h" #include "dbScanInst.h" +#include "dbScanPartition.h" #include "dbSet.h" #include "dbTable.h" #include "dbTable.hpp" @@ -132,9 +133,9 @@ dbScanInst* dbScanList::add(dbInst* inst) return dbScanInst::create(this, inst); } -dbScanList* dbScanList::create(dbScanChain* scan_chain) +dbScanList* dbScanList::create(dbScanPartition* scan_partition) { - _dbScanChain* obj = (_dbScanChain*) scan_chain; + _dbScanPartition* obj = (_dbScanPartition*) scan_partition; return (dbScanList*) obj->scan_lists_->create(); } // User Code End dbScanListPublicMethods diff --git a/src/odb/src/db/dbScanPartition.cpp b/src/odb/src/db/dbScanPartition.cpp index 5b651cbc65..a01647dbcf 100644 --- a/src/odb/src/db/dbScanPartition.cpp +++ b/src/odb/src/db/dbScanPartition.cpp @@ -38,7 +38,9 @@ #include "dbDft.h" #include "dbDiff.hpp" #include "dbScanChain.h" +#include "dbScanList.h" #include "dbScanPin.h" +#include "dbSet.h" #include "dbTable.h" #include "dbTable.hpp" namespace odb { @@ -46,13 +48,10 @@ template class dbTable<_dbScanPartition>; bool _dbScanPartition::operator==(const _dbScanPartition& rhs) const { - if (start_ != rhs.start_) { - return false; - } - if (stop_ != rhs.stop_) { + if (name_ != rhs.name_) { return false; } - if (name_ != rhs.name_) { + if (*scan_lists_ != *rhs.scan_lists_) { return false; } @@ -69,108 +68,75 @@ void _dbScanPartition::differences(dbDiff& diff, const _dbScanPartition& rhs) const { DIFF_BEGIN - DIFF_FIELD(start_); - DIFF_FIELD(stop_); DIFF_FIELD(name_); + DIFF_TABLE(scan_lists_); DIFF_END } void _dbScanPartition::out(dbDiff& diff, char side, const char* field) const { DIFF_OUT_BEGIN - DIFF_OUT_FIELD(start_); - DIFF_OUT_FIELD(stop_); DIFF_OUT_FIELD(name_); + DIFF_OUT_TABLE(scan_lists_); DIFF_END } _dbScanPartition::_dbScanPartition(_dbDatabase* db) { + scan_lists_ = new dbTable<_dbScanList>( + db, this, (GetObjTbl_t) &_dbScanPartition::getObjectTable, dbScanListObj); } _dbScanPartition::_dbScanPartition(_dbDatabase* db, const _dbScanPartition& r) { - start_ = r.start_; - stop_ = r.stop_; name_ = r.name_; + scan_lists_ = new dbTable<_dbScanList>(db, this, *r.scan_lists_); } dbIStream& operator>>(dbIStream& stream, _dbScanPartition& obj) { - stream >> obj.start_; - stream >> obj.stop_; stream >> obj.name_; + stream >> *obj.scan_lists_; return stream; } dbOStream& operator<<(dbOStream& stream, const _dbScanPartition& obj) { - stream << obj.start_; - stream << obj.stop_; stream << obj.name_; + stream << *obj.scan_lists_; return stream; } -//////////////////////////////////////////////////////////////////// -// -// dbScanPartition - Methods -// -//////////////////////////////////////////////////////////////////// - -// User Code Begin dbScanPartitionPublicMethods - -void dbScanPartition::setStart(dbBTerm* bterm) -{ - _dbScanPartition* scan_partition = (_dbScanPartition*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); - dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->start_ = dbScanPin::create(dft, bterm); -} - -void dbScanPartition::setStart(dbITerm* iterm) +dbObjectTable* _dbScanPartition::getObjectTable(dbObjectType type) { - _dbScanPartition* scan_partition = (_dbScanPartition*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); - dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->start_ = dbScanPin::create(dft, iterm); + switch (type) { + case dbScanListObj: + return scan_lists_; + default: + break; + } + return getTable()->getObjectTable(type); } -void dbScanPartition::setStop(dbBTerm* bterm) +_dbScanPartition::~_dbScanPartition() { - _dbScanPartition* scan_partition = (_dbScanPartition*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); - dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->stop_ = dbScanPin::create(dft, bterm); + delete scan_lists_; } -void dbScanPartition::setStop(dbITerm* iterm) -{ - _dbScanPartition* scan_partition = (_dbScanPartition*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); - dbDft* dft = (dbDft*) scan_chain->getOwner(); - scan_partition->stop_ = dbScanPin::create(dft, iterm); -} +//////////////////////////////////////////////////////////////////// +// +// dbScanPartition - Methods +// +//////////////////////////////////////////////////////////////////// -std::variant dbScanPartition::getStart() const +dbSet dbScanPartition::getScanLists() const { - _dbScanPartition* scan_partition = (_dbScanPartition*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); - _dbDft* dft = (_dbDft*) scan_chain->getOwner(); - dbScanPin* scan_pin = (dbScanPin*) dft->scan_pins_->getPtr( - (dbId<_dbScanPin>) scan_partition->start_); - return scan_pin->getPin(); + _dbScanPartition* obj = (_dbScanPartition*) this; + return dbSet(obj, obj->scan_lists_); } -std::variant dbScanPartition::getStop() const -{ - _dbScanPartition* scan_partition = (_dbScanPartition*) this; - _dbScanChain* scan_chain = (_dbScanChain*) scan_partition->getOwner(); - _dbDft* dft = (_dbDft*) scan_chain->getOwner(); - dbScanPin* scan_pin = (dbScanPin*) dft->scan_pins_->getPtr( - (dbId<_dbScanPin>) scan_partition->stop_); - return scan_pin->getPin(); -} +// User Code Begin dbScanPartitionPublicMethods const std::string& dbScanPartition::getName() const { @@ -178,7 +144,7 @@ const std::string& dbScanPartition::getName() const return scan_partition->name_; } -void dbScanPartition::setName(std::string_view name) +void dbScanPartition::setName(const std::string& name) { _dbScanPartition* scan_partition = (_dbScanPartition*) this; scan_partition->name_ = name; diff --git a/src/odb/src/db/dbScanPartition.h b/src/odb/src/db/dbScanPartition.h index a0832dd681..c91db33286 100644 --- a/src/odb/src/db/dbScanPartition.h +++ b/src/odb/src/db/dbScanPartition.h @@ -42,7 +42,9 @@ class dbIStream; class dbOStream; class dbDiff; class _dbDatabase; -class dbScanPin; +class _dbScanList; +template +class dbTable; class _dbScanPartition : public _dbObject { @@ -50,7 +52,7 @@ class _dbScanPartition : public _dbObject _dbScanPartition(_dbDatabase*, const _dbScanPartition& r); _dbScanPartition(_dbDatabase*); - ~_dbScanPartition() = default; + ~_dbScanPartition(); bool operator==(const _dbScanPartition& rhs) const; bool operator!=(const _dbScanPartition& rhs) const @@ -62,10 +64,11 @@ class _dbScanPartition : public _dbObject const char* field, const _dbScanPartition& rhs) const; void out(dbDiff& diff, char side, const char* field) const; + dbObjectTable* getObjectTable(dbObjectType type); - dbId start_; - dbId stop_; std::string name_; + + dbTable<_dbScanList>* scan_lists_; }; dbIStream& operator>>(dbIStream& stream, _dbScanPartition& obj); dbOStream& operator<<(dbOStream& stream, const _dbScanPartition& obj); diff --git a/src/odb/test/cpp/scan/TestScanChain.cpp b/src/odb/test/cpp/scan/TestScanChain.cpp index 07fb2344f4..35e46289c6 100644 --- a/src/odb/test/cpp/scan/TestScanChain.cpp +++ b/src/odb/test/cpp/scan/TestScanChain.cpp @@ -41,8 +41,8 @@ namespace odb { namespace { -constexpr std::string_view kPartition1 = "CHAIN_1_FALLING_1"; -constexpr std::string_view kPartition2 = "CHAIN_1_RISING_1"; +constexpr char kPartition1[] = "CHAIN_1_FALLING_1"; +constexpr char kPartition2[] = "CHAIN_1_RISING_1"; template inline constexpr bool always_false_v = false; @@ -123,7 +123,9 @@ TEST_F(TestScanChain, CreateScanChain) dbScanChain* scan_chain = dbScanChain::create(dft_); - dbScanList* scan_list = dbScanList::create(scan_chain); + dbScanPartition* scan_partition = dbScanPartition::create(scan_chain); + scan_partition->setName(kPartition1); + dbScanList* scan_list = dbScanList::create(scan_partition); dbScanInst* scan_inst = scan_list->add(inst); scan_inst->setBits(1234); @@ -139,7 +141,12 @@ TEST_F(TestScanChain, CreateScanChain) dbScanChain* scan_chain2 = *scan_chains2.begin(); - odb::dbSet scan_lists2 = scan_chain2->getScanLists(); + odb::dbSet scan_partition2 + = scan_chain2->getScanPartitions(); + EXPECT_THAT(scan_partition2.size(), 1); + EXPECT_THAT(scan_partition2.begin()->getName(), kPartition1); + + odb::dbSet scan_lists2 = scan_partition2.begin()->getScanLists(); EXPECT_THAT(scan_lists2.size(), 1); odb::dbSet scan_insts2 = scan_lists2.begin()->getScanInsts(); @@ -149,9 +156,18 @@ TEST_F(TestScanChain, CreateScanChain) TEST_F(TestScanChain, CreateScanChainWithPartition) { dbScanChain* scan_chain = dbScanChain::create(dft_); - dbScanList* scan_list = dbScanList::create(scan_chain); - for (dbInst* inst : instances_) { + std::vector instances_partition1 = {instances_[0], instances_[1]}; + std::vector instances_partition2 = {instances_[2]}; + + dbScanPartition* partition1 = dbScanPartition::create(scan_chain); + dbScanPartition* partition2 = dbScanPartition::create(scan_chain); + + partition1->setName(kPartition1); + partition2->setName(kPartition2); + + for (dbInst* inst : instances_partition1) { + dbScanList* scan_list = dbScanList::create(partition1); dbScanInst* scan_inst = scan_list->add(inst); scan_inst->setBits(1); dbITerm* iterm = inst->findITerm("a"); @@ -159,30 +175,19 @@ TEST_F(TestScanChain, CreateScanChainWithPartition) scan_inst->setAccessPins({.scan_in = iterm, .scan_out = iterm2}); } - // 2 partitions, one for the first instance and a second one for the second - // instance. The partition 1 start at a bterm (chain scan in) and ends in the - // scan out of the first instance. - // - // The second partition starts at the scan in of the second instance and ends - // in the bterm scan out of the chain. The second partition contains 2 - // elements. - // - // Partition 1: [chain scan_in, i1 scan_out] - // Partition 2: [i2 scan_in, chain scan out] - - dbScanPartition* partition1 = dbScanPartition::create(scan_chain); - dbScanPartition* partition2 = dbScanPartition::create(scan_chain); - - dbBTerm* chain_scan_in = block_->findBTerm("IN1"); - dbBTerm* chain_scan_out = block_->findBTerm("IN3"); - - partition1->setStart(chain_scan_in); - partition1->setStop(instances_[0]->findITerm("o")); - partition1->setName(kPartition1); + for (dbInst* inst : instances_partition2) { + dbScanList* scan_list = dbScanList::create(partition2); + dbScanInst* scan_inst = scan_list->add(inst); + scan_inst->setBits(1); + dbITerm* iterm = inst->findITerm("a"); + dbITerm* iterm2 = inst->findITerm("o"); + scan_inst->setAccessPins({.scan_in = iterm, .scan_out = iterm2}); + } - partition2->setStart(instances_[1]->findITerm("a")); - partition2->setStop(chain_scan_out); - partition2->setName(kPartition2); + // 2 partitions, one for the first two instances and one for the last one + // + // Partition 1: [i1, i2] + // Partition 2: [i3] //***************************** dbDatabase* db2 = writeReadDb(); @@ -206,62 +211,31 @@ TEST_F(TestScanChain, CreateScanChainWithPartition) EXPECT_THAT(partition12->getName(), kPartition1); EXPECT_THAT(partition22->getName(), kPartition2); - EXPECT_THAT(GetName(partition12->getStart()), "IN1"); - EXPECT_THAT(GetName(partition12->getStop()), "o"); - - 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); + dbSet scan_lists12 = partition12->getScanLists(); + dbSet scan_lists22 = partition22->getScanLists(); int i = 0; - for (dbScanList* scan_list : scan_lists2) { + for (dbScanList* scan_list : scan_lists12) { for (dbScanInst* scan_inst : scan_list->getScanInsts()) { - EXPECT_THAT(scan_inst->getInst()->getName(), instances_[i]->getName()); + 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; } } - 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); + for (dbScanList* scan_list : scan_lists22) { + for (dbScanInst* scan_inst : scan_list->getScanInsts()) { + 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; + } + } } } // namespace