将单元格添加到write_verilog会导致错误

时间:2020-10-26 17:19:14

标签: yosys

首先,我想说我一点都不精通c ++或verilog,因此在Yosys中实现功能时会遇到一些问题。

我目前正在寻找一种对 write_verilog 实施幼稚的信息流跟踪方法的方法。我打算实现它的方式是为每个输入/输出等创建一个新的var。所有操作类型都将与简单的''s交换。加倍的变量用作污点位。将所有导线加倍是一项容易的任务。但是,当我尝试添加新单元格时,遇到了“ std :: out_of_range ”错误(编辑:就像我再次尝试一样,它似乎是“ Found错误”在内部单元中出现错误),然后转储该模块。由于在调用dump_module函数时发生错误,因此我认为模块模型已损坏。

我所做的是,对于模块中的每条导线,我都添加了相同的导线,只是在其名称后附加了'_ taint ',其属性与原始导线相同,我基本上使用了/passes/add.cc中add_wire的略微修改版本。

// adding taint wires

void attach_ift(RTLIL::Module *module, bool precise)
{

    auto wires = module->wires_;
    for (auto &wire : wires){
        std::string ift_wire_name = RTLIL::id2cstr(wire.second->name) + std::string("_taint");
        add_wire(module, ift_wire_name, 1, wire.second->port_input, wire.second->port_output);
    }

    //add cells and connections

}

static void add_wire(RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output)
{
    RTLIL::Wire *wire = nullptr;
    name = RTLIL::escape_id(name);

    if (module->count_id(name) != 0)
    {
        wire = module->wire(name);

        if (wire != nullptr && wire->width != width)
            wire = nullptr;

        if (wire != nullptr && wire->port_input != flag_input)
            wire = nullptr;

        if (wire != nullptr && wire->port_output != flag_output)
            wire = nullptr;

        if (wire == nullptr)
            log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str());

        log("Module %s already has such an object.\n", module->name.c_str());
    }
    else
    {
        wire = module->addWire(name, width);
        wire->port_input = flag_input;
        wire->port_output = flag_output;

        if (flag_input || flag_output) {
            module->fixup_ports();
        }

        log("Added wire %s to module %s.\n", name.c_str(), module->name.c_str());
    }
}

这很好。

现在要解决细胞问题。如何正确添加单元格?
一开始我尝试使用

//add cells

void attach_ift(RTLIL::Module *module, bool precise)
{
    // add wires

    auto cells = module->cells_;
    for (auto &cell : cells){
        std::string ift_cell_name = cell.first.c_str() +std::string("_taint");
        auto cell_ = cell.second;
        add_cell(module, ift_cell_name, cell_);
    }

    // add connections
}

static void add_wire(RTLIL::Module *module, std::string name, int width, bool flag_input, bool flag_output)
{
    RTLIL::Wire *wire = nullptr;
    name = RTLIL::escape_id(name);

    if (module->count_id(name) != 0)
    {
        wire = module->wire(name);

        if (wire != nullptr && wire->width != width)
            wire = nullptr;

        if (wire != nullptr && wire->port_input != flag_input)
            wire = nullptr;

        if (wire != nullptr && wire->port_output != flag_output)
            wire = nullptr;

        if (wire == nullptr)
            log_cmd_error("Found incompatible object with same name in module %s!\n", module->name.c_str());

        log("Module %s already has such an object.\n", module->name.c_str());
    }
    else
    {
        auto ift_cell = module->addCell(name, "$or");
        auto cons = cell->connections();
        for (auto con : cons){

            auto wire_ = cell->getPort(con.first).as_wire();
            auto taint_wire_name = string(wire_->name.c_str()) + "_taint";
            auto wire = module->wire(taint_wire_name);
            ift_cell->setPort(taint_wire_name, wire);
        }

        log("Added cell %s to module %s.\n", name.c_str(), module->name.c_str());
    }
}

我在转储模块之前附加了ift函数,因此在这一点上

    void execute(std::ostream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override
    {

        // some code

        for (auto module : design->modules()) {

            //more code

            log("Attaching ift annotations to `%s'.\n", module->name.c_str());
            attach_ift(module, precise);

            log("Dumping module `%s'.\n", module->name.c_str());
            dump_module(*f, "", module);
        }

        auto_name_map.clear();
        reg_wires.clear();
    }

然后我以为我可能无法设置正确的连接。 但是,即使只是添加一个简单的module->addCell("$dummyName", "$or");也会使我的程序崩溃。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

以$开头的内部单元格具有特定的约定,它们必须遵循端口,参数等方面的规定,并且空单元格将无法实现。使用addOr等函数而不是addCell来创建这些函数。