Search code examples
c++llvmyosys

How to execute yosys passes from an LLVM pass?


I have been working with two programs llvm's opt and clifford wolf's yosys both have similar interfaces for passes.(they use shared libraries as optimization passes)

I want to use certain data structures and functions from yosys.h to build a design module(which is then written in verilog to file) based on the data generated by my llvm opt pass.

PROBLEM: I want to make use of functions,data from yosys.h in the pass for llvm-opt. How do i compile(EDIT: and also execute either on llvm-opt or on yosys or a seperate binary executable) such code? individually they can be compiled and executed as seperate passes.

COMPILE YOSYS PASS

gcc `yosys-config --cxxflags --ldlibs --ldflags` --shared yosyspass.cpp -o yosyspass.so

and execute it with

yosys -m yosyspass.so verilogfile.v

COMPILE LLVM PASS

gcc  `llvm-config --cxxflags --ldlibs` --shared llvmpass.ccp -o llvmpass.so

and execute it with

opt -load ./llvmpass.so -llvmpass Somefile.bc

but how to build code which has both components from llvm , yosys? and how to execute it?

How can i make this happen without changing source code of yosys too much? All of this is to avoid writing a verilog generation backend for my llvm-opt pass.

ONE OF MY SOLUTIONS:

Metaprogramming: i.e., generate the code which when compiled and run as a yosys pass gives me the result.(verilog design file based on llvm opt input)

Maybe i'm missing something fundamental in build shared libraries? I'm new to this sort of thing. any input is welcome.

This project(though unrelated) may be similar to Rotems C-to-Verilog and univ of toronto's legup HLS tool.


Solution

  • As Krzysztof Kosiński pointed out, until now the Yosys core functionality was not available as library. However, this was on the todo list for a long time and I have now added this functionality to Yosys git head.

    Here is a usage example:

    // example.cc
    
    #include <kernel/yosys.h>
    
    int main()
    {
        Yosys::log_streams.push_back(&std::cout);
        Yosys::log_error_stderr = true;
    
        Yosys::yosys_setup();
        Yosys::yosys_banner();
    
        Yosys::run_pass("read_verilog example.v");
        Yosys::run_pass("synth -noabc");
        Yosys::run_pass("clean -purge");
        Yosys::run_pass("write_blif example.blif");
    
        Yosys::yosys_shutdown();
        return 0;
    }
    

    Building a binary:

    yosys-config --exec --cxx -o example --cxxflags --ldflags example.cc -lyosys -lstdc++
    

    Now you can run ./example to convert example.v into example.blif.

    (As this is a brand new feature, the details of how to build programs or other libraries using libyosys are likely to change in the future.)

    Edit: In current git head the Makefile option ENABLE_LIBYOSYS must be set to 1 to enable building of libyosys.so.


    Additional feedback: You might want to consider to write a Yosys plugin instead that implements a Yosys front-end that uses LLVM libraries to load a .bc file. If you are not planning to go back and forth between LLVM and Yosys, but only want execute a sequence of LLVM passes followed by a sequence of Yosys passes, then this solution might provide a more natural and easier to debug interface between LLVM and Yosys.