3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-08-03 18:00:24 +00:00

sdc_expand, opensta: start

This commit is contained in:
Emil J. Tywoniak 2025-07-18 22:45:31 +02:00
parent e2484779e7
commit 2f3fc8d8a9
3 changed files with 270 additions and 0 deletions

View file

@ -2,6 +2,8 @@
ifneq ($(SMALL),1)
OBJS += techlibs/common/synth.o
OBJS += techlibs/common/prep.o
OBJS += techlibs/common/opensta.o
OBJS += techlibs/common/sdc_expand.o
endif
GENFILES += techlibs/common/simlib_help.inc

118
techlibs/common/opensta.cc Normal file
View file

@ -0,0 +1,118 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
#if !defined(YOSYS_DISABLE_SPAWN)
struct OpenstaPass : public Pass
{
const char* default_sta_cmd = "sta";
OpenstaPass() : Pass("opensta", "run OpenSTA") { }
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" opensta [options]\n");
log("\n");
// TOOD
log("\n");
log(" -exe <command>\n");
log(" use <command> to run OpenSTA instead of \"%s\"\n", default_sta_cmd);
log("\n");
log(" -sdc-in <filename>\n");
log(" expand SDC input file <filename>\n");
log("\n");
log(" -sdc-out <filename>\n");
log(" expand SDC file to output file <filename>\n");
log("\n");
log(" -nocleanup\n");
log("\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
string run_from, run_to;
string opensta_exe = "sta";
string sdc_filename, sdc_expanded_filename;
string tempdir_name, script_filename;
string verilog_filename, liberty_filename;
bool cleanup = true;
log_header(design, "Executing OPENSTA pass.\n");
log_push();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-exe" && argidx+1 < args.size()) {
opensta_exe = args[++argidx];
continue;
}
if (args[argidx] == "-sdc-in" && argidx+1 < args.size()) {
sdc_filename = args[++argidx];
continue;
}
if (args[argidx] == "-sdc-out" && argidx+1 < args.size()) {
sdc_expanded_filename = args[++argidx];
continue;
}
if (args[argidx] == "-verilog" && argidx+1 < args.size()) {
verilog_filename = args[++argidx];
continue;
}
if (args[argidx] == "-liberty" && argidx+1 < args.size()) {
liberty_filename = args[++argidx];
continue;
}
if (args[argidx] == "-nocleanup") {
cleanup = false;
continue;
}
break;
}
extra_args(args, argidx, design);
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
if (cleanup)
tempdir_name = get_base_tmpdir() + "/";
else
tempdir_name = "_tmp_";
tempdir_name += proc_program_prefix() + "yosys-opensta-XXXXXX";
tempdir_name = make_temp_dir(tempdir_name);
script_filename = tempdir_name + "/opensta.tcl";
// script_filename
auto top_mod = design->top_module();
if (!top_mod)
log_error("Can't find top module in current design!\n");
std::ofstream f_script;
f_script.open(script_filename);
f_script << "read_verilog " << verilog_filename << "\n";
f_script << "read_lib " << liberty_filename << "\n";
f_script << "link_design " << RTLIL::unescape_id(top_mod->name) << "\n";
f_script << "read_sdc " << sdc_filename << "\n";
f_script << "write_sdc " << sdc_expanded_filename << "\n";
f_script.close();
std::string command = opensta_exe + " -exit " + script_filename;
int ret = run_command(command);
if (ret)
log_error("OpenSTA return %d (error)\n", ret);
else
log("sdc_expanded_filename: %s\n", sdc_expanded_filename.c_str());
if (cleanup) {
log("Removing temp directory.\n");
remove_directory(tempdir_name);
}
log_pop();
}
} OpenstaPass;
#endif
PRIVATE_NAMESPACE_END

View file

@ -0,0 +1,150 @@
#include "kernel/rtlil.h"
#include "kernel/log.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SdcexpandPass : public ScriptPass
{
const char* default_sta_cmd = "sta";
SdcexpandPass() : ScriptPass("sdc_expand", "run OpenSTA") { }
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" sdc_expand [options]\n");
log("\n");
// TODO
log("\n");
log(" -exe <command>\n");
log(" use <command> to run OpenSTA instead of \"%s\"\n", default_sta_cmd);
log("\n");
log(" -sdc-in <filename>\n");
log(" expand SDC file <filename>\n");
log("\n");
log(" -nocleanup\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string opensta_exe, sdc_filename, sdc_expanded_filename;
bool cleanup;
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
string run_from, run_to;
cleanup = true;
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-exe" && argidx+1 < args.size()) {
opensta_exe = args[++argidx];
continue;
}
if (args[argidx] == "-sdc-in" && argidx+1 < args.size()) {
sdc_filename = args[++argidx];
continue;
}
if (args[argidx] == "-sdc-out" && argidx+1 < args.size()) {
sdc_expanded_filename = args[++argidx];
continue;
}
if (args[argidx] == "-nocleanup") {
cleanup = false;
continue;
}
// repetitive boring bit
if (args[argidx] == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
if (pos == std::string::npos) {
run_from = args[++argidx];
run_to = args[argidx];
} else {
run_from = args[++argidx].substr(0, pos);
run_to = args[argidx].substr(pos+1);
}
continue;
}
break;
}
extra_args(args, argidx, design);
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
log_header(design, "Executing OPENSTA pass.\n");
log_push();
run_script(design, run_from, run_to);
log_pop();
}
void script() override
{
std::string tempdir_name;
std::string liberty_path;
std::string verilog_path;
run("design -save pre_expand");
run("proc");
run("memory");
// run("dfflegalize -cell $dff");
std::string write_verilog_cmd = "write_verilog -norename -noexpr -attr2comment -defparam ";
if (help_mode) {
run(write_verilog_cmd + "<tmp_dir>/elaborated.v");
} else {
if (cleanup)
tempdir_name = get_base_tmpdir() + "/";
else
tempdir_name = "_tmp_";
tempdir_name += proc_program_prefix() + "yosys-sdc_expand-XXXXXX";
tempdir_name = make_temp_dir(tempdir_name);
verilog_path = tempdir_name + "/elaborated.v";
run(write_verilog_cmd + verilog_path);
}
run("read_verilog -setattr whitebox -defer -DSIMLIB_NOCHECKS +/simlib.v");
run("proc");
run("hierarchy -auto-top");
run("publish");
if (help_mode) {
run("icell_liberty <tmp_dir>/yosys.lib");
} else {
liberty_path = tempdir_name + "/yosys.lib";
run(stringf("icell_liberty %s", liberty_path.c_str()));
}
std::string opensta_pass_call = "opensta -exe ";
opensta_pass_call += help_mode ? "<exe>" : opensta_exe;
opensta_pass_call += " -sdc-in ";
opensta_pass_call += help_mode ? "<sdc-in>" : sdc_filename;
opensta_pass_call += " -sdc-out ";
opensta_pass_call += help_mode ? "<sdc-out>" : sdc_expanded_filename;
opensta_pass_call += " -verilog ";
opensta_pass_call += help_mode ? "<verilog>" : verilog_path;
opensta_pass_call += " -liberty ";
opensta_pass_call += help_mode ? "<tmp_dir>/yosys.lib" : liberty_path;
if (!cleanup)
opensta_pass_call += " -nocleanup";
run(opensta_pass_call.c_str());
if (!help_mode) {
if (cleanup) {
log("Removing temp directory.\n");
remove_directory(tempdir_name);
} else {
log("Keeping temp directory %s\n", tempdir_name.c_str());
}
}
run("design -load pre_expand");
}
} SdcexpandPass;
PRIVATE_NAMESPACE_END