aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backends/json/json.cc4
-rw-r--r--frontends/json/jsonparse.cc12
-rw-r--r--passes/techmap/abc9.cc61
-rw-r--r--techlibs/ecp5/cells_sim.v2
-rw-r--r--techlibs/xilinx/abc_xc7.box14
-rw-r--r--techlibs/xilinx/cells_sim.v2
-rw-r--r--tests/various/abc9.v5
-rw-r--r--tests/various/abc9.ys14
8 files changed, 104 insertions, 10 deletions
diff --git a/backends/json/json.cc b/backends/json/json.cc
index 1781a28cd..dda4dfedd 100644
--- a/backends/json/json.cc
+++ b/backends/json/json.cc
@@ -126,6 +126,10 @@ struct JsonWriter
f << stringf("%s\n", first ? "" : ",");
f << stringf(" %s: {\n", get_name(n).c_str());
f << stringf(" \"direction\": \"%s\",\n", w->port_input ? w->port_output ? "inout" : "input" : "output");
+ if (w->start_offset)
+ f << stringf(" \"offset\": %d,\n", w->start_offset);
+ if (w->upto)
+ f << stringf(" \"upto\": 1,\n");
f << stringf(" \"bits\": %s\n", get_bits(w).c_str());
f << stringf(" }");
first = false;
diff --git a/frontends/json/jsonparse.cc b/frontends/json/jsonparse.cc
index b74d41dd2..f5ae8eb72 100644
--- a/frontends/json/jsonparse.cc
+++ b/frontends/json/jsonparse.cc
@@ -292,6 +292,18 @@ void json_import(Design *design, string &modname, JsonNode *node)
if (port_wire == nullptr)
port_wire = module->addWire(port_name, GetSize(port_bits_node->data_array));
+ if (port_node->data_dict.count("upto") != 0) {
+ JsonNode *val = port_node->data_dict.at("upto");
+ if (val->type == 'N')
+ port_wire->upto = val->data_number != 0;
+ }
+
+ if (port_node->data_dict.count("offset") != 0) {
+ JsonNode *val = port_node->data_dict.at("offset");
+ if (val->type == 'N')
+ port_wire->start_offset = val->data_number;
+ }
+
if (port_direction_node->data_string == "input") {
port_wire->port_input = true;
} else
diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc
index 473c2b936..f90834aa9 100644
--- a/passes/techmap/abc9.cc
+++ b/passes/techmap/abc9.cc
@@ -80,9 +80,6 @@ void handle_loops(RTLIL::Design *design)
{
Pass::call(design, "scc -set_attr abc_scc_id {}");
- design->selection_stack.emplace_back(false);
- RTLIL::Selection& sel = design->selection_stack.back();
-
// For every unique SCC found, (arbitrarily) find the first
// cell in the component, and select (and mark) all its output
// wires
@@ -92,24 +89,70 @@ void handle_loops(RTLIL::Design *design)
if (it != cell->attributes.end()) {
auto r = ids_seen.insert(it->second);
if (r.second) {
- for (const auto &c : cell->connections()) {
+ for (auto &c : cell->connections_) {
if (c.second.is_fully_const()) continue;
if (cell->output(c.first)) {
SigBit b = c.second.as_bit();
Wire *w = b.wire;
+ log_assert(!w->port_input);
+ w->port_input = true;
+ w = module->wire(stringf("%s.abci", w->name.c_str()));
+ if (!w) {
+ w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
+ w->port_output = true;
+ }
+ else {
+ log_assert(w->port_input);
+ log_assert(b.offset < GetSize(w));
+ }
w->set_bool_attribute("\\abc_scc_break");
- sel.select(module, w);
+ module->swap_names(b.wire, w);
+ c.second = RTLIL::SigBit(w, b.offset);
}
}
}
cell->attributes.erase(it);
}
+ RTLIL::Module* box_module = design->module(cell->type);
+ if (box_module) {
+ auto jt = box_module->attributes.find("\\abc_scc_break");
+ if (jt != box_module->attributes.end()) {
+ auto it = cell->connections_.find(RTLIL::escape_id(jt->second.decode_string()));
+ if (it == cell->connections_.end())
+ log_error("abc_scc_break attribute value '%s' does not exist as port on module '%s'\n", jt->second.decode_string().c_str(), log_id(box_module));
+ log_assert(it != cell->connections_.end());
+ RTLIL::SigSpec sig;
+ for (auto b : it->second) {
+ Wire *w = b.wire;
+ if (w->port_output) {
+ log_assert(w->get_bool_attribute("\\abc_scc_break"));
+ w = module->wire(stringf("%s.abci", w->name.c_str()));
+ log_assert(w);
+ log_assert(b.offset < GetSize(w));
+ log_assert(w->port_input);
+ }
+ else {
+ log_assert(!w->port_output);
+ w->port_output = true;
+ w->set_bool_attribute("\\abc_scc_break");
+ w = module->wire(stringf("%s.abci", w->name.c_str()));
+ if (!w) {
+ w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire));
+ w->port_input = true;
+ }
+ else {
+ log_assert(w->port_input);
+ log_assert(b.offset < GetSize(w));
+ }
+ }
+ sig.append(RTLIL::SigBit(w, b.offset));
+ }
+ it->second = sig;
+ }
+ }
}
- // Then cut those selected wires to expose them as new PO/PI
- Pass::call(design, "expose -cut -sep .abc");
-
- design->selection_stack.pop_back();
+ module->fixup_ports();
}
std::string add_echos_to_abc_cmd(std::string str)
diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v
index f66147323..0239d1afe 100644
--- a/techlibs/ecp5/cells_sim.v
+++ b/techlibs/ecp5/cells_sim.v
@@ -106,7 +106,7 @@ module PFUMX (input ALUT, BLUT, C0, output Z);
endmodule
// ---------------------------------------
-//(* abc_box_id=2 *)
+(* abc_box_id=2, abc_scc_break="DI" *)
module TRELLIS_DPR16X4 (
input [3:0] DI,
input [3:0] WAD,
diff --git a/techlibs/xilinx/abc_xc7.box b/techlibs/xilinx/abc_xc7.box
index 5e6ce2ea3..dafef9fef 100644
--- a/techlibs/xilinx/abc_xc7.box
+++ b/techlibs/xilinx/abc_xc7.box
@@ -34,3 +34,17 @@ CARRY4 3 1 10 8
494 465 445 - - 433 469 - - 157
592 540 520 356 - 512 548 292 - 228
580 526 507 398 385 508 528 378 380 114
+
+# SLICEM/A6LUT
+# Inputs: A0 A1 A2 A3 A4 A5 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 WCLK WE
+# Outputs: DPO SPO
+RAM64X1D 4 0 15 2
+- - - - - - - 124 124 124 124 124 124 - -
+124 124 124 124 124 124 - - - - - - 124 - -
+
+# SLICEM/A6LUT + F7[AB]MUX
+# Inputs: A0 A1 A2 A3 A4 A5 A6 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 DPRA6 WCLK WE
+# Outputs: DPO SPO
+RAM128X1D 5 0 17 2
+- - - - - - - - 314 314 314 314 314 314 292 - -
+347 347 347 347 347 347 296 - - - - - - - - - -
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index 29abc9807..c6c49c3cd 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -306,6 +306,7 @@ module RAM32X1D (
always @(posedge clk) if (WE) mem[a] <= D;
endmodule
+(* abc_box_id = 4, abc_scc_break="D" *)
module RAM64X1D (
output DPO, SPO,
input D, WCLK, WE,
@@ -323,6 +324,7 @@ module RAM64X1D (
always @(posedge clk) if (WE) mem[a] <= D;
endmodule
+(* abc_box_id = 5, abc_scc_break="D" *)
module RAM128X1D (
output DPO, SPO,
input D, WCLK, WE,
diff --git a/tests/various/abc9.v b/tests/various/abc9.v
new file mode 100644
index 000000000..8271cd249
--- /dev/null
+++ b/tests/various/abc9.v
@@ -0,0 +1,5 @@
+module abc9_test027(output reg o);
+initial o = 1'b0;
+always @*
+ o <= ~o;
+endmodule
diff --git a/tests/various/abc9.ys b/tests/various/abc9.ys
new file mode 100644
index 000000000..922f7005d
--- /dev/null
+++ b/tests/various/abc9.ys
@@ -0,0 +1,14 @@
+read_verilog abc9.v
+proc
+design -save gold
+
+abc9 -lut 4
+check
+design -stash gate
+
+design -import gold -as gold
+design -import gate -as gate
+
+miter -equiv -flatten -make_assert -make_outputs gold gate miter
+sat -verify -prove-asserts -show-ports miter
+