对于一个新工具,以及学习源码,可以让ai帮忙分析。例如下面源码解读使用的kimi协助分析
一、基本使用
【从零开始学习VLSI设计(一)】Yosys工具概述-CSDN博客
1.安装
$ sudo apt-get install build-essential clang bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev
$ git clone https://github.com/YosysHQ/yosys.git
$ cd yosys
$ make
$ sudo make install
2.使用
//读取top.v
read_verilog top.v
//读取lib库
read_verilog -lib -specify +/xilinx/cells_sim.v
read_verilog -lib +/xilinx/cells_xtra.v
//检查层次连接
hierarchy -check -auto-top
//综合
synth_xilinx -flatten -nosrl -noclkbuf -nodsp
//显示连接关系图
show
//执行优化
opt
二、项目结构
Yosys 是一个开源的硬件描述语言(HDL)合成工具,它主要用于将 Verilog 或 VHDL 代码转换成门级网表(netlist),这些网表可以被发送到 ASIC 或 FPGA 的合成工具。Yosys 支持多种不同的后端目标,使其成为一个灵活的前端合成工具。
Yosys 的项目结构大致如下:
1. 内核(Kernel)
- 包含 Yosys 的核心功能,如内存管理、日志记录、基本数据类型和算法等。
2. 前端(Frontends)
- 用于读取和解析不同的硬件描述语言,如 Verilog、VHDL、SystemVerilog 等。
- 将 HDL 代码转换成 Yosys 内部表示(AST - Abstract Syntax Tree)。
3. 后端(Backends)
- 用于将 Yosys 内部表示转换成不同的网表格式,如 EDIF、Bels、Netlists 等。
- 支持多种不同的技术目标,如 Xilinx、Altera/Intel、Lattice 等。
4. 优化(Optimizations)
- 包含一系列优化传递(passes),用于改进和简化内部表示。
- 优化包括但不限于常数传播、死代码消除、代数简化、查找表优化等。
5. 库(Libraries)
- 提供了一系列预定义的逻辑单元(如 LUTs、Flip-Flops、内存单元等)和宏单元。
- 用于生成特定功能的标准单元和宏。
6. 工具(Tools)
- 提供了一系列用于调试、分析和转换设计的工具。
- 包括查看器、测试生成器、等价性检查器等。
7. 测试(Tests)
- 包含了用于测试 Yosys 功能的自动化测试套件。
- 用于确保 Yosys 的功能正确性和稳定性。
8. 文档(Documentation)
- 提供了用户手册、内部 API 文档和开发文档。
- 帮助用户和开发者理解如何使用和贡献 Yosys。
9. 脚本和示例(Scripts and Examples)
- 提供了一系列示例和脚本,展示如何使用 Yosys 进行不同的合成和优化任务。
- 用于教学和作为最佳实践的参考。
10. 第三方集成(Third-party Integrations)
- 包括与第三方工具链的集成,如 OpenSTA、ABC 等。
- 提供了与这些工具的接口,以便在合成流程中使用它们的特定功能。
Yosys 的项目结构设计得既模块化又可扩展,使得它可以适应不同的用户需求和目标平台。开发者可以通过添加新的前端、后端或优化传递来扩展 Yosys 的功能。
三、内部数据结构
上图为yosys内部的逻辑门类型
上图为yosys内部网表的主要数据结构
以下是 rtlil.h
和 rtlil.cc
文件中与 design->modules()
相关的一些关键点:
-
RTLIL::Design
类:- 定义了
RTLIL::Design
类,它表示整个设计,包含所有模块和其他全局信息。 RTLIL::Design
类中有一个modules
成员,它是一个std::vector
,存储设计中的所有模块。
- 定义了
-
RTLIL::Module
类:- 定义了
RTLIL::Module
类,它表示设计中的一个模块,是设计的基本构建块。 RTLIL::Module
类包含成员如wires
、cells
等,用于存储模块内的线网和单元。
- 定义了
-
RTLIL::Wire
类:- 定义了
RTLIL::Wire
类,它表示一个线网,用于连接模块内的信号。
- 定义了
-
RTLIL::Cell
类:- 定义了
RTLIL::Cell
类,它表示一个单元,如逻辑门或存储元件。
- 定义了
-
RTLIL::SigSpec
类:- 定义了
RTLIL::SigSpec
类,它表示一个信号规范,可以包含多个信号位或信号块。
- 定义了
-
RTLIL::SigBit
类:- 定义了
RTLIL::SigBit
类,它表示一个信号位,可以是一个线网的一部分或一个常量值。
- 定义了
这些数据结构共同构成了 Yosys 处理和存储网表信息的基础设施。通过这些数据结构,Yosys 可以读取、修改和输出 RTL 级别的硬件设计。
RTLIL::Design
struct RTLIL::Design
{
unsigned int hashidx_;
unsigned int hash() const { return hashidx_; }
pool<RTLIL::Monitor*> monitors;
dict<std::string, std::string> scratchpad;
bool flagBufferedNormalized = false;
void bufNormalize(bool enable=true);
int refcount_modules_;
dict<RTLIL::IdString, RTLIL::Module*> modules_;
std::vector<RTLIL::Binding*> bindings_;
std::vector<AST::AstNode*> verilog_packages, verilog_globals;
std::unique_ptr<define_map_t> verilog_defines;
std::vector<RTLIL::Selection> selection_stack;
dict<RTLIL::IdString, RTLIL::Selection> selection_vars;
std::string selected_active_module;
Design();
~Design();
RTLIL::ObjRange<RTLIL::Module*> modules();
RTLIL::Module *module(const RTLIL::IdString &name);
const RTLIL::Module *module(const RTLIL::IdString &name) const;
RTLIL::Module *top_module();
bool has(const RTLIL::IdString &id) const {
return modules_.count(id) != 0;
}
void add(RTLIL::Module *module);
void add(RTLIL::Binding *binding);
RTLIL::Module *addModule(RTLIL::IdString name);
void remove(RTLIL::Module *module);
void rename(RTLIL::Module *module, RTLIL::IdString new_name);
void scratchpad_unset(const std::string &varname);
void scratchpad_set_int(const std::string &varname, int value);
void scratchpad_set_bool(const std::string &varname, bool value);
void scratchpad_set_string(const std::string &varname, std::string value);
int scratchpad_get_int(const std::string &varname, int default_value = 0) const;
bool scratchpad_get_bool(const std::string &varname, bool default_value = false) const;
std::string scratchpad_get_string(const std::string &varname, const std::string &default_value = std::string()) const;
void sort();
void check();
void optimize();
bool selected_module(const RTLIL::IdString &mod_name) const;
bool selected_whole_module(const RTLIL::IdString &mod_name) const;
bool selected_member(const RTLIL::IdString &mod_name, const RTLIL::IdString &memb_name) const;
bool selected_module(RTLIL::Module *mod) const;
bool selected_whole_module(RTLIL::Module *mod) const;
RTLIL::Selection &selection() {
return selection_stack.back();
}
const RTLIL::Selection &selection() const {
return selection_stack.back();
}
bool full_selection() const {
return selection_stack.back().full_selection;
}
template<typename T1> bool selected(T1 *module) const {
return selected_module(module->name);
}
template<typename T1, typename T2> bool selected(T1 *module, T2 *member) const {
return selected_member(module->name, member->name);
}
template<typename T1> void select(T1 *module) {
if (selection_stack.size() > 0) {
RTLIL::Selection &sel = selection_stack.back();
sel.select(module);
}
}
template<typename T1, typename T2> void select(T1 *module, T2 *member) {
if (selection_stack.size() > 0) {
RTLIL::Selection &sel = selection_stack.back();
sel.select(module, member);
}
}
std::vector<RTLIL::Module*> selected_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules() const;
std::vector<RTLIL::Module*> selected_whole_modules_warn(bool include_wb = false) const;
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Design*> *get_all_designs(void);
#endif
};
RTLIL::Model
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_;
dict<RTLIL::IdString, RTLIL::Wire*> wires_;
dict<RTLIL::IdString, RTLIL::Cell*> cells_;
std::vector<RTLIL::SigSig> connections_;
std::vector<RTLIL::Binding*> bindings_;
RTLIL::IdString name;
idict<RTLIL::IdString> avail_parameters;
dict<RTLIL::IdString, RTLIL::Const> parameter_default_values;
dict<RTLIL::IdString, RTLIL::Memory*> memories;
dict<RTLIL::IdString, RTLIL::Process*> processes;
Module();
virtual ~Module();
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, bool mayfail = false);
virtual RTLIL::IdString derive(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Const> ¶meters, const dict<RTLIL::IdString, RTLIL::Module*> &interfaces, const dict<RTLIL::IdString, RTLIL::IdString> &modports, bool mayfail = false);
virtual size_t count_id(const RTLIL::IdString& id);
virtual void expand_interfaces(RTLIL::Design *design, const dict<RTLIL::IdString, RTLIL::Module *> &local_interfaces);
virtual bool reprocess_if_necessary(RTLIL::Design *design);
virtual void sort();
virtual void check();
virtual void optimize();
virtual void makeblackbox();
void connect(const RTLIL::SigSig &conn);
void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs);
void new_connections(const std::vector<RTLIL::SigSig> &new_conn);
const std::vector<RTLIL::SigSig> &connections() const;
std::vector<RTLIL::IdString> ports;
void fixup_ports();
pool<pair<RTLIL::Cell*, RTLIL::IdString>> bufNormQueue;
void bufNormalize();
template<typename T> void rewrite_sigspecs(T &functor);
template<typename T> void rewrite_sigspecs2(T &functor);
void cloneInto(RTLIL::Module *new_mod) const;
virtual RTLIL::Module *clone() const;
bool has_memories() const;
bool has_processes() const;
bool has_memories_warn() const;
bool has_processes_warn() const;
std::vector<RTLIL::Wire*> selected_wires() const;
std::vector<RTLIL::Cell*> selected_cells() const;
template<typename T> bool selected(T *member) const {
return design->selected_member(name, member->name);
}
RTLIL::Wire* wire(const RTLIL::IdString &id) {
auto it = wires_.find(id);
return it == wires_.end() ? nullptr : it->second;
}
RTLIL::Cell* cell(const RTLIL::IdString &id) {
auto it = cells_.find(id);
return it == cells_.end() ? nullptr : it->second;
}
const RTLIL::Wire* wire(const RTLIL::IdString &id) const{
auto it = wires_.find(id);
return it == wires_.end() ? nullptr : it->second;
}
const RTLIL::Cell* cell(const RTLIL::IdString &id) const {
auto it = cells_.find(id);
return it == cells_.end() ? nullptr : it->second;
}
RTLIL::ObjRange<RTLIL::Wire*> wires() { return RTLIL::ObjRange<RTLIL::Wire*>(&wires_, &refcount_wires_); }
RTLIL::ObjRange<RTLIL::Cell*> cells() { return RTLIL::ObjRange<RTLIL::Cell*>(&cells_, &refcount_cells_); }
void add(RTLIL::Binding *binding);
// Removing wires is expensive. If you have to remove wires, remove them all at once.
void remove(const pool<RTLIL::Wire*> &wires);
void remove(RTLIL::Cell *cell);
void remove(RTLIL::Process *process);
void rename(RTLIL::Wire *wire, RTLIL::IdString new_name);
void rename(RTLIL::Cell *cell, RTLIL::IdString new_name);
void rename(RTLIL::IdString old_name, RTLIL::IdString new_name);
void swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2);
void swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2);
RTLIL::IdString uniquify(RTLIL::IdString name);
RTLIL::IdString uniquify(RTLIL::IdString name, int &index);
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* addBuf (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::Cell* addLt (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* addLe (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* addEq (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* addNe (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* addEqx (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* addNex (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* addGe (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* addGt (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* addAdd (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* addSub (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* addMul (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 = "");
// truncating division
RTLIL::Cell* addDiv (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 = "");
// truncating modulo
RTLIL::Cell* addMod (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* addDivFloor (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* addModFloor (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* addPow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::Cell* addFa (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_x, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addLogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed = false, const std::string &src = "");
RTLIL::Cell* addLogicAnd (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* addLogicOr (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* addMux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addPmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addBmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addDemux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addBweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addBwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src = "");
RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src = "");
RTLIL::Cell* addTribuf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addAssert (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addAssume (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addLive (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addFair (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addCover (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const std::string &src = "");
RTLIL::Cell* addEquiv (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::Cell* addSr (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addFf (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addDff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsre (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addAldff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = "");
RTLIL::Cell* addAldffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdff (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdffe (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdffce (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdlatch (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchsr (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addBufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addXorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addXnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addMuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addNmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addAoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addOai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const RTLIL::SigBit &sig_y, const std::string &src = "");
RTLIL::Cell* addSrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
const RTLIL::SigSpec &sig_q, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addFfGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
RTLIL::Cell* addDffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addDffsreGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity = true, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool clk_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool clk_polarity = true, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addAldffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool aload_polarity = true, const std::string &src = "");
RTLIL::Cell* addAldffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
const RTLIL::SigSpec &sig_ad, bool clk_polarity = true, bool en_polarity = true, bool aload_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdffGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value = false, bool clk_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdffeGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addSdffceGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool srst_value = false, bool clk_polarity = true, bool en_polarity = true, bool srst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, const std::string &src = "");
RTLIL::Cell* addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q,
bool arst_value = false, bool en_polarity = true, bool arst_polarity = true, const std::string &src = "");
RTLIL::Cell* addDlatchsrGate (RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr,
RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity = true, bool set_polarity = true, bool clr_polarity = true, const std::string &src = "");
RTLIL::Cell* addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const std::string &src = "");
// The methods without the add* prefix create a cell and an output signal. They return the newly created output signal.
RTLIL::SigSpec Not (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pos (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Buf (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Neg (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec And (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Or (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Xnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceXnor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ReduceBool (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshl (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sshr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shift (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Shiftx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Lt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Le (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eq (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ne (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Eqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Nex (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Ge (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Gt (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Add (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Sub (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mul (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
// truncating division
RTLIL::SigSpec Div (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
// truncating modulo
RTLIL::SigSpec Mod (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec DivFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec ModFloor (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Pow (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool a_signed = false, bool b_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicNot (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicAnd (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec LogicOr (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed = false, const std::string &src = "");
RTLIL::SigSpec Mux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Pmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Bmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Demux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigSpec Bweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const std::string &src = "");
RTLIL::SigSpec Bwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit NandGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit OrGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit NorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit XorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit XnorGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit AndnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit OrnotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
RTLIL::SigBit MuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
RTLIL::SigBit NmuxGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_s, const std::string &src = "");
RTLIL::SigBit Aoi3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
RTLIL::SigBit Oai3Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const std::string &src = "");
RTLIL::SigBit Aoi4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
RTLIL::SigBit Oai4Gate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const RTLIL::SigBit &sig_c, const RTLIL::SigBit &sig_d, const std::string &src = "");
RTLIL::SigSpec Anyconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Anyseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Allconst (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Allseq (RTLIL::IdString name, int width = 1, const std::string &src = "");
RTLIL::SigSpec Initstate (RTLIL::IdString name, const std::string &src = "");
RTLIL::SigSpec SetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = "");
RTLIL::Cell* addSetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const std::string &src = "");
RTLIL::SigSpec GetTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = "");
RTLIL::Cell* addOverwriteTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const std::string &src = "");
RTLIL::SigSpec OriginalTag (RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const std::string &src = "");
RTLIL::SigSpec FutureFF (RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const std::string &src = "");
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Module*> *get_all_modules(void);
#endif
};
RTLIL::CELL
struct RTLIL::Cell : public RTLIL::AttrObject
{
unsigned int hashidx_;
unsigned int hash() const { return hashidx_; }
protected:
// use module->addCell() and module->remove() to create or destroy cells
friend struct RTLIL::Module;
Cell();
~Cell();
public:
// do not simply copy cells
Cell(RTLIL::Cell &other) = delete;
void operator=(RTLIL::Cell &other) = delete;
RTLIL::Module *module;
RTLIL::IdString name;
RTLIL::IdString type;
dict<RTLIL::IdString, RTLIL::SigSpec> connections_;
dict<RTLIL::IdString, RTLIL::Const> parameters;
// access cell ports
bool hasPort(const RTLIL::IdString &portname) const;
void unsetPort(const RTLIL::IdString &portname);
void setPort(const RTLIL::IdString &portname, RTLIL::SigSpec signal);
const RTLIL::SigSpec &getPort(const RTLIL::IdString &portname) const;
const dict<RTLIL::IdString, RTLIL::SigSpec> &connections() const;
// information about cell ports
bool known() const;
bool input(const RTLIL::IdString &portname) const;
bool output(const RTLIL::IdString &portname) const;
// access cell parameters
bool hasParam(const RTLIL::IdString ¶mname) const;
void unsetParam(const RTLIL::IdString ¶mname);
void setParam(const RTLIL::IdString ¶mname, RTLIL::Const value);
const RTLIL::Const &getParam(const RTLIL::IdString ¶mname) const;
void sort();
void check();
void fixup_parameters(bool set_a_signed = false, bool set_b_signed = false);
bool has_keep_attr() const {
return get_bool_attribute(ID::keep) || (module && module->design && module->design->module(type) &&
module->design->module(type)->get_bool_attribute(ID::keep));
}
template<typename T> void rewrite_sigspecs(T &functor);
template<typename T> void rewrite_sigspecs2(T &functor);
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Cell*> *get_all_cells(void);
#endif
bool has_memid() const;
bool is_mem_cell() const;
};
RTLIL::Wire
struct RTLIL::Wire : public RTLIL::AttrObject
{
unsigned int hashidx_;
unsigned int hash() const { return hashidx_; }
protected:
// use module->addWire() and module->remove() to create or destroy wires
friend struct RTLIL::Module;
Wire();
~Wire();
friend struct RTLIL::Design;
friend struct RTLIL::Cell;
friend void RTLIL_BACKEND::dump_wire(std::ostream &f, std::string indent, const RTLIL::Wire *wire);
RTLIL::Cell *driverCell_ = nullptr;
RTLIL::IdString driverPort_;
public:
// do not simply copy wires
Wire(RTLIL::Wire &other) = delete;
void operator=(RTLIL::Wire &other) = delete;
RTLIL::Module *module;
RTLIL::IdString name;
int width, start_offset, port_id;
bool port_input, port_output, upto, is_signed;
RTLIL::Cell *driverCell() const { log_assert(driverCell_); return driverCell_; };
RTLIL::IdString driverPort() const { log_assert(driverCell_); return driverPort_; };
#ifdef WITH_PYTHON
static std::map<unsigned int, RTLIL::Wire*> *get_all_wires(void);
#endif
};
四、核心代码功能
1.passes/opt
opt.cc主要调用如下功能:
1 | opt_expr | 执行表达式优化,包括常量折叠和简单表达式重写。 |
2 | opt_merge | 合并相似的逻辑单元 |
3 | opt_muxtree | 优化多路复用器树。 |
4 | opt_reduce | 简化逻辑表达式。 |
5 | opt_share | 共享逻辑单元 |
6 | opt_dff | 优化触发器 |
7 | opt_clean | 清理设计,移除不必要的元素。 |
2. passes/proc
proc.cc依次调用其他功能:
1 | proc_clean | 清理设计,移除不必要的元素,如未使用的线网和模块。 |
2 | proc_rmdead | 删除死代码,即那些不驱动任何输出的线网或模块,以简化设计 |
3 | proc_prune | |
4 | proc_init | 初始化,为触发器(如 D 触发器)分配初始值,确保设计在复位后有确定的状态。 |
5 | proc_arst | 处理异步复位信号,确保设计能够正确处理复位逻辑。 |
6 | proc_rom | 处理只读存储器(ROM),将其转换为等效的逻辑或存储器结构。 |
7 | proc_mux | 处理多路复用器,将条件语句转换为多路复用逻辑。 |
8 | proc_dlatch | 处理锁存器,将设计中的锁存器转换为等效的逻辑结构。 |
9 | proc_dff | 将过程(processes)中的触发器(flip-flops)提取出来并转换为 D 触发器单元的代码 |
10 | proc_memwr | 处理存储器写入,优化存储器的写入操作,以提高效率和减少资源消耗。 |
11 | opt_expr | 进行常量折叠和简单表达式重写 |
3.opt/opt_ffinv.cc
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2022 Marcelina Kościelnicka <mwk@0x04.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/modtools.h"
#include "kernel/ffinit.h"
#include "kernel/ff.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
//用于处理逻辑电路中的触发器(Flip-Flops, FFs)和逻辑门(如 LUTs 和 非门)的优化
struct OptFfInvWorker
{
int count = 0;
RTLIL::Module *module;
ModIndex index;
FfInitVals initvals;
// Case 1:
// - FF is driven by inverter
// - ... which has no other users
// - all users of FF are LUTs
//如果触发器的 D 输入被一个没有其他使用者的非门驱动,并且所有使用该触发器的逻辑都是查找表(LUTs),则将非门推到触发器的另一边
bool push_d_inv(FfData &ff) {
//它检查触发器的宽度是否为1
log_assert(ff.width == 1);
//检查触发器的 D 输入是否是模块的输入
if (index.query_is_input(ff.sig_d))
return false;
//检查触发器的 D 输入是否是模块的输出
if (index.query_is_output(ff.sig_d))
return false;
//查询 D 输入连接到的所有端口。如果连接的端口数量不是2,函数返回 false
auto d_ports = index.query_ports(ff.sig_d);
if (d_ports.size() != 2)
return false;
Cell *d_inv = nullptr;
//遍历 D 输入连接的端口,识别连接到非门($not 或 $_NOT_)或查找表($lut)。如果找到非门,将其存储在 d_inv 变量中。如果找到其他类型的单元,函数返回 false。
for (auto &port: d_ports) {
if (port.cell == ff.cell && port.port == ID::D)
continue;
if (port.port != ID::Y)
return false;
//识别连接到非门($not 或 $_NOT_)
if (port.cell->type.in(ID($not), ID($_NOT_))) {
// OK
}
//识别连接到或查找表($lut)
else if (port.cell->type.in(ID($lut))) {
if (port.cell->getParam(ID::WIDTH) != 1)
return false;
if (port.cell->getParam(ID::LUT).as_int() != 1)
return false;
} else {
return false;
}
log_assert(d_inv == nullptr);
d_inv = port.cell;
}
if (!d_inv) return false;
//检查触发器的 Q 输出是否是模块的输出。如果是,函数返回 false
if (index.query_is_output(ff.sig_q))
return false;
//查询 Q 输出连接到的所有端口。遍历这些端口,识别连接到非门或查找表的单元,并将它们存储在 q_luts 集合中
auto q_ports = index.query_ports(ff.sig_q);
pool<Cell *> q_luts;
for (auto &port: q_ports) {
if (port.cell == ff.cell && port.port == ID::Q)
continue;
if (port.cell == d_inv)
return false;
if (port.port != ID::A)
return false;
if (!port.cell->type.in(ID($not), ID($_NOT_), ID($lut)))
return false;
q_luts.insert(port.cell);
}
//翻转触发器的复位位
ff.flip_rst_bits({0});
//将触发器的 D 输入信号更新为非门的输入信号,直接扔掉反向器
ff.sig_d = d_inv->getPort(ID::A);
//遍历 q_luts 集合中的每个查找表(LUT),根据需要翻转 LUT 的掩码。
//如果 LUT 的宽度为1 且新掩码为2,则将 LUT 的输出直接连接到触发器的 Q 输出,并从模块中移除 LUT。否则,更新 LUT 的掩码
for (Cell *lut: q_luts) {
if (lut->type == ID($lut)) {
int flip_mask = 0;
SigSpec sig_a = lut->getPort(ID::A);//输入
for (int i = 0; i < GetSize(sig_a); i++) {
//判断lut和inv之间是否有连线
if (index.sigmap(sig_a[i]) == index.sigmap(ff.sig_q[0])) {
flip_mask |= 1 << i;
}
}
Const mask = lut->getParam(ID::LUT);
Const new_mask;
for (int j = 0; j < (1 << GetSize(sig_a)); j++) {
new_mask.bits().push_back(mask[j ^ flip_mask]);
}
if (GetSize(sig_a) == 1 && new_mask.as_int() == 2) {
module->connect(lut->getPort(ID::Y), ff.sig_q);
module->remove(lut);
} else {
lut->setParam(ID::LUT, new_mask);
}
} else {
// it was an inverter
//将lut的Y输出口,连到inv的输出口
module->connect(lut->getPort(ID::Y), ff.sig_q);
//移除lut单元
module->remove(lut);
}
}
//使用 ff.emit() 重新生成触发器
ff.emit();
return true;
}
// Case 2:
// - FF is driven by LUT
// - ... which has no other users
// - FF has one user
// - ... which is an inverter
//如果触发器的 Q 输出被一个没有其他使用者的查找表驱动,并且该查找表只有一个使用者(一个非门),则将非门推到触发器的另一边
bool push_q_inv(FfData &ff) {
if (index.query_is_input(ff.sig_d))
return false;
if (index.query_is_output(ff.sig_d))
return false;
Cell *d_lut = nullptr;
auto d_ports = index.query_ports(ff.sig_d);
if (d_ports.size() != 2)
return false;
for (auto &port: d_ports) {
if (port.cell == ff.cell && port.port == ID::D)
continue;
if (port.port != ID::Y)
return false;
if (!port.cell->type.in(ID($not), ID($_NOT_), ID($lut)))
return false;
log_assert(d_lut == nullptr);
d_lut = port.cell;
}
if (!d_lut) return false;
if (index.query_is_output(ff.sig_q))
return false;
auto q_ports = index.query_ports(ff.sig_q);
if (q_ports.size() != 2)
return false;
Cell *q_inv = nullptr;
for (auto &port: q_ports) {
if (port.cell == ff.cell && port.port == ID::Q)
continue;
if (port.cell == d_lut)
return false;
if (port.port != ID::A)
return false;
if (port.cell->type.in(ID($not), ID($_NOT_))) {
// OK
} else if (port.cell->type.in(ID($lut))) {
if (port.cell->getParam(ID::WIDTH) != 1)
return false;
if (port.cell->getParam(ID::LUT).as_int() != 1)
return false;
} else {
return false;
}
log_assert(q_inv == nullptr);
q_inv = port.cell;
}
if (!q_inv) return false;
ff.flip_rst_bits({0});
ff.sig_q = q_inv->getPort(ID::Y);
module->remove(q_inv);
if (d_lut->type == ID($lut)) {
Const mask = d_lut->getParam(ID::LUT);
Const new_mask;
for (int i = 0; i < GetSize(mask); i++) {
if (mask[i] == State::S0)
new_mask.bits().push_back(State::S1);
else
new_mask.bits().push_back(State::S0);
}
d_lut->setParam(ID::LUT, new_mask);
if (d_lut->getParam(ID::WIDTH) == 1 && new_mask.as_int() == 2) {
module->connect(ff.sig_d, d_lut->getPort(ID::A));
module->remove(d_lut);
}
} else {
// it was an inverter
module->connect(ff.sig_d, d_lut->getPort(ID::A));
module->remove(d_lut);
}
ff.emit();
return true;
}
OptFfInvWorker(RTLIL::Module *module) :
module(module), index(module), initvals(&index.sigmap, module)
{
log("Discovering LUTs.\n");
std::vector<Cell *> ffs;
for (Cell *cell : module->selected_cells())//所有cells
//检查当前单元是否是内置的触发器类型,如果是,则将其添加到 ffs 向量中
if (RTLIL::builtin_ff_cell_types().count(cell->type))
ffs.push_back(cell);
//遍历所有FF
for (Cell *cell : ffs) {
FfData ff(&initvals, cell);
//果触发器有设置/复位(set/reset)功能,则跳过当前触发器
if (ff.has_sr)
continue;
//如果触发器没有时钟信号,则跳过当前触发器
if (!ff.has_clk)
continue;
//如果触发器有异步加载功能,则跳过当前触发器。
if (ff.has_aload)
continue;
//如果触发器的宽度不是1(即不是单比特触发器),则跳过当前触发器。
if (ff.width != 1)
continue;
//尝试将触发器的数据输入(D)端的反相器推入触发器内部,如果成功,则增加 count 计数器
if (push_d_inv(ff)) {
count++;
} else if (push_q_inv(ff)) {
count++;
}
}
}
};
struct OptFfInvPass : public Pass {
OptFfInvPass() : Pass("opt_ffinv", "push inverters through FFs") { }
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" opt_ffinv [selection]\n");
log("\n");
//当 Inverters 可以合并到另一侧的 LUT 时,此通道将 inverters 推到 FF 的另一侧
log("This pass pushes inverters to the other side of a FF when they can be merged\n");
log("into LUTs on the other side.\n");
log("\n");
}
//用于遍历设计中的模块并应用优化
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
log_header(design, "Executing OPT_FFINV pass (push inverters through FFs).\n");
size_t argidx;
//命令参数个数
for (argidx = 1; argidx < args.size(); argidx++)
{
break;
}
//处理额外的命令行参数。
extra_args(args, argidx, design);
int total_count = 0;
for (auto module : design->selected_modules())
{
//对每个模块进行opt_ffinv处理
OptFfInvWorker worker(module);
//处理个数
total_count += worker.count;
}
if (total_count)
//设置一个布尔值,表明优化操作确实做了一些事情
design->scratchpad_set_bool("opt.did_something", true);
log("Pushed %d inverters.\n", total_count);
}
} OptFfInvPass;
PRIVATE_NAMESPACE_END
五、新增功能插件
在使用yosys工具时,如果想新增一些自己的功能,应该怎么办呢?例如要新增一个优化功能,有两种思路,一种是在已有的源码文件中,找一个地方单独写这部分优化代码,在执行源码功能时,就会顺带执行该部分的优化代码。除此之外,还可以自己编写插件,将自己的功能包装成一个单独的工具,这个yosys里给留了具体实施的空间。
例如opt_expr就是一个用于优化的功能插件,自己可以写一个opt_inv.cc的插件,然后编写内容,如下:
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/modtools.h"
USING_YOSYS_NAMESPACE
struct MyOptPass : public Pass {
//插件命令为opt_inv
MyOptPass() : Pass("opt_inv", "my custom optimization pass") { }
void execute(std::vector<std::string> args, RTLIL::Design *design) override {
// 您的优化逻辑
}
} MyOptPass;