xilinx_dffopt: Don't crash on missing IS_*_INVERTED.
authorMarcelina Kościelnicka <mwk@0x04.net>
Mon, 25 Jan 2021 12:01:18 +0000 (13:01 +0100)
committerMarcelina Kościelnicka <mwk@0x04.net>
Tue, 26 Jan 2021 23:32:00 +0000 (00:32 +0100)
The presence of IS_*_INVERTED on FD* cells follows Vivado, which
apparently has been decided by a dice roll.  Just assume false if the
parameter doesn't exist.

Fixes #2559.

techlibs/xilinx/xilinx_dffopt.cc
tests/arch/xilinx/mux.ys
tests/arch/xilinx/xilinx_dffopt.ys

index 365f505fb349968512cf29b306dd9ed09fd31b17..598f1b216a1ed53f677fe05f1033d72d250ad466 100644 (file)
@@ -209,7 +209,7 @@ lut_sigin_done:
                                        continue;
                                LutData lut_d = it_D->second.first;
                                Cell *cell_d = it_D->second.second;
-                               if (cell->getParam(ID(IS_D_INVERTED)).as_bool()) {
+                               if (cell->hasParam(ID(IS_D_INVERTED)) && cell->getParam(ID(IS_D_INVERTED)).as_bool()) {
                                        // Flip all bits in the LUT.
                                        for (int i = 0; i < GetSize(lut_d.first); i++)
                                                lut_d.first.bits[i] = (lut_d.first.bits[i] == State::S1) ? State::S0 : State::S1;
@@ -249,7 +249,7 @@ lut_sigin_done:
                                if (has_s) {
                                        SigBit sig_S = sigmap(cell->getPort(ID::S));
                                        LutData lut_s = LutData(Const(2, 2), {sig_S});
-                                       bool inv_s = cell->getParam(ID(IS_S_INVERTED)).as_bool();
+                                       bool inv_s = cell->hasParam(ID(IS_S_INVERTED)) && cell->getParam(ID(IS_S_INVERTED)).as_bool();
                                        auto it_S = bit_to_lut.find(sig_S);
                                        if (it_S != bit_to_lut.end())
                                                lut_s = it_S->second.first;
@@ -271,7 +271,7 @@ lut_sigin_done:
                                if (has_r) {
                                        SigBit sig_R = sigmap(cell->getPort(ID::R));
                                        LutData lut_r = LutData(Const(2, 2), {sig_R});
-                                       bool inv_r = cell->getParam(ID(IS_R_INVERTED)).as_bool();
+                                       bool inv_r = cell->hasParam(ID(IS_R_INVERTED)) && cell->getParam(ID(IS_R_INVERTED)).as_bool();
                                        auto it_R = bit_to_lut.find(sig_R);
                                        if (it_R != bit_to_lut.end())
                                                lut_r = it_R->second.first;
index 1b27884488b54d37e00f1182e47e964d263de60f..c2a23de6d966e1bdfb06e1a840512a9243786dc0 100644 (file)
@@ -40,10 +40,11 @@ proc
 equiv_opt -assert -map +/xilinx/cells_sim.v synth_xilinx -noiopad # equivalency check
 design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
 cd mux16 # Constrain all select calls below inside the top module
+select -assert-max 2 t:LUT3
 select -assert-max 2 t:LUT4
 select -assert-min 4 t:LUT6
 select -assert-max 7 t:LUT6
 select -assert-max 2 t:MUXF7
 dump
 
-select -assert-none t:LUT6 t:LUT4 t:MUXF7 %% t:* %D
+select -assert-none t:LUT6 t:LUT4 t:LUT3 t:MUXF7 %% t:* %D
index 2c729832ed05653265aac2a9e4afae9af06e14f7..c096994114bb9bb35f7f72d21d0c554122ed3eb4 100644 (file)
@@ -223,3 +223,49 @@ select -assert-count 1 t:LUT2
 select -assert-none t:FDRSE t:LUT4 t:LUT2 %% t:* %D
 
 design -reset
+
+
+read_verilog << EOT
+
+// FDSE_1, mergeable CE and S, but CE only not worth it.
+
+module t0 (...);
+input wire clk;
+input wire [7:0] i;
+output wire [7:0] o;
+
+wire [7:0] tmp ;
+
+LUT2 #(.INIT(4'h6)) lut0 (.I0(i[0]), .I1(i[1]), .O(tmp[0]));
+LUT2 #(.INIT(4'h6)) lut1 (.I0(i[1]), .I1(i[2]), .O(tmp[1]));
+
+FDSE_1 ff (.D(tmp[0]), .CE(i[7]), .S(tmp[1]), .Q(o[0]));
+
+endmodule
+
+EOT
+
+read_verilog -lib +/xilinx/cells_sim.v
+design -save t0
+
+equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt
+design -load postopt
+clean
+
+cd t0
+select -assert-count 1 t:FDSE_1
+select -assert-count 1 t:LUT5
+select -assert-none t:FDSE_1 t:LUT5 %% t:* %D
+
+design -load t0
+
+equiv_opt -blacklist xilinx_dffopt_blacklist.txt -assert -map +/xilinx/cells_sim.v xilinx_dffopt -lut4
+design -load postopt
+clean
+
+cd t0
+select -assert-count 1 t:FDSE_1
+select -assert-count 2 t:LUT2
+select -assert-none t:FDSE_1 t:LUT2 %% t:* %D
+
+design -reset