Bias pin handling (#409)

* Update STA to exclude bias pins from timing graph and subsequently in write_verilog

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* unnecessary space in orig verilog

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

* Update to use well supplies rather than bias pins

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>

---------

Signed-off-by: dsengupta0628 <dsengupta@precisioninno.com>
This commit is contained in:
Deepashree Sengupta 2026-04-07 14:00:01 -04:00 committed by GitHub
parent 645f2669c9
commit c887b2e4b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 80 additions and 4 deletions

View File

@ -41,6 +41,7 @@ public:
static PortDirection *internal() { return internal_; }
static PortDirection *ground() { return ground_; }
static PortDirection *power() { return power_; }
static PortDirection *well() { return well_; }
static PortDirection *unknown() { return unknown_; }
static PortDirection *find(const char *dir_name);
std::string_view name() const { return name_; }
@ -57,7 +58,8 @@ public:
bool isAnyTristate() const;
bool isGround() const { return this == ground_; }
bool isPower() const { return this == power_; }
// Ground or power.
bool isWell() const { return this == well_; }
// Ground, power, or well.
bool isPowerGround() const;
bool isInternal() const { return this == internal_; }
bool isUnknown() const { return this == unknown_; }
@ -76,6 +78,7 @@ private:
static PortDirection *internal_;
static PortDirection *ground_;
static PortDirection *power_;
static PortDirection *well_;
static PortDirection *unknown_;
};

View File

@ -1215,6 +1215,12 @@ LibertyReader::makePgPinPort(LibertyCell *cell,
case PwrGndType::internal_power:
dir = PortDirection::power();
break;
case PwrGndType::nwell:
case PwrGndType::pwell:
case PwrGndType::deepnwell:
case PwrGndType::deeppwell:
dir = PortDirection::well();
break;
case PwrGndType::none:
error(1291, pg_pin_group, "unknown pg_type.");
break;

View File

@ -569,7 +569,9 @@ LibertyWriter::asString(const PortDirection *dir)
return "internal";
else if (dir == PortDirection::bidirect())
return "inout";
else if (dir == PortDirection::ground() || dir == PortDirection::power())
else if (dir == PortDirection::ground()
|| dir == PortDirection::power()
|| dir == PortDirection::well())
return "input";
return "unknown";
}

View File

@ -35,6 +35,7 @@ PortDirection *PortDirection::bidirect_;
PortDirection *PortDirection::internal_;
PortDirection *PortDirection::ground_;
PortDirection *PortDirection::power_;
PortDirection *PortDirection::well_;
PortDirection *PortDirection::unknown_;
void
@ -47,7 +48,8 @@ PortDirection::init()
internal_ = new PortDirection("internal", 4);
ground_ = new PortDirection("ground", 5);
power_ = new PortDirection("power", 6);
unknown_ = new PortDirection("unknown", 7);
well_ = new PortDirection("well", 7);
unknown_ = new PortDirection("unknown", 8);
}
void
@ -67,6 +69,8 @@ PortDirection::destroy()
ground_ = nullptr;
delete power_;
power_ = nullptr;
delete well_;
well_ = nullptr;
delete unknown_;
unknown_ = nullptr;
}
@ -95,6 +99,8 @@ PortDirection::find(const char *dir_name)
return ground_;
else if (stringEqual(dir_name, "power"))
return power_;
else if (stringEqual(dir_name, "well"))
return well_;
else
return nullptr;
}
@ -125,7 +131,8 @@ bool
PortDirection::isPowerGround() const
{
return this == ground_
|| this == power_;
|| this == power_
|| this == well_;
}
} // namespace

View File

@ -165,6 +165,7 @@ record_public_tests {
report_json2
suppress_msg
verilog_attribute
verilog_well_supplies
verilog_specify
verilog_write_escape
verilog_unconnected_hpin

View File

@ -0,0 +1,26 @@
module top (y,
a);
output y;
input a;
sky130_fd_sc_hd__buf_1 u1 (.A(a),
.X(y));
endmodule
module top (y,
a);
output y;
input a;
wire VGND;
wire VNB;
wire VPB;
wire VPWR;
sky130_fd_sc_hd__buf_1 u1 (.VGND(VGND),
.VNB(VNB),
.VPB(VPB),
.VPWR(VPWR),
.A(a),
.X(y));
endmodule

View File

@ -0,0 +1,12 @@
# Check that write_verilog excludes well pins along with power/ground pins.
source helpers.tcl
read_liberty ../examples/sky130hd_tt.lib.gz
read_verilog verilog_well_supplies.v
link_design top
set verilog_file [make_result_file "verilog_well_supplies.v"]
write_verilog $verilog_file
report_file $verilog_file
set verilog_pwr_file [make_result_file "verilog_well_supplies_pwr.v"]
write_verilog -include_pwr_gnd $verilog_pwr_file
report_file $verilog_pwr_file

View File

@ -0,0 +1,17 @@
module top (
output y,
input a
);
supply1 VPWR;
supply0 VGND;
supply1 VPB;
supply0 VNB;
sky130_fd_sc_hd__buf_1 u1 (
.X(y),
.A(a),
.VPWR(VPWR),
.VGND(VGND),
.VPB(VPB),
.VNB(VNB)
);
endmodule

View File

@ -253,6 +253,8 @@ VerilogWriter::verilogPortDir(PortDirection *dir)
return "inout";
else if (dir == PortDirection::ground())
return "inout";
else if (dir == PortDirection::well())
return "inout";
else if (dir == PortDirection::internal()
|| dir == PortDirection::unknown())
return "inout";