From 645f2669c9a01f9e1ebe3b94cbf74e9e2d4b4b0f Mon Sep 17 00:00:00 2001 From: James Cherry Date: Tue, 7 Apr 2026 10:45:04 -0700 Subject: [PATCH 1/2] report_dcalc prima resolves #418 Signed-off-by: James Cherry --- dcalc/PrimaDelayCalc.cc | 9 ++++--- test/prima3.ok | 52 +++++++++++++++++++++++++++++++++++++++++ test/prima3.tcl | 1 + 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index be0a3d89..561b7953 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -931,15 +931,18 @@ std::string PrimaDelayCalc::reportGateDelay(const Pin *drvr_pin, const TimingArc *arc, const Slew &in_slew, - float, - const Parasitic *, - const LoadPinIndexMap &, + float load_cap, + const Parasitic *parasitic, + const LoadPinIndexMap &load_pin_index_map, const Scene *scene, const MinMax *min_max, int digits) { GateTimingModel *model = arc->gateModel(scene, min_max); if (model) { + // Delay calc to find ceff. + gateDelay(drvr_pin, arc, in_slew, load_cap, parasitic, + load_pin_index_map, scene, min_max); float in_slew1 = delayAsFloat(in_slew); float ceff = ceff_vth_[0]; return model->reportGateDelay(pinPvt(drvr_pin, scene, min_max), diff --git a/test/prima3.ok b/test/prima3.ok index a4ac1d9c..cd2c8cac 100644 --- a/test/prima3.ok +++ b/test/prima3.ok @@ -31,3 +31,55 @@ Path Type: max 228.48 slack (MET) +Library: asap7_small +Cell: BUFx2_ASAP7_75t_R +Arc sense: positive_unate +Arc type: combinational +A ^ -> Y ^ +P = 1.00 V = 0.70 T = 25.00 +------- input_net_transition = 59.28 +| total_output_net_capacitance = 13.54 +| 11.52 23.04 +v -------------------- +40.00 | 48.68 71.50 +80.00 | 56.23 79.10 +Table value = 56.33 +PVT scale factor = 1.00 +Delay = 56.33 + +------- input_net_transition = 59.28 +| total_output_net_capacitance = 13.54 +| 11.52 23.04 +v -------------------- +40.00 | 53.99 104.08 +80.00 | 54.58 104.40 +Table value = 63.04 +PVT scale factor = 1.00 +Slew = 63.04 + +............................................. + +A v -> Y v +P = 1.00 V = 0.70 T = 25.00 +------- input_net_transition = 52.93 +| total_output_net_capacitance = 12.09 +| 11.52 23.04 +v -------------------- +40.00 | 48.42 67.20 +80.00 | 57.92 76.86 +Table value = 52.43 +PVT scale factor = 1.00 +Delay = 52.43 + +------- input_net_transition = 52.93 +| total_output_net_capacitance = 12.09 +| 11.52 23.04 +v -------------------- +40.00 | 42.77 80.89 +80.00 | 43.84 81.48 +Table value = 45.00 +PVT scale factor = 1.00 +Slew = 45.00 + +............................................. + diff --git a/test/prima3.tcl b/test/prima3.tcl index b2e20eab..0b285c72 100644 --- a/test/prima3.tcl +++ b/test/prima3.tcl @@ -9,3 +9,4 @@ set_propagated_clock {clk1 clk2 clk3} read_spef reg1_asap7.spef sta::set_delay_calculator prima report_checks -fields {input_pins slew} -format full_clock +report_dcalc -from u1/A -to u1/Y From c887b2e4b37df2e17f324ee993e164ed5a704b5e Mon Sep 17 00:00:00 2001 From: Deepashree Sengupta Date: Tue, 7 Apr 2026 14:00:01 -0400 Subject: [PATCH 2/2] Bias pin handling (#409) * Update STA to exclude bias pins from timing graph and subsequently in write_verilog Signed-off-by: dsengupta0628 * unnecessary space in orig verilog Signed-off-by: dsengupta0628 * Update to use well supplies rather than bias pins Signed-off-by: dsengupta0628 --------- Signed-off-by: dsengupta0628 --- include/sta/PortDirection.hh | 5 ++++- liberty/LibertyReader.cc | 6 ++++++ liberty/LibertyWriter.cc | 4 +++- network/PortDirection.cc | 11 +++++++++-- test/regression_vars.tcl | 1 + test/verilog_well_supplies.ok | 26 ++++++++++++++++++++++++++ test/verilog_well_supplies.tcl | 12 ++++++++++++ test/verilog_well_supplies.v | 17 +++++++++++++++++ verilog/VerilogWriter.cc | 2 ++ 9 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 test/verilog_well_supplies.ok create mode 100644 test/verilog_well_supplies.tcl create mode 100644 test/verilog_well_supplies.v diff --git a/include/sta/PortDirection.hh b/include/sta/PortDirection.hh index 0b8186f9..1d54271c 100644 --- a/include/sta/PortDirection.hh +++ b/include/sta/PortDirection.hh @@ -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_; }; diff --git a/liberty/LibertyReader.cc b/liberty/LibertyReader.cc index b473b80e..a76b6893 100644 --- a/liberty/LibertyReader.cc +++ b/liberty/LibertyReader.cc @@ -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; diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index a27490fb..79d4f780 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -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"; } diff --git a/network/PortDirection.cc b/network/PortDirection.cc index 5a6aaae5..608eb2b0 100644 --- a/network/PortDirection.cc +++ b/network/PortDirection.cc @@ -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 diff --git a/test/regression_vars.tcl b/test/regression_vars.tcl index 9b6af334..b0cab790 100644 --- a/test/regression_vars.tcl +++ b/test/regression_vars.tcl @@ -165,6 +165,7 @@ record_public_tests { report_json2 suppress_msg verilog_attribute + verilog_well_supplies verilog_specify verilog_write_escape verilog_unconnected_hpin diff --git a/test/verilog_well_supplies.ok b/test/verilog_well_supplies.ok new file mode 100644 index 00000000..41b72482 --- /dev/null +++ b/test/verilog_well_supplies.ok @@ -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 diff --git a/test/verilog_well_supplies.tcl b/test/verilog_well_supplies.tcl new file mode 100644 index 00000000..b4028711 --- /dev/null +++ b/test/verilog_well_supplies.tcl @@ -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 diff --git a/test/verilog_well_supplies.v b/test/verilog_well_supplies.v new file mode 100644 index 00000000..6ae13580 --- /dev/null +++ b/test/verilog_well_supplies.v @@ -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 diff --git a/verilog/VerilogWriter.cc b/verilog/VerilogWriter.cc index 8edaf699..49ecedf3 100644 --- a/verilog/VerilogWriter.cc +++ b/verilog/VerilogWriter.cc @@ -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";