mirror of
https://github.com/YosysHQ/yosys.git
synced 2026-10-06 01:53:53 +02:00
Merge pull request #6228 from YosysHQ/nella/abc-no-input-boxes
read_liberty: don't mark input-less cells as boxes
This commit is contained in:
@@ -575,7 +575,7 @@ struct LibertyFrontend : public Frontend {
|
||||
for (auto &attr : attributes)
|
||||
module->attributes[attr] = 1;
|
||||
|
||||
bool simple_comb_cell = true, has_outputs = false;
|
||||
bool simple_comb_cell = true, has_inputs = false, has_outputs = false;
|
||||
|
||||
for (auto node : cell->children)
|
||||
{
|
||||
@@ -693,6 +693,7 @@ struct LibertyFrontend : public Frontend {
|
||||
}
|
||||
|
||||
if (dir && dir->value == "input") {
|
||||
has_inputs = true;
|
||||
wire->port_input = true;
|
||||
continue;
|
||||
}
|
||||
@@ -736,7 +737,7 @@ struct LibertyFrontend : public Frontend {
|
||||
simple_comb_cell = false;
|
||||
}
|
||||
|
||||
if (simple_comb_cell && has_outputs && flag_unit_delay) {
|
||||
if (simple_comb_cell && has_inputs && has_outputs && flag_unit_delay) {
|
||||
module->set_bool_attribute(ID::abc9_box);
|
||||
|
||||
for (auto wi : module->wires())
|
||||
|
||||
@@ -33,23 +33,33 @@ void check(RTLIL::Design *design, bool dff_mode)
|
||||
dict<IdString,IdString> box_lookup;
|
||||
for (auto m : design->modules()) {
|
||||
auto flop = m->get_bool_attribute(ID::abc9_flop);
|
||||
auto box = m->get_bool_attribute(ID::abc9_box);
|
||||
auto it = m->attributes.find(ID::abc9_box_id);
|
||||
if (!flop) {
|
||||
if (it == m->attributes.end())
|
||||
if (!box && it == m->attributes.end())
|
||||
continue;
|
||||
auto id = it->second.as_int();
|
||||
auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), m->name));
|
||||
if (!r.second)
|
||||
log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",
|
||||
m, id, r.first->second.unescape());
|
||||
if (it != m->attributes.end()) {
|
||||
auto id = it->second.as_int();
|
||||
auto r = box_lookup.insert(std::make_pair(stringf("$__boxid%d", id), m->name));
|
||||
if (!r.second)
|
||||
log_error("Module '%s' has the same abc9_box_id = %d value as '%s'.\n",
|
||||
m, id, r.first->second.unescape());
|
||||
}
|
||||
}
|
||||
|
||||
// Make carry in the last PI, and carry out the last PO
|
||||
// since ABC requires it this way
|
||||
IdString carry_in, carry_out;
|
||||
bool has_input = false, has_output = false;
|
||||
for (const auto &port_name : m->ports) {
|
||||
auto w = m->wire(port_name);
|
||||
log_assert(w);
|
||||
if (GetSize(w)) {
|
||||
if (w->port_input)
|
||||
has_input = true;
|
||||
if (w->port_output)
|
||||
has_output = true;
|
||||
}
|
||||
if (w->get_bool_attribute(ID::abc9_carry)) {
|
||||
if (w->port_input) {
|
||||
if (carry_in != IdString())
|
||||
@@ -69,6 +79,13 @@ void check(RTLIL::Design *design, bool dff_mode)
|
||||
if (carry_in == IdString() && carry_out != IdString())
|
||||
log_error("Module '%s' contains an (* abc9_carry *) output port but no input port.\n", m);
|
||||
|
||||
// A timing arc spans an input to an output, so a box missing either
|
||||
// carries no timing for abc to work with
|
||||
if (!flop && !has_input)
|
||||
log_error("Module '%s' with (* abc9_box *) has no input port.\n", m);
|
||||
if (!flop && !has_output)
|
||||
log_error("Module '%s' with (* abc9_box *) has no output port.\n", m);
|
||||
|
||||
if (flop) {
|
||||
int num_outputs = 0;
|
||||
for (auto port_name : m->ports) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# an abc9 box needs an input, or it can carry no timing arcs
|
||||
logger -expect error "has no input port" 1
|
||||
read_verilog -specify <<EOT
|
||||
(* abc9_box, blackbox *)
|
||||
module SRC(output Y);
|
||||
endmodule
|
||||
module top(input a, output y, z);
|
||||
SRC s (.Y(z));
|
||||
assign y = a;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -top top
|
||||
techmap
|
||||
abc_new -liberty openroad/cm_test_cells.lib
|
||||
@@ -0,0 +1,15 @@
|
||||
# an abc9 box needs an output, or it can carry no timing arcs
|
||||
logger -expect error "has no output port" 1
|
||||
read_verilog -specify <<EOT
|
||||
(* abc9_box, blackbox *)
|
||||
module SINK(input A, B);
|
||||
endmodule
|
||||
module top(input a, b, output y);
|
||||
SINK s (.A(a), .B(b));
|
||||
assign y = a & b;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
hierarchy -top top
|
||||
techmap
|
||||
abc_new -liberty openroad/cm_test_cells.lib
|
||||
@@ -3,18 +3,6 @@
|
||||
import sys
|
||||
sys.path.append("../..")
|
||||
|
||||
import glob
|
||||
|
||||
import gen_tests_makefile
|
||||
|
||||
skip = [
|
||||
"tie_box.ys",
|
||||
]
|
||||
|
||||
def create_tests():
|
||||
for ys in sorted(glob.glob("*.ys")):
|
||||
if ys in skip:
|
||||
continue
|
||||
gen_tests_makefile.generate_ys_test(ys)
|
||||
|
||||
gen_tests_makefile.generate_custom(create_tests)
|
||||
gen_tests_makefile.generate(["--yosys-scripts"])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# https://github.com/The-OpenROAD-Project/OpenROAD/blob/80443953721b0134bed51bbab17a633a575098a6/src/cut/test/sky130_const_cell.v
|
||||
|
||||
# input-less box (tie cell): abc asserts in Gia_ManLevelWithBoxes, same with abc9 -lut
|
||||
# input-less cells are not abc9 boxes as abc cannot represent a box with no inputs
|
||||
read_verilog <<EOT
|
||||
module top(clk, c);
|
||||
input clk;
|
||||
|
||||
Reference in New Issue
Block a user