首页
书签
论坛
网盘
邮件
壁纸
影视
在线音乐
更多
直播
统计
个人微博
云笔记
云存储
图片视频
友链
留言
关于
Search
1
文档内容搜索哪家强? 15款文件搜索软件横向评测
13 阅读
2
常见系统部署(1)
11 阅读
3
makfile 知识汇总
8 阅读
4
欢迎使用 Typecho
5 阅读
5
打造Ventoy多功能多系统启动U盘
5 阅读
默认分类
数字电路
芯片后端
模拟电路
芯片验证
原型验证
算法与架构
DFX与量产
windows设置
Linux设置
MacOS设置
移动OS设置
软件方案
登录
Search
标签搜索
python
PyQT
systemverilog
Alist
Docker
cadence
sv
webdav
vscode
cpp
upf
ESL
TLM
浏览器
virtuoso
tsmc8rf
TSMC
CXL
PCIE
Yosys
bennyhe
累计撰写
46
篇文章
累计收到
8
条评论
首页
栏目
默认分类
数字电路
芯片后端
模拟电路
芯片验证
原型验证
算法与架构
DFX与量产
windows设置
Linux设置
MacOS设置
移动OS设置
软件方案
页面
书签
论坛
网盘
邮件
壁纸
影视
在线音乐
直播
统计
个人微博
云笔记
云存储
图片视频
友链
留言
关于
搜索到
1
篇与
的结果
2025-05-27
Yosys工具概述
对于一个新工具,以及学习源码,可以让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 install2.使用//读取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 的项目结构大致如下:内核(Kernel)包含 Yosys 的核心功能,如内存管理、日志记录、基本数据类型和算法等。前端(Frontends)用于读取和解析不同的硬件描述语言,如 Verilog、VHDL、SystemVerilog 等。将 HDL 代码转换成 Yosys 内部表示(AST - Abstract Syntax Tree)。后端(Backends)用于将 Yosys 内部表示转换成不同的网表格式,如 EDIF、Bels、Netlists 等。支持多种不同的技术目标,如 Xilinx、Altera/Intel、Lattice 等。优化(Optimizations)包含一系列优化传递(passes),用于改进和简化内部表示。优化包括但不限于常数传播、死代码消除、代数简化、查找表优化等。库(Libraries)提供了一系列预定义的逻辑单元(如 LUTs、Flip-Flops、内存单元等)和宏单元。用于生成特定功能的标准单元和宏。工具(Tools)提供了一系列用于调试、分析和转换设计的工具。包括查看器、测试生成器、等价性检查器等。测试(Tests)包含了用于测试 Yosys 功能的自动化测试套件。用于确保 Yosys 的功能正确性和稳定性。文档(Documentation)提供了用户手册、内部 API 文档和开发文档。帮助用户和开发者理解如何使用和贡献 Yosys。脚本和示例(Scripts and Examples)提供了一系列示例和脚本,展示如何使用 Yosys 进行不同的合成和优化任务。用于教学和作为最佳实践的参考。第三方集成(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::Designstruct 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::Modelstruct 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::CELLstruct 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::Wirestruct 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/optopt.cc主要调用如下功能:1opt_expr执行表达式优化,包括常量折叠和简单表达式重写。2opt_merge合并相似的逻辑单元3opt_muxtree优化多路复用器树。4opt_reduce简化逻辑表达式。5opt_share共享逻辑单元6opt_dff优化触发器7opt_clean清理设计,移除不必要的元素。passes/procproc.cc依次调用其他功能:1proc_clean清理设计,移除不必要的元素,如未使用的线网和模块。2proc_rmdead删除死代码,即那些不驱动任何输出的线网或模块,以简化设计3proc_prune4proc_init初始化,为触发器(如 D 触发器)分配初始值,确保设计在复位后有确定的状态。5proc_arst处理异步复位信号,确保设计能够正确处理复位逻辑。6proc_rom处理只读存储器(ROM),将其转换为等效的逻辑或存储器结构。7proc_mux处理多路复用器,将条件语句转换为多路复用逻辑。8proc_dlatch处理锁存器,将设计中的锁存器转换为等效的逻辑结构。9proc_dff将过程(processes)中的触发器(flip-flops)提取出来并转换为 D 触发器单元的代码10proc_memwr处理存储器写入,优化存储器的写入操作,以提高效率和减少资源消耗。11opt_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;———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/ljjjjjjjjjjj/article/details/144077123在 Yosys 中检测组合逻辑环(Combinational Loop)可以通过以下步骤实现。组合逻辑环通常指电路中存在无寄存器隔离的反馈路径,可能导致不可预测的振荡或亚稳态问题。以下是详细操作流程:基本流程:使用 check 命令Yosys 内置的 check 命令可以检测组合环,但需要先将设计转换为逻辑网表。tcl复制读取 RTL 文件(例如 Verilog)read_verilog design.v转换为逻辑网表(综合并展开进程)synth -noabcproc; opt; clean# 检查组合环check -assert # 检测组合环和其他潜在问题输出示例:log复制Checking module \top... Found combinational loop in logic: Signal: \a -> \b -> \c -> \aERROR: Found 1 combinational loops!说明:check 命令会自动报告组合环路径,但可能需要结合其他步骤准确定位。使用 show 命令可视化环路通过生成电路图定位环路的具体路径。tcl复制读取并处理设计read_verilog design.vhierarchy -checkproc; opt; clean# 生成逻辑图并导出为 .dot 文件show -prefix comb_loop -format dot# 使用 Graphviz 查看环路system "xdot comb_loop.dot"说明:oshow 命令生成电路的图形化表示(需要安装 Graphviz)。o在生成的 .dot 文件中,反馈路径会以环路形式呈现。详细分析:通过 lsg 命令生成逻辑结构图Yosys 的 lsg(Logic Signal Graph)命令可以生成信号依赖图,帮助分析环路。tcl复制read_verilog design.vproc; opt; clean# 生成逻辑信号图lsg -output comb_loop.log检查生成的日志文件!cat comb_loop.log | grep "loop"输出示例:log复制Found loop: a -> b -> c -> a说明:lsg 会列出所有信号依赖关系,从中筛选环路。使用 Formal Verification 检测环路通过形式化验证工具(如 SymbiYosys)强制检测组合环路。步骤 1:创建验证脚本 comb_loop.sbyini复制[options]mode prove[engines]smtbmc[script]read_verilog -formal design.vprep -top top_module断言不存在组合环assert -no-loop[files]design.v步骤 2:运行验证bash复制sby -f comb_loop.sby说明:若存在组合环,形式化引擎会返回反例路径。组合环修复示例假设检测到环路路径 a -> b -> c -> a,需修改 RTL 代码打破环路。原始代码(存在环路) :verilog复制module top (input x, output y); wire a, b, c; assign a = x | c; assign b = a & ~c; assign c = b; assign y = c;endmodule修复代码(插入寄存器) :verilog复制module top (input clk, input x, output reg y); wire a, b, c; reg c_reg; always @(posedge clk) begin c_reg <= b; // 插入寄存器打破环路 end assign a = x | c_reg; assign b = a & ~c_reg; assign c = b; assign y = c_reg;endmodule进阶调试:自定义组合环检测脚本编写 Tcl 脚本遍历所有信号依赖关系,手动检测环路。read_verilog design.vproc; opt; clean # 遍历所有信号 foreach net [lsort -unique [list_nets]] { set drivers [get_drivers $net] set loads [get_loads $net] if {[llength $drivers] > 0 && [llength $loads] > 0} { puts "Signal: $net" puts " Drivers: $drivers" puts " Loads: $loads" # 检查驱动和负载是否形成环路 if {[regexp $net $drivers] || [regexp $net $loads]} { puts "ERROR: Combinational loop detected on signal $net!" } } }常见问题解决误报/漏报:check 命令可能因未综合完整逻辑而漏报,建议先运行 synth。复杂环路:多级环路需通过 show 或 lsg 图形化分析。工具依赖:可视化需安装 Graphviz,验证需 SymbiYosys。通过上述方法,可以高效定位和修复 RTL 设计中的组合逻辑环问题。
2025年05月27日
1 阅读
0 评论
0 点赞