diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e3f0f1..0b95078 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ INCLUDE_DIRECTORIES( SET(SOURCES src/coloquinte.cpp src/parameters.cpp + src/export.cpp src/place_global/net_model.cpp src/place_global/density_legalizer.cpp src/place_global/density_grid.cpp diff --git a/meson.build b/meson.build index 695d1fd..69a9b60 100644 --- a/meson.build +++ b/meson.build @@ -26,6 +26,7 @@ lemon_dep = lemon.dependency('lemon') sources = [ 'src/coloquinte.cpp', 'src/parameters.cpp', + 'src/export.cpp', 'src/place_global/net_model.cpp', 'src/place_global/density_legalizer.cpp', 'src/place_global/density_grid.cpp', diff --git a/pycoloquinte/coloquinte.py b/pycoloquinte/coloquinte.py index 5cddf69..5cdd295 100644 --- a/pycoloquinte/coloquinte.py +++ b/pycoloquinte/coloquinte.py @@ -831,6 +831,10 @@ def main(): parser.add_argument( "--image-extension", help=argparse.SUPPRESS, type=str, default="webp" ) + # Export the ISPD benchmark files after reading + parser.add_argument( + "--export-ispd", help=argparse.SUPPRESS, type=str + ) tuning_options = parser.add_argument_group("tuning options") _add_arguments(tuning_options, ColoquinteParameters(), []) @@ -864,6 +868,9 @@ def main(): print(circuit.report()) sys.stdout.flush() + if args.export_ispd is not None: + print("Exporting as ISPD benchmark") + circuit.export_ispd(args.export_ispd) callback = None if args.save_images is not None: circuit.write_image( diff --git a/pycoloquinte/module.cpp b/pycoloquinte/module.cpp index 4820459..4a7c8a6 100644 --- a/pycoloquinte/module.cpp +++ b/pycoloquinte/module.cpp @@ -320,6 +320,8 @@ Construct a circuit. "Expand the standard cells by an individual factor") .def("check", &Circuit::check, "Check the datastructure") .def("report", &Circuit::report) + .def("export_ispd", &Circuit::exportIspd, + "Export the circuit to ISPD benchmark files") .def("__str__", &Circuit::toString) .def("__repr__", &Circuit::toString); } diff --git a/src/coloquinte.hpp b/src/coloquinte.hpp index 69f0dab..69184d1 100644 --- a/src/coloquinte.hpp +++ b/src/coloquinte.hpp @@ -1029,6 +1029,11 @@ class Circuit { */ std::string toString() const; + /** + * @brief Export as an ISPD benchmark + */ + void exportIspd(const std::string &filename) const; + /** * @brief Obtain a detailed report */ diff --git a/src/export.cpp b/src/export.cpp new file mode 100644 index 0000000..aaf08de --- /dev/null +++ b/src/export.cpp @@ -0,0 +1,91 @@ + +#include + +#include "coloquinte.hpp" + +namespace coloquinte { + +void exportIspdAux(const Circuit &circuit, const std::string &filename) { + std::ofstream f(filename + ".aux"); + f << "RowBasedPlacement : " << filename << ".nodes " << filename << ".nets " + << filename << ".pl " << filename << ".scl" << std::endl; +} + +void exportIspdNodes(const Circuit &circuit, const std::string &filename) { + std::ofstream f(filename + ".nodes"); + f << "UCLA nodes 1.0\n\n"; + f << "NumNodes : " << circuit.nbCells() << "\n"; + int numTerminals = 0; + for (int i = 0; i < circuit.nbCells(); ++i) { + if (circuit.isFixed(i)) { + ++numTerminals; + } + } + f << "NumTerminals : " << numTerminals << "\n"; + + for (int i = 0; i < circuit.nbCells(); ++i) { + f << "\to" << i << "\t" << circuit.cellWidth_[i] << "\t" + << circuit.cellHeight_[i]; + if (circuit.isFixed(i)) { + f << "\tterminal"; + } + f << "\n"; + } +} + +void exportIspdPlace(const Circuit &circuit, const std::string &filename) { + std::ofstream f(filename + ".pl"); + f << "UCLA pl 1.0\n\n"; + + for (int i = 0; i < circuit.nbCells(); ++i) { + f << "o" << i << "\t" << circuit.x(i) << "\t" << circuit.y(i) + << "\t: " << toString(circuit.orientation(i)) << "\n"; + } +} + +void exportIspdNets(const Circuit &circuit, const std::string &filename) { + std::ofstream f(filename + ".nets"); + f << "UCLA nets 1.0\n\n"; + + f << "NumNets : " << circuit.nbNets() << "\n"; + f << "NumPins : " << circuit.nbPins() << "\n\n"; + + for (int i = 0; i < circuit.nbNets(); ++i) { + f << "NetDegree : " << circuit.nbPinsNet(i) << " n" << i << "\n"; + for (int j = 0; j < circuit.nbPinsNet(i); ++j) { + int c = circuit.pinCell(i, j); + f << "\to" << c << " I : "; + double x = circuit.pinXOffset(i, j) - 0.5 * circuit.cellWidth_[c]; + double y = circuit.pinYOffset(i, j) - 0.5 * circuit.cellHeight_[c]; + f << x << " " << y << "\n"; + } + } +} + +void exportIspdRows(const Circuit &circuit, const std::string &filename) { + std::ofstream f(filename + ".scl"); + f << "UCLA scl 1.0\n\n"; + + f << "NumRows : " << circuit.nbRows() << "\n\n"; + for (int i = 0; i < circuit.nbRows(); ++i) { + f << "CoreRow Horizontal\n"; + f << " Coordinate : " << circuit.rows()[i].minY << "\n"; + f << " Height : " << circuit.rows()[i].height() << "\n"; + f << " Sitewidth : 1\n"; + f << " Sitespacing : 1\n"; + f << " Siteorient : 1\n"; + f << " Sitesymmetry : 1\n"; + f << " SubrowOrigin : " << circuit.rows()[i].minX + << " NumSites : " << circuit.rows()[i].width() << "\n"; + f << "End\n"; + } +} + +void Circuit::exportIspd(const std::string &filename) const { + exportIspdAux(*this, filename); + exportIspdNodes(*this, filename); + exportIspdPlace(*this, filename); + exportIspdNets(*this, filename); + exportIspdRows(*this, filename); +} +} // namespace coloquinte \ No newline at end of file