1 #include "NetlistFile.h"
2 #include "NetlistFile.h"
4 #include "../parse_error.h"
5 #include "../invalid_odb_error.h"
9 #include "../../Constants.h"
15 #include "../parse_info.h"
16 #include "../../ProtoBuf/netlistfile.pb.h"
18 using namespace std::filesystem;
20 namespace Odb::Lib::FileModel::Design
22 NetlistFile::NetlistFile(std::filesystem::path path)
25 , m_staggered(Staggered::Unknown)
29 NetlistFile::~NetlistFile()
32 m_netRecordsByName.clear();
33 m_netPointRecords.clear();
36 std::filesystem::path NetlistFile::GetPath()
const
41 std::string NetlistFile::GetName()
const
46 std::string NetlistFile::GetUnits()
const
51 bool NetlistFile::GetOptimized()
const
56 NetlistFile::Staggered NetlistFile::GetStaggered()
const
61 const NetlistFile::NetRecord::Vector& NetlistFile::GetNetRecords()
const
66 const NetlistFile::NetRecord::StringMap& NetlistFile::GetNetRecordsByName()
const
68 return m_netRecordsByName;
71 const NetlistFile::NetPointRecord::Vector& NetlistFile::GetNetPointRecords()
const
73 return m_netPointRecords;
76 bool NetlistFile::Parse()
78 std::ifstream netlistFile;
84 m_name = std::filesystem::path(m_path).filename().string();
86 loginfo(
"Parsing netlist: " + m_name +
"...");
88 auto netlistFilePath = m_path /
"netlist";
90 if (!std::filesystem::exists(netlistFilePath))
92 auto message =
"netlist file does not exist: [" + m_path.string() +
"]";
93 throw invalid_odb_error(message.c_str());
96 else if (!std::filesystem::is_regular_file(netlistFilePath))
98 auto message =
"netlist file is not a file: [" + m_path.string() +
"]";
99 throw invalid_odb_error(message.c_str());
102 netlistFile.open(netlistFilePath.string(), std::ios::in);
103 if (!netlistFile.is_open())
105 auto message =
"unable to open netlist file: [" + m_path.string() +
"]";
106 throw invalid_odb_error(message.c_str());
109 while (std::getline(netlistFile, line))
114 std::stringstream lineStream(line);
116 if (line.find(Constants::COMMENT_TOKEN) == 0)
120 else if (line.find(Constants::UNITS_TOKEN) == 0)
124 if (!std::getline(lineStream, token,
'='))
126 throw_parse_error(m_path, line, token, lineNumber);
128 else if (!std::getline(lineStream, token,
'='))
130 throw_parse_error(m_path, line, token, lineNumber);
134 else if (line.find(HEADER_TOKEN) == 0)
144 if (token !=
"optimize")
146 throw_parse_error(m_path, line, token, lineNumber);
150 if (!(lineStream >> optimized))
152 throw_parse_error(m_path, line, token, lineNumber);
155 if (optimized ==
'Y' || std::tolower(optimized) ==
'y')
159 else if (optimized ==
'N' || std::tolower(optimized) ==
'n')
165 throw_parse_error(m_path, line, token, lineNumber);
169 if (lineStream >> token && token == STAGGERED_KEY)
172 if (!(lineStream >> staggered))
174 throw_parse_error(m_path, line, token, lineNumber);
177 if (staggered ==
'Y' || std::tolower(staggered) ==
'y')
179 m_staggered = Staggered::Yes;
181 else if (staggered ==
'N' || std::tolower(staggered) ==
'n')
183 m_staggered = Staggered::No;
187 throw_parse_error(m_path, line, token, lineNumber);
192 m_staggered = Staggered::Unknown;
195 else if (line.find(NetRecord::FIELD_TOKEN) == 0)
201 if (!(lineStream >> token))
203 throw_parse_error(m_path, line, token, lineNumber);
206 auto strSerialNumber = token;
207 strSerialNumber.erase(0, 1);
208 auto ulSerialNumber = std::stoul(strSerialNumber);
209 if (ulSerialNumber > UINT_MAX)
211 throw_parse_error(m_path, line, token, lineNumber);
214 auto unSerialNumber =
static_cast<unsigned int>(ulSerialNumber);
217 if (!(lineStream >> token))
219 throw_parse_error(m_path, line, token, lineNumber);
222 auto& netName = token;
224 auto pNetRecord = std::make_shared<NetRecord>();
225 pNetRecord->serialNumber = unSerialNumber;
226 pNetRecord->netName = netName;
227 m_netRecords.push_back(pNetRecord);
233 if (!(lineStream >> token))
235 throw_parse_error(m_path, line, token, lineNumber);
238 auto ulNetNumber = std::stoul(token);
239 if (ulNetNumber >= UINT_MAX)
241 throw_parse_error(m_path, line, token, lineNumber);
244 auto unNetNumber =
static_cast<unsigned int>(ulNetNumber);
246 auto pNetPointRecord = std::make_shared<NetPointRecord>();
247 pNetPointRecord->netNumber = unNetNumber;
249 if (!(lineStream >> pNetPointRecord->radius))
251 throw_parse_error(m_path, line, token, lineNumber);
254 if (!(lineStream >> pNetPointRecord->x))
256 throw_parse_error(m_path, line, token, lineNumber);
259 if (!(lineStream >> pNetPointRecord->y))
261 throw_parse_error(m_path, line, token, lineNumber);
266 m_netPointRecords.push_back(pNetPointRecord);
271 loginfo(
"Parsing netlist: " + m_name +
" complete");
275 catch (parse_error& pe)
277 auto m = pe.toString(
"Parse Error:");
284 catch (std::exception& e)
286 parse_info pi(m_path, line, lineNumber);
287 const auto m = pi.toString();
288 logexception_msg(e, m);
296 std::unique_ptr<Protobuf::NetlistFile> NetlistFile::to_protobuf()
const
298 std::unique_ptr<Protobuf::NetlistFile> pNetlistFileMessage(
new Protobuf::NetlistFile);
299 pNetlistFileMessage->set_units(m_units);
300 pNetlistFileMessage->set_path(m_path.string());
301 pNetlistFileMessage->set_name(m_name);
302 pNetlistFileMessage->set_optimized(m_optimized);
303 pNetlistFileMessage->set_staggered(
static_cast<Protobuf::NetlistFile::Staggered
>(m_staggered));
305 for (
const auto& pNetRecord : m_netRecords)
307 auto pNetRecordMessage = pNetRecord->to_protobuf();
308 pNetlistFileMessage->add_netrecordss()->CopyFrom(*pNetRecordMessage);
311 for (
const auto& kvNetRecord : m_netRecordsByName)
313 (*pNetlistFileMessage->mutable_netrecordsbyname())[kvNetRecord.first] = *kvNetRecord.second->to_protobuf();
316 for (
const auto& pNetPointRecord : m_netPointRecords)
318 auto pNetPointRecordMessage = pNetPointRecord->to_protobuf();
319 pNetlistFileMessage->add_netpointrecords()->CopyFrom(*pNetPointRecordMessage);
322 return pNetlistFileMessage;
325 void NetlistFile::from_protobuf(
const Protobuf::NetlistFile& message)
327 m_name = message.name();
328 m_path = message.path();
329 m_units = message.units();
330 m_optimized = message.optimized();
331 m_staggered =
static_cast<Staggered
>(message.staggered());
333 for (
const auto& netRecordMessage : message.netrecordss())
335 auto pNetRecord = std::make_shared<NetRecord>();
336 pNetRecord->from_protobuf(netRecordMessage);
337 m_netRecords.push_back(pNetRecord);
340 for (
const auto& kvNetRecord : message.netrecordsbyname())
342 auto pNetRecord = std::make_shared<NetRecord>();
343 pNetRecord->from_protobuf(kvNetRecord.second);
344 m_netRecordsByName[pNetRecord->netName] = pNetRecord;
347 for (
const auto& netPointRecordMessage : message.netpointrecords())
349 auto pNetPointRecord = std::make_shared<NetPointRecord>();
350 pNetPointRecord->from_protobuf(netPointRecordMessage);
351 m_netPointRecords.push_back(pNetPointRecord);
355 bool NetlistFile::Save(std::ostream& os)
357 os <<
'H' <<
" optimize " << (m_optimized ?
'Y' :
'N') <<
"staggered " << (m_staggered == Staggered::Yes ?
'Y' :
'N') << std::endl;
358 os << Constants::UNITS_TOKEN <<
" = " << m_units << std::endl;
360 for (
const auto& netRecord : m_netRecords)
362 os << NetRecord::FIELD_TOKEN << netRecord->serialNumber <<
" " << netRecord->netName << std::endl;
365 for (
const auto& netPointRecord : m_netPointRecords)
367 netPointRecord->Save(os);
374 bool NetlistFile::Save(
const std::filesystem::path& directory)
376 auto netlistDir = directory / m_name;
377 if (!create_directory(netlistDir))
return false;
379 std::ofstream netlistFile(netlistDir /
"netlist");
380 if (!netlistFile.is_open())
return false;
381 if (! Save(netlistFile))
return false;
387 std::unique_ptr<Protobuf::NetlistFile::NetRecord> NetlistFile::NetRecord::to_protobuf()
const
389 std::unique_ptr<Protobuf::NetlistFile::NetRecord> pNetRecordMessage(
new Protobuf::NetlistFile::NetRecord);
390 pNetRecordMessage->set_serialnumber(serialNumber);
391 pNetRecordMessage->set_netname(netName);
392 return pNetRecordMessage;
395 void NetlistFile::NetRecord::from_protobuf(
const Protobuf::NetlistFile::NetRecord& message)
397 serialNumber = message.serialnumber();
398 netName = message.netname();
401 std::unique_ptr<Protobuf::NetlistFile::NetPointRecord> NetlistFile::NetPointRecord::to_protobuf()
const
403 std::unique_ptr<Protobuf::NetlistFile::NetPointRecord> pNetPointRecordMessage(
new Protobuf::NetlistFile::NetPointRecord);
404 pNetPointRecordMessage->set_netnumber(netNumber);
405 pNetPointRecordMessage->set_radius(radius);
406 pNetPointRecordMessage->set_x(x);
407 pNetPointRecordMessage->set_y(y);
408 pNetPointRecordMessage->set_epoint(std::to_string(epoint));
409 pNetPointRecordMessage->set_width(width);
410 pNetPointRecordMessage->set_exp(std::to_string(exp));
411 pNetPointRecordMessage->set_fiducialpoint(fiducialPoint);
412 pNetPointRecordMessage->set_height(height);
413 pNetPointRecordMessage->set_commentpoint(commentPoint);
414 pNetPointRecordMessage->set_netnumber(netNumber);
415 pNetPointRecordMessage->set_side(
static_cast<Protobuf::NetlistFile::NetPointRecord::AccessSide
>(side));
416 pNetPointRecordMessage->set_staggeredradius(staggeredRadius);
417 pNetPointRecordMessage->set_staggeredx(staggeredX);
418 pNetPointRecordMessage->set_staggeredy(staggeredY);
419 pNetPointRecordMessage->set_testexecutionside(std::to_string(testExecutionSide));
420 pNetPointRecordMessage->set_testpoint(testPoint);
421 pNetPointRecordMessage->set_viapoint(viaPoint);
422 pNetPointRecordMessage->set_fiducialpoint(fiducialPoint);
423 return pNetPointRecordMessage;
426 void NetlistFile::NetPointRecord::from_protobuf(
const Protobuf::NetlistFile::NetPointRecord& message)
428 netNumber = message.netnumber();
429 radius = message.radius();
432 if (message.epoint().empty())
434 epoint = message.epoint()[0];
436 width = message.width();
437 if (!message.exp().empty())
439 exp = message.exp()[0];
441 fiducialPoint = message.fiducialpoint();
442 height = message.height();
443 commentPoint = message.commentpoint();
444 netNumber = message.netnumber();
445 side =
static_cast<AccessSide
>(message.side());
446 staggeredRadius = message.staggeredradius();
447 staggeredX = message.staggeredx();
448 staggeredY = message.staggeredy();
449 if (!message.testexecutionside().empty())
451 testExecutionSide = message.testexecutionside()[0];
453 testPoint = message.testpoint();
454 viaPoint = message.viapoint();
455 fiducialPoint = message.fiducialpoint();
458 bool NetlistFile::NetPointRecord::Save(std::ostream& os)