FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Yosysの使い方を勉強する (4. RTLIL中間表現を観察する)

YosysのRTLILについて見て行っている。

RTLILのコードとしては、いくつかのstructが定義されている。

  • /yosys/kernel/rtlil.h
namespace RTLIL
/* ...途中省略 ...*/
    struct Const;
    struct AttrObject;
    struct Selection;
    struct Monitor;
    struct Design;
    struct Module;
    struct Wire;
    struct Memory;
    struct Cell;
    struct SigChunk;
    struct SigBit;
    struct SigSpecIterator;
    struct SigSpecConstIterator;
    struct SigSpec;
    struct CaseRule;
    struct SwitchRule;
    struct MemWriteAction;
    struct SyncRule;
    struct Process;
    struct Binding;

struct Moduleにはいくつかのデータ構造とメソッドが定義されていた。

struct RTLIL::Module : public RTLIL::AttrObject
{
    unsigned int hashidx_;
    unsigned int hash() const { return hashidx_; }

protected:
    void add(RTLIL::Wire *wire);
    void add(RTLIL::Cell *cell);
    void add(RTLIL::Process *process);

public:
    RTLIL::Design *design;
    pool<RTLIL::Monitor*> monitors;

    int refcount_wires_;
    int refcount_cells_;
/* ... 途中省略 ... */

なんか大量のメソッドが定義されている。これらでデザインを構築していくという訳か?

    RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1);
    RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other);

    RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type);
    RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other);

    RTLIL::Memory *addMemory(RTLIL::IdString name, const RTLIL::Memory *other);

    RTLIL::Process *addProcess(RTLIL::IdString name);
    RTLIL::Process *addProcess(RTLIL::IdString name, const RTLIL::Process *other);

    // The add* methods create a cell and return the created cell. All signals must exist in advance.

    RTLIL::Cell* addNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addPos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addNeg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");

    RTLIL::Cell* addAnd  (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addOr   (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addXor  (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");

    RTLIL::Cell* addReduceAnd  (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addReduceOr   (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addReduceXor  (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");

    RTLIL::Cell* addShl    (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addShr    (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addSshl   (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addSshr   (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addShift  (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
    RTLIL::Cell* addShiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");

例えば、RTLIL::SigSpecというのは、すべての「信号」を管理しているらしい。

  • 定数:1337, 16’b0000010100111001, 1’b1, 1’bx
  • ビットの選択:mywire, mywire[24], mywire[15:8]
  • 信号の接続:{16’d1337, mywire[15:8]}