3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-01-18 16:28:57 +00:00

Add Design::run_pass() API for programmatic pass execution

This commit adds a new run_pass() method to the RTLIL::Design class,
providing a convenient API for executing Yosys passes programmatically.

This is particularly useful for PyYosys users who want to run passes
on a design object without needing to manually construct Pass::call()
invocations. The method wraps Pass::call() with appropriate logging
to maintain consistency with command-line pass execution.

Example usage (from Python):
    design = ys.Design()
    # ... build or load design ...
    design.run_pass("hierarchy")
    design.run_pass("proc")
    design.run_pass("opt")

Changes:
- kernel/rtlil.h: Add run_pass() method declaration
- kernel/rtlil.cc: Implement run_pass() method
- tests/unit/kernel/test_design_run_pass.cc: Add unit tests
This commit is contained in:
Natalia 2026-01-14 17:35:45 -08:00
parent 967b47d984
commit fb864e91ee
3 changed files with 69 additions and 0 deletions

View file

@ -1610,6 +1610,13 @@ std::vector<RTLIL::Module*> RTLIL::Design::selected_modules(RTLIL::SelectPartial
return result;
}
void RTLIL::Design::run_pass(std::string command)
{
log("\n-- Running command `%s' --\n", command.c_str());
Pass::call(this, command);
log_flush();
}
RTLIL::Module::Module()
{
static unsigned int hashidx_count = 123456789;

View file

@ -2031,6 +2031,9 @@ struct RTLIL::Design
// returns all selected unboxed whole modules, warning the user if any
// partially selected or boxed modules have been ignored
std::vector<RTLIL::Module*> selected_unboxed_whole_modules_warn() const { return selected_modules(SELECT_WHOLE_WARN, SB_UNBOXED_WARN); }
void run_pass(std::string command);
static std::map<unsigned int, RTLIL::Design*> *get_all_designs(void);
std::string to_rtlil_str(bool only_selected = true) const;

View file

@ -0,0 +1,59 @@
#include <gtest/gtest.h>
#include "kernel/rtlil.h"
#include "kernel/register.h"
YOSYS_NAMESPACE_BEGIN
class DesignRunPassTest : public testing::Test {
protected:
DesignRunPassTest() {
if (log_files.empty()) log_files.emplace_back(stdout);
}
virtual void SetUp() override {
IdString::ensure_prepopulated();
}
};
TEST_F(DesignRunPassTest, RunPassExecutesSuccessfully)
{
// Create a design with a simple module
RTLIL::Design *design = new RTLIL::Design;
RTLIL::Module *module = new RTLIL::Module;
module->name = RTLIL::IdString("\\test_module");
design->add(module);
// Add a simple wire to the module
RTLIL::Wire *wire = module->addWire(RTLIL::IdString("\\test_wire"), 1);
wire->port_input = true;
wire->port_id = 1;
module->fixup_ports();
// Call run_pass with a simple pass
// We use "check" which is a simple pass that just validates the design
ASSERT_NO_THROW(design->run_pass("check"));
// Verify the design still exists and has the module
EXPECT_EQ(design->modules().size(), 1);
EXPECT_NE(design->module(RTLIL::IdString("\\test_module")), nullptr);
delete design;
}
TEST_F(DesignRunPassTest, RunPassWithHierarchy)
{
// Create a design with a simple module
RTLIL::Design *design = new RTLIL::Design;
RTLIL::Module *module = new RTLIL::Module;
module->name = RTLIL::IdString("\\top");
design->add(module);
// Call run_pass with hierarchy pass
ASSERT_NO_THROW(design->run_pass("hierarchy"));
// Verify the design still has the module
EXPECT_EQ(design->modules().size(), 1);
delete design;
}
YOSYS_NAMESPACE_END