将单元格添加到 write_verilog 导致错误
Adding cell to write_verilog causes error
首先,我想说我根本不精通 c++ 或 verilog,所以我在 Yosys 中实现一些东西时遇到了一些问题。
我目前正在寻找一种方法来实现 write_verilog 的简单信息流跟踪方法。我打算实现它的方式是为每个 input/output 等创建一个新的 var。所有操作类型将与简单的 'or's. The doubled variables serve as taint bits. Doubling all the wires was an easy task. However when I try to add a new cell, I run into a '[= 交换31=]std::out_of_range'错误(编辑:就像我再次尝试一样,它似乎是'在内部单元格中发现错误 ' 错误)在转储模块时。由于在调用 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");
也会使我的程序崩溃。
有人可以帮我吗?
以 $ 开头的内部单元格在端口、参数等方面必须遵循特定的约定,空单元格将无法实现。使用 addOr 之类的函数而不是 addCell 来创建它们。
首先,我想说我根本不精通 c++ 或 verilog,所以我在 Yosys 中实现一些东西时遇到了一些问题。
我目前正在寻找一种方法来实现 write_verilog 的简单信息流跟踪方法。我打算实现它的方式是为每个 input/output 等创建一个新的 var。所有操作类型将与简单的 'or's. The doubled variables serve as taint bits. Doubling all the wires was an easy task. However when I try to add a new cell, I run into a '[= 交换31=]std::out_of_range'错误(编辑:就像我再次尝试一样,它似乎是'在内部单元格中发现错误 ' 错误)在转储模块时。由于在调用 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");
也会使我的程序崩溃。
有人可以帮我吗?
以 $ 开头的内部单元格在端口、参数等方面必须遵循特定的约定,空单元格将无法实现。使用 addOr 之类的函数而不是 addCell 来创建它们。