Merge branch 'xaig' into xc7mux

This commit is contained in:
Eddie Hung 2019-05-31 13:03:03 -07:00
commit eb08e71bd1
5 changed files with 99 additions and 15 deletions

View File

@ -51,6 +51,7 @@ struct XAigerWriter
//pool<SigBit> initstate_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::pair<SigBit,SigBit>> ff_bits;
vector<pair<int, int>> aig_gates;
vector<int> aig_latchin, aig_latchinit, aig_outputs;
@ -180,6 +181,7 @@ struct XAigerWriter
for (auto cell : module->cells())
{
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);
if (!holes_mode) {
@ -256,7 +258,32 @@ struct XAigerWriter
// 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;
}
else {
@ -479,11 +506,22 @@ struct XAigerWriter
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) {
RTLIL::SigBit bit = std::get<0>(c);
aig_m++, aig_i++;
log_assert(!aig_map.count(bit));
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()) {
@ -557,6 +595,11 @@ struct XAigerWriter
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()) {
aig_o++;
aig_outputs.push_back(0);
@ -714,7 +757,7 @@ struct XAigerWriter
f << "c";
if (!box_list.empty()) {
if (!box_list.empty() || !ff_bits.empty()) {
std::stringstream h_buffer;
auto write_h_buffer = [&h_buffer](int i32) {
// TODO: Don't assume we're on little endian
@ -729,12 +772,12 @@ struct XAigerWriter
if (omode && num_outputs == 0)
num_outputs = 1;
write_h_buffer(1);
log_debug("ciNum = %zu\n", input_bits.size() + ci_bits.size());
write_h_buffer(input_bits.size() + ci_bits.size());
log_debug("coNum = %zu\n", num_outputs + co_bits.size());
write_h_buffer(num_outputs + co_bits.size());
log_debug("piNum = %zu\n", input_bits.size());
write_h_buffer(input_bits.size());
log_debug("ciNum = %zu\n", input_bits.size() + ff_bits.size() + ci_bits.size());
write_h_buffer(input_bits.size() + ff_bits.size() + ci_bits.size());
log_debug("coNum = %zu\n", num_outputs + ff_bits.size() + co_bits.size());
write_h_buffer(num_outputs + ff_bits.size()+ co_bits.size());
log_debug("piNum = %zu\n", input_bits.size() + ff_bits.size());
write_h_buffer(input_bits.size()+ ff_bits.size());
log_debug("poNum = %d\n", num_outputs);
write_h_buffer(num_outputs);
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(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) {
// NB: fixup_ports() will sort ports by name
//holes_module->fixup_ports();

View File

@ -249,6 +249,24 @@ void AigerReader::parse_xaiger()
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') {
parse_xaiger_literal(f);
f >> s;

View File

@ -537,11 +537,6 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri
output_bits.insert({wire, i});
}
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
// exists the possibility that different bits of a port
// 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");
//}
cleanup:
if (cleanup)
{
log("Removing temp directory.\n");

View File

@ -149,7 +149,7 @@ module SB_DFF ((* abc_flop_q *) output `SB_DFF_REG, input C, (* abc_flop_d *) in
always @(posedge C)
Q <= D;
`else
always @* Q = D;
always @* Q <= D;
`endif
endmodule

View File

@ -294,6 +294,7 @@ struct SynthXilinxPass : public ScriptPass
else
run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
run("clean");
// This shregmap call infers fixed length shift registers after abc
// has performed any necessary retiming
if (!nosrl || help_mode)