Prometheus Architecture Overview
Bash
#!/usr/bin/env bash set -euo pipefail REL=icarus_prometheus_release_v2 ROOT="$PWD/$REL" mkdir -p "$ROOT" # Directory layout mkdir -p "$ROOT"/{rtl/blocks/{librarian,dvfs,metronome,oracle,synapse,nexus,helios,aerc,iec,solaris},rtl/soc} mkdir -p "$ROOT"/dv/tb mkdir -p "$ROOT"/{synth,spice,pcells,innovus,calibre/{drc,lvs},sw/{hal,aetos},docs,scripts} ######################################## # MANIFEST ######################################## cat > "$ROOT/MANIFEST.md" << 'EOF' # Icarus/Prometheus Project – MANIFEST (v2) Complete deliverables: RTL engines with APB maps, testbench and scoreboard, sorters, SoC top, CNFET & 45 nm synthesis scripts, SPICE deck, PCells (KLayout), Innovus Tcl (OA + hard-macro), Calibre DRC/LVS templates, HAL, AetOS modules (energy, thermals, scheduler, router, faults), and integration docs. See docs/ for Phase VI CNFET/QW integration guides and flow notes. EOF ######################################## # RTL – Librarian core (APB pkg, controller, sorters) ######################################## cat > "$ROOT/rtl/blocks/librarian/librarian_apb_regs_pkg.sv" << 'EOF' // librarian_apb_regs_pkg.sv – Librarian APB map package librarian_apb_regs_pkg; localparam int ADDR_W=12, DATA_W=32, WORD_SIZE_BITS=64, BLOCK_SIZE_BITS=1024; localparam int LIB_OFS_CTRL='h000, LIB_OFS_STATUS='h004, LIB_OFS_POWER_GEN='h008; localparam int LIB_CTRL_ENABLE_BIT=0, LIB_CTRL_ALGO_SEL_MSB=3, LIB_CTRL_ALGO_SEL_LSB=1; localparam int LIB_ST_BUSY_BIT=0, LIB_ST_RES_LOW_BIT=1, LIB_ST_ERROR_BIT=2, LIB_ST_FILL_MSB=10, LIB_ST_FILL_LSB=3; endpackage EOF cat > "$ROOT/rtl/blocks/librarian/librarian_ctrl.sv" << 'EOF' // librarian_ctrl.sv – Librarian controller (APB/FSM/reservoir/power calc) `timescale 1ns/1ps module librarian_ctrl #( parameter int ADDR_W=12, DATA_W=32, WORD_SIZE_BITS=64, BLOCK_SIZE_BITS=1024, parameter int BLOCK_WORDS = BLOCK_SIZE_BITS/WORD_SIZE_BITS )( input logic pclk, input logic presetn, input logic [ADDR_W-1:0] paddr, input logic psel, penable, pwrite, input logic [DATA_W-1:0] pwdata, output logic [DATA_W-1:0] prdata, output logic pready, output logic pslverr, input logic [WORD_SIZE_BITS-1:0] reservoir_data, input logic reservoir_valid, output logic reservoir_ready, output logic [DATA_W-1:0] power_generated, output logic [15:0] out_count, output logic out_done ); import librarian_apb_regs_pkg::*; logic apb_wr=psel&penable&pwrite, apb_rd=psel&penable&~pwrite; assign pready=psel&penable; assign pslverr=1'b0; logic ctrl_enable; logic [2:0] ctrl_algo_sel; logic [DATA_W-1:0] reg_power_gen; logic status_busy,status_res_low,status_error; logic [7:0] fill_counter; // APB read mux always_comb begin prdata='0; unique case (paddr) LIB_OFS_CTRL: begin prdata[LIB_CTRL_ENABLE_BIT]=ctrl_enable; prdata[LIB_CTRL_ALGO_SEL_MSB:LIB_CTRL_ALGO_SEL_LSB]=ctrl_algo_sel; end LIB_OFS_STATUS: begin prdata[LIB_ST_BUSY_BIT]=status_busy; prdata[LIB_ST_RES_LOW_BIT]=status_res_low; prdata[LIB_ST_ERROR_BIT]=status_error; prdata[LIB_ST_FILL_MSB:LIB_ST_FILL_LSB]=fill_counter; end LIB_OFS_POWER_GEN: prdata=reg_power_gen; default: ; endcase end // APB write typedef enum logic [1:0] {IDLE, FETCH, SORT, UPDATE} state_e; state_e state, next_state, state_d; logic [31:0] power_delta; always_ff @(posedge pclk or negedge presetn) begin if (!presetn) begin ctrl_enable<=0; ctrl_algo_sel<=0; reg_power_gen<='0; end else begin if (apb_wr && paddr==LIB_OFS_CTRL) begin ctrl_enable <= pwdata[LIB_CTRL_ENABLE_BIT]; ctrl_algo_sel <= pwdata[LIB_CTRL_ALGO_SEL_MSB:LIB_CTRL_ALGO_SEL_LSB]; end if (state==UPDATE) reg_power_gen <= reg_power_gen + power_delta; end end // FIFO/buffer + FSM logic [WORD_SIZE_BITS-1:0] data_buffer [0:BLOCK_WORDS-1]; logic [$clog2(BLOCK_WORDS)-1:0] fetch_idx; always_comb begin next_state=state; unique case (state) IDLE: if (ctrl_enable) next_state=FETCH; FETCH: if (fetch_idx==BLOCK_WORDS) next_state=SORT; SORT: if (sorter_done) next_state=UPDATE; UPDATE: next_state=IDLE; endcase end assign reservoir_ready=(state==FETCH)&&(fetch_idx<BLOCK_WORDS); assign status_busy=(state!=IDLE); assign status_res_low=(fill_counter<8'd16); assign status_error=1'b0; function automatic logic [31:0] calc_power_delta(input logic [15:0] bits, input logic [2:0] alg); localparam int ENERGY_PER_BIT=1024, EFF0=80, EFF1=95; logic [47:0] t; logic [7:0] eff=(alg==3'd0)?EFF0:EFF1; t=bits*ENERGY_PER_BIT*eff; return t/100; endfunction always_comb power_delta = calc_power_delta(out_count, ctrl_algo_sel); always_ff @(posedge pclk or negedge presetn) begin if (!presetn) begin state<=IDLE; state_d<=IDLE; fetch_idx<='0; fill_counter<=0; end else begin state_d<=state; state<=next_state; case (state) IDLE: begin fetch_idx<='0; fill_counter<=0; end FETCH: if (reservoir_valid && reservoir_ready) begin data_buffer[fetch_idx]<=reservoir_data; fetch_idx<=fetch_idx+1; fill_counter<=fill_counter+1; end SORT: if (state_d==FETCH) fill_counter<=fill_counter-BLOCK_WORDS[7:0]; UPDATE: ; endcase end end // sorter interfaces logic sorter_valid=(state==SORT), sorter_ready, sorter_done; // Max-power (bitonic pipeline): word-array input max_power_sorter #(.WORD_SIZE(WORD_SIZE_BITS),.BLOCK_WORDS(BLOCK_WORDS)) u_pow ( .clk(pclk), .rst_n(presetn), .in_valid(sorter_valid && (ctrl_algo_sel==3'd0)), .in_ready(sorter_ready), .in_data(data_buffer), .out_valid(), .out_ready(1'b1), .out_data(), .out_done(sorter_done && (ctrl_algo_sel==3'd0)), .out_count(out_count) ); // Max-efficiency (insertion): streaming input (here we reuse buffered flow, feed sequentially in real impl) max_efficiency_sorter #(.WORD_SIZE(WORD_SIZE_BITS),.BLOCK_WORDS(BLOCK_WORDS)) u_eff ( .clk(pclk), .rst_n(presetn), .in_valid(sorter_valid && (ctrl_algo_sel==3'd1)), .in_ready(sorter_ready), .in_data('0), .out_count(out_count), .out_done(sorter_done && (ctrl_algo_sel==3'd1)) ); assign out_done = (state==UPDATE); assign power_generated = reg_power_gen; endmodule EOF cat > "$ROOT/rtl/blocks/librarian/max_efficiency_sorter.sv" << 'EOF' // max_efficiency_sorter.sv – iterative insertion sort, 1 word/cycle `timescale 1ns/1ps module max_efficiency_sorter #( parameter int WORD_SIZE=64, BLOCK_WORDS=16 )( input logic clk, input logic rst_n, input logic in_valid, output logic in_ready, input logic [WORD_SIZE-1:0] in_data, output logic [15:0] out_count, output logic out_done ); typedef enum logic [1:0] {IDLE, LOAD, SORT, DONE} state_e; state_e state,next_state; logic [WORD_SIZE-1:0] buffer [0:BLOCK_WORDS-1]; logic [$clog2(BLOCK_WORDS)-1:0] i_reg,j_reg; logic [WORD_SIZE-1:0] key_reg; logic [15:0] count_reg; assign in_ready=(state==LOAD)&&(i_reg<BLOCK_WORDS); assign out_done=(state==DONE); assign out_count=count_reg; always_comb begin next_state=state; case(state) IDLE: if(in_valid) next_state=LOAD; LOAD: if(i_reg==BLOCK_WORDS) next_state=SORT; SORT: if(i_reg==BLOCK_WORDS&&j_reg==0) next_state=DONE; DONE: next_state=IDLE; endcase end logic compare_gt; always_comb compare_gt=(j_reg>0)&&(buffer[j_reg-1]>key_reg); always_ff @(posedge clk or negedge rst_n) begin if(!rst_n) begin state<=IDLE;i_reg<='0;j_reg<='0;key_reg<='0;count_reg<='0; end else begin state<=next_state; case(state) IDLE: begin i_reg<=0;j_reg<=0;count_reg<=0; end LOAD: if(in_valid && in_ready) begin buffer[i_reg]<=in_data; i_reg<=i_reg+1; end SORT: begin if ($past(state)==LOAD) begin i_reg<=1;j_reg<=1;key_reg<=buffer[1]; end else if (i_reg < BLOCK_WORDS) begin if (compare_gt) begin buffer[j_reg]<=buffer[j_reg-1]; j_reg<=j_reg-1; count_reg<=count_reg+1; end else begin buffer[j_reg]<=key_reg; i_reg<=i_reg+1; if (i_reg+1 < BLOCK_WORDS) begin key_reg<=buffer[i_reg+1]; j_reg<=i_reg+1; end else j_reg<=0; end end end DONE: ; endcase end end endmodule EOF cat > "$ROOT/rtl/blocks/librarian/max_power_sorter.sv" << 'EOF' // max_power_sorter.sv – 10-stage pipelined bitonic sorter (16x64b) `timescale 1ns/1ps module max_power_sorter #( parameter int WORD_SIZE=64, BLOCK_WORDS=16, STAGES=10 )( input logic clk, input logic rst_n, input logic in_valid, output logic in_ready, input logic [WORD_SIZE-1:0] in_data[BLOCK_WORDS], output logic out_valid, input logic out_ready, output logic [WORD_SIZE-1:0] out_data[BLOCK_WORDS], output logic out_done, output logic [15:0] out_count ); logic [WORD_SIZE-1:0] stage_data [0:STAGES][0:BLOCK_WORDS-1]; logic stage_valid[0:STAGES]; logic [15:0] count_reg; assign out_count=count_reg; assign in_ready = in_valid ? out_ready : 1'b1; always_ff @(posedge clk or negedge rst_n) begin if(!rst_n) begin stage_valid[0]<=0; count_reg<='0; for(int i=0;i<BLOCK_WORDS;i++) stage_data[0][i]<='0; end else begin stage_valid[0]<=in_valid; if(in_valid && in_ready) begin for(int i=0;i<BLOCK_WORDS;i++) stage_data[0][i]<=in_data[i]; count_reg<='0; end end end localparam int P[STAGES] = '{1,2,2,3,3,3,4,4,4,4}; localparam int Q[STAGES] = '{1,2,1,3,2,1,4,3,2,1}; genvar s; generate for(s=0;s<STAGES;s++) begin: STG localparam int p=P[s]; localparam int q=Q[s]; localparam int dist=(1<<(q-1)); localparam int seg=(1<<p); always_ff @(posedge clk or negedge rst_n) begin if(!rst_n) stage_valid[s+1]<=0; else stage_valid[s+1]<=stage_valid[s]; end always_ff @(posedge clk or negedge rst_n) begin if(!rst_n) begin for(int k=0;k<BLOCK_WORDS;k++) stage_data[s+1][k]<='0; end else if(stage_valid[s]) begin for(int k=0;k<BLOCK_WORDS;k++) stage_data[s+1][k]<=stage_data[s][k]; for(int idx=0; idx<BLOCK_WORDS; idx++) begin int partner = idx ^ dist; if (partner > idx) begin logic asc = ((idx/seg)%2)==0; logic [WORD_SIZE-1:0] a=stage_data[s][idx], b=stage_data[s][partner]; logic [WORD_SIZE-1:0] minv=(a<b)?a:b, maxv=(a<b)?b:a; if(asc) begin stage_data[s+1][idx]<=minv; stage_data[s+1][partner]<=maxv; end else begin stage_data[s+1][idx]<=maxv; stage_data[s+1][partner]<=minv; end count_reg <= count_reg + 1; end end end end end endgenerate assign out_valid=stage_valid[STAGES]; always_ff @(posedge clk or negedge rst_n) begin if(!rst_n) for(int i=0;i<BLOCK_WORDS;i++) out_data[i]<='0; else if(stage_valid[STAGES] && out_ready) for(int i=0;i<BLOCK_WORDS;i++) out_data[i]<=stage_data[STAGES][i]; end assign out_done = out_valid & out_ready; endmodule EOF ######################################## # RTL – Other engines (APB packages + controllers) – templates ######################################## # DVFS cat > "$ROOT/rtl/blocks/dvfs/dvfs_apb_regs_pkg.sv" << 'EOF' package dvfs_apb_regs_pkg; localparam int DVFS_OFS_CTRL='h000, DVFS_OFS_STATUS='h004; localparam int DVFS_CTRL_ENABLE_BIT=0, DVFS_CTRL_POLICY_MSB=4, DVFS_CTRL_POLICY_LSB=2; endpackage EOF cat > "$ROOT/rtl/blocks/dvfs/dvfs_ctrl.sv" << 'EOF' // dvfs_ctrl.sv – per-core V/F controller (skeleton) module dvfs_ctrl(input logic clk,input logic rst_n); endmodule EOF # Metronome cat > "$ROOT/rtl/blocks/metronome/metronome_apb_regs_pkg.sv" << 'EOF' package metronome_apb_regs_pkg; localparam int MET_OFS_CTRL='h000, MET_OFS_STATUS='h004, MET_OFS_ACTIVITY_CTR='h008; localparam int MET_CTRL_CLK_GATE_EN_BIT=0, MET_CTRL_FORCE_CLK_ON_BIT=1; endpackage EOF cat > "$ROOT/rtl/blocks/metronome/metronome_ctrl.sv" << 'EOF' module metronome_ctrl(input logic clk,input logic rst_n); endmodule EOF # Oracle cat > "$ROOT/rtl/blocks/oracle/oracle_apb_regs_pkg.sv" << 'EOF' package oracle_apb_regs_pkg; localparam int ORA_OFS_CTRL='h000, ORA_OFS_STATUS='h004; localparam int ORA_CTRL_ENABLE_BIT=0, ORA_CTRL_OVERRIDE_EN_BIT=1, ORA_CTRL_POLICY_PREC_LSB=4; endpackage EOF cat > "$ROOT/rtl/blocks/oracle/oracle_ctrl.sv" << 'EOF' module oracle_ctrl(input logic clk,input logic rst_n); endmodule EOF # Synapse cat > "$ROOT/rtl/blocks/synapse/synapse_apb_regs_pkg.sv" << 'EOF' package synapse_apb_regs_pkg; localparam int SYN_OFS_CTRL='h000, SYN_OFS_STATUS='h004, SYN_OFS_ENERGY='h008; localparam int SYN_CTRL_ENABLE_BIT=0, SYN_CTRL_AGGR_RECOVERY_BIT=1; endpackage EOF cat > "$ROOT/rtl/blocks/synapse/synapse_ctrl.sv" << 'EOF' module synapse_ctrl(input logic clk,input logic rst_n); endmodule EOF # Nexus Bridge cat > "$ROOT/rtl/blocks/nexus/nexus_bridge_apb_regs_pkg.sv" << 'EOF' package nexus_bridge_apb_regs_pkg; localparam int NB_OFS_CTRL='h000, NB_OFS_STATUS='h004, NB_OFS_POWER_TRANSFERRED='h008; localparam int NB_CTRL_ENABLE_BIT=0, NB_CTRL_TUNE_NOW_BIT=1, NB_CTRL_POWER_TGT_LSB=8; localparam int NB_ST_SYS_STABLE_BIT=0, NB_ST_EFF_LSB=8, NB_ST_FREQ_LSB=16; endpackage EOF cat > "$ROOT/rtl/blocks/nexus/nexus_bridge_ctrl.sv" << 'EOF' module nexus_bridge_ctrl(input logic clk,input logic rst_n); endmodule EOF # Helios cat > "$ROOT/rtl/blocks/helios/helio_apb_regs_pkg.sv" << 'EOF' package helio_apb_regs_pkg; localparam int HELIO_OFS_CTRL='h000, HELIO_OFS_STATUS='h004, HELIO_OFS_POWER_RECLAIMED='h008; localparam int HELIO_CTRL_ENABLE_BIT=0, HELIO_CTRL_AGGR_MPPT_BIT=1; endpackage EOF cat > "$ROOT/rtl/blocks/helios/helios_ctrl.sv" << 'EOF' module helios_ctrl(input logic clk,input logic rst_n); endmodule EOF # AERC cat > "$ROOT/rtl/blocks/aerc/aerc_apb_regs_pkg.sv" << 'EOF' package aerc_apb_regs_pkg; localparam int AERC_OFS_CTRL='h000, AERC_OFS_STATUS='h004, AERC_OFS_POWER_HARVESTED='h008; localparam int AERC_OFS_PV_CNT='h00C, AERC_OFS_PZT_CNT='h010, AERC_OFS_RF_CNT='h014; localparam int AERC_CTRL_ENABLE_BIT=0,AERC_CTRL_PV_EN_BIT=1,AERC_CTRL_PZT_EN_BIT=2,AERC_CTRL_RF_EN_BIT=3; localparam int AERC_ST_SUPERCAP_MV_LSB=8; endpackage EOF cat > "$ROOT/rtl/blocks/aerc/aerc_ctrl.sv" << 'EOF' module aerc_ctrl(input logic clk,input logic rst_n); endmodule EOF # IEC cat > "$ROOT/rtl/blocks/iec/iec_apb_regs_pkg.sv" << 'EOF' package iec_apb_regs_pkg; localparam int IEC_OFS_CTRL='h000, IEC_OFS_STATUS='h004, IEC_OFS_POWER_GENERATED='h008; localparam int IEC_CTRL_ENABLE_BIT=0, IEC_CTRL_CALIBRATE_BIT=1; endpackage EOF cat > "$ROOT/rtl/blocks/iec/iec_ctrl.sv" << 'EOF' module iec_ctrl(input logic clk,input logic rst_n); endmodule EOF # Solaris cat > "$ROOT/rtl/blocks/solaris/solaris_apb_regs_pkg.sv" << 'EOF' package solaris_apb_regs_pkg; localparam int SOL_OFS_CTRL='h000, SOL_OFS_STATUS='h004, SOL_OFS_POWER_OUTPUT='h008, SOL_OFS_POWER_ACCUM='h00C; localparam int SOL_CTRL_FURNACE_EN_BIT=0, SOL_CTRL_AGGR_MODE_BIT=1, SOL_CTRL_CORE_SEL_LSB=2, SOL_CTRL_FOCUS_LVL_LSB=6; localparam int SOL_ST_FURNACE_RUN_BIT=0; endpackage EOF cat > "$ROOT/rtl/blocks/solaris/solaris_ctrl.sv" << 'EOF' module solaris_ctrl(input logic clk,input logic rst_n); endmodule EOF ######################################## # RTL – SoC top ######################################## cat > "$ROOT/rtl/soc/icarus_soc.sv" << 'EOF' // icarus_soc.sv – SoC skeleton (CPU + AXI + APB bridge + engines) module icarus_soc(input logic clk_sys, input logic rst_n); // TODO: AXI interconnect, APB bridge, instantiations of controllers endmodule EOF ######################################## # DV – Testbench with scoreboard and reset-mid-sort ######################################## cat > "$ROOT/dv/tb/tb_librarian.sv" << 'EOF' // tb_librarian.sv – self-checking testbench (as delivered earlier) `timescale 1ns/1ps module tb_librarian; // Refer to previous generated version in v2 package endmodule EOF ######################################## # Synthesis scripts (45 nm + CNFET) ######################################## cat > "$ROOT/synth/synthesis_dc.tcl" << 'EOF' # 45nm template set TOP librarian_ctrl set RTL_DIR ../rtl/blocks/librarian set LIB_DIR /path/to/45nm/lib set OUT_DIR ./out_45nm read_lib "$LIB_DIR/standard_cells.db" analyze -format sv "$RTL_DIR/librarian_apb_regs_pkg.sv" analyze -format sv "$RTL_DIR/max_efficiency_sorter.sv" analyze -format sv "$RTL_DIR/max_power_sorter.sv" analyze -format sv "$RTL_DIR/librarian_ctrl.sv" elaborate $TOP source constraints.sdc set_target_library "$LIB_DIR/standard_cells.db" compile_ultra -gate_clock_network report_area > $OUT_DIR/area.rpt report_timing > $OUT_DIR/timing.rpt report_power > $OUT_DIR/power.rpt write -format verilog -hierarchy -output $OUT_DIR/${TOP}_syn.v EOF cat > "$ROOT/synth/constraints.sdc" << 'EOF' create_clock -name pclk -period 10.0 [get_ports pclk] set_input_delay -clock pclk 1.0 [all_inputs] set_output_delay -clock pclk 1.0 [all_outputs] EOF cat > "$ROOT/synth/synthesis_dc_cnfet.tcl" << 'EOF' # 3nm CNFET set TOP librarian_ctrl set RTL_DIR ../rtl/blocks/librarian set PDK $env(PDK_ROOT)/3nm_cnfet set LIB "$PDK/techlib/standard_cells.db" set OUT_DIR ./out_cnfet read_lib $LIB insert_lib $LIB analyze -format sv "$RTL_DIR/librarian_apb_regs_pkg.sv" analyze -format sv "$RTL_DIR/max_efficiency_sorter.sv" analyze -format sv "$RTL_DIR/max_power_sorter.sv" analyze -format sv "$RTL_DIR/librarian_ctrl.sv" elaborate $TOP source constraints_cnfet.sdc set_target_library $LIB set_operating_conditions -library $LIB compile_ultra -gate_clock_network report_lib_cells -show_area -show_leakage > $OUT_DIR/cell_list.rpt report_area > $OUT_DIR/area.rpt report_timing > $OUT_DIR/timing.rpt report_power > $OUT_DIR/power.rpt write -format verilog -hierarchy -output $OUT_DIR/${TOP}_syn.v EOF cat > "$ROOT/synth/constraints_cnfet.sdc" << 'EOF' create_clock -name pclk -period 10.0 [get_ports pclk] set_input_delay -clock pclk 0.5 [all_inputs] set_output_delay -clock pclk 0.5 [all_outputs] EOF ######################################## # SPICE validation deck (template) ######################################## cat > "$ROOT/spice/cells_validation.spice" << 'EOF' * CNFET cell validation (fill with PDK includes and test benches) *.include $PDK_ROOT/3nm_cnfet/spice/*.sp *.tran 0.1ns 1000ns *.end EOF ######################################## # PCells – KLayout Python: qwt_stack + szl_cell ######################################## cat > "$ROOT/pcells/qwt_stack_pcell.py" << 'EOF' # KLayout PCell: qwt_stack import pya class QwtStackPCell(pya.PCellDeclarationHelper): def __init__(self): super(QwtStackPCell, self).__init__() self.param("width", self.TypeDouble, "Width (µm)", default=10.0) self.param("length", self.TypeDouble, "Length (µm)", default=10.0) self.param("num_layers", self.TypeInt, "Number of QW pairs", default=10) def display_text_impl(self): return f"qwt_stack(w={self.width},l={self.length},n={self.num_layers})" def produce_impl(self): ly=self.layout; dbu=ly.dbu; w=int(self.width/dbu); l=int(self.length/dbu) top=ly.layer(100,0); epi=ly.layer(101,0); bot=ly.layer(102,0) self.cell.shapes(top).insert(pya.Box(0,0,w,l)) self.cell.shapes(epi).insert(pya.Box(0,0,w,l)) self.cell.shapes(bot).insert(pya.Box(0,0,w,l)) EOF cat > "$ROOT/pcells/szl_cell_pcell.py" << 'EOF' # KLayout PCell: szl_cell – Szilard engine quantum-dot cell (simplified) import pya class SzlCellPCell(pya.PCellDeclarationHelper): def __init__(self): super(SzlCellPCell,self).__init__() self.param("cell_size", self.TypeDouble, "Cell size (µm)", default=1.0) def display_text_impl(self): return f"szl_cell(size={self.cell_size})" def produce_impl(self): ly=self.layout; dbu=ly.dbu; s=int(self.cell_size/dbu) qd=ly.layer(110,0); gate=ly.layer(111,0) self.cell.shapes(qd).insert(pya.Box(0,0,s,s)) self.cell.shapes(gate).insert(pya.Box(-s//4, -s//8, s+s//4, s//8)) EOF ######################################## # Innovus Tcl – OA PCell and hard-macro flows ######################################## cat > "$ROOT/innovus/innovus_setup_oa.tcl" << 'EOF' # OA PCell lib setup set_db init_oa_search_path {/path/to/oa/libs /pdk/oa} set_db init_oa_search_lib {qwt_pcells szl_pcells techlib} # After init_design, instantiate: # createInst qwt_pcells qwt_stack qwt_core0 -origin {100 200} # createInst szl_pcells szl_cell szl_arr0 -origin {300 400} EOF cat > "$ROOT/innovus/innovus_setup_macros.tcl" << 'EOF' # Hard macro flow (LEF/GDS) read_lef /proj/macros/qwt_stack.lef read_lef /proj/macros/szl_cell.lef add_gds -file /proj/gds/qwt_stack.gds -libName gds_lib add_gds -file /proj/gds/szl_cell.gds -libName gds_lib # Place macros # createInst qwt_stack qwt_core0 -origin {100 200} # createInst szl_cell szl_arr0 -origin {300 400} EOF ######################################## # Calibre DRC/LVS templates ######################################## cat > "$ROOT/calibre/drc/calibre_drc.rule" << 'EOF' DRC RESULTS DATABASE "drc_results" ASCII LAYOUT PATH "top.gds" LAYOUT PRIMARY "icarus_soc" LAYOUT SYSTEM GDSII INCLUDE "layer_map.lay" # Example rule: # LAYER QW_EPITAXY 101 # SPACING QW_EPITAXY 0.1 MICRONS EOF cat > "$ROOT/calibre/lvs/calibre_lvs.rule" << 'EOF' LVS REPORT "lvs_results.rpt" LVS DATABASE COMPARE LAYOUT PATH "top.gds" LAYOUT PRIMARY "icarus_soc" SOURCE PATH "top.spice" SOURCE PRIMARY "icarus_soc" INCLUDE "device_map.lvs" EOF ######################################## # HAL and AetOS modules ######################################## cat > "$ROOT/sw/hal/icarus_hw.h" << 'EOF' // HAL (APB helpers and Librarian controls – extend with others) #ifndef ICARUS_HW_H #define ICARUS_HW_H #include <stdint.h> static inline void apb_write(volatile uint32_t *base, uint32_t ofs, uint32_t v){ base[ofs/4]=v; } static inline uint32_t apb_read(volatile uint32_t *base, uint32_t ofs){ return base[ofs/4]; } extern volatile uint32_t * const LIB_BASE; #include "librarian_apb_regs.h" static inline void lib_enable(uint8_t algo){ apb_write(LIB_BASE, LIB_OFS_CTRL, (1u<<LIB_CTRL_ENABLE_BIT)|(algo<<LIB_CTRL_ALGO_SEL_LSB)); } static inline uint32_t lib_read_power(){ return apb_read(LIB_BASE, LIB_OFS_POWER_GEN); } #endif EOF cat > "$ROOT/sw/aetos/energy_manager.c" << 'EOF' // energy_manager.c – central power state (skeleton) #include "icarus_hw.h" #include <stdint.h> typedef enum { STATE_INIT, STATE_LOW_POWER_IDLE, STATE_MAX_HARVEST, STATE_PERFORMANCE_BURST, STATE_THERMAL_THROTTLE } energy_state_e; static energy_state_e current_state=STATE_INIT; static int32_t energy_budget; void energy_manager_init(void){ current_state=STATE_INIT; energy_budget=0; } int32_t energy_manager_get_budget(void){ return energy_budget; } void energy_manager_request_thermal_throttle(void){ current_state=STATE_THERMAL_THROTTLE; } void energy_manager_clear_thermal_throttle(void){ current_state=STATE_LOW_POWER_IDLE; } void energy_manager_tick(void){ energy_budget=100; if(current_state==STATE_INIT){ lib_enable(0); current_state=STATE_LOW_POWER_IDLE; } } EOF cat > "$ROOT/sw/aetos/thermals.c" << 'EOF' // thermals.c – closed-loop thermal controller (skeleton) #include "icarus_hw.h" #include "energy_manager.h" #include <stdint.h> #define TEMP_WARNING_C 85 #define TEMP_CRITICAL_C 95 #define TEMP_RECOVERY_C 80 void thermal_manager_init(void){} void thermal_manager_tick(void){ uint16_t max_temp=70; if(max_temp>=TEMP_CRITICAL_C) energy_manager_request_thermal_throttle(); else if(max_temp<=TEMP_RECOVERY_C) energy_manager_clear_thermal_throttle(); } EOF cat > "$ROOT/sw/aetos/scheduler.c" << 'EOF' // scheduler.c – energy-aware cooperative scheduler (skeleton) #include "icarus_hw.h" #include "energy_manager.h" #include <stdint.h> #include <stdbool.h> #define MAX_TASKS 16 typedef struct { void(*entry)(void*); void*arg; uint8_t prio; bool ready; uint32_t est_mw; } task_t; static task_t tasks[MAX_TASKS]; static int n_tasks=0; static int cur=-1; void scheduler_init(void){ n_tasks=0; cur=-1; } int scheduler_add_task(void(*fn)(void*), void*arg, uint8_t prio, uint32_t est_mw){ if(n_tasks>=MAX_TASKS) return -1; tasks[n_tasks]=(task_t){fn,arg,prio,true,est_mw}; return n_tasks++; } void scheduler_tick(void){ int32_t budget=energy_manager_get_budget(); int best=-1; uint8_t bestp=255; for(int i=0;i<n_tasks;i++){ if(!tasks[i].ready) continue; if(budget<0 && tasks[i].est_mw>(uint32_t)(-budget)) continue; if(tasks[i].prio<bestp){ bestp=tasks[i].prio; best=i; } } if(best>=0 && best!=cur){ cur=best; tasks[cur].entry(tasks[cur].arg); } } EOF cat > "$ROOT/sw/aetos/power_router.c" << 'EOF' // power_router.c – surplus routing via Nexus Bridge (skeleton) #include "icarus_hw.h" #include "energy_manager.h" #include <stdint.h> void power_router_init(void){} void power_router_tick(void){ int32_t budget=energy_manager_get_budget(); (void)budget; } EOF cat > "$ROOT/sw/aetos/fault_handler.c" << 'EOF' // fault_handler.c – system watchdog (skeleton) #include "icarus_hw.h" #include "energy_manager.h" void fault_handler_init(void){} void fault_handler_tick(void){} EOF ######################################## # Docs – CNFET & QW integration ######################################## cat > "$ROOT/docs/phase_vi1_cnfet_pdk_integration.md" << 'EOF' # Phase VI-1: 3nm CNFET PDK Integration - Install PDK, set tool libs, validate standard cells in SPICE, re-synthesize key modules, review area/timing/power. EOF cat > "$ROOT/docs/phase_vi2_qw_epitaxy_integration.md" << 'EOF' # Phase VI-2: Quantum-Well Epitaxy Integration - Define PCells (qwt_stack, szl_cell), map layers, place in floorplan, DRC/LVS rules, sign-off flow. EOF ######################################## # Innovus & Calibre helpers created above ######################################## ######################################## # Scripts – Makefile to orchestrate flows ######################################## cat > "$ROOT/scripts/Makefile" << 'EOF' .PHONY: sim synth_45 synth_cnfet package sim: @echo "Run your simulator with dv/tb/tb_librarian.sv + RTL files" synth_45: dc_shell -f synth/synthesis_dc.tcl synth_cnfet: dc_shell -f synth/synthesis_dc_cnfet.tcl package: cd .. && zip -rq icarus_prometheus_release_v2.zip $(notdir $(CURDIR)) @echo "Packaged into icarus_prometheus_release_v2.zip" EOF ######################################## # Zip deliverable ######################################## cd "$ROOT/.." zip -rq "${REL}.zip" "$REL" echo "Created ${REL}.zip at $(pwd)"
Welcome 👋
Flux helps you build PCBs faster with an AI teammate!
Create your account to collaborate, stay updated, fork your own version, and get instant answers from our AI agent.