Merge pull request #1700 from YosysHQ/eddie/abc9_fixes

Use (* abc9_init *) attribute, fix use of abc9_arrival for flops
This commit is contained in:
Eddie Hung 2020-02-13 17:32:54 -08:00 committed by GitHub
commit 0cf7598cd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 29 deletions

View File

@ -643,14 +643,13 @@ struct XAigerWriter
write_s_buffer(ff_bits.size());
for (const auto &i : ff_bits) {
const SigBit &d = i.first;
const Cell *cell = i.second;
int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int();
log_assert(mergeability > 0);
write_r_buffer(mergeability);
Const init = cell->attributes.at(ID(abc9_init));
Const init = cell->attributes.at(ID(abc9_init), State::Sx);
log_assert(GetSize(init) == 1);
if (init == State::S1)
write_s_buffer(1);
@ -661,7 +660,11 @@ struct XAigerWriter
write_s_buffer(0);
}
write_i_buffer(arrival_times.at(d, 0));
auto it = cell->attributes.find(ID(abc9_arrival));
if (it != cell->attributes.end())
write_i_buffer(it->second.as_int());
else
write_i_buffer(0);
//write_o_buffer(0);
}

View File

@ -192,20 +192,9 @@ void prep_dff(RTLIL::Module *module)
clkdomain_t key(abc9_clock);
auto r = clk_to_mergeability.insert(std::make_pair(abc9_clock, clk_to_mergeability.size() + 1));
auto r2 YS_ATTRIBUTE(unused) = cell->attributes.insert(std::make_pair(ID(abc9_mergeability), r.first->second));
log_assert(r2.second);
Wire *abc9_init_wire = module->wire(stringf("%s.init", cell->name.c_str()));
if (abc9_init_wire == NULL)
log_error("'%s.init' is not a wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
log_assert(GetSize(abc9_init_wire) == 1);
SigSpec abc9_init = assign_map(abc9_init_wire);
if (!abc9_init.is_fully_const())
log_error("'%s.init' is not a constant wire present in module '%s'.\n", cell->name.c_str(), log_id(module));
if (abc9_init == State::S1)
log_error("'%s.init' in module '%s' has value 1'b1 which is not supported by 'abc9 -dff'.\n", cell->name.c_str(), log_id(module));
r2 = cell->attributes.insert(std::make_pair(ID(abc9_init), abc9_init.as_const()));
auto r2 = cell->attributes.insert(ID(abc9_mergeability));;
log_assert(r2.second);
r2.first->second = r.first->second;
}
RTLIL::Module *holes_module = design->module(stringf("%s$holes", module->name.c_str()));
@ -265,13 +254,19 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
SigMap sigmap(module);
dict<SigBit, Cell*> abc9_ff_d;
dict<SigBit, pool<IdString>> bit_drivers, bit_users;
TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
dict<IdString, std::vector<IdString>> box_ports;
for (auto cell : module->cells()) {
if (cell->type == "$__ABC9_FF_")
if (cell->type == "$__ABC9_FF_") {
auto d = sigmap(cell->getPort(ID(D)));
auto r = abc9_ff_d.insert(d);
log_assert(r.second);
r.first->second = cell;
continue;
}
if (cell->has_keep_attr())
continue;
@ -368,6 +363,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
IdString derived_type = box_module->derive(design, cell->parameters);
box_module = design->module(derived_type);
auto abc9_flop = box_module->get_bool_attribute("\\abc9_flop");
auto r = cell_cache.insert(derived_type);
auto &holes_cell = r.first->second;
@ -406,7 +402,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
// For flops only, create an extra 1-bit input that drives a new wire
// called "<cell>.abc9_ff.Q" that is used below
if (box_module->get_bool_attribute("\\abc9_flop")) {
if (abc9_flop) {
box_inputs++;
Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
if (!holes_wire) {
@ -436,6 +432,28 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
holes_module->connect(holes_wire, holes_cell->getPort(port_name));
else // blackbox
holes_module->connect(holes_wire, Const(State::S0, GetSize(w)));
// Transfer abc9_arrival value from flop box output to $__ABC9_FF_ cell
if (abc9_flop) {
auto it = w->attributes.find(ID(abc9_arrival));
if (it == w->attributes.end())
continue;
auto jt = cell->connections_.find(port_name);
if (jt == cell->connections_.end())
continue;
auto kt = abc9_ff_d.find(jt->second);
if (kt == abc9_ff_d.end())
continue;
#ifndef NDEBUG
if (ys_debug(1)) {
static std::set<std::pair<IdString,IdString>> seen;
if (seen.emplace(cell->type, port_name).second) log("%s.%s abc9_arrival = %d\n", log_id(cell->type), log_id(port_name), it->second.as_int());
}
#endif
auto r = kt->second->attributes.insert(ID(abc9_arrival));
log_assert(r.second);
r.first->second = it->second;
}
}
}
}

View File

@ -68,9 +68,10 @@
// (c) a special abc9_ff.clock wire to capture its clock domain and polarity
// (indicated to `abc9' so that it only performs sequential synthesis
// (with reachability analysis) correctly on one domain at a time)
// (d) a special abc9_ff.init wire to encode the flop's initial state
// NOTE: in order to perform sequential synthesis, `abc9' also requires
// that the initial value of all flops be zero
// (d) an (* abc9_init *) attribute on the $__ABC9_FF_ cell capturing its
// initial state
// NOTE: in order to perform sequential synthesis, `abc9' requires that
// the initial value of all flops be zero
// (e) a special _TECHMAP_REPLACE_.abc9_ff.Q wire that will be used for feedback
// into the (combinatorial) FD* cell to facilitate clock-enable behaviour
@ -103,11 +104,11 @@ module FDRE (output Q, (* techmap_autopurge *) input C, CE, D, R);
);
end
endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
@ -130,11 +131,11 @@ module FDRE_1 (output Q, (* techmap_autopurge *) input C, CE, D, R);
);
end
endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
@ -166,11 +167,11 @@ module FDSE (output Q, (* techmap_autopurge *) input C, CE, D, S);
.D(D), .Q($Q), .C(C), .CE(CE), .S(S)
);
end endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
@ -192,11 +193,11 @@ module FDSE_1 (output Q, (* techmap_autopurge *) input C, CE, D, S);
.D(D), .Q($Q), .C(C), .CE(CE), .S(S)
);
end endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q(QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = QQ;
endmodule
@ -242,11 +243,11 @@ module FDCE (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
// Since this is an async flop, async behaviour is dealt with here
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR ^ IS_CLR_INVERTED), .Y(QQ));
end endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
@ -280,11 +281,11 @@ module FDCE_1 (output Q, (* techmap_autopurge *) input C, CE, D, CLR);
);
$__ABC9_ASYNC0 abc_async (.A($QQ), .S(CLR), .Y(QQ));
end endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
@ -328,11 +329,11 @@ module FDPE (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE ^ IS_PRE_INVERTED), .Y(QQ));
end endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, IS_C_INVERTED};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
@ -366,11 +367,11 @@ module FDPE_1 (output Q, (* techmap_autopurge *) input C, CE, D, PRE);
);
$__ABC9_ASYNC1 abc_async (.A($QQ), .S(PRE), .Y(QQ));
end endgenerate
(* abc9_init = 1'b0 *)
$__ABC9_FF_ abc9_ff (.D($Q), .Q($QQ));
// Special signals
wire [1:0] abc9_ff.clock = {C, 1'b1 /* IS_C_INVERTED */};
wire [0:0] abc9_ff.init = 1'b0;
wire [0:0] _TECHMAP_REPLACE_.abc9_ff.Q = $QQ;
endmodule
`endif