9 #include "../FileModel/Design/FileArchive.h"
10 #include "../FileModel/Design/EdaDataFile.h"
13 namespace Odb::Lib::ProductModel
22 m_componentsByName.clear();
26 m_packagesByName.clear();
28 m_partsByName.clear();
31 const std::string& Design::GetName()
const
36 const std::string& Design::GetProductModel()
const
38 return m_productModel;
41 const Net::Vector& Design::GetNets()
const
46 const Net::StringMap Design::GetNetsByName()
const
51 const Package::Vector& Design::GetPackages()
const
56 const Package::StringMap& Design::GetPackagesByName()
const
58 return m_packagesByName;
61 const Component::Vector& Design::GetComponents()
const
66 const Component::StringMap& Design::GetComponentsByName()
const
68 return m_componentsByName;
71 std::shared_ptr<Component> Design::GetComponent(
const std::string& refDes)
const
73 auto findIt = m_componentsByName.find(refDes);
74 if (findIt != m_componentsByName.end())
76 return findIt->second;
82 const Part::Vector& Design::GetParts()
const
87 const Part::StringMap& Design::GetPartsByName()
const
92 std::shared_ptr<Net> Design::GetNet(
const std::string& name)
const
94 auto findIt = m_netsByName.find(name);
95 if (findIt != m_netsByName.end())
97 return findIt->second;
102 std::shared_ptr<Net> Design::GetNoneNet()
const
104 return GetNet(NONE_NET_NAME);
107 bool Design::Build(std::string path)
109 auto pFileModel = std::make_shared<FileModel::Design::FileArchive>(path);
110 if (pFileModel->ParseFileModel())
112 return Build(pFileModel);
117 bool Design::Build(std::shared_ptr<FileModel::Design::FileArchive> pFileModel)
119 if (pFileModel ==
nullptr)
return false;
121 m_pFileModel = pFileModel;
127 if (! BuildNets())
return false;
128 if (! BuildPackages())
return false;
129 if (! BuildAllParts())
return false;
130 if (! BuildAllComponents())
return false;
133 if (! BuildPlacementsFromComponentsFiles())
return false;
139 if (CLIP_FILEMODEL_AFTER_BUILD)
147 std::shared_ptr<FileModel::Design::FileArchive> Design::GetFileModel()
const
152 void Design::ClipFileModel()
154 m_pFileModel =
nullptr;
157 std::unique_ptr<Odb::Lib::Protobuf::ProductModel::Design> Design::to_protobuf()
const
159 auto pDesignMsg = std::make_unique<Odb::Lib::Protobuf::ProductModel::Design>();
160 pDesignMsg->set_name(m_name);
161 pDesignMsg->set_productmodel(m_productModel);
163 if (m_pFileModel !=
nullptr)
165 pDesignMsg->mutable_filemodel()->CopyFrom(*m_pFileModel->to_protobuf());
168 for (
const auto& pNet : m_nets)
170 pDesignMsg->add_nets()->CopyFrom(*pNet->to_protobuf());
173 for (
const auto& kvNet : m_netsByName)
175 (*pDesignMsg->mutable_netsbyname())[kvNet.first] = *kvNet.second->to_protobuf();
178 for (
const auto& pPackage : m_packages)
180 pDesignMsg->add_packages()->CopyFrom(*pPackage->to_protobuf());
183 for (
const auto& kvPackage : m_packagesByName)
185 (*pDesignMsg->mutable_packagesbyname())[kvPackage.first] = *kvPackage.second->to_protobuf();
188 for (
const auto& pComponent : m_components)
190 pDesignMsg->add_components()->CopyFrom(*pComponent->to_protobuf());
193 for (
const auto& kvComponent : m_componentsByName)
195 (*pDesignMsg->mutable_componentsbyname())[kvComponent.first] = *kvComponent.second->to_protobuf();
198 for (
const auto& pPart : m_parts)
200 pDesignMsg->add_parts()->CopyFrom(*pPart->to_protobuf());
203 for (
const auto& kvPart : m_partsByName)
205 (*pDesignMsg->mutable_partsbyname())[kvPart.first] = *kvPart.second->to_protobuf();
211 void Design::from_protobuf(
const Odb::Lib::Protobuf::ProductModel::Design& message)
213 m_name = message.name();
214 m_productModel = message.productmodel();
216 m_pFileModel = std::make_shared<FileModel::Design::FileArchive>();
217 m_pFileModel->from_protobuf(message.filemodel());
219 for (
const auto& pNetMsg : message.nets())
221 auto pNet = std::make_shared<Net>(
"", -1);
222 pNet->from_protobuf(pNetMsg);
223 m_nets.push_back(pNet);
226 for (
const auto& kvNetMsg : message.netsbyname())
228 auto pNet = std::make_shared<Net>(
"", -1);
229 pNet->from_protobuf(kvNetMsg.second);
230 m_netsByName[kvNetMsg.first] = pNet;
233 for (
const auto& pPackageMsg : message.packages())
235 auto pPackage = std::make_shared<Package>(
"", -1);
236 pPackage->from_protobuf(pPackageMsg);
237 m_packages.push_back(pPackage);
240 for (
const auto& kvPackageMsg : message.packagesbyname())
242 auto pPackage = std::make_shared<Package>(
"", -1);
243 pPackage->from_protobuf(kvPackageMsg.second);
244 m_packagesByName[kvPackageMsg.first] = pPackage;
247 for (
const auto& pComponentMsg : message.components())
249 auto pComponent = std::make_shared<Component>(
"",
"",
nullptr, -1, BoardSide::BsNone,
nullptr);
250 pComponent->from_protobuf(pComponentMsg);
251 m_components.push_back(pComponent);
254 for (
const auto& kvComponentMsg : message.componentsbyname())
256 auto pComponent = std::make_shared<Component>(
"",
"",
nullptr, -1, BoardSide::BsNone,
nullptr);
257 pComponent->from_protobuf(kvComponentMsg.second);
258 m_componentsByName[kvComponentMsg.first] = pComponent;
261 for (
const auto& pPartMsg : message.parts())
263 auto pPart = std::make_shared<Part>(
"");
264 pPart->from_protobuf(pPartMsg);
265 m_parts.push_back(pPart);
268 for (
const auto& kvPartMsg : message.partsbyname())
270 auto pPart = std::make_shared<Part>(
"");
271 pPart->from_protobuf(kvPartMsg.second);
272 m_partsByName[kvPartMsg.first] = pPart;
276 bool Design::BuildAllComponents()
278 if (m_pFileModel ==
nullptr)
return false;
279 const auto& steps = m_pFileModel->GetStepsByName();
280 if (steps.empty())
return false;
281 auto& pStepDirectory = steps.begin()->second;
284 auto pTopComponentsFile = pStepDirectory->GetTopComponentsFile();
285 if (pTopComponentsFile ==
nullptr)
return false;
286 if (! BuildComponents(pTopComponentsFile))
return false;
289 auto pBottomComponentsFile = pStepDirectory->GetBottomComponentsFile();
290 if (pBottomComponentsFile ==
nullptr)
return false;
291 if (!BuildComponents(pBottomComponentsFile))
return false;
298 const auto& componentRecords = pComponentsFile->GetComponentRecords();
299 for (
const auto& pComponentRecord : componentRecords)
301 auto& pPackage = m_packages[pComponentRecord->pkgRef];
302 auto index = pComponentRecord->index;
303 auto& pPart = m_partsByName[pComponentRecord->partName];
304 auto pComponent = std::make_shared<Component>(pComponentRecord->compName, pComponentRecord->partName, pPackage, index, pComponentsFile->GetSide(), pPart);
306 m_components.push_back(pComponent);
307 m_componentsByName[pComponent->GetRefDes()] = pComponent;
313 bool Design::BuildVias()
318 bool Design::BuildNets()
320 if (m_pFileModel ==
nullptr)
return false;
322 const auto& steps = m_pFileModel->GetStepsByName();
323 if (steps.empty())
return false;
325 auto& pStepDirectory = steps.begin()->second;
326 const auto& edaData = pStepDirectory->GetEdaDataFile();
327 const auto& netRecords = edaData.GetNetRecords();
329 for (
const auto& pNetRecord : netRecords)
331 auto pNet = std::make_shared<Net>(pNetRecord->name, pNetRecord->index);
332 m_nets.push_back(pNet);
333 m_netsByName[pNet->GetName()] = pNet;
339 bool Design::BuildPackages()
341 if (m_pFileModel ==
nullptr)
return false;
343 const auto& steps = m_pFileModel->GetStepsByName();
344 if (steps.empty())
return false;
346 auto& pStepDirectory = steps.begin()->second;
347 const auto& edaData = pStepDirectory->GetEdaDataFile();
348 const auto& packageRecords = edaData.GetPackageRecords();
350 for (
const auto& pPackageRecord : packageRecords)
352 auto index = pPackageRecord->index;
353 auto pPackage = std::make_shared<Package>(pPackageRecord->name, index);
355 for (
const auto& pPinRecord : pPackageRecord->m_pinRecords)
358 pPackage->AddPin(pPinRecord->name);
361 m_packages.push_back(pPackage);
362 m_packagesByName[pPackage->GetName()] = pPackage;
368 bool Design::BuildAllParts()
370 if (m_pFileModel ==
nullptr)
return false;
372 const auto& steps = m_pFileModel->GetStepsByName();
373 if (steps.empty())
return false;
375 auto& pStepDirectory = steps.begin()->second;
377 auto pTopComponentsFile = pStepDirectory->GetTopComponentsFile();
378 if (pTopComponentsFile ==
nullptr)
return false;
379 if (! BuildParts(pTopComponentsFile))
return false;
381 auto pBottomComponentsFile = pStepDirectory->GetBottomComponentsFile();
382 if (pBottomComponentsFile ==
nullptr)
return false;
383 if (! BuildParts(pBottomComponentsFile))
return false;
390 const auto& componentRecords = pComponentsFile->GetComponentRecords();
391 for (
const auto& pComponentRecord : componentRecords)
393 auto& partName = pComponentRecord->partName;
394 auto findIt = m_partsByName.find(partName);
395 if (findIt == m_partsByName.end())
397 auto pPart = std::make_shared<Part>(partName);
398 m_parts.push_back(pPart);
399 m_partsByName[partName] = pPart;
406 bool Design::BuildPlacementsFromComponentsFiles()
408 if (m_pFileModel ==
nullptr)
return false;
410 const auto& steps = m_pFileModel->GetStepsByName();
411 if (steps.empty())
return false;
414 auto& pStepDirectory = steps.begin()->second;
416 auto pTopComponentsFile = pStepDirectory->GetTopComponentsFile();
417 if (pTopComponentsFile ==
nullptr)
return false;
418 if (! BuildPlacementsFromComponentsFile(pTopComponentsFile))
return false;
420 auto pBottomComponentsFile = pStepDirectory->GetBottomComponentsFile();
421 if (pBottomComponentsFile ==
nullptr)
return false;
422 if (!BuildPlacementsFromComponentsFile(pBottomComponentsFile))
return false;
429 const auto& componentRecords = pComponentsFile->GetComponentRecords();
430 for (
const auto& pComponentRecord : componentRecords)
432 const auto& toeprintRecords = pComponentRecord->m_toeprintRecords;
433 for (
const auto& pToeprintRecord : toeprintRecords)
435 auto& toeprintName = pToeprintRecord->name;
436 auto pinNumber = pToeprintRecord->pinNumber;
437 auto netNumber = pToeprintRecord->netNumber;
438 auto& refDes = pComponentRecord->compName;
442 if (netNumber !=
static_cast<unsigned int>(-1))
444 if (!CreatePinConnection(refDes, netNumber, pinNumber, toeprintName))
return false;
452 bool Design::CreatePinConnection(
const std::string& refDes,
unsigned int netNumber,
unsigned int pinNumber,
const std::string& pinName)
454 if (netNumber < m_nets.size())
456 auto& pComponent = m_componentsByName[refDes];
457 if (pComponent ==
nullptr)
return false;
459 auto pPin = pComponent->GetPackage()->GetPin(pinNumber);
460 if (pPin ==
nullptr)
return false;
462 auto& pNet = m_nets[netNumber];
463 if (pNet ==
nullptr)
return false;
465 if (!pNet->AddPinConnection(pComponent, pPin))
return false;
470 logwarn(
"netNumber out of range: " + std::to_string(netNumber) +
", size = " + std::to_string(m_nets.size()));
476 bool Design::BuildNoneNet()
478 auto pStepDirectory = m_pFileModel->GetStepDirectory();
479 if (pStepDirectory ==
nullptr)
return false;
481 const auto& edaData = pStepDirectory->GetEdaDataFile();
482 auto findIt = edaData.GetNetRecordsByName().find(NONE_NET_NAME);
483 if (findIt == edaData.GetNetRecordsByName().end())
return false;
485 auto& pNoneNet = findIt->second;
486 if (pNoneNet ==
nullptr)
return false;
488 if (!CreateNetConnections(pNoneNet, pStepDirectory))
return false;
493 bool Design::BreakSinglePinNets()
495 const auto& pNoneNet = GetNoneNet();
496 if (pNoneNet ==
nullptr)
return false;
498 auto& pinConnections = pNoneNet->GetPinConnections();
499 while (!pinConnections.empty())
501 const auto& pExistingPinConnection = pinConnections.back();
503 std::string newNetName =
"$NC_" + pExistingPinConnection->GetComponent()->GetRefDes() +
"_" + pExistingPinConnection->GetPin()->GetName();
504 auto pNewNet = std::make_shared<Net>(newNetName, -1);
505 pNewNet->AddPinConnection(pExistingPinConnection->GetComponent(), pExistingPinConnection->GetPin());
506 m_nets.push_back(pNewNet);
507 m_netsByName[pNewNet->GetName()] = pNewNet;
509 pinConnections.pop_back();
515 bool Design::BuildPlacementsFromEdaDataFile()
517 auto pStepDirectory = m_pFileModel->GetStepDirectory();
518 if (pStepDirectory ==
nullptr)
return false;
520 const auto& edaData = pStepDirectory->GetEdaDataFile();
522 for (
const auto& pNetRecord : edaData.GetNetRecords())
524 if (!CreateNetConnections(pNetRecord, pStepDirectory))
return false;
530 bool Design::CreateNetConnections(
const std::shared_ptr<Odb::Lib::FileModel::Design::EdaDataFile::NetRecord>& pNetRecord,
const std::shared_ptr<FileModel::Design::StepDirectory>& pStepDirectory)
532 for (
const auto& pSubnetRecord : pNetRecord->m_subnetRecords)
534 if (pSubnetRecord->type == FileModel::Design::EdaDataFile::NetRecord::SubnetRecord::Type::Toeprint)
536 const FileModel::Design::ComponentsFile* pComponentsFileToUse =
nullptr;
538 auto side = pSubnetRecord->side;
539 if (side == BoardSide::Top)
541 pComponentsFileToUse = pStepDirectory->GetTopComponentsFile();
545 pComponentsFileToUse = pStepDirectory->GetBottomComponentsFile();
548 if (pComponentsFileToUse ==
nullptr)
return false;
550 auto componentNumber = pSubnetRecord->componentNumber;
551 if (componentNumber >= pComponentsFileToUse->GetComponentRecords().size())
return false;
553 auto& pComponentRecord = pComponentsFileToUse->GetComponentRecords()[componentNumber];
554 if (pComponentRecord ==
nullptr)
return false;
556 auto toeprintNumber = pSubnetRecord->toeprintNumber;
557 if (toeprintNumber >= pComponentRecord->m_toeprintRecords.size())
return false;
559 auto& pToeprintRecord = pComponentRecord->m_toeprintRecords[toeprintNumber];
560 if (pToeprintRecord ==
nullptr)
return false;
562 auto& toeprintName = pToeprintRecord->name;
563 auto pinNumber = pToeprintRecord->pinNumber;
564 auto netNumber = pToeprintRecord->netNumber;
565 auto& refDes = pComponentRecord->compName;
568 if (!CreatePinConnection(refDes, netNumber, pinNumber, toeprintName))
return false;
570 else if (pSubnetRecord->type == FileModel::Design::EdaDataFile::NetRecord::SubnetRecord::Type::Via)