From 7b646101e936cacd20938c20ddfbaa63ee268fb2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 20:57:13 -0700 Subject: Only xaig if GetSize(output_bits) > 0 --- backends/aiger/xaiger.cc | 296 ++++++++++++++++++++++++----------------------- 1 file changed, 149 insertions(+), 147 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..c1ab59600 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,175 +575,177 @@ struct XAigerWriter f << "c"; - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - std::stringstream h_buffer; - auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); - write_h_buffer(1); - log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); - write_h_buffer(input_bits.size() + ci_bits.size()); - log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); - write_h_buffer(output_bits.size() + GetSize(co_bits)); - log_debug("piNum = %d\n", GetSize(input_bits)); - write_h_buffer(input_bits.size()); - log_debug("poNum = %d\n", GetSize(output_bits)); - write_h_buffer(output_bits.size()); - log_debug("boxNum = %d\n", GetSize(box_list)); - write_h_buffer(box_list.size()); - - auto write_buffer_float = [](std::stringstream &buffer, float f32) { - buffer.write(reinterpret_cast(&f32), sizeof(f32)); - }; - std::stringstream i_buffer; - auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); - for (auto bit : input_bits) - write_i_buffer(arrival_times.at(bit, 0)); - //std::stringstream o_buffer; - //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); - //for (auto bit : output_bits) - // write_o_buffer(0); - - if (!box_list.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); - log_assert(holes_module); - - int port_id = 1; - int box_count = 0; - for (auto cell : box_list) { - RTLIL::Module* box_module = module->design->module(cell->type); - int box_inputs = 0, box_outputs = 0; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - } + if (GetSize(output_bits) > 0) { + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + std::stringstream h_buffer; + auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); + write_h_buffer(1); + log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); + write_h_buffer(input_bits.size() + ci_bits.size()); + log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); + write_h_buffer(output_bits.size() + GetSize(co_bits)); + log_debug("piNum = %d\n", GetSize(input_bits)); + write_h_buffer(input_bits.size()); + log_debug("poNum = %d\n", GetSize(output_bits)); + write_h_buffer(output_bits.size()); + log_debug("boxNum = %d\n", GetSize(box_list)); + write_h_buffer(box_list.size()); + + auto write_buffer_float = [](std::stringstream &buffer, float f32) { + buffer.write(reinterpret_cast(&f32), sizeof(f32)); + }; + std::stringstream i_buffer; + auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); + for (auto bit : input_bits) + write_i_buffer(arrival_times.at(bit, 0)); + //std::stringstream o_buffer; + //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); + //for (auto bit : output_bits) + // write_o_buffer(0); + + if (!box_list.empty()) { + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + log_assert(holes_module); + + int port_id = 1; + int box_count = 0; + for (auto cell : box_list) { + RTLIL::Module* box_module = module->design->module(cell->type); + int box_inputs = 0, box_outputs = 0; + Cell *holes_cell = nullptr; + if (box_module->get_bool_attribute("\\whitebox")) { + holes_cell = holes_module->addCell(cell->name, cell->type); + holes_cell->parameters = cell->parameters; + } - // NB: Assume box_module->ports are sorted alphabetically - // (as RTLIL::Module::fixup_ports() would do) - for (const auto &port_name : box_module->ports) { - RTLIL::Wire *w = box_module->wire(port_name); - log_assert(w); - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; - if (w->port_input) { - for (int i = 0; i < GetSize(w); i++) { - box_inputs++; - holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; + // NB: Assume box_module->ports are sorted alphabetically + // (as RTLIL::Module::fixup_ports() would do) + for (const auto &port_name : box_module->ports) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + RTLIL::Wire *holes_wire; + RTLIL::SigSpec port_wire; + if (w->port_input) { + for (int i = 0; i < GetSize(w); i++) { + box_inputs++; + holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + } + if (holes_cell) + port_wire.append(holes_wire); + } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); + } + if (w->port_output) { + box_outputs += GetSize(w); + for (int i = 0; i < GetSize(w); i++) { + if (GetSize(w) == 1) + holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + else + holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); + holes_wire->port_output = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); + if (holes_cell) + port_wire.append(holes_wire); + else + holes_module->connect(holes_wire, State::S0); } - if (holes_cell) - port_wire.append(holes_wire); + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); } - if (w->port_output) { - box_outputs += GetSize(w); - for (int i = 0; i < GetSize(w); i++) { - if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); - else - holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); - holes_wire->port_output = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_wire.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); - } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } - } - write_h_buffer(box_inputs); - write_h_buffer(box_outputs); - write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); - write_h_buffer(box_count++); - } + write_h_buffer(box_inputs); + write_h_buffer(box_outputs); + write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); + write_h_buffer(box_count++); + } - std::stringstream r_buffer; - auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); - write_r_buffer(0); - f << "r"; - std::string buffer_str = r_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); + std::stringstream r_buffer; + auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); + write_r_buffer(0); + f << "r"; + std::string buffer_str = r_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); - if (holes_module) { - log_push(); + if (holes_module) { + log_push(); - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); + // NB: fixup_ports() will sort ports by name + //holes_module->fixup_ports(); + holes_module->check(); - holes_module->design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = holes_module->design->selection_stack.back(); - sel.select(holes_module); + holes_module->design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = holes_module->design->selection_stack.back(); + sel.select(holes_module); - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); + // TODO: Should not need to opt_merge if we only instantiate + // each box type once... + Pass::call(holes_module->design, "opt_merge -share_all"); - Pass::call(holes_module->design, "flatten -wb"); + Pass::call(holes_module->design, "flatten -wb"); - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call - Pass::call(holes_module->design, "techmap"); - Pass::call(holes_module->design, "aigmap"); - for (auto cell : holes_module->cells()) - if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, + // instead of per write_xaiger call + Pass::call(holes_module->design, "techmap"); + Pass::call(holes_module->design, "aigmap"); + for (auto cell : holes_module->cells()) + if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - holes_module->design->selection_stack.pop_back(); + holes_module->design->selection_stack.pop_back(); - // Move into a new (temporary) design so that "clean" will only - // operate (and run checks on) this one module - RTLIL::Design *holes_design = new RTLIL::Design; - holes_module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - Pass::call(holes_design, "clean -purge"); + // Move into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *holes_design = new RTLIL::Design; + holes_module->design->modules_.erase(holes_module->name); + holes_design->add(holes_module); + Pass::call(holes_design, "clean -purge"); - std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); - writer.write_aiger(a_buffer, false /*ascii_mode*/); + std::stringstream a_buffer; + XAigerWriter writer(holes_module, true /* holes_mode */); + writer.write_aiger(a_buffer, false /*ascii_mode*/); - delete holes_design; + delete holes_design; - f << "a"; - std::string buffer_str = a_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); + f << "a"; + std::string buffer_str = a_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); - log_pop(); + log_pop(); + } } - } - f << "h"; - std::string buffer_str = h_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); - - f << "i"; - buffer_str = i_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); - //f << "o"; - //buffer_str = o_buffer.str(); - //buffer_size_be = to_big_endian(buffer_str.size()); - //f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - //f.write(buffer_str.data(), buffer_str.size()); + f << "h"; + std::string buffer_str = h_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + + f << "i"; + buffer_str = i_buffer.str(); + buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + //f << "o"; + //buffer_str = o_buffer.str(); + //buffer_size_be = to_big_endian(buffer_str.size()); + //f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + //f.write(buffer_str.data(), buffer_str.size()); + } f << stringf("Generated by %s\n", yosys_version_str); } -- cgit v1.2.3 From 4d123b7638b7036da70de169d16d2ae21b89b8e2 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 21:22:38 -0700 Subject: Revert "Only xaig if GetSize(output_bits) > 0" This reverts commit 7b646101e936cacd20938c20ddfbaa63ee268fb2. --- backends/aiger/xaiger.cc | 296 +++++++++++++++++++++++------------------------ 1 file changed, 147 insertions(+), 149 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index c1ab59600..0d69e0f13 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,178 +575,176 @@ struct XAigerWriter f << "c"; - if (GetSize(output_bits) > 0) { - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - std::stringstream h_buffer; - auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); - write_h_buffer(1); - log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); - write_h_buffer(input_bits.size() + ci_bits.size()); - log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); - write_h_buffer(output_bits.size() + GetSize(co_bits)); - log_debug("piNum = %d\n", GetSize(input_bits)); - write_h_buffer(input_bits.size()); - log_debug("poNum = %d\n", GetSize(output_bits)); - write_h_buffer(output_bits.size()); - log_debug("boxNum = %d\n", GetSize(box_list)); - write_h_buffer(box_list.size()); - - auto write_buffer_float = [](std::stringstream &buffer, float f32) { - buffer.write(reinterpret_cast(&f32), sizeof(f32)); - }; - std::stringstream i_buffer; - auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); - for (auto bit : input_bits) - write_i_buffer(arrival_times.at(bit, 0)); - //std::stringstream o_buffer; - //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); - //for (auto bit : output_bits) - // write_o_buffer(0); - - if (!box_list.empty()) { - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); - log_assert(holes_module); - - int port_id = 1; - int box_count = 0; - for (auto cell : box_list) { - RTLIL::Module* box_module = module->design->module(cell->type); - int box_inputs = 0, box_outputs = 0; - Cell *holes_cell = nullptr; - if (box_module->get_bool_attribute("\\whitebox")) { - holes_cell = holes_module->addCell(cell->name, cell->type); - holes_cell->parameters = cell->parameters; - } + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + std::stringstream h_buffer; + auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); + write_h_buffer(1); + log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); + write_h_buffer(input_bits.size() + ci_bits.size()); + log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); + write_h_buffer(output_bits.size() + GetSize(co_bits)); + log_debug("piNum = %d\n", GetSize(input_bits)); + write_h_buffer(input_bits.size()); + log_debug("poNum = %d\n", GetSize(output_bits)); + write_h_buffer(output_bits.size()); + log_debug("boxNum = %d\n", GetSize(box_list)); + write_h_buffer(box_list.size()); + + auto write_buffer_float = [](std::stringstream &buffer, float f32) { + buffer.write(reinterpret_cast(&f32), sizeof(f32)); + }; + std::stringstream i_buffer; + auto write_i_buffer = std::bind(write_buffer_float, std::ref(i_buffer), std::placeholders::_1); + for (auto bit : input_bits) + write_i_buffer(arrival_times.at(bit, 0)); + //std::stringstream o_buffer; + //auto write_o_buffer = std::bind(write_buffer_float, std::ref(o_buffer), std::placeholders::_1); + //for (auto bit : output_bits) + // write_o_buffer(0); + + if (!box_list.empty()) { + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); + log_assert(holes_module); + + int port_id = 1; + int box_count = 0; + for (auto cell : box_list) { + RTLIL::Module* box_module = module->design->module(cell->type); + int box_inputs = 0, box_outputs = 0; + Cell *holes_cell = nullptr; + if (box_module->get_bool_attribute("\\whitebox")) { + holes_cell = holes_module->addCell(cell->name, cell->type); + holes_cell->parameters = cell->parameters; + } - // NB: Assume box_module->ports are sorted alphabetically - // (as RTLIL::Module::fixup_ports() would do) - for (const auto &port_name : box_module->ports) { - RTLIL::Wire *w = box_module->wire(port_name); - log_assert(w); - RTLIL::Wire *holes_wire; - RTLIL::SigSpec port_wire; - if (w->port_input) { - for (int i = 0; i < GetSize(w); i++) { - box_inputs++; - holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); - if (!holes_wire) { - holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); - holes_wire->port_input = true; - holes_wire->port_id = port_id++; - holes_module->ports.push_back(holes_wire->name); - } - if (holes_cell) - port_wire.append(holes_wire); - } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); - } - if (w->port_output) { - box_outputs += GetSize(w); - for (int i = 0; i < GetSize(w); i++) { - if (GetSize(w) == 1) - holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); - else - holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); - holes_wire->port_output = true; + // NB: Assume box_module->ports are sorted alphabetically + // (as RTLIL::Module::fixup_ports() would do) + for (const auto &port_name : box_module->ports) { + RTLIL::Wire *w = box_module->wire(port_name); + log_assert(w); + RTLIL::Wire *holes_wire; + RTLIL::SigSpec port_wire; + if (w->port_input) { + for (int i = 0; i < GetSize(w); i++) { + box_inputs++; + holes_wire = holes_module->wire(stringf("\\i%d", box_inputs)); + if (!holes_wire) { + holes_wire = holes_module->addWire(stringf("\\i%d", box_inputs)); + holes_wire->port_input = true; holes_wire->port_id = port_id++; holes_module->ports.push_back(holes_wire->name); - if (holes_cell) - port_wire.append(holes_wire); - else - holes_module->connect(holes_wire, State::S0); } - if (!port_wire.empty()) - holes_cell->setPort(w->name, port_wire); + if (holes_cell) + port_wire.append(holes_wire); } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); + } + if (w->port_output) { + box_outputs += GetSize(w); + for (int i = 0; i < GetSize(w); i++) { + if (GetSize(w) == 1) + holes_wire = holes_module->addWire(stringf("%s.%s", cell->name.c_str(), w->name.c_str())); + else + holes_wire = holes_module->addWire(stringf("%s.%s[%d]", cell->name.c_str(), w->name.c_str(), i)); + holes_wire->port_output = true; + holes_wire->port_id = port_id++; + holes_module->ports.push_back(holes_wire->name); + if (holes_cell) + port_wire.append(holes_wire); + else + holes_module->connect(holes_wire, State::S0); + } + if (!port_wire.empty()) + holes_cell->setPort(w->name, port_wire); } - - write_h_buffer(box_inputs); - write_h_buffer(box_outputs); - write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); - write_h_buffer(box_count++); } - std::stringstream r_buffer; - auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); - write_r_buffer(0); - f << "r"; - std::string buffer_str = r_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); - - if (holes_module) { - log_push(); + write_h_buffer(box_inputs); + write_h_buffer(box_outputs); + write_h_buffer(box_module->attributes.at("\\abc_box_id").as_int()); + write_h_buffer(box_count++); + } - // NB: fixup_ports() will sort ports by name - //holes_module->fixup_ports(); - holes_module->check(); + std::stringstream r_buffer; + auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); + write_r_buffer(0); + f << "r"; + std::string buffer_str = r_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); - holes_module->design->selection_stack.emplace_back(false); - RTLIL::Selection& sel = holes_module->design->selection_stack.back(); - sel.select(holes_module); + if (holes_module) { + log_push(); - // TODO: Should not need to opt_merge if we only instantiate - // each box type once... - Pass::call(holes_module->design, "opt_merge -share_all"); + // NB: fixup_ports() will sort ports by name + //holes_module->fixup_ports(); + holes_module->check(); - Pass::call(holes_module->design, "flatten -wb"); + holes_module->design->selection_stack.emplace_back(false); + RTLIL::Selection& sel = holes_module->design->selection_stack.back(); + sel.select(holes_module); - // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, - // instead of per write_xaiger call - Pass::call(holes_module->design, "techmap"); - Pass::call(holes_module->design, "aigmap"); - for (auto cell : holes_module->cells()) - if (!cell->type.in("$_NOT_", "$_AND_")) - log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); + // TODO: Should not need to opt_merge if we only instantiate + // each box type once... + Pass::call(holes_module->design, "opt_merge -share_all"); - holes_module->design->selection_stack.pop_back(); + Pass::call(holes_module->design, "flatten -wb"); - // Move into a new (temporary) design so that "clean" will only - // operate (and run checks on) this one module - RTLIL::Design *holes_design = new RTLIL::Design; - holes_module->design->modules_.erase(holes_module->name); - holes_design->add(holes_module); - Pass::call(holes_design, "clean -purge"); + // TODO: Should techmap/aigmap/check all lib_whitebox-es just once, + // instead of per write_xaiger call + Pass::call(holes_module->design, "techmap"); + Pass::call(holes_module->design, "aigmap"); + for (auto cell : holes_module->cells()) + if (!cell->type.in("$_NOT_", "$_AND_")) + log_error("Whitebox contents cannot be represented as AIG. Please verify whiteboxes are synthesisable.\n"); - std::stringstream a_buffer; - XAigerWriter writer(holes_module, true /* holes_mode */); - writer.write_aiger(a_buffer, false /*ascii_mode*/); + holes_module->design->selection_stack.pop_back(); - delete holes_design; + // Move into a new (temporary) design so that "clean" will only + // operate (and run checks on) this one module + RTLIL::Design *holes_design = new RTLIL::Design; + holes_module->design->modules_.erase(holes_module->name); + holes_design->add(holes_module); + Pass::call(holes_design, "clean -purge"); - f << "a"; - std::string buffer_str = a_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); + std::stringstream a_buffer; + XAigerWriter writer(holes_module, true /* holes_mode */); + writer.write_aiger(a_buffer, false /*ascii_mode*/); - log_pop(); - } - } + delete holes_design; - f << "h"; - std::string buffer_str = h_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); + f << "a"; + std::string buffer_str = a_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); - f << "i"; - buffer_str = i_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); - //f << "o"; - //buffer_str = o_buffer.str(); - //buffer_size_be = to_big_endian(buffer_str.size()); - //f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - //f.write(buffer_str.data(), buffer_str.size()); + log_pop(); + } } + f << "h"; + std::string buffer_str = h_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + + f << "i"; + buffer_str = i_buffer.str(); + buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + //f << "o"; + //buffer_str = o_buffer.str(); + //buffer_size_be = to_big_endian(buffer_str.size()); + //f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + //f.write(buffer_str.data(), buffer_str.size()); + f << stringf("Generated by %s\n", yosys_version_str); } -- cgit v1.2.3 From 8182cb9d91555d5be52abbfeeb5d22af05342d8a Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 20 Aug 2019 21:30:16 -0700 Subject: Fix omode which inserts an output if none exists (otherwise abc9 breaks) --- backends/aiger/xaiger.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..8c8ff2f7e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -504,16 +504,16 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } + if (output_bits.empty()) { + output_bits.insert(State::S0); + omode = true; + } + for (auto bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } - if (output_bits.empty()) { - aig_o++; - aig_outputs.push_back(0); - omode = true; - } } void write_aiger(std::ostream &f, bool ascii_mode) @@ -575,6 +575,7 @@ struct XAigerWriter f << "c"; + log_assert(!output_bits.empty()); auto write_buffer = [](std::stringstream &buffer, int i32) { int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); @@ -796,11 +797,11 @@ struct XAigerWriter f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); output_lines.sort(); + if (omode) + output_lines[State::S0] = "output 0 0 $__dummy__\n"; for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); - if (omode && output_bits.empty()) - f << "output " << output_lines.size() << " 0 $__dummy__\n"; wire_lines.sort(); for (auto &it : wire_lines) -- cgit v1.2.3 From 8f0c1232d7c511a6473f4581e4c27a90088cedb7 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 11:29:40 -0700 Subject: Revert "Fix omode which inserts an output if none exists (otherwise abc9 breaks)" This reverts commit 8182cb9d91555d5be52abbfeeb5d22af05342d8a. --- backends/aiger/xaiger.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8c8ff2f7e..0d69e0f13 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -504,16 +504,16 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } - if (output_bits.empty()) { - output_bits.insert(State::S0); - omode = true; - } - for (auto bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } + if (output_bits.empty()) { + aig_o++; + aig_outputs.push_back(0); + omode = true; + } } void write_aiger(std::ostream &f, bool ascii_mode) @@ -575,7 +575,6 @@ struct XAigerWriter f << "c"; - log_assert(!output_bits.empty()); auto write_buffer = [](std::stringstream &buffer, int i32) { int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); @@ -797,11 +796,11 @@ struct XAigerWriter f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); output_lines.sort(); - if (omode) - output_lines[State::S0] = "output 0 0 $__dummy__\n"; for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); + if (omode && output_bits.empty()) + f << "output " << output_lines.size() << " 0 $__dummy__\n"; wire_lines.sort(); for (auto &it : wire_lines) -- cgit v1.2.3 From 399ac760ff2bf4a7d438ed388820e7bfb511de6b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 21 Aug 2019 11:31:18 -0700 Subject: Output "h" extension only if boxes --- backends/aiger/xaiger.cc | 60 ++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 28 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..b66706ffa 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,24 +575,6 @@ struct XAigerWriter f << "c"; - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - std::stringstream h_buffer; - auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); - write_h_buffer(1); - log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); - write_h_buffer(input_bits.size() + ci_bits.size()); - log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); - write_h_buffer(output_bits.size() + GetSize(co_bits)); - log_debug("piNum = %d\n", GetSize(input_bits)); - write_h_buffer(input_bits.size()); - log_debug("poNum = %d\n", GetSize(output_bits)); - write_h_buffer(output_bits.size()); - log_debug("boxNum = %d\n", GetSize(box_list)); - write_h_buffer(box_list.size()); - auto write_buffer_float = [](std::stringstream &buffer, float f32) { buffer.write(reinterpret_cast(&f32), sizeof(f32)); }; @@ -606,6 +588,24 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty()) { + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + std::stringstream h_buffer; + auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); + write_h_buffer(1); + log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); + write_h_buffer(input_bits.size() + ci_bits.size()); + log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); + write_h_buffer(output_bits.size() + GetSize(co_bits)); + log_debug("piNum = %d\n", GetSize(input_bits)); + write_h_buffer(input_bits.size()); + log_debug("poNum = %d\n", GetSize(output_bits)); + write_h_buffer(output_bits.size()); + log_debug("boxNum = %d\n", GetSize(box_list)); + write_h_buffer(box_list.size()); + RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); @@ -669,12 +669,18 @@ struct XAigerWriter write_h_buffer(box_count++); } + f << "h"; + std::string buffer_str = h_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); + std::stringstream r_buffer; auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); write_r_buffer(0); f << "r"; - std::string buffer_str = r_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); + buffer_str = r_buffer.str(); + buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); @@ -727,16 +733,14 @@ struct XAigerWriter log_pop(); } } - - f << "h"; - std::string buffer_str = h_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); + else { + log_debug("piNum = %d\n", GetSize(input_bits)); + log_debug("poNum = %d\n", GetSize(output_bits)); + } f << "i"; - buffer_str = i_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); + std::string buffer_str = i_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); //f << "o"; -- cgit v1.2.3 From 082a01954b95f50cb0ab1b2a1105c06391c0b1b4 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 17:30:54 -0700 Subject: Revert "Output "h" extension only if boxes" This reverts commit 399ac760ff2bf4a7d438ed388820e7bfb511de6b. --- backends/aiger/xaiger.cc | 60 ++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index b66706ffa..0d69e0f13 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -575,6 +575,24 @@ struct XAigerWriter f << "c"; + auto write_buffer = [](std::stringstream &buffer, int i32) { + int32_t i32_be = to_big_endian(i32); + buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); + }; + std::stringstream h_buffer; + auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); + write_h_buffer(1); + log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); + write_h_buffer(input_bits.size() + ci_bits.size()); + log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); + write_h_buffer(output_bits.size() + GetSize(co_bits)); + log_debug("piNum = %d\n", GetSize(input_bits)); + write_h_buffer(input_bits.size()); + log_debug("poNum = %d\n", GetSize(output_bits)); + write_h_buffer(output_bits.size()); + log_debug("boxNum = %d\n", GetSize(box_list)); + write_h_buffer(box_list.size()); + auto write_buffer_float = [](std::stringstream &buffer, float f32) { buffer.write(reinterpret_cast(&f32), sizeof(f32)); }; @@ -588,24 +606,6 @@ struct XAigerWriter // write_o_buffer(0); if (!box_list.empty()) { - auto write_buffer = [](std::stringstream &buffer, int i32) { - int32_t i32_be = to_big_endian(i32); - buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); - }; - std::stringstream h_buffer; - auto write_h_buffer = std::bind(write_buffer, std::ref(h_buffer), std::placeholders::_1); - write_h_buffer(1); - log_debug("ciNum = %d\n", GetSize(input_bits) + GetSize(ci_bits)); - write_h_buffer(input_bits.size() + ci_bits.size()); - log_debug("coNum = %d\n", GetSize(output_bits) + GetSize(co_bits)); - write_h_buffer(output_bits.size() + GetSize(co_bits)); - log_debug("piNum = %d\n", GetSize(input_bits)); - write_h_buffer(input_bits.size()); - log_debug("poNum = %d\n", GetSize(output_bits)); - write_h_buffer(output_bits.size()); - log_debug("boxNum = %d\n", GetSize(box_list)); - write_h_buffer(box_list.size()); - RTLIL::Module *holes_module = module->design->addModule("$__holes__"); log_assert(holes_module); @@ -669,18 +669,12 @@ struct XAigerWriter write_h_buffer(box_count++); } - f << "h"; - std::string buffer_str = h_buffer.str(); - int32_t buffer_size_be = to_big_endian(buffer_str.size()); - f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); - f.write(buffer_str.data(), buffer_str.size()); - std::stringstream r_buffer; auto write_r_buffer = std::bind(write_buffer, std::ref(r_buffer), std::placeholders::_1); write_r_buffer(0); f << "r"; - buffer_str = r_buffer.str(); - buffer_size_be = to_big_endian(buffer_str.size()); + std::string buffer_str = r_buffer.str(); + int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); @@ -733,16 +727,18 @@ struct XAigerWriter log_pop(); } } - else { - log_debug("piNum = %d\n", GetSize(input_bits)); - log_debug("poNum = %d\n", GetSize(output_bits)); - } - f << "i"; - std::string buffer_str = i_buffer.str(); + f << "h"; + std::string buffer_str = h_buffer.str(); int32_t buffer_size_be = to_big_endian(buffer_str.size()); f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); f.write(buffer_str.data(), buffer_str.size()); + + f << "i"; + buffer_str = i_buffer.str(); + buffer_size_be = to_big_endian(buffer_str.size()); + f.write(reinterpret_cast(&buffer_size_be), sizeof(buffer_size_be)); + f.write(buffer_str.data(), buffer_str.size()); //f << "o"; //buffer_str = o_buffer.str(); //buffer_size_be = to_big_endian(buffer_str.size()); -- cgit v1.2.3 From 3247442bf9b1f5b672a360b1fc55af9170d000c5 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 28 Aug 2019 17:34:00 -0700 Subject: Revert "Revert "Fix omode which inserts an output if none exists (otherwise abc9 breaks)"" This reverts commit 8f0c1232d7c511a6473f4581e4c27a90088cedb7. --- backends/aiger/xaiger.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 0d69e0f13..8c8ff2f7e 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -504,16 +504,16 @@ struct XAigerWriter aig_outputs.push_back(bit2aig(bit)); } + if (output_bits.empty()) { + output_bits.insert(State::S0); + omode = true; + } + for (auto bit : output_bits) { ordered_outputs[bit] = aig_o++; aig_outputs.push_back(bit2aig(bit)); } - if (output_bits.empty()) { - aig_o++; - aig_outputs.push_back(0); - omode = true; - } } void write_aiger(std::ostream &f, bool ascii_mode) @@ -575,6 +575,7 @@ struct XAigerWriter f << "c"; + log_assert(!output_bits.empty()); auto write_buffer = [](std::stringstream &buffer, int i32) { int32_t i32_be = to_big_endian(i32); buffer.write(reinterpret_cast(&i32_be), sizeof(i32_be)); @@ -796,11 +797,11 @@ struct XAigerWriter f << stringf("box %d %d %s\n", box_count++, 0, log_id(cell->name)); output_lines.sort(); + if (omode) + output_lines[State::S0] = "output 0 0 $__dummy__\n"; for (auto &it : output_lines) f << it.second; log_assert(output_lines.size() == output_bits.size()); - if (omode && output_bits.empty()) - f << "output " << output_lines.size() << " 0 $__dummy__\n"; wire_lines.sort(); for (auto &it : wire_lines) -- cgit v1.2.3 From e9bb252e77ba979a4c7041e6a221862a6464bf99 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 30 Aug 2019 20:15:09 -0700 Subject: Recognise built-in types (e.g. $_DFF_*) --- backends/aiger/xaiger.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/aiger/xaiger.cc b/backends/aiger/xaiger.cc index 8c8ff2f7e..fa6ba0aca 100644 --- a/backends/aiger/xaiger.cc +++ b/backends/aiger/xaiger.cc @@ -263,12 +263,12 @@ struct XAigerWriter } } else { - bool cell_known = inst_module; + bool cell_known = inst_module || cell->known(); for (const auto &c : cell->connections()) { if (c.second.is_fully_const()) continue; auto port_wire = inst_module ? inst_module->wire(c.first) : nullptr; - auto is_input = !cell_known || port_wire->port_input; - auto is_output = !cell_known || port_wire->port_output; + auto is_input = (port_wire && port_wire->port_input) || !cell_known || cell->input(c.first); + auto is_output = (port_wire && port_wire->port_output) || !cell_known || cell->output(c.first); if (!is_input && !is_output) log_error("Connection '%s' on cell '%s' (type '%s') not recognised!\n", log_id(c.first), log_id(cell), log_id(cell->type)); -- cgit v1.2.3 From c1b628508d54eb0ab6e5c9559063330a409d0a51 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Sun, 8 Sep 2019 15:47:09 +0800 Subject: backends: smt2: use $(CXX) variable for compiler The Makefile assumes the compiler is called `gcc`, which isn't always true. In fact, if we're building on msys2 or msys2-64, the compiler is called `i686-w64-mingw32-g++` or `x86_64-w64-mingw32-g++`. Use the variable instead of hardcoding the name, to fix building on these systems. Signed-off-by: Sean Cross --- backends/smt2/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/smt2/Makefile.inc b/backends/smt2/Makefile.inc index 92941d4cf..68394a909 100644 --- a/backends/smt2/Makefile.inc +++ b/backends/smt2/Makefile.inc @@ -16,7 +16,7 @@ yosys-smtbmc-script.py: backends/smt2/smtbmc.py -e "s|#!/usr/bin/env python3|#!$(PYTHON)|" < $< > $@ yosys-smtbmc.exe: misc/launcher.c yosys-smtbmc-script.py - $(P) gcc -DGUI=0 -O -s -o $@ $< + $(P) $(CXX) -DGUI=0 -O -s -o $@ $< # Other targets else TARGETS += yosys-smtbmc -- cgit v1.2.3 From b88d2e5f30712f797a5c4fb2b7308494155b95d0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 18 Sep 2019 11:56:14 +0200 Subject: Fix stupid bug in btor back-end Signed-off-by: Clifford Wolf --- backends/btor/btor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/btor/btor.cc b/backends/btor/btor.cc index 7c054d655..4472993d4 100644 --- a/backends/btor/btor.cc +++ b/backends/btor/btor.cc @@ -685,7 +685,7 @@ struct BtorWorker } else { - int nid_init_val = next_nid++; + nid_init_val = next_nid++; btorf("%d state %d\n", nid_init_val, sid); for (int i = 0; i < nwords; i++) { -- cgit v1.2.3 From 779ce3537fa921daf6ffd780264f0867a8ebc4be Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 18 Sep 2019 13:33:02 +0200 Subject: Add "write_aiger -L" Signed-off-by: Clifford Wolf --- backends/aiger/aiger.cc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'backends') diff --git a/backends/aiger/aiger.cc b/backends/aiger/aiger.cc index 7c851bb91..0798fb35d 100644 --- a/backends/aiger/aiger.cc +++ b/backends/aiger/aiger.cc @@ -101,7 +101,7 @@ struct AigerWriter return a; } - AigerWriter(Module *module, bool zinit_mode, bool imode, bool omode, bool bmode) : module(module), zinit_mode(zinit_mode), sigmap(module) + AigerWriter(Module *module, bool zinit_mode, bool imode, bool omode, bool bmode, bool lmode) : module(module), zinit_mode(zinit_mode), sigmap(module) { pool undriven_bits; pool unused_bits; @@ -367,6 +367,12 @@ struct AigerWriter aig_latchin.push_back(a); } + if (lmode && aig_l == 0) { + aig_m++, aig_l++; + aig_latchinit.push_back(0); + aig_latchin.push_back(0); + } + if (!initstate_bits.empty() || !init_inputs.empty()) aig_latchin.push_back(1); @@ -704,9 +710,9 @@ struct AigerBackend : public Backend { log(" -vmap \n"); log(" like -map, but more verbose\n"); log("\n"); - log(" -I, -O, -B\n"); - log(" If the design contains no input/output/assert then create one\n"); - log(" dummy input/output/bad_state pin to make the tools reading the\n"); + log(" -I, -O, -B, -L\n"); + log(" If the design contains no input/output/assert/flip-flop then create one\n"); + log(" dummy input/output/bad_state-pin or latch to make the tools reading the\n"); log(" AIGER file happy.\n"); log("\n"); } @@ -720,6 +726,7 @@ struct AigerBackend : public Backend { bool imode = false; bool omode = false; bool bmode = false; + bool lmode = false; std::string map_filename; log_header(design, "Executing AIGER backend.\n"); @@ -764,6 +771,10 @@ struct AigerBackend : public Backend { bmode = true; continue; } + if (args[argidx] == "-L") { + lmode = true; + continue; + } break; } extra_args(f, filename, args, argidx); @@ -773,7 +784,7 @@ struct AigerBackend : public Backend { if (top_module == nullptr) log_error("Can't find top module in current design!\n"); - AigerWriter writer(top_module, zinit_mode, imode, omode, bmode); + AigerWriter writer(top_module, zinit_mode, imode, omode, bmode, lmode); writer.write_aiger(*f, ascii_mode, miter_mode, symbols_mode); if (!map_filename.empty()) { -- cgit v1.2.3