From c314ca3c51579a9c5305cbf9a69635e123db0423 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 10 Jun 2019 16:16:26 -0700 Subject: [PATCH 1/7] Add test --- tests/various/shregmap.v | 22 ++++++++++++++++++++++ tests/various/shregmap.ys | 31 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 tests/various/shregmap.v create mode 100644 tests/various/shregmap.ys diff --git a/tests/various/shregmap.v b/tests/various/shregmap.v new file mode 100644 index 000000000..56e05c2c0 --- /dev/null +++ b/tests/various/shregmap.v @@ -0,0 +1,22 @@ +module shregmap_test(input i, clk, output [1:0] q); +reg head = 1'b0; +reg [3:0] shift1 = 4'b0000; +reg [3:0] shift2 = 4'b0000; + +always @(posedge clk) begin + head <= i; + shift1 <= {shift1[2:0], head}; + shift2 <= {shift2[2:0], head}; +end + +assign q = {shift2[3], shift1[3]}; +endmodule + +module $__SHREG_DFF_P_(input C, D, output Q); +parameter DEPTH = 1; +parameter [DEPTH-1:0] INIT = {DEPTH{1'b0}}; +reg [DEPTH-1:0] r = INIT; +always @(posedge C) + r <= { r[DEPTH-2:0], D }; +assign Q = r[DEPTH-1]; +endmodule diff --git a/tests/various/shregmap.ys b/tests/various/shregmap.ys new file mode 100644 index 000000000..ca7f47015 --- /dev/null +++ b/tests/various/shregmap.ys @@ -0,0 +1,31 @@ +read_verilog shregmap.v +design -copy-to model $__SHREG_DFF_P_ +hierarchy -top shregmap_test +prep +design -save gold + +techmap +shregmap -init + +opt + +stat +# show -width +select -assert-count 1 t:$_DFF_P_ +select -assert-count 2 t:$__SHREG_DFF_P_ + +design -stash gate + +design -import gold -as gold +design -import gate -as gate +design -copy-from model -as $__SHREG_DFF_P_ \$__SHREG_DFF_P_ +prep + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports -seq 5 miter + +design -load gold +stat + +design -load gate +stat From f19aa8d989df9e443d26cf6beaf389c2f3d6a424 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 10 Jun 2019 16:16:40 -0700 Subject: [PATCH 2/7] If d_bit already in sigbit_chain_next, create extra wire --- passes/techmap/shregmap.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 21dfe9619..46f6a79fb 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -293,10 +293,13 @@ struct ShregmapWorker if (opts.init || sigbit_init.count(q_bit) == 0) { - if (sigbit_chain_next.count(d_bit)) { + auto r = sigbit_chain_next.insert(std::make_pair(d_bit, cell)); + if (!r.second) { sigbit_with_non_chain_users.insert(d_bit); - } else - sigbit_chain_next[d_bit] = cell; + Wire *wire = module->addWire(NEW_ID); + module->connect(wire, d_bit); + sigbit_chain_next.insert(std::make_pair(wire, cell)); + } sigbit_chain_prev[q_bit] = cell; continue; From 2f427acc9ed23c77e89386f4fbf53ac580bf0f0b Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 11 Jun 2019 15:48:20 -0700 Subject: [PATCH 3/7] Try way that doesn't involve creating a new wire --- passes/techmap/shregmap.cc | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 46f6a79fb..3adcd8968 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -294,12 +294,8 @@ struct ShregmapWorker if (opts.init || sigbit_init.count(q_bit) == 0) { auto r = sigbit_chain_next.insert(std::make_pair(d_bit, cell)); - if (!r.second) { + if (!r.second) sigbit_with_non_chain_users.insert(d_bit); - Wire *wire = module->addWire(NEW_ID); - module->connect(wire, d_bit); - sigbit_chain_next.insert(std::make_pair(wire, cell)); - } sigbit_chain_prev[q_bit] = cell; continue; @@ -319,14 +315,14 @@ struct ShregmapWorker { for (auto it : sigbit_chain_next) { + Cell *c1, *c2 = it.second; + if (opts.tech == nullptr && sigbit_with_non_chain_users.count(it.first)) goto start_cell; - if (sigbit_chain_prev.count(it.first) != 0) + c1 = sigbit_chain_prev.at(it.first, nullptr); + if (c1 != nullptr) { - Cell *c1 = sigbit_chain_prev.at(it.first); - Cell *c2 = it.second; - if (c1->type != c2->type) goto start_cell; @@ -336,6 +332,15 @@ struct ShregmapWorker IdString d_port = opts.ffcells.at(c1->type).first; IdString q_port = opts.ffcells.at(c1->type).second; + // If the previous cell's D has other non chain users, + // then it is possible that this previous cell could + // be a start of the chain + SigBit d_bit = sigmap(c1->getPort(d_port).as_bit()); + if (sigbit_with_non_chain_users.count(d_bit)) { + c2 = c1; + goto start_cell; + } + auto c1_conn = c1->connections(); auto c2_conn = c1->connections(); @@ -352,7 +357,7 @@ struct ShregmapWorker } start_cell: - chain_start_cells.insert(it.second); + chain_start_cells.insert(c2); } } From 6cdea93724b69695938ca021fd3841f644b478bf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Tue, 11 Jun 2019 16:05:42 -0700 Subject: [PATCH 4/7] Revert "Try way that doesn't involve creating a new wire" This reverts commit 2f427acc9ed23c77e89386f4fbf53ac580bf0f0b. --- passes/techmap/shregmap.cc | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 3adcd8968..46f6a79fb 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -294,8 +294,12 @@ struct ShregmapWorker if (opts.init || sigbit_init.count(q_bit) == 0) { auto r = sigbit_chain_next.insert(std::make_pair(d_bit, cell)); - if (!r.second) + if (!r.second) { sigbit_with_non_chain_users.insert(d_bit); + Wire *wire = module->addWire(NEW_ID); + module->connect(wire, d_bit); + sigbit_chain_next.insert(std::make_pair(wire, cell)); + } sigbit_chain_prev[q_bit] = cell; continue; @@ -315,14 +319,14 @@ struct ShregmapWorker { for (auto it : sigbit_chain_next) { - Cell *c1, *c2 = it.second; - if (opts.tech == nullptr && sigbit_with_non_chain_users.count(it.first)) goto start_cell; - c1 = sigbit_chain_prev.at(it.first, nullptr); - if (c1 != nullptr) + if (sigbit_chain_prev.count(it.first) != 0) { + Cell *c1 = sigbit_chain_prev.at(it.first); + Cell *c2 = it.second; + if (c1->type != c2->type) goto start_cell; @@ -332,15 +336,6 @@ struct ShregmapWorker IdString d_port = opts.ffcells.at(c1->type).first; IdString q_port = opts.ffcells.at(c1->type).second; - // If the previous cell's D has other non chain users, - // then it is possible that this previous cell could - // be a start of the chain - SigBit d_bit = sigmap(c1->getPort(d_port).as_bit()); - if (sigbit_with_non_chain_users.count(d_bit)) { - c2 = c1; - goto start_cell; - } - auto c1_conn = c1->connections(); auto c2_conn = c1->connections(); @@ -357,7 +352,7 @@ struct ShregmapWorker } start_cell: - chain_start_cells.insert(c2); + chain_start_cells.insert(it.second); } } From 45c2a5f87694a83e0cf96477ede02567a93b32a8 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 12 Jun 2019 08:34:06 -0700 Subject: [PATCH 5/7] Add shregmap -tech xilinx test --- tests/various/shregmap.v | 28 +++++++++++++++++++++++++++- tests/various/shregmap.ys | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/tests/various/shregmap.v b/tests/various/shregmap.v index 56e05c2c0..604c2c976 100644 --- a/tests/various/shregmap.v +++ b/tests/various/shregmap.v @@ -1,4 +1,4 @@ -module shregmap_test(input i, clk, output [1:0] q); +module shregmap_static_test(input i, clk, output [1:0] q); reg head = 1'b0; reg [3:0] shift1 = 4'b0000; reg [3:0] shift2 = 4'b0000; @@ -20,3 +20,29 @@ always @(posedge C) r <= { r[DEPTH-2:0], D }; assign Q = r[DEPTH-1]; endmodule + +module shregmap_variable_test(input i, clk, input [1:0] l1, l2, output [1:0] q); +reg head = 1'b0; +reg [3:0] shift1 = 4'b0000; +reg [3:0] shift2 = 4'b0000; + +always @(posedge clk) begin + head <= i; + shift1 <= {shift1[2:0], head}; + shift2 <= {shift2[2:0], head}; +end + +assign q = {shift2[l2], shift1[l1]}; +endmodule + +module $__XILINX_SHREG_(input C, D, input [1:0] L, output Q); +parameter CLKPOL = 1; +parameter ENPOL = 1; +parameter DEPTH = 1; +parameter [DEPTH-1:0] INIT = {DEPTH{1'b0}}; +reg [DEPTH-1:0] r = INIT; +wire clk = C ^ CLKPOL; +always @(posedge C) + r <= { r[DEPTH-2:0], D }; +assign Q = r[L]; +endmodule diff --git a/tests/various/shregmap.ys b/tests/various/shregmap.ys index ca7f47015..d644a88aa 100644 --- a/tests/various/shregmap.ys +++ b/tests/various/shregmap.ys @@ -1,6 +1,8 @@ read_verilog shregmap.v +design -save read + design -copy-to model $__SHREG_DFF_P_ -hierarchy -top shregmap_test +hierarchy -top shregmap_static_test prep design -save gold @@ -29,3 +31,36 @@ stat design -load gate stat + +########## + +design -load read +design -copy-to model $__XILINX_SHREG_ +hierarchy -top shregmap_variable_test +prep +design -save gold + +simplemap t:$dff t:$dffe +shregmap -tech xilinx + +stat +# show -width +write_verilog -noexpr -norename +select -assert-count 1 t:$_DFF_P_ +select -assert-count 2 t:$__XILINX_SHREG_ + +design -stash gate + +design -import gold -as gold +design -import gate -as gate +design -copy-from model -as $__XILINX_SHREG_ \$__XILINX_SHREG_ +prep + +miter -equiv -flatten -make_assert -make_outputs gold gate miter +sat -verify -prove-asserts -show-ports -seq 5 miter + +design -load gold +stat + +design -load gate +stat From 9c61fb0e0c23f00bacf316f7efd358c66f2f6397 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 20 Jun 2019 16:57:54 -0700 Subject: [PATCH 6/7] Add comment as per @cliffordwolf --- passes/techmap/shregmap.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 46f6a79fb..8881ba468 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -295,7 +295,18 @@ struct ShregmapWorker { auto r = sigbit_chain_next.insert(std::make_pair(d_bit, cell)); if (!r.second) { + // Insertion not successful means that d_bit is already + // connected to another register, thus mark it as a + // non chain user ... sigbit_with_non_chain_users.insert(d_bit); + // ... and clone d_bit into another wire, and use that + // wire as a different key in the d_bit-to-cell dictionary + // so that it can be identified as another chain + // (omitting this common flop) + // Link: https://github.com/YosysHQ/yosys/pull/1085 + // NB: This relies on us not updating sigmap with this + // alias otherwise it would think they are the same + // wire Wire *wire = module->addWire(NEW_ID); module->connect(wire, d_bit); sigbit_chain_next.insert(std::make_pair(wire, cell)); From e63324f5ef2ebb14fa0cc88544f577406f95b223 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Thu, 20 Jun 2019 17:03:05 -0700 Subject: [PATCH 7/7] Actually, there might not be any harm in updating sigmap... --- passes/techmap/shregmap.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 8881ba468..d9d1e257b 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -304,11 +304,9 @@ struct ShregmapWorker // so that it can be identified as another chain // (omitting this common flop) // Link: https://github.com/YosysHQ/yosys/pull/1085 - // NB: This relies on us not updating sigmap with this - // alias otherwise it would think they are the same - // wire Wire *wire = module->addWire(NEW_ID); module->connect(wire, d_bit); + sigmap.add(wire, d_bit); sigbit_chain_next.insert(std::make_pair(wire, cell)); }