diff --git a/passes/techmap/clockgate.cc b/passes/techmap/clockgate.cc index b68e5d93d1a..650719cd595 100644 --- a/passes/techmap/clockgate.cc +++ b/passes/techmap/clockgate.cc @@ -337,6 +337,8 @@ struct ClockgatePass : public Pass { FfData ff(nullptr, cell); // It would be odd to get constants, but we better handle it if (ff.has_ce) { + if (ff.has_srst && !ff.ce_over_srst) + continue; if (!ff.sig_clk.is_bit() || !ff.sig_ce.is_bit()) continue; if (!ff.sig_clk[0].is_wire() || !ff.sig_ce[0].is_wire()) diff --git a/tests/techmap/clockgate.lib b/tests/techmap/clockgate.lib index 9f83baa551c..5843251089a 100644 --- a/tests/techmap/clockgate.lib +++ b/tests/techmap/clockgate.lib @@ -6,6 +6,7 @@ library(test) { pin (GCLK) { clock_gate_out_pin : true; direction : output; + function : "CLK&CE"; } pin (CLK) { clock_gate_clock_pin : true; @@ -26,6 +27,7 @@ library(test) { pin (GCLK) { clock_gate_out_pin : true; direction : output; + function : "CLK&CE"; } pin (CLK) { clock_gate_clock_pin : true; @@ -42,6 +44,7 @@ library(test) { pin (GCLK) { clock_gate_out_pin : true; direction : output; + function : "CLK&CE"; } pin (CLK) { clock_gate_clock_pin : true; @@ -58,6 +61,7 @@ library(test) { pin (GCLK) { clock_gate_out_pin : true; direction : output; + function : "CLK|!CE"; } pin (CLK) { clock_gate_clock_pin : true; @@ -74,6 +78,7 @@ library(test) { pin (GCLK) { clock_gate_out_pin : true; direction : output; + function : "CLK|!CE"; } pin (CLK) { clock_gate_clock_pin : true; @@ -94,6 +99,7 @@ library(test) { pin (GCLK) { clock_gate_out_pin : true; direction : output; + function : "CLK|!CE"; } pin (CLK) { clock_gate_clock_pin : true; diff --git a/tests/techmap/clockgate.ys b/tests/techmap/clockgate.tcl similarity index 81% rename from tests/techmap/clockgate.ys rename to tests/techmap/clockgate.tcl index c28852ef878..84682f78049 100644 --- a/tests/techmap/clockgate.ys +++ b/tests/techmap/clockgate.tcl @@ -1,53 +1,7 @@ -read_verilog << EOT - -module dffe_00( input clk, en, - input d1, output reg q1, - ); - always @( negedge clk ) begin - if ( ~en ) - q1 <= d1; - end -endmodule - -module dffe_01( input clk, en, - input d1, output reg q1, - ); - always @( negedge clk ) begin - if ( en ) - q1 <= d1; - end -endmodule - -module dffe_10( input clk, en, - input d1, output reg q1, - ); - always @( posedge clk ) begin - if ( ~en ) - q1 <= d1; - end -endmodule - -module dffe_11( input clk, en, - input d1, output reg q1, - ); - always @( posedge clk ) begin - if ( en ) - q1 <= d1; - end -endmodule - -module dffe_wide_11( input clk, en, - input [3:0] d1, output reg [3:0] q1, - ); - always @( posedge clk ) begin - if ( en ) - q1 <= d1; - end -endmodule - -EOT - -proc +yosys -import +read_verilog clockgate.v +read_verilog ../sim/sdffe.v +yosys proc opt design -save before @@ -128,41 +82,7 @@ select -module dffe_11 -assert-count 0 t:\\pdk_icg #------------------------------------------------------------------------------ design -reset -read_rtlil << EOT - -module \bad1 - wire input 1 \clk - wire input 3 \d1 - wire input 2 \en - wire output 4 \q1 - cell $dffe $auto$ff.cc:266:slice$27 - parameter \CLK_POLARITY 1 - parameter \EN_POLARITY 1 - parameter \WIDTH 1 - connect \CLK \clk - connect \D \d1 - connect \EN 1'1 - connect \Q \q1 - end -end - -module \bad2 - wire input 1 \clk - wire input 3 \d1 - wire input 2 \en - wire output 4 \q1 - cell $dffe $auto$ff.cc:266:slice$27 - parameter \CLK_POLARITY 1 - parameter \EN_POLARITY 1 - parameter \WIDTH 1 - connect \CLK 1'1 - connect \D \d1 - connect \EN \en - connect \Q \q1 - end -end - -EOT +read_rtlil clockgate_bad.il # Check we don't choke on constants clockgate -pos pdk_icg ce:clkin:clkout -tie_lo scanen @@ -173,19 +93,8 @@ select -module bad2 -assert-count 0 t:\\pdk_icg # Regression test: EN is a bit from a multi-bit wire design -reset -read_verilog << EOT -module dffe_wide_11( input clk, input [1:0] en, - input [3:0] d1, output reg [3:0] q1, - ); - always @( posedge clk ) begin - if ( en[0] ) - q1 <= d1; - end -endmodule - -EOT - -proc +read_verilog clockgate_wide.v +yosys proc opt clockgate -pos pdk_icg ce:clkin:clkout -tie_lo scanen @@ -193,8 +102,18 @@ select -assert-count 1 t:\\pdk_icg #------------------------------------------------------------------------------ -design -load before -clockgate -liberty c*ckgate.lib +design -reset +read_liberty c*ckgate.lib +design -save map +foreach mod {dffe_00 dffe_01 dffe_10 dffe_11} { + design -load before + hierarchy -top $mod + read_liberty -lib c*ckgate.lib + equiv_opt -map %map -multiclock clockgate -liberty c*ckgate.lib + design -load postopt + design -copy-to final $mod +} +design -load final # rising edge ICGs select -module dffe_00 -assert-count 0 t:\\pos_small @@ -276,6 +195,9 @@ select -module dffe_11 -assert-count 0 t:\\neg_small_tielo select -module dffe_10 -assert-count 1 t:\$_NOT_ select -module dffe_11 -assert-count 0 t:\$_NOT_ +# $sdffe is not gated +select -module sdffe -assert-count 0 sdffe t:* t:\$sdffe %d + #------------------------------------------------------------------------------ design -load before diff --git a/tests/techmap/clockgate.v b/tests/techmap/clockgate.v new file mode 100644 index 00000000000..3b493685255 --- /dev/null +++ b/tests/techmap/clockgate.v @@ -0,0 +1,44 @@ +module dffe_00( input clk, en, + input d1, output reg q1, + ); + always @( negedge clk ) begin + if ( ~en ) + q1 <= d1; + end +endmodule + +module dffe_01( input clk, en, + input d1, output reg q1, + ); + always @( negedge clk ) begin + if ( en ) + q1 <= d1; + end +endmodule + +module dffe_10( input clk, en, + input d1, output reg q1, + ); + always @( posedge clk ) begin + if ( ~en ) + q1 <= d1; + end +endmodule + +module dffe_11( input clk, en, + input d1, output reg q1, + ); + always @( posedge clk ) begin + if ( en ) + q1 <= d1; + end +endmodule + +module dffe_wide_11( input clk, en, + input [3:0] d1, output reg [3:0] q1, + ); + always @( posedge clk ) begin + if ( en ) + q1 <= d1; + end +endmodule \ No newline at end of file diff --git a/tests/techmap/clockgate_bad.il b/tests/techmap/clockgate_bad.il new file mode 100644 index 00000000000..c967b04e6fd --- /dev/null +++ b/tests/techmap/clockgate_bad.il @@ -0,0 +1,31 @@ +module \bad1 + wire input 1 \clk + wire input 3 \d1 + wire input 2 \en + wire output 4 \q1 + cell $dffe $auto$ff.cc:266:slice$27 + parameter \CLK_POLARITY 1 + parameter \EN_POLARITY 1 + parameter \WIDTH 1 + connect \CLK \clk + connect \D \d1 + connect \EN 1'1 + connect \Q \q1 + end +end + +module \bad2 + wire input 1 \clk + wire input 3 \d1 + wire input 2 \en + wire output 4 \q1 + cell $dffe $auto$ff.cc:266:slice$27 + parameter \CLK_POLARITY 1 + parameter \EN_POLARITY 1 + parameter \WIDTH 1 + connect \CLK 1'1 + connect \D \d1 + connect \EN \en + connect \Q \q1 + end +end \ No newline at end of file diff --git a/tests/techmap/clockgate_wide.v b/tests/techmap/clockgate_wide.v new file mode 100644 index 00000000000..687fd710403 --- /dev/null +++ b/tests/techmap/clockgate_wide.v @@ -0,0 +1,8 @@ +module dffe_wide_11( input clk, input [1:0] en, + input [3:0] d1, output reg [3:0] q1, + ); + always @( posedge clk ) begin + if ( en[0] ) + q1 <= d1; + end +endmodule \ No newline at end of file