From 65c19e7005c3687e18dacd17fefa3af3ffb35761 Mon Sep 17 00:00:00 2001 From: maksyuki Date: Thu, 15 Oct 2026 14:05:46 +0800 Subject: [PATCH] feat(hp): replace the OpenC906 clock-gating cells with per-PDK ICGs Complete the integration manual chapter 3 cell swap (the ICG half; the SRAM half landed earlier). Three new reviewed overrides, registered in generate_openc906.py with sha256 pins on the vendored files and added to the generated-filelist stamp prerequisites: - gated_clk_cell.v (216 CPU instances) and tdt_gated_clk_cell.v (DTM): pass-through upstream by default; with PDK_IHP130/PDK_ICS55/PDK_SKY130/ PDK_GF180 and without PDK_BEHAV they instantiate the process ICG cell (sg13g2_slgcp_1 with SCE, ICGX1H7R with the scan enable ORed into E because the ICS55 cell has no TE pin, sky130_fd_sc_hd__sdlclkp_1 with SCE, gf180mcu_fd_sc_mcu7t5v0__icgtp_1 with TE and notifier tied off). - BUFGCE.v (PLIC/CLINT div-2 gate): the upstream behavioral latch model stays byte-identical by default; the same four PDK branches substitute the process cell with the scan input tied off. The GF180 branch uses a repo-owned icgtp_1 functional model in rtl/tech/gf180_seq_sim_cells.v (following the file's dff precedent) because the vendor functional model references a UDP latch primitive that the locked gf180mcu-pdk checkout never ships. SKY130 picks up the vendor sdlclkp model through pdk_sky130.fl, following the existing cell pattern. ASIC CI profiles with PDK_BEHAV unset now compile real clock gating; PDK_BEHAV=YES profiles are bit-identical. Evidence: the manual's MEM_INTF c906_icg_test_tb passes on all four PDK cell paths (Icarus adaptation); the five-mode boot testbench suite passes on top of this change. --- Makefile | 5 +- rtl/filelist/pdk_sky130.fl | 2 + rtl/mini/ip_overrides/BUFGCE.v | 114 +++++++++++++ rtl/mini/ip_overrides/gated_clk_cell.v | 131 ++++++++++++++ rtl/mini/ip_overrides/tdt_gated_clk_cell.v | 190 +++++++++++++++++++++ rtl/tech/gf180_seq_sim_cells.v | 18 ++ scripts/generate_openc906.py | 22 ++- 7 files changed, 480 insertions(+), 2 deletions(-) create mode 100644 rtl/mini/ip_overrides/BUFGCE.v create mode 100644 rtl/mini/ip_overrides/gated_clk_cell.v create mode 100644 rtl/mini/ip_overrides/tdt_gated_clk_cell.v diff --git a/Makefile b/Makefile index 7510e603..15466355 100644 --- a/Makefile +++ b/Makefile @@ -1132,7 +1132,10 @@ $(HP_GENERATED_STAMP): $(ROOT_PATH)/scripts/generate_openc906.py \ $(ROOT_PATH)/rtl/mini/ip_overrides/aq_spsram_128x8.v \ $(ROOT_PATH)/rtl/mini/ip_overrides/aq_spsram_64x58.v \ $(ROOT_PATH)/rtl/mini/ip_overrides/aq_spsram_64x88.v \ - $(ROOT_PATH)/rtl/mini/ip_overrides/aq_spsram_64x98.v $(LOCK_FILE) + $(ROOT_PATH)/rtl/mini/ip_overrides/aq_spsram_64x98.v \ + $(ROOT_PATH)/rtl/mini/ip_overrides/gated_clk_cell.v \ + $(ROOT_PATH)/rtl/mini/ip_overrides/tdt_gated_clk_cell.v \ + $(ROOT_PATH)/rtl/mini/ip_overrides/BUFGCE.v $(LOCK_FILE) python3 $(ROOT_PATH)/scripts/generate_openc906.py \ --root $(ROOT_PATH) --source $(OPENC906_ROOT) --output $(HP_GENERATED_DIR) \ --manifest $(HP_GENERATED_MANIFEST) --lock $(LOCK_FILE) diff --git a/rtl/filelist/pdk_sky130.fl b/rtl/filelist/pdk_sky130.fl index 968acc51..cddc467d 100644 --- a/rtl/filelist/pdk_sky130.fl +++ b/rtl/filelist/pdk_sky130.fl @@ -5,6 +5,7 @@ +incdir+/physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinv +incdir+/physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/mux2 +incdir+/physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/xor2 ++incdir+/physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/sdlclkp /tech/sky130_io_sim_cells.v /clusterip/common/rtl/tech/ram.sv /tech/sky130_sram_sim_cells.sv @@ -12,3 +13,4 @@ /physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/clkinv/sky130_fd_sc_hd__clkinv_1.v /physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/mux2/sky130_fd_sc_hd__mux2_1.v /physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/xor2/sky130_fd_sc_hd__xor2_1.v +/physical/pdk/skywater-pdk/libraries/sky130_fd_sc_hd/latest/cells/sdlclkp/sky130_fd_sc_hd__sdlclkp_1.v diff --git a/rtl/mini/ip_overrides/BUFGCE.v b/rtl/mini/ip_overrides/BUFGCE.v new file mode 100644 index 00000000..792f8c7c --- /dev/null +++ b/rtl/mini/ip_overrides/BUFGCE.v @@ -0,0 +1,114 @@ +// retroSoC controlled override of the vendored OpenC906 BUFGCE.v. +// +// Source: openc906 dependency (dependencies.lock.json "openc906"), +// C906_RTL_FACTORY/gen_rtl/common/rtl/BUFGCE.v +// revision b0c06eb1f8b3bae663bd8b87eac89ff48e68a57f +// License: Apache-2.0 (T-Head Semiconductor) +// +// retroSoC change (OpenC906 integration manual chapter 3 ICG swap): with a +// PDK define and without PDK_BEHAV, the clock buffer-gate feeding the +// PLIC/CLINT divide-by-2 domain (aq_mp_clk_top.v apb_clk_buf) uses the +// process integrated clock-gating cell (same selection as +// gated_clk_cell.v; there is no scan enable on this instance, so SCE/TE are +// tied off). PDK_BEHAV and PDK-less builds keep the upstream behavioral +// latch-based gate byte-identical. Keep in sync when the lock revision +// changes. + +/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +module BUFGCE( + I, + CE, + O +); + +input I; +input CE ; +output O; + +`ifndef PDK_BEHAV +`ifdef PDK_IHP130 +`define _AQ_BUFGCE_IHP130_ +`endif +`ifdef PDK_ICS55 +`define _AQ_BUFGCE_ICS55_ +`endif +`ifdef PDK_SKY130 +`define _AQ_BUFGCE_SKY130_ +`endif +`ifdef PDK_GF180 +`define _AQ_BUFGCE_GF180_ +`endif +`endif + +`ifdef _AQ_BUFGCE_IHP130_ +sg13g2_slgcp_1 u_icg ( + .CLK (I), + .GATE (CE), + .SCE (1'b0), + .GCLK (O) +); +`elsif _AQ_BUFGCE_ICS55_ +ICGX1H7R u_icg ( + .CK (I), + .E (CE), + .ECK (O) +); +`elsif _AQ_BUFGCE_SKY130_ +sky130_fd_sc_hd__sdlclkp_1 u_icg ( + .CLK (I), + .GATE (CE), + .SCE (1'b0), + .GCLK (O) +); +`elsif _AQ_BUFGCE_GF180_ +gf180mcu_fd_sc_mcu7t5v0__icgtp_1 u_icg ( + .CLK (I), + .E (CE), + .TE (1'b0), + .Q (O), + .notifier (1'b0) +); +`else +reg clk_en_af_latch; +always @(I or CE) +begin + if(!I) + clk_en_af_latch <= CE; +end + +reg clk_en ; +always @ (clk_en_af_latch ) +begin + clk_en <= clk_en_af_latch; +end +assign O = I && clk_en ; +`endif + +`ifdef _AQ_BUFGCE_IHP130_ +`undef _AQ_BUFGCE_IHP130_ +`endif +`ifdef _AQ_BUFGCE_ICS55_ +`undef _AQ_BUFGCE_ICS55_ +`endif +`ifdef _AQ_BUFGCE_SKY130_ +`undef _AQ_BUFGCE_SKY130_ +`endif +`ifdef _AQ_BUFGCE_GF180_ +`undef _AQ_BUFGCE_GF180_ +`endif + +endmodule diff --git a/rtl/mini/ip_overrides/gated_clk_cell.v b/rtl/mini/ip_overrides/gated_clk_cell.v new file mode 100644 index 00000000..0afbed70 --- /dev/null +++ b/rtl/mini/ip_overrides/gated_clk_cell.v @@ -0,0 +1,131 @@ +// retroSoC controlled override of the vendored OpenC906 gated_clk_cell.v. +// +// Source: openc906 dependency (dependencies.lock.json "openc906"), +// C906_RTL_FACTORY/gen_rtl/clk/rtl/gated_clk_cell.v +// revision b0c06eb1f8b3bae663bd8b87eac89ff48e68a57f +// License: Apache-2.0 (T-Head Semiconductor) +// +// retroSoC change (OpenC906 integration manual chapter 3 ICG swap): with a +// PDK define and without PDK_BEHAV, the upstream pass-through clock gate is +// replaced by the process integrated clock-gating cell: +// PDK_IHP130 -> sg13g2_slgcp_1 (GATE=enable, SCE=scan enable) +// PDK_ICS55 -> ICGX1H7R (no test-enable pin; the scan enable is ORed +// into E so scan mode forces the clock on) +// PDK_SKY130 -> sky130_fd_sc_hd__sdlclkp_1 (GATE=enable, SCE=scan enable) +// PDK_GF180 -> gf180mcu_fd_sc_mcu7t5v0__icgtp_1 (E=enable, TE=scan enable) +// PDK_BEHAV and PDK-less builds keep the upstream pass-through +// byte-identical. Keep in sync when the lock revision changes. + +/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +module gated_clk_cell( + clk_in, + global_en, + module_en, + local_en, + external_en, + pad_yy_icg_scan_en, + clk_out +); + +input clk_in; +input global_en; +input module_en; +input local_en; +input external_en; +input pad_yy_icg_scan_en; +output clk_out; + +wire clk_en_bf_latch; +wire SE; + +assign clk_en_bf_latch = (global_en && (module_en || local_en)) || external_en ; + +// SE driven from primary input, held constant +assign SE = pad_yy_icg_scan_en; + +`ifndef PDK_BEHAV +`ifdef PDK_IHP130 +`define _AQ_GATED_CLK_CELL_IHP130_ +`endif +`ifdef PDK_ICS55 +`define _AQ_GATED_CLK_CELL_ICS55_ +`endif +`ifdef PDK_SKY130 +`define _AQ_GATED_CLK_CELL_SKY130_ +`endif +`ifdef PDK_GF180 +`define _AQ_GATED_CLK_CELL_GF180_ +`endif +`endif + +`ifdef _AQ_GATED_CLK_CELL_IHP130_ +sg13g2_slgcp_1 u_icg ( + .CLK (clk_in), + .GATE (clk_en_bf_latch), + .SCE (SE), + .GCLK (clk_out) +); +`elsif _AQ_GATED_CLK_CELL_ICS55_ +// ICGX1H7R has no test-enable pin; OR the scan enable into the enable input. +wire s_en_se; + +assign s_en_se = clk_en_bf_latch | SE; + +ICGX1H7R u_icg ( + .CK (clk_in), + .E (s_en_se), + .ECK (clk_out) +); +`elsif _AQ_GATED_CLK_CELL_SKY130_ +sky130_fd_sc_hd__sdlclkp_1 u_icg ( + .CLK (clk_in), + .GATE (clk_en_bf_latch), + .SCE (SE), + .GCLK (clk_out) +); +`elsif _AQ_GATED_CLK_CELL_GF180_ +gf180mcu_fd_sc_mcu7t5v0__icgtp_1 u_icg ( + .CLK (clk_in), + .E (clk_en_bf_latch), + .TE (SE), + .Q (clk_out), + .notifier (1'b0) +); +`else +// // &Connect( .clk_in (clk_in), @50 +// // .SE (SE), @51 +// // .external_en (clk_en_bf_latch), @52 +// // .clk_out (clk_out) @53 +// // ) ; @54 + +assign clk_out = clk_in; +`endif + +`ifdef _AQ_GATED_CLK_CELL_IHP130_ +`undef _AQ_GATED_CLK_CELL_IHP130_ +`endif +`ifdef _AQ_GATED_CLK_CELL_ICS55_ +`undef _AQ_GATED_CLK_CELL_ICS55_ +`endif +`ifdef _AQ_GATED_CLK_CELL_SKY130_ +`undef _AQ_GATED_CLK_CELL_SKY130_ +`endif +`ifdef _AQ_GATED_CLK_CELL_GF180_ +`undef _AQ_GATED_CLK_CELL_GF180_ +`endif + +endmodule diff --git a/rtl/mini/ip_overrides/tdt_gated_clk_cell.v b/rtl/mini/ip_overrides/tdt_gated_clk_cell.v new file mode 100644 index 00000000..f3e9fbd3 --- /dev/null +++ b/rtl/mini/ip_overrides/tdt_gated_clk_cell.v @@ -0,0 +1,190 @@ +// retroSoC controlled override of the vendored OpenC906 tdt_gated_clk_cell.v. +// +// Source: openc906 dependency (dependencies.lock.json "openc906"), +// C906_RTL_FACTORY/gen_rtl/tdt/rtl/common/tdt_gated_clk_cell.v +// revision b0c06eb1f8b3bae663bd8b87eac89ff48e68a57f +// License: Apache-2.0 (T-Head Semiconductor) +// +// retroSoC change (OpenC906 integration manual chapter 3 ICG swap): the +// upstream `ifdef TDT_GATED_CELL branch is preserved verbatim; with a PDK +// define and without PDK_BEHAV the debug module clock gate uses the process +// integrated clock-gating cell (same selection as gated_clk_cell.v; +// ICGX1H7R has no test-enable pin, so the scan enable is ORed into E). +// PDK_BEHAV and PDK-less builds keep the upstream pass-through +// byte-identical. Keep in sync when the lock revision changes. + +/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +module tdt_gated_clk_cell( + clk_in, + global_en, + module_en, + local_en, + external_en, + pad_yy_icg_scan_en, + clk_out +); + +input clk_in; +input global_en; +input module_en; +input local_en; +input external_en; +input pad_yy_icg_scan_en; +output clk_out; + +wire clk_en_bf_latch; +wire SE; + +assign clk_en_bf_latch = (global_en && (module_en || local_en)) || external_en ; + +// SE driven from primary input, held constant +assign SE = pad_yy_icg_scan_en; + +`ifndef PDK_BEHAV +`ifdef PDK_IHP130 +`define _TDT_GATED_CLK_CELL_IHP130_ +`endif +`ifdef PDK_ICS55 +`define _TDT_GATED_CLK_CELL_ICS55_ +`endif +`ifdef PDK_SKY130 +`define _TDT_GATED_CLK_CELL_SKY130_ +`endif +`ifdef PDK_GF180 +`define _TDT_GATED_CLK_CELL_GF180_ +`endif +`endif + +`ifdef TDT_GATED_CELL +tdt_gated_cell x_tdt_gated_cell( + .clk_in (clk_in), + .external_en (clk_en_bf_latch), + .SE (SE), + .clk_out (clk_out) + ); +//`ifdef TDT_SMIC +// `ifdef TDT_PROCESS55LL +//HVT_CLKLANQHDV8 x_gated_clk_cell( +//.CK(clk_in), +// `endif +//.TE(SE), +//.E(clk_en_bf_latch), +//.Q(clk_out)); +//`endif +//`ifdef TDT_TSMC +// `ifdef TDT_PROCESS40LP +//CKLNQD1BWP x_gated_clk_cell( +//.CP(clk_in), +//.TE(SE), +//.E(clk_en_bf_latch), +//.Q(clk_out)); +// `endif +// `ifdef TDT_PROCESS28HPC +// CKLNQD8BWP35P140 x_gated_clk_cell ( +// .CP (clk_in), +// .TE (SE), +// .E (clk_en_bf_latch), +// .Q (clk_out) +// ); +// `endif +//`endif +//`ifdef TDT_GSMC +// `ifdef TDT_PROCESS130 +//CLKGTPHD8X x_gated_clk_cell( +//.CK(clk_in), +// `endif +//.TE(SE), +//.E(clk_en_bf_latch), +//.Z(clk_out)); +//`endif +// +//`ifdef TDT_UMC +// `ifdef TDT_PROCESS28HDE +// PREICG_X4B_A9PP140ZTR_C30 x_gated_clk_cell ( +// .CK(clk_in), +// .SE(SE), +// .E(clk_en_bf_latch), +// .ECK(clk_out) +// ); +// `endif +// `ifdef TDT_PROCESS22HDE +// PREICG_X4B_A9PP140ZTS_C30 x_gated_clk_cell ( +// .CK(clk_in), +// .SE(SE), +// .E(clk_en_bf_latch), +// .ECK(clk_out) +// ); +// +// `endif +//`endif +`elsif _TDT_GATED_CLK_CELL_IHP130_ +sg13g2_slgcp_1 u_icg ( + .CLK (clk_in), + .GATE (clk_en_bf_latch), + .SCE (SE), + .GCLK (clk_out) +); +`elsif _TDT_GATED_CLK_CELL_ICS55_ +// ICGX1H7R has no test-enable pin; OR the scan enable into the enable input. +wire s_en_se; + +assign s_en_se = clk_en_bf_latch | SE; + +ICGX1H7R u_icg ( + .CK (clk_in), + .E (s_en_se), + .ECK (clk_out) +); +`elsif _TDT_GATED_CLK_CELL_SKY130_ +sky130_fd_sc_hd__sdlclkp_1 u_icg ( + .CLK (clk_in), + .GATE (clk_en_bf_latch), + .SCE (SE), + .GCLK (clk_out) +); +`elsif _TDT_GATED_CLK_CELL_GF180_ +gf180mcu_fd_sc_mcu7t5v0__icgtp_1 u_icg ( + .CLK (clk_in), + .E (clk_en_bf_latch), + .TE (SE), + .Q (clk_out), + .notifier (1'b0) +); +`else +//STN_CKGTPLT_V5_1 x_gated_clk_cell ( +// .CK (clk_in), +// .SE (SE), +// .EN (clk_en_bf_latch), +// .Q (clk_out) +//); +assign clk_out = clk_in; +`endif + +`ifdef _TDT_GATED_CLK_CELL_IHP130_ +`undef _TDT_GATED_CLK_CELL_IHP130_ +`endif +`ifdef _TDT_GATED_CLK_CELL_ICS55_ +`undef _TDT_GATED_CLK_CELL_ICS55_ +`endif +`ifdef _TDT_GATED_CLK_CELL_SKY130_ +`undef _TDT_GATED_CLK_CELL_SKY130_ +`endif +`ifdef _TDT_GATED_CLK_CELL_GF180_ +`undef _TDT_GATED_CLK_CELL_GF180_ +`endif + +endmodule diff --git a/rtl/tech/gf180_seq_sim_cells.v b/rtl/tech/gf180_seq_sim_cells.v index 3ee75618..5fd851df 100644 --- a/rtl/tech/gf180_seq_sim_cells.v +++ b/rtl/tech/gf180_seq_sim_cells.v @@ -53,3 +53,21 @@ module gf180mcu_fd_sc_mcu7t5v0__dffsnq_1 ( else Q <= D; end endmodule + +// The upstream icgtp functional model references a UDP latch primitive +// (UDP_GF018hv5v_mcu_sc7_TT_1P8V_25C_verilog_nonpg_MGM_N_IQ_LATCH_UDP) that +// is not shipped anywhere in the locked GF180 checkout, so the vendor model +// cannot elaborate; this functional model retains the PDK cell interface. +module gf180mcu_fd_sc_mcu7t5v0__icgtp_1 ( + input wire TE, + input wire E, + input wire CLK, + output wire Q, + input wire notifier +); + reg s_en_latch; + always @(CLK or E or TE) begin + if (!CLK) s_en_latch <= E | TE; + end + assign Q = CLK & s_en_latch; +endmodule diff --git a/scripts/generate_openc906.py b/scripts/generate_openc906.py index 8f790a68..87736308 100644 --- a/scripts/generate_openc906.py +++ b/scripts/generate_openc906.py @@ -18,8 +18,16 @@ for their vendored counterparts: integration manual chapter 3 memory swap). Each override keeps the upstream behavioral ``aq_f_spsram_*`` instance by default and substitutes IHP130 ``RM_IHPSG13_1P_*`` macro combinations (depth/width stacking per manual - section 3.1.5) only when the build defines ``PDK_IHP130`` and + section 3.1.5) or exact-geometry ICS55 ``ics55_ecos_sram_*`` macros only + when the build defines ``PDK_IHP130``/``PDK_ICS55`` and ``HAVE_SRAM_MACRO`` without ``PDK_BEHAV``. +- ``gated_clk_cell.v`` / ``tdt_gated_clk_cell.v`` / ``BUFGCE.v``: the + clock-gating cells (manual chapter 3 ICG swap). Each override keeps the + upstream default (pass-through for the two ``*_gated_clk_cell`` wrappers, + behavioral latch gate for ``BUFGCE``) unless a PDK define is set without + ``PDK_BEHAV``, in which case the process ICG cell is instantiated + (``sg13g2_slgcp_1`` / ``ICGX1H7R`` / ``sky130_fd_sc_hd__sdlclkp_1`` / + ``gf180mcu_fd_sc_mcu7t5v0__icgtp_1``). All sources are concatenated into a single compilation unit (``openc906_combined.v``) because gen_rtl relies on header macros being @@ -88,6 +96,18 @@ OVERRIDES = { "aq_spsram_64x98.v", "99680fb11271eee6cfe6ff7aaa95cbdd04ef4f78d7b0e23a18c17ef064a8bedf", ), + "C906_RTL_FACTORY/gen_rtl/clk/rtl/gated_clk_cell.v": ( + "gated_clk_cell.v", + "22a4a5f41c7733bd4935adc8a036870a110a8e2f2a70f1f3cf64476b7a49eb9e", + ), + "C906_RTL_FACTORY/gen_rtl/tdt/rtl/common/tdt_gated_clk_cell.v": ( + "tdt_gated_clk_cell.v", + "9c38f1d71a3aaa64e00d2aa7d5a43f5836080c604f245dd414a85935241d26bd", + ), + "C906_RTL_FACTORY/gen_rtl/common/rtl/BUFGCE.v": ( + "BUFGCE.v", + "b0907982b81c64494756d7f62a3a35bf961f6cbf7d54241460a476dde36a333a", + ), }