1 #include "NetlistFile.h"
2 #include "NetlistFile.h"
3 #include "NetlistFile.h"
4 #include "NetlistFile.h"
5 #include "NetlistFile.h"
6 #include "NetlistFile.h"
7 #include "NetlistFile.h"
8 #include "NetlistFile.h"
12 #include "../parse_error.h"
13 #include "../invalid_odb_error.h"
16 namespace Odb::Lib::FileModel::Design
18 NetlistFile::NetlistFile(std::filesystem::path path)
21 , m_staggered(Staggered::Unknown)
25 NetlistFile::~NetlistFile()
28 m_netRecordsByName.clear();
29 m_netPointRecords.clear();
32 std::filesystem::path NetlistFile::GetPath()
const
37 std::string NetlistFile::GetName()
const
42 std::string NetlistFile::GetUnits()
const
47 bool NetlistFile::GetOptimized()
const
52 NetlistFile::Staggered NetlistFile::GetStaggered()
const
57 const NetlistFile::NetRecord::Vector& NetlistFile::GetNetRecords()
const
62 const NetlistFile::NetRecord::StringMap& NetlistFile::GetNetRecordsByName()
const
64 return m_netRecordsByName;
67 const NetlistFile::NetPointRecord::Vector& NetlistFile::GetNetPointRecords()
const
69 return m_netPointRecords;
72 bool NetlistFile::Parse()
74 std::ifstream netlistFile;
80 m_name = std::filesystem::path(m_path).filename().string();
82 loginfo(
"Parsing netlist: " + m_name +
"...");
84 auto netlistFilePath = m_path /
"netlist";
86 if (!std::filesystem::exists(netlistFilePath))
88 auto message =
"netlist file does not exist: [" + m_path.string() +
"]";
89 throw invalid_odb_error(message.c_str());
92 else if (!std::filesystem::is_regular_file(netlistFilePath))
94 auto message =
"netlist file is not a file: [" + m_path.string() +
"]";
95 throw invalid_odb_error(message.c_str());
98 netlistFile.open(netlistFilePath.string(), std::ios::in);
99 if (!netlistFile.is_open())
101 auto message =
"unable to open netlist file: [" + m_path.string() +
"]";
102 throw invalid_odb_error(message.c_str());
105 while (std::getline(netlistFile, line))
110 std::stringstream lineStream(line);
112 if (line.find(COMMENT_TOKEN) == 0)
116 else if (line.find(UNITS_TOKEN) == 0)
120 if (!std::getline(lineStream, token,
'='))
122 throw_parse_error(m_path, line, token, lineNumber);
124 else if (!std::getline(lineStream, token,
'='))
126 throw_parse_error(m_path, line, token, lineNumber);
130 else if (line.find(HEADER_TOKEN) == 0)
140 if (token !=
"optimize")
142 throw_parse_error(m_path, line, token, lineNumber);
146 if (!(lineStream >> optimized))
148 throw_parse_error(m_path, line, token, lineNumber);
151 if (optimized ==
'Y' || std::tolower(optimized) ==
'y')
155 else if (optimized ==
'N' || std::tolower(optimized) ==
'n')
161 throw_parse_error(m_path, line, token, lineNumber);
165 if (lineStream >> token && token ==
"staggered")
168 if (!(lineStream >> staggered))
170 throw_parse_error(m_path, line, token, lineNumber);
173 if (staggered ==
'Y' || std::tolower(staggered) ==
'y')
175 m_staggered = Staggered::Yes;
177 else if (staggered ==
'N' || std::tolower(staggered) ==
'n')
179 m_staggered = Staggered::No;
183 throw_parse_error(m_path, line, token, lineNumber);
188 m_staggered = Staggered::Unknown;
191 else if (line.find(NetRecord::FIELD_TOKEN) == 0)
197 if (!(lineStream >> token))
199 throw_parse_error(m_path, line, token, lineNumber);
202 auto strSerialNumber = token;
203 strSerialNumber.erase(0, 1);
204 auto ulSerialNumber = std::stoul(strSerialNumber);
205 if (ulSerialNumber > UINT_MAX)
207 throw_parse_error(m_path, line, token, lineNumber);
210 auto unSerialNumber =
static_cast<unsigned int>(ulSerialNumber);
213 if (!(lineStream >> token))
215 throw_parse_error(m_path, line, token, lineNumber);
218 auto& netName = token;
220 auto pNetRecord = std::make_shared<NetRecord>();
221 pNetRecord->serialNumber = unSerialNumber;
222 pNetRecord->netName = netName;
223 m_netRecords.push_back(pNetRecord);
229 if (!(lineStream >> token))
231 throw_parse_error(m_path, line, token, lineNumber);
234 auto ulNetNumber = std::stoul(token);
235 if (ulNetNumber >= UINT_MAX)
237 throw_parse_error(m_path, line, token, lineNumber);
240 auto unNetNumber =
static_cast<unsigned int>(ulNetNumber);
242 auto pNetPointRecord = std::make_shared<NetPointRecord>();
243 pNetPointRecord->netNumber = unNetNumber;
245 if (!(lineStream >> pNetPointRecord->radius))
247 throw_parse_error(m_path, line, token, lineNumber);
250 if (!(lineStream >> pNetPointRecord->x))
252 throw_parse_error(m_path, line, token, lineNumber);
255 if (!(lineStream >> pNetPointRecord->y))
257 throw_parse_error(m_path, line, token, lineNumber);
262 m_netPointRecords.push_back(pNetPointRecord);
267 loginfo(
"Parsing netlist: " + m_name +
" complete");
271 catch (parse_error& pe)
273 auto m = pe.toString(
"Parse Error:");
280 catch (std::exception& e)
282 parse_info pi(m_path, line, lineNumber);
283 const auto m = pi.toString();
284 logexception_msg(e, m);
292 std::unique_ptr<Odb::Lib::Protobuf::NetlistFile> NetlistFile::to_protobuf()
const
294 std::unique_ptr<Odb::Lib::Protobuf::NetlistFile> pNetlistFileMessage(
new Odb::Lib::Protobuf::NetlistFile);
295 pNetlistFileMessage->set_units(m_units);
296 pNetlistFileMessage->set_path(m_path.string());
297 pNetlistFileMessage->set_name(m_name);
298 pNetlistFileMessage->set_optimized(m_optimized);
299 pNetlistFileMessage->set_staggered(
static_cast<Odb::Lib::Protobuf::NetlistFile::Staggered
>(m_staggered));
301 for (
const auto& pNetRecord : m_netRecords)
303 auto pNetRecordMessage = pNetRecord->to_protobuf();
304 pNetlistFileMessage->add_netrecordss()->CopyFrom(*pNetRecordMessage);
307 for (
const auto& kvNetRecord : m_netRecordsByName)
309 (*pNetlistFileMessage->mutable_netrecordsbyname())[kvNetRecord.first] = *kvNetRecord.second->to_protobuf();
312 for (
const auto& pNetPointRecord : m_netPointRecords)
314 auto pNetPointRecordMessage = pNetPointRecord->to_protobuf();
315 pNetlistFileMessage->add_netpointrecords()->CopyFrom(*pNetPointRecordMessage);
318 return pNetlistFileMessage;
321 void NetlistFile::from_protobuf(
const Odb::Lib::Protobuf::NetlistFile& message)
323 m_name = message.name();
324 m_path = message.path();
325 m_units = message.units();
326 m_optimized = message.optimized();
327 m_staggered =
static_cast<Staggered
>(message.staggered());
329 for (
const auto& netRecordMessage : message.netrecordss())
331 auto pNetRecord = std::make_shared<NetRecord>();
332 pNetRecord->from_protobuf(netRecordMessage);
333 m_netRecords.push_back(pNetRecord);
336 for (
const auto& kvNetRecord : message.netrecordsbyname())
338 auto pNetRecord = std::make_shared<NetRecord>();
339 pNetRecord->from_protobuf(kvNetRecord.second);
340 m_netRecordsByName[pNetRecord->netName] = pNetRecord;
343 for (
const auto& netPointRecordMessage : message.netpointrecords())
345 auto pNetPointRecord = std::make_shared<NetPointRecord>();
346 pNetPointRecord->from_protobuf(netPointRecordMessage);
347 m_netPointRecords.push_back(pNetPointRecord);
351 std::unique_ptr<Odb::Lib::Protobuf::NetlistFile::NetRecord> NetlistFile::NetRecord::to_protobuf()
const
353 std::unique_ptr<Odb::Lib::Protobuf::NetlistFile::NetRecord> pNetRecordMessage(
new Odb::Lib::Protobuf::NetlistFile::NetRecord);
354 pNetRecordMessage->set_serialnumber(serialNumber);
355 pNetRecordMessage->set_netname(netName);
356 return pNetRecordMessage;
359 void NetlistFile::NetRecord::from_protobuf(
const Odb::Lib::Protobuf::NetlistFile::NetRecord& message)
361 serialNumber = message.serialnumber();
362 netName = message.netname();
365 std::unique_ptr<Odb::Lib::Protobuf::NetlistFile::NetPointRecord> NetlistFile::NetPointRecord::to_protobuf()
const
367 std::unique_ptr<Odb::Lib::Protobuf::NetlistFile::NetPointRecord> pNetPointRecordMessage(
new Odb::Lib::Protobuf::NetlistFile::NetPointRecord);
368 pNetPointRecordMessage->set_netnumber(netNumber);
369 pNetPointRecordMessage->set_radius(radius);
370 pNetPointRecordMessage->set_x(x);
371 pNetPointRecordMessage->set_y(y);
372 pNetPointRecordMessage->set_epoint(std::to_string(epoint));
373 pNetPointRecordMessage->set_width(width);
374 pNetPointRecordMessage->set_exp(std::to_string(exp));
375 pNetPointRecordMessage->set_fiducialpoint(fiducialPoint);
376 pNetPointRecordMessage->set_height(height);
377 pNetPointRecordMessage->set_commentpoint(commentPoint);
378 pNetPointRecordMessage->set_netnumber(netNumber);
379 pNetPointRecordMessage->set_side(
static_cast<Odb::Lib::Protobuf::NetlistFile::NetPointRecord::AccessSide
>(side));
380 pNetPointRecordMessage->set_staggeredradius(staggeredRadius);
381 pNetPointRecordMessage->set_staggeredx(staggeredX);
382 pNetPointRecordMessage->set_staggeredy(staggeredY);
383 pNetPointRecordMessage->set_testexecutionside(std::to_string(testExecutionSide));
384 pNetPointRecordMessage->set_testpoint(testPoint);
385 pNetPointRecordMessage->set_viapoint(viaPoint);
386 pNetPointRecordMessage->set_fiducialpoint(fiducialPoint);
387 return pNetPointRecordMessage;
390 void NetlistFile::NetPointRecord::from_protobuf(
const Odb::Lib::Protobuf::NetlistFile::NetPointRecord& message)
392 netNumber = message.netnumber();
393 radius = message.radius();
396 if (message.epoint().empty())
398 epoint = message.epoint()[0];
400 width = message.width();
401 if (!message.exp().empty())
403 exp = message.exp()[0];
405 fiducialPoint = message.fiducialpoint();
406 height = message.height();
407 commentPoint = message.commentpoint();
408 netNumber = message.netnumber();
409 side =
static_cast<AccessSide
>(message.side());
410 staggeredRadius = message.staggeredradius();
411 staggeredX = message.staggeredx();
412 staggeredY = message.staggeredy();
413 if (!message.testexecutionside().empty())
415 testExecutionSide = message.testexecutionside()[0];
417 testPoint = message.testpoint();
418 viaPoint = message.viapoint();
419 fiducialPoint = message.fiducialpoint();