Merge pull request #5817 from YosysHQ/emil/clockgate-reject-sdffe

clockgate: reject $sdffe to fix priority handling
This commit is contained in:
Emil J 2026-05-08 18:38:51 +00:00 committed by GitHub
commit 1f02343268
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 113 additions and 100 deletions

View File

@ -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())

View File

@ -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;

View File

@ -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

44
tests/techmap/clockgate.v Normal file
View File

@ -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

View File

@ -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

View File

@ -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