mirror of https://github.com/YosysHQ/yosys.git
Merge branch 'xaig' into xc7mux
This commit is contained in:
commit
eb08e71bd1
|
@ -51,6 +51,7 @@ struct XAigerWriter
|
||||||
//pool<SigBit> initstate_bits;
|
//pool<SigBit> initstate_bits;
|
||||||
vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits;
|
vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int>> ci_bits;
|
||||||
vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits;
|
vector<std::tuple<SigBit,RTLIL::Cell*,RTLIL::IdString,int,int>> co_bits;
|
||||||
|
vector<std::pair<SigBit,SigBit>> ff_bits;
|
||||||
|
|
||||||
vector<pair<int, int>> aig_gates;
|
vector<pair<int, int>> aig_gates;
|
||||||
vector<int> aig_latchin, aig_latchinit, aig_outputs;
|
vector<int> aig_latchin, aig_latchinit, aig_outputs;
|
||||||
|
@ -180,6 +181,7 @@ struct XAigerWriter
|
||||||
for (auto cell : module->cells())
|
for (auto cell : module->cells())
|
||||||
{
|
{
|
||||||
RTLIL::Module* inst_module = module->design->module(cell->type);
|
RTLIL::Module* inst_module = module->design->module(cell->type);
|
||||||
|
bool inst_flop = inst_module ? inst_module->attributes.count("\\abc_flop") : false;
|
||||||
bool known_type = yosys_celltypes.cell_known(cell->type);
|
bool known_type = yosys_celltypes.cell_known(cell->type);
|
||||||
|
|
||||||
if (!holes_mode) {
|
if (!holes_mode) {
|
||||||
|
@ -256,7 +258,32 @@ struct XAigerWriter
|
||||||
// continue;
|
// continue;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (inst_module && inst_module->attributes.count("\\abc_box_id")) {
|
if (inst_flop) {
|
||||||
|
SigBit d, q;
|
||||||
|
for (const auto &c : cell->connections()) {
|
||||||
|
for (auto b : c.second.bits()) {
|
||||||
|
auto is_input = cell->input(c.first);
|
||||||
|
auto is_output = cell->output(c.first);
|
||||||
|
log_assert(is_input || is_output);
|
||||||
|
if (is_input && inst_module->wire(c.first)->attributes.count("\\abc_flop_d")) {
|
||||||
|
SigBit I = sigmap(b);
|
||||||
|
if (I != b)
|
||||||
|
alias_map[b] = I;
|
||||||
|
d = b;
|
||||||
|
}
|
||||||
|
if (is_output && inst_module->wire(c.first)->attributes.count("\\abc_flop_q")) {
|
||||||
|
SigBit O = sigmap(b);
|
||||||
|
q = O;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!abc_box_seen)
|
||||||
|
abc_box_seen = inst_module->attributes.count("\\abc_box_id");
|
||||||
|
|
||||||
|
ff_bits.emplace_back(d, q);
|
||||||
|
undriven_bits.erase(q);
|
||||||
|
}
|
||||||
|
else if (inst_module && inst_module->attributes.count("\\abc_box_id")) {
|
||||||
abc_box_seen = true;
|
abc_box_seen = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -479,11 +506,22 @@ struct XAigerWriter
|
||||||
aig_map[bit] = 2*aig_m;
|
aig_map[bit] = 2*aig_m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &f : ff_bits) {
|
||||||
|
auto bit = f.second;
|
||||||
|
aig_m++, aig_i++;
|
||||||
|
aig_map[bit] = 2*aig_m;
|
||||||
|
}
|
||||||
|
|
||||||
|
dict<SigBit, int> ff_aig_map;
|
||||||
for (auto &c : ci_bits) {
|
for (auto &c : ci_bits) {
|
||||||
RTLIL::SigBit bit = std::get<0>(c);
|
RTLIL::SigBit bit = std::get<0>(c);
|
||||||
aig_m++, aig_i++;
|
aig_m++, aig_i++;
|
||||||
log_assert(!aig_map.count(bit));
|
log_assert(!aig_map.count(bit));
|
||||||
aig_map[bit] = 2*aig_m;
|
aig_map[bit] = 2*aig_m;
|
||||||
|
//auto r = aig_map.insert(std::make_pair(c.first, c.second));
|
||||||
|
//if (!r.second) {
|
||||||
|
// ff_aig_map[std::get<0>(c)] = 2*aig_m;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imode && input_bits.empty()) {
|
if (imode && input_bits.empty()) {
|
||||||
|
@ -557,6 +595,11 @@ struct XAigerWriter
|
||||||
aig_outputs.push_back(bit2aig(bit));
|
aig_outputs.push_back(bit2aig(bit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &f : ff_bits) {
|
||||||
|
aig_o++;
|
||||||
|
aig_outputs.push_back(ff_aig_map.at(f.second));
|
||||||
|
}
|
||||||
|
|
||||||
if (omode && output_bits.empty()) {
|
if (omode && output_bits.empty()) {
|
||||||
aig_o++;
|
aig_o++;
|
||||||
aig_outputs.push_back(0);
|
aig_outputs.push_back(0);
|
||||||
|
@ -714,7 +757,7 @@ struct XAigerWriter
|
||||||
|
|
||||||
f << "c";
|
f << "c";
|
||||||
|
|
||||||
if (!box_list.empty()) {
|
if (!box_list.empty() || !ff_bits.empty()) {
|
||||||
std::stringstream h_buffer;
|
std::stringstream h_buffer;
|
||||||
auto write_h_buffer = [&h_buffer](int i32) {
|
auto write_h_buffer = [&h_buffer](int i32) {
|
||||||
// TODO: Don't assume we're on little endian
|
// TODO: Don't assume we're on little endian
|
||||||
|
@ -729,12 +772,12 @@ struct XAigerWriter
|
||||||
if (omode && num_outputs == 0)
|
if (omode && num_outputs == 0)
|
||||||
num_outputs = 1;
|
num_outputs = 1;
|
||||||
write_h_buffer(1);
|
write_h_buffer(1);
|
||||||
log_debug("ciNum = %zu\n", input_bits.size() + ci_bits.size());
|
log_debug("ciNum = %zu\n", input_bits.size() + ff_bits.size() + ci_bits.size());
|
||||||
write_h_buffer(input_bits.size() + ci_bits.size());
|
write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size());
|
||||||
log_debug("coNum = %zu\n", num_outputs + co_bits.size());
|
log_debug("coNum = %zu\n", num_outputs + ff_bits.size() + co_bits.size());
|
||||||
write_h_buffer(num_outputs + co_bits.size());
|
write_h_buffer(num_outputs + ff_bits.size()+ co_bits.size());
|
||||||
log_debug("piNum = %zu\n", input_bits.size());
|
log_debug("piNum = %zu\n", input_bits.size() + ff_bits.size());
|
||||||
write_h_buffer(input_bits.size());
|
write_h_buffer(input_bits.size()+ ff_bits.size());
|
||||||
log_debug("poNum = %d\n", num_outputs);
|
log_debug("poNum = %d\n", num_outputs);
|
||||||
write_h_buffer(num_outputs);
|
write_h_buffer(num_outputs);
|
||||||
log_debug("boxNum = %zu\n", box_list.size());
|
log_debug("boxNum = %zu\n", box_list.size());
|
||||||
|
@ -813,6 +856,34 @@ struct XAigerWriter
|
||||||
f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
|
f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
|
||||||
f.write(buffer_str.data(), buffer_str.size());
|
f.write(buffer_str.data(), buffer_str.size());
|
||||||
|
|
||||||
|
if (!ff_bits.empty()) {
|
||||||
|
std::stringstream r_buffer;
|
||||||
|
auto write_r_buffer = [&r_buffer](int i32) {
|
||||||
|
// TODO: Don't assume we're on little endian
|
||||||
|
#ifdef _WIN32
|
||||||
|
int i32_be = _byteswap_ulong(i32);
|
||||||
|
#else
|
||||||
|
int i32_be = __builtin_bswap32(i32);
|
||||||
|
#endif
|
||||||
|
r_buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be));
|
||||||
|
};
|
||||||
|
write_r_buffer(ff_bits.size());
|
||||||
|
int mergeability_class = 1;
|
||||||
|
for (auto cell : ff_bits)
|
||||||
|
write_r_buffer(mergeability_class++);
|
||||||
|
|
||||||
|
f << "r";
|
||||||
|
std::string buffer_str = r_buffer.str();
|
||||||
|
// TODO: Don't assume we're on little endian
|
||||||
|
#ifdef _WIN32
|
||||||
|
int buffer_size_be = _byteswap_ulong(buffer_str.size());
|
||||||
|
#else
|
||||||
|
int buffer_size_be = __builtin_bswap32(buffer_str.size());
|
||||||
|
#endif
|
||||||
|
f.write(reinterpret_cast<const char*>(&buffer_size_be), sizeof(buffer_size_be));
|
||||||
|
f.write(buffer_str.data(), buffer_str.size());
|
||||||
|
}
|
||||||
|
|
||||||
if (holes_module) {
|
if (holes_module) {
|
||||||
// NB: fixup_ports() will sort ports by name
|
// NB: fixup_ports() will sort ports by name
|
||||||
//holes_module->fixup_ports();
|
//holes_module->fixup_ports();
|
||||||
|
|
|
@ -249,6 +249,24 @@ void AigerReader::parse_xaiger()
|
||||||
module->addLut(stringf("\\__%d__$lut", rootNodeID), input_sig, output_sig, std::move(lut_mask));
|
module->addLut(stringf("\\__%d__$lut", rootNodeID), input_sig, output_sig, std::move(lut_mask));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (c == 'r') {
|
||||||
|
/*uint32_t dataSize =*/ parse_xaiger_literal(f);
|
||||||
|
uint32_t flopNum = parse_xaiger_literal(f);
|
||||||
|
f.ignore(flopNum * sizeof(uint32_t));
|
||||||
|
log_assert(inputs.size() >= flopNum);
|
||||||
|
for (auto it = inputs.end() - flopNum; it != inputs.end(); ++it) {
|
||||||
|
log_assert((*it)->port_input);
|
||||||
|
(*it)->port_input = false;
|
||||||
|
}
|
||||||
|
inputs.erase(inputs.end() - flopNum, inputs.end());
|
||||||
|
log_assert(outputs.size() >= flopNum);
|
||||||
|
for (auto it = outputs.end() - flopNum; it != outputs.end(); ++it) {
|
||||||
|
log_assert((*it)->port_output);
|
||||||
|
(*it)->port_output = false;
|
||||||
|
}
|
||||||
|
outputs.erase(outputs.end() - flopNum, outputs.end());
|
||||||
|
module->fixup_ports();
|
||||||
|
}
|
||||||
else if (c == 'n') {
|
else if (c == 'n') {
|
||||||
parse_xaiger_literal(f);
|
parse_xaiger_literal(f);
|
||||||
f >> s;
|
f >> s;
|
||||||
|
|
|
@ -537,11 +537,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
output_bits.insert({wire, i});
|
output_bits.insert({wire, i});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//if (w->name == "\\__dummy_o__") {
|
|
||||||
// log("Don't call ABC as there is nothing to map.\n");
|
|
||||||
// goto cleanup;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Attempt another wideports_split here because there
|
// Attempt another wideports_split here because there
|
||||||
// exists the possibility that different bits of a port
|
// exists the possibility that different bits of a port
|
||||||
// could be an input and output, therefore parse_xaiger()
|
// could be an input and output, therefore parse_xaiger()
|
||||||
|
@ -752,7 +747,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
|
||||||
// log("Don't call ABC as there is nothing to map.\n");
|
// log("Don't call ABC as there is nothing to map.\n");
|
||||||
//}
|
//}
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (cleanup)
|
if (cleanup)
|
||||||
{
|
{
|
||||||
log("Removing temp directory.\n");
|
log("Removing temp directory.\n");
|
||||||
|
|
|
@ -149,7 +149,7 @@ module SB_DFF ((* abc_flop_q *) output `SB_DFF_REG, input C, (* abc_flop_d *) in
|
||||||
always @(posedge C)
|
always @(posedge C)
|
||||||
Q <= D;
|
Q <= D;
|
||||||
`else
|
`else
|
||||||
always @* Q = D;
|
always @* Q <= D;
|
||||||
`endif
|
`endif
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
|
@ -294,6 +294,7 @@ struct SynthXilinxPass : public ScriptPass
|
||||||
else
|
else
|
||||||
run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
|
run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
|
||||||
run("clean");
|
run("clean");
|
||||||
|
|
||||||
// This shregmap call infers fixed length shift registers after abc
|
// This shregmap call infers fixed length shift registers after abc
|
||||||
// has performed any necessary retiming
|
// has performed any necessary retiming
|
||||||
if (!nosrl || help_mode)
|
if (!nosrl || help_mode)
|
||||||
|
|
Loading…
Reference in New Issue