From 7dc4c623160c6159e57415f1f490f6de01e82ed9 Mon Sep 17 00:00:00 2001 From: dwoen Date: Thu, 22 Aug 2024 18:43:35 -0700 Subject: [PATCH 1/5] edp wire opt --- .DS_Store | Bin 6148 -> 8196 bytes cacti-main/.DS_Store | Bin 12292 -> 12292 bytes cacti-main/base_cache.cfg | 4 +- cacti-main/cacti_interface.h | 4 + cacti-main/cacti_python/.DS_Store | Bin 8196 -> 8196 bytes cacti-main/cacti_python/Ucache-org.py | 847 ------ cacti-main/cacti_python/Ucache.py | 30 +- .../__pycache__/Ucache.cpython-310.pyc | Bin 0 -> 23701 bytes .../__pycache__/Ucache.cpython-311.pyc | Bin 0 -> 60472 bytes .../__pycache__/area.cpython-310.pyc | Bin 0 -> 1175 bytes .../__pycache__/area.cpython-311.pyc | Bin 0 -> 1567 bytes .../__pycache__/bank.cpython-310.pyc | Bin 0 -> 4255 bytes .../__pycache__/bank.cpython-311.pyc | Bin 0 -> 10940 bytes .../__pycache__/basic_circuit.cpython-311.pyc | Bin 0 -> 22846 bytes .../cacti_interface.cpython-310.pyc | Bin 0 -> 15794 bytes .../cacti_interface.cpython-311.pyc | Bin 0 -> 25278 bytes .../__pycache__/component.cpython-310.pyc | Bin 0 -> 3576 bytes .../__pycache__/component.cpython-311.pyc | Bin 0 -> 7435 bytes .../__pycache__/const.cpython-310.pyc | Bin 0 -> 3508 bytes .../__pycache__/const.cpython-311.pyc | Bin 0 -> 4011 bytes .../__pycache__/decoder.cpython-310.pyc | Bin 0 -> 25556 bytes .../__pycache__/decoder.cpython-311.pyc | Bin 0 -> 70035 bytes .../__pycache__/get_dat.cpython-310.pyc | Bin 0 -> 8909 bytes .../__pycache__/get_dat.cpython-311.pyc | Bin 0 -> 20159 bytes .../__pycache__/htree.cpython-310.pyc | Bin 0 -> 11488 bytes .../__pycache__/htree.cpython-311.pyc | Bin 0 -> 33537 bytes .../__pycache__/mat.cpython-310.pyc | Bin 0 -> 32288 bytes .../__pycache__/mat.cpython-311.pyc | Bin 0 -> 105718 bytes .../__pycache__/memorybus.cpython-310.pyc | Bin 0 -> 12109 bytes .../__pycache__/memorybus.cpython-311.pyc | Bin 0 -> 31553 bytes .../__pycache__/nuca.cpython-310.pyc | Bin 0 -> 3662 bytes .../__pycache__/nuca.cpython-311.pyc | Bin 0 -> 6716 bytes .../__pycache__/parameter.cpython-310.pyc | Bin 0 -> 72788 bytes .../__pycache__/parameter.cpython-311.pyc | Bin 0 -> 171116 bytes .../__pycache__/powergating.cpython-310.pyc | Bin 0 -> 2385 bytes .../__pycache__/powergating.cpython-311.pyc | Bin 0 -> 4798 bytes .../__pycache__/subarray.cpython-310.pyc | Bin 0 -> 3555 bytes .../__pycache__/subarray.cpython-311.pyc | Bin 0 -> 9893 bytes .../__pycache__/tsv.cpython-310.pyc | Bin 0 -> 4733 bytes .../__pycache__/tsv.cpython-311.pyc | Bin 0 -> 10773 bytes .../__pycache__/uca.cpython-310.pyc | Bin 0 -> 18737 bytes .../__pycache__/uca.cpython-311.pyc | Bin 0 -> 53848 bytes .../__pycache__/wire.cpython-310.pyc | Bin 0 -> 13615 bytes .../__pycache__/wire.cpython-311.pyc | Bin 0 -> 36323 bytes cacti-main/cacti_python/basic_circuit.py | 482 ---- cacti-main/cacti_python/cacti_interface.py | 55 +- cacti-main/cacti_python/component.py | 183 +- cacti-main/cacti_python/const.py | 6 +- cacti-main/cacti_python/decoder.py | 191 +- cacti-main/cacti_python/htree.py | 266 +- cacti-main/cacti_python/mat.py | 76 +- cacti-main/cacti_python/nuca.py | 7 +- cacti-main/cacti_python/parameter.py | 508 ++-- cacti-main/cacti_python/parameter_org.py | 2386 ----------------- cacti-main/cacti_python/subarray.py | 12 - cacti-main/cacti_python/uca.py | 67 +- cacti-main/cacti_python/wire.py | 597 +++-- cacti-main/component.cc | 4 - cacti-main/io.cc | 10 + cacti-main/mem_cache.cfg | 2 +- ...e_mem_cache.cfg => mem_validate_cache.cfg} | 8 +- cacti-main/nuca.cc | 2 +- cacti-main/validate_cache_2.cfg | 167 -- ...ache.cfg => validate_mem_energy_cache.cfg} | 10 +- cacti-main/wire.cc | 11 + 65 files changed, 969 insertions(+), 4966 deletions(-) delete mode 100644 cacti-main/cacti_python/Ucache-org.py create mode 100644 cacti-main/cacti_python/__pycache__/Ucache.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/Ucache.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/area.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/area.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/bank.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/bank.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/basic_circuit.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/cacti_interface.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/cacti_interface.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/component.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/component.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/const.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/const.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/decoder.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/decoder.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/get_dat.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/get_dat.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/htree.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/htree.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/mat.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/mat.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/memorybus.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/memorybus.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/nuca.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/nuca.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/parameter.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/parameter.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/powergating.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/powergating.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/subarray.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/subarray.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/tsv.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/tsv.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/uca.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/uca.cpython-311.pyc create mode 100644 cacti-main/cacti_python/__pycache__/wire.cpython-310.pyc create mode 100644 cacti-main/cacti_python/__pycache__/wire.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/basic_circuit.py delete mode 100644 cacti-main/cacti_python/parameter_org.py rename cacti-main/{validate_mem_cache.cfg => mem_validate_cache.cfg} (98%) delete mode 100644 cacti-main/validate_cache_2.cfg rename cacti-main/{validate_cache.cfg => validate_mem_energy_cache.cfg} (97%) diff --git a/.DS_Store b/.DS_Store index e66baee4ab1b4eb8fb94b0a1cd88a7057c95b709..d670f388c3a641d9eb08f44605c6b4a86cd06d74 100644 GIT binary patch delta 901 zcma)5&2JJx6o0Q!*cOn50^(Qv;Gjv>(5UIfq!eomdVok{Ag$uE4BORZX4ze+^#X?` zo;;9^@!*k@C)4m3cxm*Y@#0w%{{b(?qt5PPz|T0z=Kc1)-*4WVnfG?HySX#~V7}8> z0&t+fKgWupK|3`#e=-?y;`|>#g>%pZ2`<3JQA|krM<;~GzF|-h27Nz9?BVRAKK2!c`}oY%onLF;lfvMys1{ zdW*CQw8?5>+$o``J0bH{j~FHgzlkbU$uK0Uko?YVO{x>ENb}6HSgWG)b2zoTIm@~v zt5nIXeCF@O*IXud#zP`xJOGf%DSa0Ui65@9#q}O#lyFta^JH>2#vuU~VHL`-32o@Z zQy9VvcnNRe6MTVh7{L^t!bLobmv9+#SitMJfp<~Dd!BxVH;ucFjqTW=$-&f{_jp&0 z8%0x=$}(%|Q-Uetgx6wgYhH7JFnVu1k6zwi{dv=AZsXtF6{oGo1?XGoTA zC&kg}z(?Hczs8u)t2-Uy_Np^Md`iCh>}aB37sG+j=t D{;bqt delta 279 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~50D9i(r2a9ET=Hw?Q<>V)AEL_RV z4-#i(NM=X`;u40;$twipxsmyI1WxE6@pIA*gOl@f3xK*{07*7C-(@nRhzN=S|AfU& zk(3l<;4`2sxF|0tKQA30#Qyo}NHc zlB36H6)*Y(7C1wMkKl-_SmW_-GDC=K9VdK<-r<2yyJ!e4J}x&57-OgyDmINt)D4Df zV^AtS8!6103}+@s+_Z6Es>qp9Jauvzv?VvpI1+-vFM6>eR7?r+C%Y)V` WMjsW&W4GMyf*dT7f}_N~|KS&(@@_`} delta 387 zcmX|)y-Pw-7{=eDrb9yK*1hL`nOqCai$M{j1Qtj`gM_xVl!gTvg-ZxcH3-oVL{C92 zZ4ON(w)H1OF5zDg&1O*0QXL(7mgoIF?^mr@E1u=pN+bU`#8S;5?|8AKMiA2!9HvF2Dg>k8IylA$^)5g1OcO<4n6!#+oNQfZz#3a^) zJS1FP2?ehr#4_i48b1=2^)bxr9EZAtiu5~u7B{+rPd$b=$q8c|mZ6|vB#|>X>P8e7 zeHQ2%4xVHdFa&blAEUr zC@=#R6#x|#0dX!vDnkhn7XcOL1IhHs2LwbWPY__;yi(YWQIwY<6sS89h%Az}ej<{|w3%Jv8_VQcks?A$)0hC2)hrbN diff --git a/cacti-main/cacti_python/Ucache-org.py b/cacti-main/cacti_python/Ucache-org.py deleted file mode 100644 index eda4a63..0000000 --- a/cacti-main/cacti_python/Ucache-org.py +++ /dev/null @@ -1,847 +0,0 @@ -import math -from typing import List -from threading import Thread -from cacti_interface import * -from cacti_interface import MemArray -from nuca import NucaOrgT -from parameter import g_ip, g_tp -from parameter import * -from uca import UCA -from parameter import _log2 -import sympy as sp - -BIGNUM = float('inf') -NTHREADS = 4 -MAXDATAN = 4 -MAX_COL_MUX = 4 -MAXDATASPD = 4.0 -Full_swing, Global, Low_swing = 0, 1, 2 # Just example values - -class MinValuesT: - def __init__(self): - self.min_delay = BIGNUM - self.min_dyn = BIGNUM - self.min_leakage = BIGNUM - self.min_area = BIGNUM - self.min_cyc = BIGNUM - - def update_min_values(self, val): - self.min_delay = sp.Min(self.min_delay, val.min_delay) - self.min_dyn = sp.Min(self.min_dyn, val.min_dyn) - self.min_leakage = sp.Min(self.min_leakage, val.min_leakage) - self.min_area = sp.Min(self.min_area, val.min_area) - self.min_cyc = sp.Min(self.min_cyc, val.min_cyc) - - def update_min_values_from_uca(self, res: uca_org_t): - self.min_delay = sp.Min(self.min_delay, res.access_time) - self.min_dyn = sp.Min(self.min_dyn, res.power.readOp.dynamic) - self.min_leakage = sp.Min(self.min_leakage, res.power.readOp.leakage) - self.min_area = sp.Min(self.min_area, res.area) - self.min_cyc = sp.Min(self.min_cyc, res.cycle_time) - - def update_min_values_from_nuca(self, res: NucaOrgT): - self.min_delay = sp.Min(self.min_delay, res.nuca_pda.access_time) - self.min_dyn = sp.Min(self.min_dyn, res.nuca_pda.power.readOp.dynamic) - self.min_leakage = sp.Min(self.min_leakage, res.nuca_pda.power.readOp.leakage) - self.min_area = sp.Min(self.min_area, res.nuca_pda.area) - self.min_cyc = sp.Min(self.min_cyc, res.nuca_pda.cycle_time) - - def update_min_values_from_mem_array(self, res: MemArray): - if(not contains_any_symbol(self.min_delay) and math.isnan(self.min_delay)): - self.min_delay = res.access_time - elif(not contains_any_symbol(res.access_time) and math.isnan(res.access_time)): - self.min_delay = self.min_delay - else: - self.min_delay = sp.Min(self.min_delay, res.access_time) - - if not sp.contains_any_symbol(self.min_dyn) and math.isnan(self.min_dyn): - self.min_dyn = res.power.readOp.dynamic - elif not sp.contains_any_symbol(res.power.readOp.dynamic) and math.isnan(res.power.readOp.dynamic): - self.min_dyn = self.min_dyn - else: - self.min_dyn = sp.Min(self.min_dyn, res.power.readOp.dynamic) - - if not sp.contains_any_symbol(self.min_leakage) and math.isnan(self.min_leakage): - self.min_leakage = res.power.readOp.leakage - elif not sp.contains_any_symbol(res.power.readOp.leakage) and math.isnan(res.power.readOp.leakage): - self.min_leakage = self.min_leakage - else: - self.min_leakage = sp.Min(self.min_leakage, res.power.readOp.leakage) - - if not sp.contains_any_symbol(self.min_area) and math.isnan(self.min_area): - self.min_area = res.area - elif not sp.contains_any_symbol(res.area) and math.isnan(res.area): - self.min_area = self.min_area - else: - self.min_area = sp.Min(self.min_area, res.area) - - if not sp.contains_any_symbol(self.min_cyc) and math.isnan(self.min_cyc): - self.min_cyc = res.cycle_time - elif not sp.contains_any_symbol(res.cycle_time) and math.isnan(res.cycle_time): - self.min_cyc = self.min_cyc - else: - self.min_cyc = sp.Min(self.min_cyc, res.cycle_time) - - # self.min_dyn = sp.Min(self.min_dyn, res.power.readOp.dynamic) - # self.min_leakage = sp.Min(self.min_leakage, res.power.readOp.leakage) - # self.min_area = sp.Min(self.min_area, res.area) - # self.min_cyc = sp.Min(self.min_cyc, res.cycle_time) - -class CalcTimeMtWrapperStruct: - def __init__(self): - self.tid = 0 - self.is_tag = False - self.pure_ram = False - self.pure_cam = False - self.is_main_mem = False - self.Nspd_min = 0.0 - self.data_res = None # Assuming min_values_t is another class or type, set to None by default - self.tag_res = None # Assuming min_values_t is another class or type, set to None by default - self.data_arr = [] # list is translated to a list in Python - self.tag_arr = [] # list is translated to a list in Python - -def calc_time_mt_wrapper(void_obj): - calc_obj = void_obj - tid = calc_obj.tid - data_arr = calc_obj.data_arr - tag_arr = calc_obj.tag_arr - is_tag = calc_obj.is_tag - pure_ram = calc_obj.pure_ram - pure_cam = calc_obj.pure_cam - is_main_mem = calc_obj.is_main_mem - Nspd_min = calc_obj.Nspd_min - data_res = calc_obj.data_res - tag_res = calc_obj.tag_res - - data_arr.clear() - data_arr.append(MemArray()) - tag_arr.clear() - tag_arr.append(MemArray()) - - Ndwl_niter = int(_log2(MAXDATAN)) + 1 - Ndbl_niter = int(_log2(MAXDATAN)) + 1 - Ndcm_niter = int(_log2(MAX_COL_MUX)) + 1 - niter = Ndwl_niter * Ndbl_niter * Ndcm_niter - - is_valid_partition = False - wt_min = 0 - wt_max = 0 - - if g_ip.force_wiretype: - if g_ip.wt == 'Full_swing': - wt_min = 'Global' - wt_max = 'Low_swing'-1 - else: - if g_ip.wt == 'Global': - wt_min = wt_max = 'Global' - elif g_ip.wt == 'Global_5': - wt_min = wt_max = 'Global_5' - elif g_ip.wt == 'Global_10': - wt_min = wt_max = 'Global_10' - elif g_ip.wt == 'Global_20': - wt_min = wt_max = 'Global_20' - elif g_ip.wt == 'Global_30': - wt_min = wt_max = 'Global_30' - elif g_ip.wt == 'Low_swing': - wt_min = wt_max = 'Low_swing' - else: - raise ValueError("Unknown wire type!") - else: - wt_min = 'Global' - wt_max = 'Low_swing' - - print("CHECKPOINT Nspd_min") - print(Nspd_min) - # print(MAXDATASPD) - # print() - #TODO Npsd_min messed up - for Nspd in range(int(Nspd_min), int(MAXDATASPD), int(math.ceil(Nspd_min*2))): - # replace with proper enum - if(wt_min == "Global"): - wt_min = 0 - elif(wt_min == "Global_5"): - wt_min = 1 - elif(wt_min == "Global_10"): - wt_min = 2 - elif(wt_min == "Global_20"): - wt_min = 3 - elif(wt_min == "Global_30"): - wt_min = 4 - elif(wt_min == "Low_swing"): - wt_min = 5 - elif(wt_min == "Semi_global"): - wt_min = 6 - elif(wt_min == "Full_swing"): - wt_min = 7 - elif(wt_min == "Transmission"): - wt_min = 8 - elif(wt_min == "Optical"): - wt_min = 9 - else: - wt_min = 10 - - if(wt_max == "Global"): - wt_max = 0 - elif(wt_max == "Global_5"): - wt_max = 1 - elif(wt_max == "Global_10"): - wt_max = 2 - elif(wt_max == "Global_20"): - wt_max = 3 - elif(wt_max == "Global_30"): - wt_max = 4 - elif(wt_max == "Low_swing"): - wt_max = 5 - elif(wt_max == "Semi_global"): - wt_max = 6 - elif(wt_max == "Full_swing"): - wt_max = 7 - elif(wt_max == "Transmission"): - wt_max = 8 - elif(wt_max == "Optical"): - wt_max = 9 - else: - wt_max = 10 - - print("CHECKPOINT") - print(wt_min) - print(wt_max) - print() - - for wr in range(wt_min, wt_max+1): - for iter in range(tid, niter, NTHREADS): - Ndwl = 1 << (iter // (Ndbl_niter * Ndcm_niter)) - Ndbl = 1 << ((iter // Ndcm_niter) % Ndbl_niter) - Ndcm = 1 << (iter % Ndcm_niter) - Ndsam_lev_1 = 1 - Ndsam_lev_2 = 1 - for Ndsam_lev_1 in range(1, MAX_COL_MUX+1, Ndsam_lev_1*2): - for Ndsam_lev_2 in range(1, MAX_COL_MUX+1, Ndsam_lev_2*2): - if g_ip.force_cache_config and not is_tag: - wr = g_ip.wt - Ndwl = g_ip.ndwl - Ndbl = g_ip.ndbl - Ndcm = g_ip.ndcm - if g_ip.nspd != 0: - Nspd = g_ip.nspd - if g_ip.ndsam1 != 0: - Ndsam_lev_1 = g_ip.ndsam1 - Ndsam_lev_2 = g_ip.ndsam2 - - if is_tag: - is_valid_partition = calculate_time(is_tag, pure_ram, pure_cam, Nspd, Ndwl, - Ndbl, Ndcm, Ndsam_lev_1, Ndsam_lev_2, - tag_arr[-1], 0, None, None, wr, is_main_mem) - if not is_tag or g_ip.fully_assoc: - is_valid_partition = calculate_time(is_tag, pure_ram, pure_cam, Nspd, Ndwl, - Ndbl, Ndcm, Ndsam_lev_1, Ndsam_lev_2, - data_arr[-1], 0, None, None, wr, is_main_mem) - if g_ip.is_3d_mem: - Ndsam_lev_1 = MAX_COL_MUX+1 - Ndsam_lev_2 = MAX_COL_MUX+1 - - if is_valid_partition: - if is_tag: - tag_arr[-1].wt = wr - tag_res.update_min_values_from_mem_array(tag_arr[-1]) - tag_arr.append(MemArray()) - if not is_tag or g_ip.fully_assoc: - data_arr[-1].wt = wr - data_res.update_min_values_from_mem_array(data_arr[-1]) - data_arr.append(MemArray()) - - if g_ip.force_cache_config and not is_tag: - wr = wt_max - iter = niter - if g_ip.nspd != 0: - Nspd = MAXDATASPD - if g_ip.ndsam1 != 0: - Ndsam_lev_1 = MAX_COL_MUX+1 - Ndsam_lev_2 = MAX_COL_MUX+1 - # Ndsam_lev_1 += 1 - # Ndsam_lev_1 += 1 - - data_arr.pop() - tag_arr.pop() - -def calculate_time( - is_tag, - pure_ram, - pure_cam, - Nspd, - Ndwl, - Ndbl, - Ndcm, - Ndsam_lev_1, - Ndsam_lev_2, - ptr_array, - flag_results_populate, - ptr_results, - ptr_fin_res, - wt, - is_main_mem -): - dyn_p = DynamicParameter(is_tag, pure_ram, pure_cam, Nspd, Ndwl, Ndbl, Ndcm, Ndsam_lev_1, Ndsam_lev_2, wt, is_main_mem) - - if not dyn_p.is_valid: - return False - - uca = UCA(dyn_p) - - if flag_results_populate: - # For the final solution, populate the ptr_results data structure -- TODO: copy only necessary variables - pass - else: - num_act_mats_hor_dir = uca.bank.dp.num_act_mats_hor_dir - num_mats = uca.bank.dp.num_mats - is_fa = uca.bank.dp.fully_assoc - pure_cam = uca.bank.dp.pure_cam - - ptr_array.Ndwl = Ndwl - ptr_array.Ndbl = Ndbl - ptr_array.Nspd = Nspd - ptr_array.deg_bl_muxing = dyn_p.deg_bl_muxing - ptr_array.Ndsam_lev_1 = Ndsam_lev_1 - ptr_array.Ndsam_lev_2 = Ndsam_lev_2 - ptr_array.access_time = uca.access_time - ptr_array.cycle_time = uca.cycle_time - ptr_array.multisubbank_interleave_cycle_time = uca.multisubbank_interleave_cycle_time - ptr_array.area_ram_cells = uca.area_all_dataramcells - ptr_array.area = uca.area.get_area() - - if g_ip.is_3d_mem: - ptr_array.area = uca.area.get_area() - if g_ip.num_die_3d > 1: - ptr_array.area += uca.area_TSV_tot - - ptr_array.height = uca.area.h - ptr_array.width = uca.area.w - ptr_array.mat_height = uca.bank.mat.area.h - ptr_array.mat_length = uca.bank.mat.area.w - ptr_array.subarray_height = uca.bank.mat.subarray.area.h - ptr_array.subarray_length = uca.bank.mat.subarray.area.w - ptr_array.power = uca.power - ptr_array.delay_senseamp_mux_decoder = sp.Max(uca.delay_array_to_sa_mux_lev_1_decoder, uca.delay_array_to_sa_mux_lev_2_decoder) - ptr_array.delay_before_subarray_output_driver = uca.delay_before_subarray_output_driver - ptr_array.delay_from_subarray_output_driver_to_output = uca.delay_from_subarray_out_drv_to_out - ptr_array.delay_route_to_bank = uca.htree_in_add.delay - ptr_array.delay_input_htree = uca.bank.htree_in_add.delay - ptr_array.delay_row_predecode_driver_and_block = uca.bank.mat.r_predec.delay - ptr_array.delay_row_decoder = uca.bank.mat.row_dec.delay - ptr_array.delay_bitlines = uca.bank.mat.delay_bitline - ptr_array.delay_matchlines = uca.bank.mat.delay_matchchline - ptr_array.delay_sense_amp = uca.bank.mat.delay_sa - ptr_array.delay_subarray_output_driver = uca.bank.mat.delay_subarray_out_drv_htree - ptr_array.delay_dout_htree = uca.bank.htree_out_data.delay - ptr_array.delay_comparator = uca.bank.mat.delay_comparator - - if g_ip.is_3d_mem: - ptr_array.delay_row_activate_net = uca.membus_RAS.delay_bus - ptr_array.delay_row_predecode_driver_and_block = uca.membus_RAS.delay_add_predecoder - ptr_array.delay_row_decoder = uca.membus_RAS.delay_add_decoder - ptr_array.delay_local_wordline = uca.membus_RAS.delay_lwl_drv - ptr_array.delay_column_access_net = uca.membus_CAS.delay_bus - ptr_array.delay_column_predecoder = uca.membus_CAS.delay_add_predecoder - ptr_array.delay_column_decoder = uca.membus_CAS.delay_add_decoder - ptr_array.delay_column_selectline = 0 - ptr_array.delay_datapath_net = uca.membus_data.delay_bus - ptr_array.delay_global_data = uca.membus_data.delay_global_data - ptr_array.delay_local_data_and_drv = uca.membus_data.delay_local_data - ptr_array.delay_data_buffer = uca.membus_data.delay_data_buffer - ptr_array.energy_row_activate_net = uca.membus_RAS.power_bus.readOp.dynamic - ptr_array.energy_row_predecode_driver_and_block = uca.membus_RAS.power_add_predecoder.readOp.dynamic - ptr_array.energy_row_decoder = uca.membus_RAS.power_add_decoders.readOp.dynamic - ptr_array.energy_local_wordline = uca.membus_RAS.power_lwl_drv.readOp.dynamic - ptr_array.energy_bitlines = dyn_p.Ndwl * uca.bank.mat.power_bitline.readOp.dynamic - ptr_array.energy_sense_amp = dyn_p.Ndwl * uca.bank.mat.power_sa.readOp.dynamic - ptr_array.energy_column_access_net = uca.membus_CAS.power_bus.readOp.dynamic - ptr_array.energy_column_predecoder = uca.membus_CAS.power_add_predecoder.readOp.dynamic - ptr_array.energy_column_decoder = uca.membus_CAS.power_add_decoders.readOp.dynamic - ptr_array.energy_column_selectline = uca.membus_CAS.power_col_sel.readOp.dynamic - ptr_array.energy_datapath_net = uca.membus_data.power_bus.readOp.dynamic - ptr_array.energy_global_data = uca.membus_data.power_global_data.readOp.dynamic - ptr_array.energy_local_data_and_drv = uca.membus_data.power_local_data.readOp.dynamic - ptr_array.energy_subarray_output_driver = uca.bank.mat.power_subarray_out_drv.readOp.dynamic - ptr_array.energy_data_buffer = 0 - ptr_array.area_lwl_drv = uca.area_lwl_drv - ptr_array.area_row_predec_dec = uca.area_row_predec_dec - ptr_array.area_col_predec_dec = uca.area_col_predec_dec - ptr_array.area_subarray = uca.area_subarray - ptr_array.area_bus = uca.area_bus - ptr_array.area_address_bus = uca.area_address_bus - ptr_array.area_data_bus = uca.area_data_bus - ptr_array.area_data_drv = uca.area_data_drv - ptr_array.area_IOSA = uca.area_IOSA - ptr_array.area_sense_amp = uca.area_sense_amp - - ptr_array.all_banks_height = uca.area.h - ptr_array.all_banks_width = uca.area.w - ptr_array.area_efficiency = uca.area_all_dataramcells * 100 / ptr_array.area - ptr_array.power_routing_to_bank = uca.power_routing_to_bank - ptr_array.power_addr_input_htree = uca.bank.htree_in_add.power - ptr_array.power_data_input_htree = uca.bank.htree_in_data.power - ptr_array.power_data_output_htree = uca.bank.htree_out_data.power - ptr_array.power_row_predecoder_drivers = uca.bank.mat.r_predec.driver_power - ptr_array.power_row_predecoder_drivers.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_predecoder_drivers.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_predecoder_drivers.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_predecoder_blocks = uca.bank.mat.r_predec.block_power - ptr_array.power_row_predecoder_blocks.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_predecoder_blocks.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_predecoder_blocks.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_decoders = uca.bank.mat.power_row_decoders - ptr_array.power_row_decoders.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_decoders.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_row_decoders.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_predecoder_drivers = uca.bank.mat.b_mux_predec.driver_power - ptr_array.power_bit_mux_predecoder_drivers.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_predecoder_drivers.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_predecoder_drivers.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_predecoder_blocks = uca.bank.mat.b_mux_predec.block_power - ptr_array.power_bit_mux_predecoder_blocks.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_predecoder_blocks.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_predecoder_blocks.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_decoders = uca.bank.mat.power_bit_mux_decoders - ptr_array.power_bit_mux_decoders.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_decoders.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bit_mux_decoders.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_predecoder_drivers = uca.bank.mat.sa_mux_lev_1_predec.driver_power - ptr_array.power_senseamp_mux_lev_1_predecoder_drivers.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_predecoder_drivers.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_predecoder_drivers.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_predecoder_blocks = uca.bank.mat.sa_mux_lev_1_predec.block_power - ptr_array.power_senseamp_mux_lev_1_predecoder_blocks.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_predecoder_blocks.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_predecoder_blocks.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_decoders = uca.bank.mat.power_sa_mux_lev_1_decoders - ptr_array.power_senseamp_mux_lev_1_decoders.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_decoders.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_1_decoders.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_predecoder_drivers = uca.bank.mat.sa_mux_lev_2_predec.driver_power - ptr_array.power_senseamp_mux_lev_2_predecoder_drivers.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_predecoder_drivers.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_predecoder_drivers.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_predecoder_blocks = uca.bank.mat.sa_mux_lev_2_predec.block_power - ptr_array.power_senseamp_mux_lev_2_predecoder_blocks.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_predecoder_blocks.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_predecoder_blocks.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_decoders = uca.bank.mat.power_sa_mux_lev_2_decoders - ptr_array.power_senseamp_mux_lev_2_decoders.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_decoders.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_senseamp_mux_lev_2_decoders.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bitlines = uca.bank.mat.power_bitline - ptr_array.power_bitlines.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bitlines.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_bitlines.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_sense_amps = uca.bank.mat.power_sa - ptr_array.power_sense_amps.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_sense_amps.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_sense_amps.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_prechg_eq_drivers = uca.bank.mat.power_bl_precharge_eq_drv - ptr_array.power_prechg_eq_drivers.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_prechg_eq_drivers.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_prechg_eq_drivers.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_output_drivers_at_subarray = uca.bank.mat.power_subarray_out_drv - ptr_array.power_output_drivers_at_subarray.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_output_drivers_at_subarray.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_output_drivers_at_subarray.searchOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_comparators = uca.bank.mat.power_comparator - ptr_array.power_comparators.readOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_comparators.writeOp.dynamic *= num_act_mats_hor_dir - ptr_array.power_comparators.searchOp.dynamic *= num_act_mats_hor_dir - - if is_fa or pure_cam: - ptr_array.power_htree_in_search = uca.bank.htree_in_search.power - ptr_array.power_htree_out_search = uca.bank.htree_out_search.power - ptr_array.power_searchline = uca.bank.mat.power_searchline - ptr_array.power_searchline.searchOp.dynamic *= num_mats - ptr_array.power_searchline_precharge = uca.bank.mat.power_searchline_precharge - ptr_array.power_searchline_precharge.searchOp.dynamic *= num_mats - ptr_array.power_matchlines = uca.bank.mat.power_matchline - ptr_array.power_matchlines.searchOp.dynamic *= num_mats - ptr_array.power_matchline_precharge = uca.bank.mat.power_matchline_precharge - ptr_array.power_matchline_precharge.searchOp.dynamic *= num_mats - ptr_array.power_matchline_to_wordline_drv = uca.bank.mat.power_ml_to_ram_wl_drv - - ptr_array.activate_energy = uca.activate_energy - ptr_array.read_energy = uca.read_energy - ptr_array.write_energy = uca.write_energy - ptr_array.precharge_energy = uca.precharge_energy - ptr_array.refresh_power = uca.refresh_power - ptr_array.leak_power_subbank_closed_page = uca.leak_power_subbank_closed_page - ptr_array.leak_power_subbank_open_page = uca.leak_power_subbank_open_page - ptr_array.leak_power_request_and_reply_networks = uca.leak_power_request_and_reply_networks - ptr_array.precharge_delay = uca.precharge_delay - - if g_ip.is_3d_mem: - ptr_array.t_RCD = uca.t_RCD - ptr_array.t_RAS = uca.t_RAS - ptr_array.t_RC = uca.t_RC - ptr_array.t_CAS = uca.t_CAS - ptr_array.t_RP = uca.t_RP - ptr_array.t_RRD = uca.t_RRD - ptr_array.activate_energy = uca.activate_energy - ptr_array.read_energy = uca.read_energy - ptr_array.write_energy = uca.write_energy - ptr_array.precharge_energy = uca.precharge_energy - ptr_array.activate_power = uca.activate_power - ptr_array.read_power = uca.read_power - ptr_array.write_power = uca.write_power - ptr_array.peak_read_power = uca.read_energy / ((g_ip.burst_depth) / (g_ip.sys_freq_MHz * 1e6) / 2) - ptr_array.num_row_subarray = dyn_p.num_r_subarray - ptr_array.num_col_subarray = dyn_p.num_c_subarray - ptr_array.delay_TSV_tot = uca.delay_TSV_tot - ptr_array.area_TSV_tot = uca.area_TSV_tot - ptr_array.dyn_pow_TSV_tot = uca.dyn_pow_TSV_tot - ptr_array.dyn_pow_TSV_per_access = uca.dyn_pow_TSV_per_access - ptr_array.num_TSV_tot = uca.num_TSV_tot - - if g_ip.power_gating: - ptr_array.sram_sleep_tx_width = uca.bank.mat.sram_sleep_tx.width - ptr_array.sram_sleep_tx_area = uca.bank.mat.array_sleep_tx_area - ptr_array.sram_sleep_wakeup_latency = uca.bank.mat.array_wakeup_t - ptr_array.sram_sleep_wakeup_energy = uca.bank.mat.array_wakeup_e.readOp.dynamic - ptr_array.wl_sleep_tx_width = uca.bank.mat.row_dec.sleeptx.width - ptr_array.wl_sleep_tx_area = uca.bank.mat.wl_sleep_tx_area - ptr_array.wl_sleep_wakeup_latency = uca.bank.mat.wl_wakeup_t - ptr_array.wl_sleep_wakeup_energy = uca.bank.mat.wl_wakeup_e.readOp.dynamic - ptr_array.bl_floating_wakeup_latency = uca.bank.mat.blfloating_wakeup_t - ptr_array.bl_floating_wakeup_energy = uca.bank.mat.blfloating_wakeup_e.readOp.dynamic - ptr_array.array_leakage = uca.bank.array_leakage - ptr_array.wl_leakage = uca.bank.wl_leakage - ptr_array.cl_leakage = uca.bank.cl_leakage - - ptr_array.num_active_mats = uca.bank.dp.num_act_mats_hor_dir - ptr_array.num_submarray_mats = uca.bank.mat.num_subarrays_per_mat - - return True - -def check_uca_org(u, minval): - if ((u.access_time - minval.min_delay) * 100 / minval.min_delay) > g_ip.delay_dev: - return False - if ((u.power.readOp.dynamic - minval.min_dyn) / minval.min_dyn) * 100 > g_ip.dynamic_power_dev: - return False - if ((u.power.readOp.leakage - minval.min_leakage) / minval.min_leakage) * 100 > g_ip.leakage_power_dev: - return False - if ((u.cycle_time - minval.min_cyc) / minval.min_cyc) * 100 > g_ip.cycle_time_dev: - return False - if ((u.area - minval.min_area) / minval.min_area) * 100 > g_ip.area_dev: - return False - return True - -def check_mem_org(u, minval): - if ((u.access_time - minval.min_delay) * 100 / minval.min_delay) > g_ip.delay_dev: - return False - if ((u.power.readOp.dynamic - minval.min_dyn) / minval.min_dyn) * 100 > g_ip.dynamic_power_dev: - return False - if ((u.power.readOp.leakage - minval.min_leakage) / minval.min_leakage) * 100 > g_ip.leakage_power_dev: - return False - if ((u.cycle_time - minval.min_cyc) / minval.min_cyc) * 100 > g_ip.cycle_time_dev: - return False - if ((u.area - minval.min_area) / minval.min_area) * 100 > g_ip.area_dev: - return False - return True - -def find_optimal_uca(res, minval, ulist): - cost = 0 - min_cost = BIGNUM - dp = g_ip.dynamic_power_wt - lp = g_ip.leakage_power_wt - a = g_ip.area_wt - d = g_ip.delay_wt - c = g_ip.cycle_time_wt - - if not ulist: - print("ERROR: no valid cache organizations found") - exit(0) - - for niter in ulist: - if g_ip.ed == 1: - cost = (niter.access_time / minval.min_delay) * (niter.power.readOp.dynamic / minval.min_dyn) - if min_cost > cost: - min_cost = cost - res.update(niter) - elif g_ip.ed == 2: - cost = ((niter.access_time / minval.min_delay) ** 2) * (niter.power.readOp.dynamic / minval.min_dyn) - if min_cost > cost: - min_cost = cost - res.update(niter) - else: - if check_uca_org(niter, minval): - cost = ( - d * (niter.access_time / minval.min_delay) + - c * (niter.cycle_time / minval.min_cyc) + - dp * (niter.power.readOp.dynamic / minval.min_dyn) + - lp * (niter.power.readOp.leakage / minval.min_leakage) + - a * (niter.area / minval.min_area) - ) - if min_cost > cost: - min_cost = cost - res.update(niter) - ulist.remove(niter) - else: - ulist.remove(niter) - - if min_cost == BIGNUM: - print("ERROR: no cache organizations met optimization criteria") - exit(0) - -def filter_tag_arr(min_val, mem_list): - cost = float('inf') - cur_cost = 0.0 - wt_delay = g_ip.delay_wt - wt_dyn = g_ip.dynamic_power_wt - wt_leakage = g_ip.leakage_power_wt - wt_cyc = g_ip.cycle_time_wt - wt_area = g_ip.area_wt - res = None - - if not mem_list: - print("ERROR: no valid tag organizations found") - exit(1) - - while mem_list: - print(len(mem_list)) - v = check_mem_org(mem_list[-1], min_val) - if v: - cur_cost = (wt_delay * (mem_list[-1].access_time / min_val.min_delay) + - wt_dyn * (mem_list[-1].power.readOp.dynamic / min_val.min_dyn) + - wt_leakage * (mem_list[-1].power.readOp.leakage / min_val.min_leakage) + - wt_area * (mem_list[-1].area / min_val.min_area) + - wt_cyc * (mem_list[-1].cycle_time / min_val.min_cyc)) - else: - cur_cost = float('inf') - - if cur_cost < cost: - if res is not None: - del res - cost = cur_cost - res = mem_list[-1] - else: - del mem_list[-1] - - if(len(mem_list) > 0): - mem_list.pop() - - if not res: - print("ERROR: no valid tag organizations found") - exit(0) - - mem_list.append(res) - -# def filter_data_arr(curr_list): -# if not curr_list: -# print("ERROR: no valid data array organizations found") -# exit(1) - -# iter_list = list(curr_list) - -# for m in iter_list: -# if m is None: -# exit(1) - -# if (((m.access_time - m.arr_min.min_delay) / m.arr_min.min_delay > 0.5) and -# ((m.power.readOp.dynamic - m.arr_min.min_dyn) / m.arr_min.min_dyn > 0.5)): -# del m -# curr_list.remove(m) - -def filter_data_arr(curr_list): - if not curr_list: - print("ERROR: no valid data array organizations found") - exit(1) - - iter_list = list(curr_list) - - for m in iter_list: - if m is None: - exit(1) - - if (math.isnan(m.access_time) or math.isnan(m.arr_min.min_delay) or - math.isnan(m.power.readOp.dynamic) or math.isnan(m.arr_min.min_dyn)): - continue # Skip this iteration if any relevant value is NaN - - if (((m.access_time - m.arr_min.min_delay) / m.arr_min.min_delay > 0.5) and - ((m.power.readOp.dynamic - m.arr_min.min_dyn) / m.arr_min.min_dyn > 0.5)): - curr_list.remove(m) - -import threading -from functools import cmp_to_key - -def solve(fin_res): - pure_ram = g_ip.pure_ram - pure_cam = g_ip.pure_cam - - g_tp.init(g_ip.F_sz_um, False) - g_ip.print_detail_debug = 0 - - tag_arr = [] - data_arr = [] - sol_list = [uca_org_t()] - - fin_res.tag_array.access_time = 0 - fin_res.tag_array.Ndwl = 0 - fin_res.tag_array.Ndbl = 0 - fin_res.tag_array.Nspd = 0 - fin_res.tag_array.deg_bl_muxing = 0 - fin_res.tag_array.Ndsam_lev_1 = 0 - fin_res.tag_array.Ndsam_lev_2 = 0 - - calc_array = [CalcTimeMtWrapperStruct() for _ in range(NTHREADS)] - threads = [None] * NTHREADS - - for t in range(NTHREADS): - calc_array[t].tid = t - calc_array[t].pure_ram = pure_ram - calc_array[t].pure_cam = pure_cam - calc_array[t].data_res = MinValuesT() - calc_array[t].tag_res = MinValuesT() - - if not (pure_ram or pure_cam or g_ip.fully_assoc): - is_tag = True - g_tp.init(g_ip.F_sz_um, is_tag) - - for t in range(NTHREADS): - calc_array[t].is_tag = is_tag - calc_array[t].is_main_mem = False - calc_array[t].Nspd_min = 0.125 - threads[t] = threading.Thread(target=calc_time_mt_wrapper, args=(calc_array[t],)) - threads[t].start() - - for t in range(NTHREADS): - threads[t].join() - - - print("HELLo?") - for t in range(NTHREADS): - calc_array[t].data_arr.sort(key=cmp_to_key(MemArray.lt)) - - # CHECKPOINT - print(f'WAT {calc_array[t].data_arr[0].access_time}') - - data_arr.extend(calc_array[t].data_arr) - calc_array[t].tag_arr.sort(key=cmp_to_key(MemArray.lt)) - tag_arr.extend(calc_array[t].tag_arr) - - is_tag = False - g_tp.init(g_ip.F_sz_um, is_tag) - - for t in range(NTHREADS): - calc_array[t].is_tag = is_tag - calc_array[t].is_main_mem = g_ip.is_main_mem - if not (pure_cam or g_ip.fully_assoc): - calc_array[t].Nspd_min = g_ip.out_w / (g_ip.block_sz * 8) - else: - calc_array[t].Nspd_min = 1 - - threads[t] = threading.Thread(target=calc_time_mt_wrapper, args=(calc_array[t],)) - threads[t].start() - - for t in range(NTHREADS): - threads[t].join() - - data_arr.clear() - for t in range(NTHREADS): - calc_array[t].data_arr.sort(key=cmp_to_key(MemArray.lt)) - data_arr.extend(calc_array[t].data_arr) - - d_min = MinValuesT() - t_min = MinValuesT() - cache_min = MinValuesT() - - for t in range(NTHREADS): - d_min.update_min_values(calc_array[t].data_res) - t_min.update_min_values(calc_array[t].tag_res) - - for m in data_arr: - m.arr_min = d_min - - filter_data_arr(data_arr) - if not (pure_ram or pure_cam or g_ip.fully_assoc): - filter_tag_arr(t_min, tag_arr) - - if pure_ram or pure_cam or g_ip.fully_assoc: - for m in data_arr: - curr_org = sol_list[-1] - curr_org.tag_array2 = None - curr_org.data_array2 = m - - curr_org.find_delay() - print(f'ACCESS TIME: {curr_org.access_time}') - curr_org.find_energy() - curr_org.find_area() - curr_org.find_cyc() - - cache_min.update_min_values_from_uca(curr_org) - - sol_list.append(uca_org_t()) - else: - while tag_arr: - arr_temp = tag_arr.pop() - for m in data_arr: - curr_org = sol_list[-1] - curr_org.tag_array2 = arr_temp - curr_org.data_array2 = m - - curr_org.find_delay() - print(f'ACCESS TIME: {curr_org.access_time}') - curr_org.find_energy() - curr_org.find_area() - curr_org.find_cyc() - - cache_min.update_min_values_from_uca(curr_org) - - sol_list.append(uca_org_t()) - - sol_list.pop() - - find_optimal_uca(fin_res, cache_min, sol_list) - - sol_list.clear() - - for m in data_arr: - if m != fin_res.data_array2: - del m - data_arr.clear() - - for t in range(NTHREADS): - del calc_array[t].data_res - del calc_array[t].tag_res - - del calc_array - del cache_min - del d_min - del t_min - -def update(fin_res): - if fin_res.tag_array2: - g_tp.init(g_ip.F_sz_um, True) - tag_arr_dyn_p = DynamicParameter( - True, g_ip.pure_ram, g_ip.pure_cam, - fin_res.tag_array2.Nspd, fin_res.tag_array2.Ndwl, - fin_res.tag_array2.Ndbl, fin_res.tag_array2.Ndcm, - fin_res.tag_array2.Ndsam_lev_1, fin_res.tag_array2.Ndsam_lev_2, - fin_res.data_array2.wt, g_ip.is_main_mem - ) - if tag_arr_dyn_p.is_valid: - tag_arr = UCA(tag_arr_dyn_p) - fin_res.tag_array2.power = tag_arr.power - else: - print("ERROR: Cannot retrieve array structure for leakage feedback") - exit(1) - - g_tp.init(g_ip.F_sz_um, False) - data_arr_dyn_p = DynamicParameter( - False, g_ip.pure_ram, g_ip.pure_cam, - fin_res.data_array2.Nspd, fin_res.data_array2.Ndwl, - fin_res.data_array2.Ndbl, fin_res.data_array2.Ndcm, - fin_res.data_array2.Ndsam_lev_1, fin_res.data_array2.Ndsam_lev_2, - fin_res.data_array2.wt, g_ip.is_main_mem - ) - if data_arr_dyn_p.is_valid: - data_arr = UCA(data_arr_dyn_p) - fin_res.data_array2.power = data_arr.power - else: - print("ERROR: Cannot retrieve array structure for leakage feedback") - exit(1) - - fin_res.find_energy() diff --git a/cacti-main/cacti_python/Ucache.py b/cacti-main/cacti_python/Ucache.py index 2a09f17..778e284 100644 --- a/cacti-main/cacti_python/Ucache.py +++ b/cacti-main/cacti_python/Ucache.py @@ -151,11 +151,7 @@ def calc_time_mt_wrapper(void_obj): wt_min = 'Global' wt_max = 'Low_swing' - print("CHECKPOINT Nspd_min") - print(Nspd_min) - # print(MAXDATASPD) - # print() - #TODO Npsd_min messed up + # Check Npsd_min for Nspd in range(int(Nspd_min), int(MAXDATASPD), int(math.ceil(Nspd_min*2))): # replace with proper enum if(wt_min == "Global"): @@ -204,11 +200,6 @@ def calc_time_mt_wrapper(void_obj): else: wt_max = 10 - print("CHECKPOINT") - print(wt_min) - print(wt_max) - print() - for wr in range(wt_min, wt_max+1): for iter in range(tid, niter, NTHREADS): Ndwl = 1 << (iter // (Ndbl_niter * Ndcm_niter)) @@ -322,7 +313,11 @@ def calculate_time( ptr_array.subarray_height = uca.bank.mat.subarray.area.h ptr_array.subarray_length = uca.bank.mat.subarray.area.w ptr_array.power = uca.power + + #RECENT CHANGE: MAX - ignore to reduce expression size ptr_array.delay_senseamp_mux_decoder = symbolic_convex_max(uca.delay_array_to_sa_mux_lev_1_decoder, uca.delay_array_to_sa_mux_lev_2_decoder) + # ptr_array.delay_senseamp_mux_decoder = uca.delay_array_to_sa_mux_lev_1_decoder + ptr_array.delay_before_subarray_output_driver = uca.delay_before_subarray_output_driver ptr_array.delay_from_subarray_output_driver_to_output = uca.delay_from_subarray_out_drv_to_out ptr_array.delay_route_to_bank = uca.htree_in_add.delay @@ -711,14 +706,8 @@ def solve(fin_res): for t in range(NTHREADS): threads[t].join() - - print("HELLo?") for t in range(NTHREADS): calc_array[t].data_arr.sort(key=cmp_to_key(MemArray.lt)) - - # CHECKPOINT - print(f'WAT {calc_array[t].data_arr[0].access_time}') - data_arr.extend(calc_array[t].data_arr) calc_array[t].tag_arr.sort(key=cmp_to_key(MemArray.lt)) tag_arr.extend(calc_array[t].tag_arr) @@ -767,7 +756,6 @@ def solve(fin_res): curr_org.data_array2 = m curr_org.find_delay() - print(f'ACCESS TIME: {curr_org.access_time}') curr_org.find_energy() curr_org.find_area() curr_org.find_cyc() @@ -784,7 +772,6 @@ def solve(fin_res): curr_org.data_array2 = m curr_org.find_delay() - print(f'ACCESS TIME: {curr_org.access_time}') curr_org.find_energy() curr_org.find_area() curr_org.find_cyc() @@ -907,8 +894,9 @@ def calculate_time_single( ptr_array.subarray_height = uca.bank.mat.subarray.area.h ptr_array.subarray_length = uca.bank.mat.subarray.area.w ptr_array.power = uca.power - # TODO check + ptr_array.delay_senseamp_mux_decoder = symbolic_convex_max(uca.delay_array_to_sa_mux_lev_1_decoder, uca.delay_array_to_sa_mux_lev_2_decoder) + ptr_array.delay_before_subarray_output_driver = uca.delay_before_subarray_output_driver ptr_array.delay_from_subarray_output_driver_to_output = uca.delay_from_subarray_out_drv_to_out ptr_array.delay_route_to_bank = uca.htree_in_add.delay @@ -1137,7 +1125,7 @@ def solve_single(): curr_org.data_array2 = data_arr curr_org.find_delay() - # curr_org.find_energy() + curr_org.find_energy() # curr_org.find_area() # curr_org.find_cyc() @@ -1147,7 +1135,7 @@ def solve_single(): curr_org.data_array2 = data_arr curr_org.find_delay() - # curr_org.find_energy() + curr_org.find_energy() # curr_org.find_area() # curr_org.find_cyc() diff --git a/cacti-main/cacti_python/__pycache__/Ucache.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/Ucache.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5216b6ff2fa51ece1706d5dcc1355c9b9591d845 GIT binary patch literal 23701 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 Yjc^bC&kSE2?&ql}IMMJLhQz)97oRed$p8QV literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/Ucache.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/Ucache.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a8ea8b3223b0816cec836384b237feba5c44044 GIT binary patch literal 60472 zcmeIb3wTsldLURORY|v`Dpl$ImP&6434z2*fOrT5h=;@*W7+sxs0vV_2fkH2EzxSX zJ1rb_T6S=(By^(gQ9C%s6OzFRJ%ckOLrA0p6?J_gVW;{DPi`U(=N%k@O z|L4{@=iX8kNR2!5ZPpj@*MI->|NnXY=Y8%uzvXhJS>Soe_r|I3{)NTzAMk}esZr$f zfYoAo$Ktd2tb>+b{7o9P4kh&_SrJbjOdhiJ+9+-tv>!p5eb7FX(wjnQDTAp)Qm;hu z)IrBkT5sA=dT)A^-$D7MLFbUG*F|X#;K}ICptyC=-RnuR_%nTJ??M>fhyVK1o8?RI z&4&Lu@ITk*?9KDJUQD)Fdh>e=dJ93q6DVT5z6`VMix98g;@*~DYkau?YkheD>wNhD>wN_P8+?TT zmqB`12a|h~;kRh8aj2=c3F1}^F3Wu-0GoZK09W|R0Iu{|4_g|_KSl3*8mtl9zJXu} zep8N|QT%;Az^uyvNZtOS4n^s^jCjxa{=WUn=_3tE5!-2b;2grxIdDlny1fH_?DF8q z>DEZ{!0@S0ZJ_tG9yia{hGYd}`Y9&rr-)r??g^grd3$^p2LYT!&_4tq*f%5(`Y*^W z2E5gKQR&w;>5wJb=bPdE9gE-6YxP-rlYCZ)RfYk=bm^l%q6Iwc!q8d4)k!E=#h$X_KF-WAMMB_BZnfruatQjBPgKcJdvUR=AlIZq_ZR z@cM;m-;KeW+i&gF^4my$n{H91H`dNnlgifH+wbhxiaSYhXVk=sZlp|yZj9aRzcr{8 zY$OF6b(4#$22D^Y!;mK{{$PAN{FTMqA-9qR>HKs%D6)dYnua^tc$lAUvE)*lUL31$LzZ0UB&1y|2ID z9}LQ&fgwM&-iZC&$VI;rNx^1r|G7x2@A7cp&_F-6>PTv|5~b!Hv0*JrjXaVD)##v~ zs(DX0c%>Tjn+(2afl14!l#wABn$0UUPqKW@Mpb?T^qPx+TPxg33b)1I=8x1-@_{34P&Z!{iIM=LH%$e?pDC zl$bPTfGN>ufkw_R%8om>>`234xiVDZN-ZeS>;5{#>Jc;`piKd`@_KvFh!{2sN)v+R z08AyMI6(85UdSxV};HRH~7R7iVL#d2I)c{V;^<+C8OCGxfbcCL9bZ?{4~VCJluOb=)1QaT6v}2(D2?ea_@CxiY@TpQlWt?4@H}5+Y%PXvf+-gh z<_WJPA-3GNCFTj&vB*%yPp1T0XrAzpnL?R3PXzzd{EE#JE}1Y-cvT-0+r%|Y0ts5f z@FoRf#`%W(6ZmcoaQ;R5o=}3OEBDdld*ZrA@Ei5UrXlA_5DQDd&5S%I7Ig{hngkL` z2GlhkrVV1j`LH2Q;J-m)k^U!?0RIiKd7}TuI)jJO82SaB3eF`u6`7Ij{*mEO-@tHC z?i;?0lL#kA2KBzVZKyAFCSo554)+b~T?{WIjNW;t1I;>o{h2!(-UOYEA^#9ekHDPP zmBy#{I5=}FgeCaLU^&q3a97T(p53guTZy~%vBmD#Vf`?4=gR%+2hG~LgJj)7ofaObFU)qRp`?m>qoYGY4=w@XxG{fkhTLlEnHl7 zV?8NuB*m*haNoqf`OIvRS$8w}mV?x{k@~G#W(UdaK#%uWf8cu%P!Ap<2YboEK5}qC z+ZiA`1G-zdxco-DuHsQK9ca%s!LZyxR&K>ESMhFAyc?Za&`9lC&ApDe*I_sgSwHH$ zx95I{?0QaXKTg_@>%?$*<&Ddvd<7|AH_=I)C91O|aqtd3A$W(Z;qod_#I!sruefnx z#s^`zn|#kf+PWY;wDNu;_R?NH2n5GlPe9O=>*O5#})?^2WVX_7vT-Dl-k@jOc&5%n;~B!7F~VE+-AQ|Jyor}UjW=T{Dgl=J2c(<0m@vbda&<(a8IxWBRubICMX_4g6 zfG?6V023yCrz6t2^NL?q`i7!dKVa$LHU!nV3^gMx3BWWyPVhw}nCk13Vcsl~3X&Aj zNl?@3BtR5gDbXjPbrV73y5dccmV7GtMU?6WFm4HF=fFTq3g;EWPkOijXOvy+r`StJ zZs7uS1ZoNW$;UTmxS&XXE5tWGx6#vJQ`UiIr47M)1k~U+B8GE;dN?;BhTsMGAH>pN zH03mV(PPU(pv$9_$ttjA!@T|cKSI~-9mu0GD>SM=(4Vm+c;j|4mJDy)F2-!|#_eLv z4sYBp#!}#o+r?Naym7l2li-cp#h3%$xLu5;!5g=WvGmd889wY`VZz^c;s5)bV6^}r z?|O1FAR!$7M<26{x$6QNY>V{C_N+dIaDqDegfM>@jyW8C%%L;C`K(ufYs~ot>2W30 z<7J_N^fnEL%x}@~WQ;mTT~{E_M>7zPxqV4v9$)fUCj8F|RSI2!EQTxJGtqI5pFTd@ zS!!j9!@Ra z>vAD$w2D|xqgx1D-{@o3XX3(^Ir;>6nH+WasKuD&V&0&Jd7sxZotCNO6Bov^M>Bma z&y&%{h7SXUZj01C^iWM2kQ+JM6HB-!T%$_k*cv`_YVfKm&T z%xG>T`?7#i3KV9c$-Zo$Q*RcOwk z7^}*BqHETZT+KB!=r!2mD5f2)`OE`7u!y7+XUB3(yh)?(&}wFHP|8>SRSQj;5*c2&}LC;ew51I3&6q(;eV0QSD!WH6@Kbr9W9Jn_`(pl z#tNS*U6erDdg4EW-^MzXw<*enQF}0Ca^v+Xq>@nv*G1_wmS>{#Hfb#1MCa|(Sb>RN z&h+?_&(e~rIODsIWt-^U1#)J++#OQN814!tH&!%iSE@og*gNEzeKch>bu@c4Z!~|j zV6E_;uQ|;+JW6DmeHJ1>0Ou}c%M%ZjCnwlIn-55tFrwmJ|r*B2U8rXx%Qle zRs-?%GIyxO_4dAK)T4YCLb)44Z;F%5^LI3TrbfsK%*-EK0-@*gtbM1%X@{XTrH>)B zX$eAW;$INjXYT2l@L>y79WhF;j1-feGm8_$~XNN~F4tp;SD1L9~@;QISmF(?ZJGSpV zuzz>Y5ic8{DOm76#kxYl+0IX)zX*%thy6nX@@eY-r%=;cKE**o#Cb&N8x9T)1cL)3 z!=K_vA(FcPTxg)bZ}3wbDSV0pgh-n3<n|{pSa9uM2K7 zh@_u_+`TOK1%o5~5eJNySHT$BKSXCpBFX1Q&NUQAqzfYhK6&J1AR?hOVn0LjrQr@b z88%_Th6cb-8u0$1DBZ3*XF)h%7Y=xOu1^UKgdl4pDHlU@@J@gGE=6o;Es&B*#70%x zP(4s-0^kg z-W5*Enrs^14mfdp;WZTMlH9F?vFWli#o>#3{qvfq7d23bA+J~8i6Di@$l8KZ@Hiw#4uGzfA z=2dOpd7ERRUQh3zN|wyLxBI8--yFI=^u5C$6n#gYl|SrUKc zB-g~CCKVH@Se1(B;qBBl*Q9I0Wk#>1PNq(zKFZ3UPMJxWdF4BjmeoMA8Xj9(9FTbc zCbrENluq~0tofi`D_BJeU{zzK3!DH<*~0k+(?@0kw>N0Do3zr+TK*QD=7WM$w(|BK zBkjlxyf$n3D}be}d@7xS`KtPxnIG)EYkjZ#?#BDCe1DTxwVPD!er#Em34Q>W+B;v@ zbo1bc>32JR*LC;Rk6XS!rqy+my6(r8hFo9)Fr7YMTuzE%vBy!k;qF@cGhb0Nn?Jp6 zzN&6^{d8x{PkGgi%QriI?dtT^`MSp0%QLolpuBpsZ?1fWTE1ewx%JlBne^z-!{Q2< zzb_oJ&bMs2pYpM!9_m$Jd|5qtD!jGxzVG9`>hr$v)?FVbJxKrfpnBkldJLRjQeQs% znLVj>$odltLbas%af-!T``D6F*#1EdX@H4zz@DVB>*K5k&X4=lgGbfpUQkcSYTqDg z9HttFQR7cRWA%-zk1a{1?eop+?^e7wgn^DC4~v&Swn&BT;qn>?e(A<=%c_~wn@O|j zvl(G;-6!6zId9j;`Rc*LKP=X~M~U~S>OBe$zm@Ubj1MlocjeX<&AWkkH>lnX;VLkO zC>CyAJtN)Bnsv^)!`}K&yu0VTyFad14^tq|xM2TXY;H;rRGn=>5FUM+jr?QMZ^84#GxvSSZH+Tl5)qn|tgqvPx5u zrZR_1Mm=J-Sj-d~W{EQsaA04MK4V!4IK*snb^;FUrRh47Aa)L!&oM(x9WtL|hPXS# zMh=K6-&O&1fv3V7rXzhuC3wT`wEpH1%kx0zDG%Wi3+)bB;GO`k`RK9^S>PTqPYQa( z7|#>Hl_2`e;9Ay#=Ut$@7G`9n>dYzg3IIr=EuA#9xInRMbdZ2I_;&eF92C3h6& zM1^+ni4VrFKnnIJiO?BCA--aP@bfX6iG$Bx00*D301mWm`ULoVh49~`myhe7DrNM` z8&z*fAjM}V68OqzGL|53^uNmBKc7W_G~jq>FXMo%ZnX>t-|7r_J;TkjX`qMCGK0i2 z#szeNdjgFHI=3m{U(VFy30SMPK@zBR7r?hbha$K&&Ef{aCe8y@%Z(_RFV<_EnAsH07ugFfxN{5wT>G(aD=T>9kMZRwnoX8KqtdMhcO=n z2ae6@0~|X!?g`*Xoj#^;bTKM~RB#x>fs+9AF>x5fv4?TMsnrx8>NmhY67X}m^;L1E5ifF zITqiq=b5`ns+Um{`1JyFhgMd!#zxB)<@ZI#8&4Nqb9Bfj7|$Z~y~KE*pigEz5G!F( zPfPcg<4Qd(-TUH7JuTf&#+B-4)Oc|N%kVLGlhr;gUjDdJrx-PXU#FS7$*(hvnm}rR zxr0yt6a{=JIbg5Bkvfan(RZggGSz~ad}0} z(!$&WUtt)8W?bL_jtgsr9<8WrGp|4jK|fYd90r-MGEGa6d2Nw0#*~T|qpvYN5Tn-x z9^m*AVkBf1A0r|2Y%%(}2)k^+0~}vMJcP{R;~`|8EgrwX;$gD2Z!qepBf#+`#7M|2 zK1M?3i;9ua)+P)w;`kC`BxDvJBO&u_F}fzgE*tOw$CnTfA+z{+2$^S##~UmjCR_VO zMg?2r_!43yWELMIA@fDW$Y^Vmh8S^t2{95fi;t0zdA1mRQ-odqC4mPxzJz!PnZ?IL z$UIv-zQw|Bvb8Bj1zY3z5@IA|79S%a^F_tTXlrj8V#M(!#7M|2K1M?3*<$pT2)q2t z0uOL}3Gomzi;stpdA4})ks$PGt{dXP@g>AV$Sgh{Lgv}x!AGDFkGBo+;P?{aA!HUG z4iUgUEn|e z9Qe@SufRQl-#5?&?g{*Xfi7@^MVM0eF5@;)zt5;XJI-R^%#|+%VRR1bpE7rtJ^p7L zcgXiR?hbs!afkee9QOqNImaEczzr*%(54h}9#7yt#~rf3J%K+m&;{-Z{IP+~aZ~L6 z1>=Bvv^_z6_ki&PN*M;>`T@t|*JA&YyF27R;dp%BkGZ=;{!@;}=lxgAU9?ArIW>p; zubF#-*sNmifgf_r7_T2OY6AH`S|;6{#rYv2&Lk;BF~#QqMjwg{t|LL}PczvS)? z`L7tRAC1_vlWtkok8bpV+h3#m`0LFbbTjdhhWUu6Q$IZGKp%W0>c?HE65D2~qyclp zcCv5yY$VBdE|N2R9zMJ8hYhEFp`d(bM3H?1z>ZX;C_!M?_X)p-*w+wz1y#6w{?jt- zY#lm(3ARfsI5nu?yqs04GQ7(4U1>yp(rJH)o}fs#8Y>~BrC~^Y1Af@d8*x&hBZrU4p^;F; zdM1)`#y@cS44@Yy_KO2PIMpB-A{9vkAV-}jKIk7l4UQ57m7YKlaWjmu34+e6)L~S; z7=q+(*rHoSPkz+TF96@=U>_!oerP6~3W=vUDoKL1>7%S(11JAn1Dy9iE;uV;ye>l{C>zkxzFc| z*r{kFTi2j~HrQT0B2$CP)QJPbsE0~LBt<@__#pz3Y9?_pN`W+qh8d2a@PRFj^q-BS zDzM!i*`vCmuQdI@ahTy5|0o!Sh3q$@H zG^SX@BU!p{h@XRlMrhoknXP~FKx+b)f_kv2V1X_uDAa5)icxXol24vLbqY#>gB~Xc zZ$YIVi)sTF)qMZ3UpakQUYNEzcTC#W7}$B_7n*FA5RRrqFp^~uWy#~x`B=W>Mp@5VRN$KxIM7pq=1l2716Vq( z>7&xcaiu8-lp^8COP2E_Z4&idiFkDmC>;i>DFEdOIij9Kqt8@ukFrf|c+|f}U7M+O zrYBSP}GWs6~sh9a5{CO>&lDiSKlhLXPyGIjs}1;}c}Y5Vcj^Na1*^ z5br5PqW%~f;Y{5hK?z3Oym;s)%ZgVl*`pJ%iH|ZyO=$t0M-NK?ZGMYbjxq{nnI6rE zTX*A~78Ytw;HkqY2I*)Rh6b@3zz%e@8xSoALIj*yZ-6GNoA);K3N@0BNAb$h7bh*p z?9IbN%P20ze+nwUGtpvQh6ncQIHo=w0Q3)z1pWA(8+`az632Z6zBSZcYYeW6{}ni* z8v6avMO6If-~&GBnLxnLLPm*D(5^wm9+D4j@1#G_t+C-7zF;2*Uk*^0L!D6PvW^u^ z>PQ-msg9@X5ski_Jg(jh9^{}cEaQlF-PjPu4Tm6OBFc=AXC%PsM$yh%Bpo#|CMONMe7X-CgNQ4LMi3nI z`_IXtOOb5TD}1MkqatYR;M_INq@PlsW#+^-2OBG7yx4cve;(9D3Jp9_B7Sd)ZIYSQ zA1PSK8a1s{8aN1BCYUMMPbhXI(UQX=iyf`>l#8~}xeC304=oW{-XfRZf+*5=4iBK>|2R}y6(NAR~>Bs>k z8L9fqDd;EwLBY8O`n52O0nsia$#C+R@-3v|ax7Qrdm!&_gw75#AkIfvvdFgJ>-O&9bAFoyqzNo%5pq?F4N3LkjSBdjg_!cwWGr9S( z#cIzDyK^SaKT2~=_^&OSTsFS_VQR@^%gf33J=T9GIUm9yc9(9vO3JsWQb{;F?|R$y zjU>BnLJE7buS?g{iKlMDZlpgfES+#nW`xZ@m35?Y&4hzUI5`5RGKVDm;ns_$Q^! zbMSFo=}J<%a$@&n&pdoN`jwf?=$E6O!l{hw88cOIh`#1&Mf@QgLf3X<1L`jb7nR>#P#Kx%2wsvsq2+h*HI)h1-{hHL6) zkI%kHYPRERr3g5_R)kwt-zm6LLRxz9wV5)Lns!pNP3LC9`YX+Z&nz{L4dE57x2}>E zyC!xMXH$67)_X6JO)ulihVZiGx0=baJ@`@=UcU0yOJwfwIUe2g?xrHxUpZqfpbFX~)PD{k$l$9==u+((eqfPsf(F$KPL z&7Bpb^$=-&p0xHM*NX7k^?Kl*Cu?6OYtJBYRk*PUf9oNaNzEEWE5l7I;LvYG8;ode z1F2ny)T(er^=t`ZW#NV<(y$59S};29Za^z*W|yOTdAM#Fsaua|^+Rew)ViX!w?{X; z>N--r>3*_Sz5V{cgJG?jnsWu@CRs);wGJcNMjE%0#+@ipAARp2jl1-BNSiJQJZajE z?+uuI)RcFUmcvMC4ojH;p?s;*CMa5J$5Bl>s^iRQttxFM(q?trF-L5~wy5o6GdS1tw(*{-AMx<@(&R$LG)p6#uQI)n6X}h}X z1x?FTgJfQ~b#7FAl0(cg4XlMd=QRLBpc z2Tro}WwLb$z1T#V!HPOnX&-@fKH$?NpN=!99jeq#Ae|5THOa5z%xR}8^$@8?J#AQ4t5PRMzw1R!dQr!}OeJCSPe`Sh_82+6M5KUwOZ$bNW2(74rayDS_;uk1zidUe}YjA2+r449-n-6KyAsy#6(s9)P zbEuB64~0D>+N@O3@K+^H1aOL%2pE2Fic{G_2m7%l-SMJzs_QfQi+zbRqJfsQJ(iA8qSs=eIu0 zvXJ(cSMXlXKIrv8{}RJS`^5FPn#i)vWZ6!#jOwZ5MiMnU)|ZL)$I(b{jY5|m%#^G+ zhI*Q~0n%>zO769(r>PH7+EG9sdyuNN_~NAl5%vNW1f!_Eq`DJxz5;rPdN+sm-Krm^ zyC+ubXH6u*D3?8mC&T~G=U~{2rwa#|3*N~EH2uNTUE!2F*q39X!tR`qjqw<-or#_; zkmO4`j5;}w*lQq88wQQ3Ob7a7dIukLe@*^KjDHdSI2bSJ#XSb}iTWen^Zd#qg+3@g83%%q-|nj7~SBgH8{_qdLWVe4Uw$->B1<3|B$IncdgGap#fuvh)oQ zx$vf+h!$Pi_4zO8n+EuDq<-&NCd{SaMQ72;Qe<0(viSfanbGMYgCp*&(C*q}KYZXVX8mA9b++^$L6e-L_bbuRU&ntGH@!XRV*WEpXk&(zK~YmSw-ci!pI zq;2>6wbb1|>LmM4&ZVAIQ%^2nCY7r-$LhN&qz#+ykAeN*kB=NDM*?%H0W~$i`Aeo# zZe(bV+MBhvnl-8I?shG8%MYr_wxcnD$eXIYzCv?U%p8OJ9HiBEleN^1ANlSL&86;D zQ{ezIm@o=|Sv3EDSTvQF!L*e=1g8O*?mdeZ0@$5E3&9Y$=RzS+<H%#_Gp9n>|n~ z>veb&)U$9KvUMyOw;-`+%oZ}#_=eNr?It?cIF@3f^SXO1)kH^M=`$vo=qa4;7)=V6 zg?PONHF=WxscBnsjy-oLy zrin9xL~SiD8UlVEM!Me=Vg~2v+eVY4wQ2rnGMuDunc=lCiy{7wrp1POvNu6!*@@J9 zo)lX6h8tQp;NWe{-%FV9gsMcWM&XQq^Qkk+yKsim6Vh1!?i@I>m=;LYY=*N`y@Kgw z|5@TjB~ube;>13Ez)x)6=wtFT6(sYR3vgi@Mjs=WDbJghmgl2MGX+ei@pqwhzzMQ} zC2@as)MhNrQH%GQ%9TCV2A^E6@Pt`<%4~{$qsNto9fuC>KeWL+JmRHietPM-re0`( z`-TUuz(Ul>aL{{dJ3w3iL&6{!0U)NRr=Y=;+YhkTD&b6#bqj z+O^Q{oy4u*qH|;DufV0RLn9ab4e9jqR%HOH--!MEAY6S82f~g3q<3c{ru-5HA!+bj z#M&3J`XbhT0xA9-eIq4kln1>%1{UK7(cn2LIC)qu4kfNHgUehN4qz%9|aZo=_@nL4( zV@sjE`ZEL*cKwXdzBk$@+QT`8B&X(P3ap7}Ic;~3-g|*;+D|q;r}n-~de3N^&S=>K z6P<8U>U8xRUzzv{TpBcmD^~BMy_Gh-M)On0DB{?B+2z{ZA|0q~&Z5>!gO8J8$)9g&VY-jh`i3bK4*0dop5Sl?k+1Ff0&zZbSCR|Yel=YoIRhVCg<+8K9(%GdDFQ!ie^sDj%bBz zw4Ak{Ic&M>9w%Eeb023|a!RIsZ*7^{0{2Nxb%k^C-`Vrlp6T;iP7Nfcno|R*`p&+$ z_RZvKIdvqbPR*(N+lQXqcbsoIr;lo$D&nb9Jyn1_Om)A#b}qG0O)aFE2UAsD1gE6B z44F3p=V3m!Tcjf3S~!H`&Hq(s!p+A8#x|*AFd&1@LHzE3xtk!m1Lkgm=nj~>38Fh- z?k0%tfaJ5_RWdPMg5)PwUA9=)Q7e2vk!!5{LcE#5p`)4K{07|(-aH_$&yEFOe@0`j z#)fNd(v&x$6JX*J9Sa!L@&=kUBG9y%x%p5~bT&j+12pgs1=A31=AN#Fcbh;9Z*omq z;0hmO{6u3661>4QNx&6ACJCNaAi*0?qr_P9u-kZ3>;h{`hQk_@&e8;idjuU{wO(~V zvkDg$8T}b^48x^GKKmxilX4QS&Y+g3hyFEzf_?rG z1m_Uoby&(P2(ZypF#RLRu=iiVLBf+;zIaWXp#eOP`eY11dL$J_=6L)!G;lBm!3Iyc zj6O;I=M~r)ge@PO1+H&y!qdQ^6^C6UA-;YFbG`( zyh9B4fGCsTRS&j?KLiBsPfYhrD_fv|(Ha<8-=0)@G<%AEsq}2B&7@am3&3pQ^t$G&!V6 zC9rb>HfhW|3#aR6T5mMnOoc)d#eK zgW-a*nfjZpvrRCKKq@zq%I)`0KN!&}k7@M ztK6#rWOIRPD))hb8(%>@Gv^H85 zt_C+{4T4$#I6i@Wa0A2imfCo8smet#X}AT_0kx+>Yg4%90V_N@lCTa1(WYUPppOpR z(b|yiZ^!EJmqGd(R)<-D;NT!f6u-@yzJ)^CVyM#|d2*(nf75;4J-+*)3;O+Ob}t3A z`kGij@AOP%UfVUfYhu?Ur)P4{)GOD=G-nO0>wsQI?gu%r@uuU>ZnAop*3d;7;BHKy zf)M4rc>OBLU#>ZuVG-nUGCH)by|e7@!F$h>O+8xce$u+1k{>#A9%i^Fho<{(43M%G zEu-c3!8^~BHC>vk>*G~(t{&CZ69$IUlfxvVdghhc%cQPN%V@jXac?(i@77%1>Vd;^ zuEVP9Fsz|{;w+hSmP{YioaM0jMRk_{&Es4aD_W^ESR-lu@KqXY9zN^8Y`Q=ZO_^3P zO)$*^{bP7#k67RsvzqAG4%25WDSojsaq~(Csw;eTyf8Y>x zvkT9&P#xom?Ni1`~0=VbGkKBu`myrIdFMt!0LPL@qSN=9JYkIk4!Mmq5(TKJd?-pXftr2z&X_$CqlhbLgln)`BD8zbPdG zUZ!=%po7t1$#sVT-zo4wHN(wexh0w3A#BEw$K<;3-IpX%U35Tx-SX`PO)Xq)Rm1!? z{w9i7Yl6mt?=XrkgoDt&xu?1+vSpSZycyL{=1-2OY)4DT(vWd6)G1C$5+u6My>ZsC_u zNA&*v*AdTJrYB!W+%Cd`9=EXAx_d1B32x3s=iN3)v9uZ7v9RDV+ohNdi!J4FS>s~l zd8-~PKe>I>1_MsVm^>(iu$Hk5xOOu`Zf3giVj0855E(NonTzpvfkhiz7SQmN zb|Yh^#i)(pv06tnW?Gq>@iz|NDx*8Y7w|b}Rx>x_FI=SqJ;e8UFA>txK4a*|2;Ri~ z_E-&*zdx*wCM$miZO&RDFEDf1;PM`{nK-#K>i#l!V$=4E$eq#T+kXan7LhklUyq1< z8@0f7>UQ(R#nfIFRrAwa&VVxLf)U;drZsvwul1^H671j$ZbPzS+mM%Y%r)W5xs%yf zQ?5F%rd>^^Qzsd4qz{gZOv7oM<-sMF&#`WN$8s9x*-m(1_{gh? znLG5q+twdvHE3ClB&(6r=&Znz=q%3tE#PGe9ODBA^+as&6TFhrwPWADku5N9kPH(B zS8UI99Puj0L9f2TjkEDrTpioD?>Kzedt`U_jt$<1Hhn^V8!~N2fE!WZ>PxsVGm^Sf z4qlPZ55ds@c#kMdjfeUM;G7fx$@8a`4anz+&TjWz)@SKoLk(X;@D&7aBKSIjUqFBX zR{{vOBEauxei&TU!j^b7>cC$FTn@0K6({v#Eu`2UyMlfvwDb`@)F8cA@~+b;gl4erjMlY zXthSt*_2h^<<>|VUF6o62+}DY{rJ>DU+6cp5=CL5K*45*E3m)!RZoUs#2TVspu#ty^v+WF+#06nU<$4eHW<>`y0^d& zx}c%pCM!HN16CmXL+66HEC;i3rbnNevs1HFz7LYWiFTNpO4lc%>k<0TBb)U4?r-`g z2d8&vwn}2FRBe@TvEbJ`iLLlyh6ffV+?lX=;VFDG{d)QYtYbW^t{LA&Y`Mf%5iW&0 zODS5E0IjWyGE{{PVgh|g%fyFAKWh73`Hl>wLCf4hGIzlJq3-O7Q*U3=GRntyJ#uBe z-F8i$lpkB{_T?17)L=>JMA}r#q>D&};fe-^ml^T-ipKAhz{hG)zOs4mvhO%&o$S3- zl}cgW?=wq*y>(imKi}&l)vGBM&di-ifl10q$J^D{n`Tlpsg8c4QTGV$@x1hA`So%L zh(iYx9dO6r1WZg$cH=JR`sEC-3D+!Rc;$RyC2R!!am$X6d)4F5|L}ym??tungjRTh z6rPyaHPvwqE=|pz>X_W4&mL;dGWf<$rGExLt&TGIcGpn`e(K!c+W*FW%~?vEr7Hb{ zYYiP46KAfuC*2e7c@bF20rxusK*2mcsFj~M>*kzwAME+?(w$c|{BRDwGpN&?oy6Ix zIy*s=D@)DVI$bo=aif$JuDER_g{`D;Gtl5qqaPi>_Xd!L7>MaTGq2p}CMB(!a}|7B zsKV!k%%h4=oV9b#+7C8-c;?Pot#KP^+@?Bf;j;#UUp8!qn0%|}jh^WZGkrHUk>Zt_ zvxPWYRQmVOl?7{L+(>t7wkl$)Qf*ZRt8mzh;m%5XF<3=;4a?n<`RaPeO!it4_7vdP z!gb&7BqdE0o3Ck@?fr1|olW;!v{jv2%?_Sbs92=SlAK6RA_yYiVK04LhaMK9LIMqykMUf^9A;{WFBpYKIGN0YE5q?r*u@ zaBET_7_dtJVz2R?7j~ayUx}0GxS}Uz=~iF%iBvTwReg~5VcVUJTKyJM4`J7ZflXkOZ)3CAN_ z_EeWlYR?Isy z)vUIedQ!O-e&J7ZuBRW=tcOs2;`Giry_&NUzKaEupp>#XXPM^of-)6~I`WjxIZOFO z|3jSoUpePodAmS!Zh)_!Rp*9i`S|wkU)_6SujZ_W4{lZZ_qZ6tTxM~@qKDhDJe*(l z&Z}>|`sUd6F$j8YDefPF>JGq^HC$XZv+YJZ>}9HLo|0fcPPncff2(0R^b=3j9PZAk zA)Xr5Q#0?$RrA_s;4ASB@C$#MXA|*kQaziX2z=tHp7T^|o?7CmRXw$oQaR_T)I8Oo zO!ZV#O2wR~f^YkI=qdcfvwF_6`u1_nvzd4{tDeo^>pSkZ+~0G2Cw(?u^E43;-oOlh zkIPwX9#@(!5`ARLnR;$|;AVklYbCZ;)z%to?$lV4>{)1ZSzvVO&Z$(0=v;c0nqC$5 zWd03aYi+#d+GMMhC{_t#dYwbFi&k@x$?*43%7X8_z*^yN!aiYNxU`F_33T1%0YLMo zCCa}yF29N`$)OaGi9TZ4b>XT?h_7tmwqcVL*I=STJFP#^+h(X?WyM6rULAc*)U>!% z9u5;PUtcj%`RWQ#`HG6z4`d22-x(BhwJR)Pi_1urijZLzGj{J2E_0i9{jdmF#8suk zWg)|8CC>J2K4*aoys@LNCFP+lc9z1Fhc;8}pPq*z{rFO|DOHVmD0q!|D5%Cf6jWm# z3hEb;hp;OuVIIb$F>E`xnevc_^(=WY>cj@ zZ|@r(9tn9Be@GedU+_m)(_x>``To#(#SgoM6>oGWulJPS?>pJof0hodb~fZI@8R$P z^GNwNVwi`@Zy@%Ih>6ZV9T|y%((C9d#z?=751=x_yhEWzPayMYPL>%{XJvHPzRadZ*11E3=S{dkxQs0hJIsLX=D2na01r)H2; zXeTr5Iig={)1(?WRz#I*<_qe>P7ic;mwzv37TV-&=zYQmd^69HnssmhNJ7H0o4ZKU zX3~VcS7>UXsnk2s=_!S2KY?4i(m>L+%E>zZfB zCU#M;s#Rz8BW#YLJ9~gQ52(%q#-)GW1r+0y`P>?)&c7L&9Q(HK#t`(X;Hq}`lzIk_ zoFSDP5)$fe=97kY*ebv{%D!hK-j$!Fr{twTkn>W;dmzYC9!Z71wjH)(W#>&@)v{|z zb}bx#Q{6P%Gm%QYs!*j0xF%lBfI}GQApp`o!@h=xw)9VI`E#~>%~nWkg(~~g+aA6e z4LQf#o?oe?YyOa5?16ckMO>k6tlOS=VKxi{^~Z1#qK(nU@WSkP9B5tip%-SynQwPUA0l~42QysD~Zv@A71BWpm1P69g=mWm&;J7ESli{Xt>|#`i zui!9-qbn|lF&w@g;kZ%iD5EBjI>y`~Mj|JkW7GsvxDY@elN4XIO(50FrQBlI9%v9X zgeV0sFy45&^v@~f7a0#+c_MKf%kf$E z2HFNW?vMrk5BDN%(OWY1doJ))NYtOYXyC|XxGz~RX`)|)-#39pU1A)N!k0O2zDQe? zYSHfV9t-HW!sU!5_Ekm=7i|9{W<(v-rD*_jnfC_7a%dbUU z%P!0o6o)}(oM~Eu%vTpFV@#=dF?x;Zf%N^Fzylm#LX3pWIMejh7zvqYi_z=MM~H_3 zH(dP9+rX!WiOUBT9}gk(Z1MOyi$}m{Yrnv#aIq}Mmyk0;X7Mo+GGA1TjJEa-LyS1S zgcu2##m7jAV$Sgh{Lgv}x z!AFA77x-mEJUG6DcnF!r$3w_GTRiv(6ykB+5D$(oAs#|z@$nEc&lZojMcCzE5qN;( zONfV%S$sT%%(KOVk0~KP-Z8|3<4cH#kXd{@gv_(WV_Jk={#AhoIKG5<2${vlL&z*P z9>xo^lURri7kpPS8syBcbKE%gxxuKWQR255)ig>J z42#hJo7_Foh1}1kf5xEyI|2`I{29alU7=Gp;D!sipDq0V$e@3gqTyQ|2z(Bg34UL;hFHJwa?*nS0=0bIcg8A2MnJ`5$q2hb-{;Vf`}$@4w-A zd|s8gCy1BE+!KUrj=MYLKj(OSzX)?r;Mb3tyUDM=;8ce!aH9{O7&ruOm<tzg5dU`wcA6R2R#t6;UJ{1$?n2;M`04U+Ocf?Eha zK!8n!@;eA_BlukezlY$TAi#=M!CF-LeFT4i;4T8J=@hKu6s+46tke{&%@nN0lz)!k zK7v0&fE9~^HHU%~g@Uz#g4KY6WnIBSu3$-4u(&E%5)~|X3YI7Zi;cLpSHY5_VDV6} z3@B*m3R<{A5TLCpXpRb6oPtKBptUGy5(?Ua@>dAv5&RDb{zn845&Sy@{~p1AK=3~y zc!c18M)21N{v(1<5&S0v{|kcujNpGo@Lv%8ZwMYE_zc1Sj^J|yKSA(Q1pgJm|AF9d z5d1BIzeDhUBKW@${ND)v9|ZpmfyD~IiXaI=G6EX{JAxDhsR$$l4g_fk(h=a@YKjX% z1_Cz%4}wetc)X30jUWd>E`mG+`3MRS6e1`>P>i4iK`DYV1my_42r3X%BB(-8ji3fW zErL1(^#~deEJM(Upb5cp1kDImAXtf@1wku>k6{Dg{Lv?s%@3bnKf}{G0t~E)B9W-eD?~c@cx5Lk>sB>MZktKz=q7H%W)f0 zYDR5%rtfHq_(l(Ifk=^aSPGA(%;YlM_-nRRt7W(vHQ_nE&#GxO1!miA(X*_MG~~rQ z#!3GWnSO)(n>b~b0zsqaHtAFCI1i?bAZ-xA5Q1R@=McPtU>rdw0{V3`{W$r35Nk*^ ze9*ib-MauplHn*JdO(r#2f!4>D#WWl`cXqpdejh`hx;SoIbs98>wv(G2#Y>(=ut-A zwZLRxeAm1?|Js$wD{%5qTK2WZ$ws&v0Z$1@vG-c>m=OGpo)dy-;=_8R(&)}$vvp-t>!;RslRksh`wcYjoVB3#ur0Y1`Y2fI!{shht z@3q2_5(p(rMs|WTXl#YkwQ#pV*N47413$=lP&n_co^^b%`qp|Noc+P-2OGoQ`kNIu zkKA7UQPxLC$fj;kZ{LsV0pf`j040kA_XWG{Wq7O!{6vp60W6%I2j3f)RZd9owQ;z- z4u4A?N}f-o;yI~UlS+w%XBffXW2Yr2A9-t@!uvSQ;>;P}PaBnn7G*W&ZA$3!IXs68 z+Z5$HkYn^ju814Xo(c`fa6Fh_In~$i*U#Rv4dVq+nEw&Sxjv;2?#=Qmx`|?`Qcj>e zT?oR;6HfHHJaq1|;zg&gq7xP@{iLuy#7-hOgJ3U$eF(Y%L{dTUj=J%;1>{#Bfutvp43K95mOX=4WMWAk`X+diyr<(j{%D~PMsg_4~?K|v`%_D7X4J7 z&K@ghy7cfjnncvN|4wQj8u6VU^lw)F6kOrY65Ij}$>U_J)f%>>kJEo)OTKFU3tLK5 z^IzCfsN6JEwMs*LB=h?p#r~DcZUqSr^nStH*8QzKPDM z>gn{E7j9QRwr#O)1xt<(Kcn=Y7+v=zrCZ?~q=f*k%C;8$L^u?kOtQjRFb3FVzmjZ) zqGEuTQqz&bK@rC&t!Np#a&X+*V1)w^IJjWVw8B*b9MoE@nX1L3|1C`W$F}`R){Ms% f13YQ-Vr)3rXNADQnMVdVn%ZoInrk7T2KN5~h7>)& literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/area.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/area.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..434d0abb440e6d46958d00521e983ef6d7e932e5 GIT binary patch literal 1175 zcma)5J8#=C5GE;ErWGqmQ}+dQF5o5l13}TE2D*6(x_Brd=#XC}bT{gCf=qYLaFhQHx^MO**1BYfT9q zvu@D|$2hIR_qND#xf2H%kv{Nt&smUM3R6qzu_AFPR;vGtjbas4a#6{$3NvO}$trZk z=xQY_s{h?fKe@uXlon}kn$O3@WaiR*N`)I@-Frv{P974n}Fq*1#=_TVeZlge8P8jn9Dup?E}2wo5-BxS7j4M`~(k(hXfX! zb+|GM9~&Nuu2BLSid=mUJKV#zdg$TCnuBGtfH#?}k@&J61w=!&_Jl=O*%qsTTA00V zI&||XTYWeA!Rl`Ml<-xG<)QjTujAJ_2qV^KG7uYKv{d{}ckvupJ1W_Ddko{y2ypVHz#w n7u&&A3oUg+2mFh4&uhRhsnA0Y zq4c02q(~2*l;A(pW7(77$y+3zdh&a-*)?f{`I1g28O95-zcQ;a z_MMb)7z3f7gV13bd&UIYV}gH%$Dnuw{SFGJ|C9rlt;)Id_a)aBBGCdU9l7BUUdH&@-J-P%qn3QCS+xt{^IB{hl@u~-#Y$P{*zFTTxj5kO+I~6_@MWU2X(rar}>aK13N!zZki_JBXQ?~tjv$7WK$VahrtoYV+nk)+mQhB?<`5u~`8CF23W z_>4MDyJtbAs`!*pLPhQdF{Cyq!l%}QAn}LtCe{?|yAXOh=e(!QaCkfqKWXjP1slro EZ(YzQZvX%Q literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/bank.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/bank.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d6bb14246c0b6499133ca13847aae16e8b5f2c7 GIT binary patch literal 4255 zcmbtXTW{RP73Pp!F88Xnys<8ER7HuCY%W%s7D&<-MG`w`ineNCyC}ey0mY%DWw@8j zaJ`VR>Wd5nX!}s~7uZjQ|I)nX$$z0}l744~>y>25bsa8v?sMkMnc+FJqgJc#;JMZL z+upYuj`J-sCm$coCwSFg0E8o0?hIJO7}0L-4!p=SvbXA0TEvi9Z%j<(i)L_nU98njI`;KU&wXAvUMJ-60q6JASZGdl!@V3)yKV}G` z$8_*TA=C5&Q2svekAW*ZAMKNXy-m_jWf}u}e~6367~<@JsofY2#-m|6ED{o(e8}x5 zc-1CA>O@R9ktsFMSw7>x@P9Tb2v^V4Snnq@CZ=49#;T%dZ7+E zAI5`}b6w|rFcOoT=qBf1PvX4P)IJr0AJB4i>tVJkg6H4X$X@F?sC9mqAfQ57HJYWwU=FHg4;cns0oXkBY+Mltk0vrHWfkWUL za9xnLVPMn17LCc;@*{(nj$DH~N5)rn>Bu+y@=;~jEG}oz140W39UwHu!ou!~GjnGi zpuggDouk0$UV_Z>hy}AcZ_hz#-w{wPX0@ zufM>^Yi8sdFEH{=GxDvXcZ@jrCSrM`jF#}0OFOp7Df&&mHT>7JW|-Ax;f!+hf3NC- zkIFgyIKW^kvi`z2!%eBquEHp0T(K?_|-6rHl`Gp2lCr z`>C!^^97wO==MaV2zAWIv5W^wH)$$4<>Qeo=A1amO=ZcMpp>o2##&OH(pSnAs>v=D zQN=|{RoBQ77~kb2=17w9Q_4qA$s2o=_e3s{qd<`;kt zSm;^~8rMp$x*gUr?YCp7CPsAKHmkE$x6YPX@cpWH8i)Sog*vjmQjX~YhyDh^REz{om~H1v-*^V&Ie`2 z&QmivTkJYfYbLt$GQ8t3}G&X|sG&X|sG&X`# zLuW_+4&PI6-G0K|`L{P7P0^~-VJi0zAvyk-z^eqd2)qV>_F&p9rdYG#?B;wd)8rtQ`zcSq z=0e^@k2I00Shq@}ev$Ww=)9$(Y%$!lDS0>Q407roX!{(O1GtdCpc#Kj;3I$@GiB>+ zsoH^RAFm>!&N}WEqu;u_Zr%+*BSBTBpZi1Ib-%BB?srY!{ZH`2dT8y8Jp*k=0&lQ; zYp2SdjoYTaSCvbcPj(1gB0wEPQr(mkh;Ef#CQ0*r-f7Ig!QYaJDY9#zXsDtaTZl3n z-s*Ugq`f6wG2Pi-2WsXrloqKpcN$5BR{op-b#`+=?48a}(Qb8(&WibGEo;zg|8q#q kA4KE)L;_7f6pIdjW&aTWnhLq1TSOB9Q4^fQWw%@XFQgVA2><{9 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/bank.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/bank.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..10ef386234632c76f2368f4121bbcb7e03a01d17 GIT binary patch literal 10940 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 U;)2u?O3i=c6Jb>92J;s)}-V9FO| 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 Tc{uV==GDlfk@K0a42=CRubxvfc|ESF1hB`GJM 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 Yk`rEVr`<02ik;zON`JabEFCWY7fXG9`v3p{ literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/component.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/component.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5dea2a9dc140dd50ff2397f5eb4944949d126f0b GIT binary patch literal 3576 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/decoder.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/decoder.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bdcd66b43776cf3b09c0347d5e137a20f859e890 GIT binary patch literal 25556 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/decoder.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/decoder.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0fce810e0f8a715d608805d9d9925c9f37b15ddd GIT binary patch literal 70035 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 XN7@~GAR*;WoDL+W-m%j^{>A@)8p*&b literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/get_dat.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/get_dat.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1307c790f75641da4b764da551fc56f0e2c2aa26 GIT binary patch literal 8909 zcmb`MU2GiJb;oCBXLo0pOG>0D>cetHTXtniA!*rhVmtIF^%2rL!?=NfkS(iRuxOYm^eomR}uY}C2xPqS` z5Sq|EZB7%0$a(rj&DG`%mgVMh9Gi2dle?L}TX0N-MGh?vOHO%H7p5>bbDR36u2Wq( zukWHJ@}lsOHdhfvVIl4pB~eB^Ao@fF@h;IX1`zKSyToq9gJMt&As%w}h&@Y&oD;)y z!%oF9oMF_ciM<ol(5 zGo*yRo{t_0wOAL%hVjRh^+H^@t8Z%S#VfdviT_4U*P7M|E!ek;d(rAwinXnLB)F-hK=Qr}P zCW=$qtuM3Qg8tpG2))Jn9EietDK4#-+e8UO$V91|5ZY2sdU2^~#@by=U@TB`Ijy-5 zIs;5l8HM^JeeVWAH)qN zjxzB*CXQx^r$D^J#26DlU}7vo90Tzx6UUkODHF#t#Fs!!GBM7?--cz3(>RFy2CP<0 zK!2F^ldS(I)=#GTr=j1)`V*}G57wVZ_0LRctbLZX_gVXFs{Jxbf0y;oL2t-1>z_;Y zUxEH3)>G>Yd64zptqWOCtuy2?)_1o~u%23H$QN1P)w60=PF856S^;$li%V&cb4T*?raQ{oB}f5pU=4DoJCTxH@Pn7EoD=2GGs z6Q410Ekn$w#C0Zq8Db?6*TsAA{$#P_{q2-_AB>5)Pt5zGnqh9FOpTdC%+$K-5h>#^ zGr^40#Vn-EA~UZtv)IMdQ^sZH0yAzGb2DX@m=Vk@bunJbG?-aorqRVTQ^sfJ4l{li z(@L3J%=`&6x4IaaG66F`WG3ih!jxHN<}a98?qXI_W|f)0V`jCBxt%g=%=`=c(lv~F zvQk8;{u`|SFV=q})yJgA&On>h#@1&}D_usFQ8yTExIy4H7a!aD6@HO9epv{mUsgH9 zQE7Zd2)pKZUQ`~x(r_A-tg2F)jQUe?tKkQ#vaO+9M%nCAQVtbXrBmg~RVhtIyT+?Q z%a+y9^%LDdcV5zN7KOuL#csJ_tsa@DCzl(l)DiTvQn=NI6FO2=NVA=b`dH~X&Bd^; z%A`ut(cX3`$8&0SSa)knO(zJ{a8kNk8tr4a<~PG?EwrT*xItKL)*LlL_=ECjIH}!f zc@CbeX|K8h_us>ncMGF~NekVkBhhTSaVXsyRT`)R+~8g+bexdY2KSkL*7lofpgSK8 zWB?lE{*Io;x{^^(tG-P>F9l3k#|*lfhWj>Tb*Ss%!poX!|RUtUFbqhI>h)k?}^gCjAHKy*#g?HechXRJwYu#s*;3S0xs!(CoPWdh+;9!IEqBrw^u z10u||s@JMl?Vwf-$p`g!W#Jg%)G(ZhpHr1=4$6k>d1%c_)mwH{C7XkDsQc25b~*+) zpHLlms46-zjyV+eEVch(8a#ySiOh5McV*G1iOs_ev{bp1MjvtKO1p)JXtL63uf;KsO2KKX#mT7NC-H$({Zt}IxpYMC*Ri6v#U@4{=wZ zL&K`;A-b`=sEmacd>MD1Nzt6ex5v0CYkN1LDj2nv^lv70TIquhrArv!o*H;hlXF<| z@1L2x6gV=N6swab{n~QFX@!NfWgPuPnd?GSM;)e=vU?k6=MKt_;8Ft`Xfd zD*6btJFj8L=o->1#&$Xz_u#=%yMOD@*w6JO;TNdQ7-9Z*6dFTZ8->Q_+PBT0$$5-R z%|x*MDfXuAu_?CW3#&73@Yp23ghz5bnoi>a6WL*QE}#aOJ4TO$0kT z?2oiNntb+-w%uWWs4eIsC(MtmFh}RG8^%eEyUvu8?XD}vIdq*BqdO01NR_w~i%BPv z3>{fUNA}G`uV;GiH%xM;*J!W5{i6XOBiMuM7Y7k6YO!{`w62GE7BUAK?C%)2jM>Ct z+%u#AC2I)o8OoS=TIudRUDioR9z{~ms`8YFy?f1Xv|j!U`Crg&4rg6q(d+wKD zz4AS(kj!DMu+tK9ScK&=>Dg73*;RCmL9USM9SX=CQ~@g}w)<=rc&Dv9vQfpFOwOX0 zk-UX6|A{LYMzHNMXh|~lLy4gfQ6t0H{?V79)KFq%;#{aLX+hx)?L!@DeOQalecE~< zH0~zfciQfky~z}e#$@+f%y<)g-$}iR1v8;@K>9L-?>TXS{YWumCM<&=v0x^pnW)x# zynm0h_m>SZyB`=CjhaT`VT#LT60ub;YLpPjjQ>caH-nVD15 z7wxw%oPPuH+4D2@#j9_hnpJ~s>dM&*rxMW)E6W&IX@`NSQn~|^=jrxrW_hiOe1N%(-9mu(_fW18!|N40gUXJvN}R#lfK)lzI$)((OeQ|96RKb0 z&|n2`fi~^A@s2`oC2Anuw$ttILuSHN1&(ayAMmp?847-&&5wpFA!(husT!It9X9wu>oG#F^9vA6@a9e^8 z!YrYoPMA_#LW7-1@Tr#>3~yV4eIZLqsidzh!3SXsyW4h5mAKe;O!$D9u3s#h)xx3} z*w8=J$95${FF(TL$`27l^W>H0XOo@dyf{8T@yfh7#{0uB5b(B=Q+fL--?B(7*B(+Ob zzD#El{2n~^z=HKHYR0=1+@atD3V3PaolKpwJ8bU_$c}8=9yt@TzoDFI&|6pMZyK;Y z!!jiC%ChZ7)ot2#w0~k^lHU_y?bSvwdE)t}n~e#)*|~L8IyS<-Q03|5G;F`nCZx&* zYk@LwU~RUlcyljQTX^pms#v`du)w_OyEx|(uH@}HZb>i2wynzbRXbQ~-0;1C-&1(+ z&3i6M>!~E?$5SM2D^-AkCRM;IeWnxAS*Wb3hA);q=Vcn-;3))_Mw8CM|0zsA%h0}M Vowv&PSMWb<9W*gLv6}zi{{wqnnxFsx literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/get_dat.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/get_dat.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2b44061c988034bcb6fca753636d93c85c2bd4b GIT binary patch literal 20159 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 z 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/mat.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/mat.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e80dc7512950264afe3f83fa1a6c63a7e097002c GIT binary patch literal 105718 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/nuca.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/nuca.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..711d2d4f3b51bf1f03929e5a6a79cb41a944c1a4 GIT binary patch literal 6716 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 J>h+6h_&@(Hlq>)M literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/parameter.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/parameter.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3d9cd2007aba64da98df4f25c0c9df0ff93a83b GIT binary patch literal 72788 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 z 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≠kR+x13)MxF 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 D{KSSw literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/powergating.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/powergating.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b9a0fe7dfbf5e6554b2ced6b837188160af6db5 GIT binary patch literal 2385 zcmb_d%Wm676rJHq)XS0`IdumU4c^InKQ$ATwb1YmABgs0@oki-v{@ag#3w} zvzG&%@8DLy0dT@;LV~KL0p%9A6YGGKtzEWG;-qfiQXF%Edx2MSJ8>5Cs`*}0OZ~uK zJgY69)fa8!fIK9;#{HLs`=WVl2Q5zbNx%LMq9A+kC}5u&`U!wDWO`DyF}ABwo=&D( zuwe)gN)bl5=`hm@D?z|*{!(Hw{>sFxz-YepepoW2% z+I}L$l;lnww%lJZ%0IrwV2G-dm zCwvw87SS8yO&nvF3V6BkrNX;PEa>UWdW%DxFybSY>-_N*?)1p9%bhLqq7LIQ@}f~J z7>qUb)nnZ48a%u9`g+lPL*d<#-zXXtfBgaGgA+)jyLa$FT9B-F2>qMJRnv)(#%CQT^mrkA@Lf4MAZ!sxPN z8b9Sv;w08{mIZ#g;Ktcu`SZYu0L}U&%@xx*%dk~POolqnrHhBx9^k+8NWZ0~&RCR$N-_49{QcwhFG@(Y&1c*9^Jtoi zOsnlE=R(E9?35@OZAbXgDrA$n9_88gB%cWhE{(I{oylBcA;Q?yX8;ZAo%=QH2CaTA z>n>fPw=AEwDBke1j=KAmAMY%s6Je29UMMfze+O>0QW_Jy4sHjtpi!uNsKJ_JTRY%= zl)XFl${F~yb_@b%XoFJd8z|^TkLV_}_L*6(Zf$|3U~XHlls4#`uF>7`>UgcR5v+yr z&iDcYB#8&H;FaD>zpn2laVA2E%EN)m0zs>CEZQ}k z8~-s%H!v-5ctrg3EK$2*VSJH2!r9@e+yEm$Hy zLiqRu`p7;6*oIqe0<@@S-K3v_ylzmhcKe?NvyL{FGCOCx2o<)xkfZugZGT~9!D9E8 z?v+O_VlYiDQm8kfo=R~p7Sl~c_%s{}HV}e838Saq;!e1&LytC>A)KG|p5pQRWeoCj z=*TY+@TL2-%EJ2zFg1qRXY2=@cMssGvpi|>r0-*8h9nE9%nioUoKF+vEyjMGhDr6L zG;*0v`6X`k6@Y0k$_9Qm#?HL&ZJbhm0Q}>`0;SNXK70cIy5H^E636>(sDzSNKN>BT*^2zH>4Q&p8uV enH>zw_+M8q`VHn&p*?)!gEXqzQ?*sUXa5T}y-|(; literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/powergating.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/powergating.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..80133e1f17116aedb2b0b97e13dd5b4ff92d0178 GIT binary patch literal 4798 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/tsv.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/tsv.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4c50184e6933399bf2925230bfbf73f8d0399ca GIT binary patch literal 4733 zcmb_g&2JmW72j_zKSW8izAVYkCQVY)O>8s>n$&PxDY9j|NEE|Xl0t1UUGFTZU6WjT zc4*ZE1r$*3?L7!!0|knn+kYefz+4)jht{`VdPxuI@6D1l6(>dy6)|si-h1jT;8{c?LLXxrf)C6pr%Df2Rw3+OqU-@AB7i{mN58k_e zhuzrTzkZk9-QT`(J)#-2e>MhNX!(x-V&lN%#(~9aw69Oi1DiYC{nR*ciq#KX?(;In z9kcm(xnW}=$j##gotbEla^oG1A#4-jgZcpy0GVtb*8!(zTqYtc{zr-jU} z6zS7YFP-L?S!T?z`rH}?LC_JZ(h-B%E{wSOVnr)i_3#XD-pRQ37FnyQ5LuUY=~Du{%Ys) zN4VDfGC#U}EsF--xF_?=QO0p%?cTGGTtt_nFp^0DS^tqd%zBrh-lhH{l83nzF({2d&D@voxzleZj}!DxbkAKDSRy za)h+>U7Q=nv8CnhK%P6YJ~KYIXpV#IZ<&kT#9qo={fzXSDuI#W*7ILyMimFLpHTojyNycLtCLMJ525sePoY4N7 z$=XR2cE~3)Aw``i=Lno9a7@C`Ao_j*Po0=#C?4RW|xDQ_cO27`Vevp~YEhqXXQsT@{&CHTq- z2Hm&XfBNUmOJBcS-g-(V+I&e{v9dqrTsbsdRo^S(8wIo?wN#?G(_x3O)Rr<2l`Fzt zJJv?07AMA`ZC}Sg`_|sa+Jp;Z{sC4IZxDDB023&Y+{y>{SSJqeQwX(_-a~EKYQ7-0 zrzHP&b`*phGMA+rcdi>fihq4VUewlb4%`d0v9@1ficwG1sd7!7~`>52&j>{=RY~+tD#3#fr+$AjJ1zNp8m)WGMEhK22_$!<*&2uyBJ9-xTp}q z%WvFMG%&fNODnf1tw8mFwK!fz$ejKZi+53KPm3voQyg%3Rddy*T;$De>ZPSIr9P!l zkwp}LEO}u{q5Mmf@|e4Z0s5c8A}?ti3_^UM#4-Eb?oxa|q*}V z%|b%_#TVOr#Wm`~{Q zM9+|i#|ULsnv1#|(1o-1#lkiB=|Hy#kn@U<2v8;!WaNVWwIFT~peP`&6WAp{nO%p6 zrdgzOdQm+qcvZP5xUuoyfsh9P^!{1FZvkyx|KOSUt(Xloynp7veQ7$cY3?gXDJbG~2-g+1pk)Mw1Mw>Y&-SFhbR|BioO601`UV2TYyOgd zz7`0gU`3}J%0pGADl6;ZNeET&;>PL6qNvT>DC_02c*d4@CTx28x2>rBtHr*5O5tO? LEWP)rE!qDCf2eVW literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/tsv.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/tsv.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35d5b3648921f367a3507be77745aa6b354b0e07 GIT binary patch literal 10773 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 VjERLc?VQIwKaifEcIhWG{U1?y!E68k literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/uca.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/uca.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03c46c92e36596ef9a7b9479b95db04f425170d4 GIT binary patch literal 18737 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/uca.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/uca.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b66dd121a8a9f434c0fe84b23bcae3d794f1f35 GIT binary patch literal 53848 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/wire.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/wire.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df41372ec634b6a223f8279fb083c51e7ed5f382 GIT binary patch literal 13615 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 literal 0 HcmV?d00001 diff --git a/cacti-main/cacti_python/__pycache__/wire.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/wire.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f6405271780c4780e301becfa2affa8d5a57b777 GIT binary patch literal 36323 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 1: - num >>= 1 - log2 += 1 - return log2 - -def factorial(n, m=1): - fa = m - for i in range(m + 1, n + 1): - fa *= i - return fa - -def combination(n, m): - return factorial(n, m + 1) // factorial(n - m) - - -outside_mat = "outside_mat" -inside_mat = "inside_mat" -local_wires = "local_wires" - - -Add_htree = "Add_htree" -Data_in_htree = "Data_in_htree" -Data_out_htree = "Data_out_htree" -Search_in_htree = "Search_in_htree" -Search_out_htree = "Search_out_htree" - - -Row_add_path = "Row_add_path" -Col_add_path = "Col_add_path" -Data_path = "Data_path" - - -nmos = "nmos" -pmos = "pmos" -inv = "inv" -nand = "nand" -nor = "nor" -tri = "tri" -tg = "tg" - -parallel = "parallel" -series = "series" - -class WirePlacement: - outside_mat = "outside_mat" - inside_mat = "inside_mat" - local_wires = "local_wires" - -class HtreeType: - Add_htree = "Add_htree" - Data_in_htree = "Data_in_htree" - Data_out_htree = "Data_out_htree" - Search_in_htree = "Search_in_htree" - Search_out_htree = "Search_out_htree" - -class MemorybusType: - Row_add_path = "Row_add_path" - Col_add_path = "Col_add_path" - Data_path = "Data_path" - -class GateType: - nmos = "nmos" - pmos = "pmos" - inv = "inv" - nand = "nand" - nor = "nor" - tri = "tri" - tg = "tg" - -class HalfNetTopology: - parallel = "parallel" - series = "series" - -def logtwo(x): - assert x > 0 - return math.log(x) / math.log(2.0) - -def gate_C(width, wirelength, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - return (dt.C_g_ideal + dt.C_overlap + 3 * dt.C_fringe) * width + dt.l_phy * Cpolywire - -def gate_C_pass(width, wirelength, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - return gate_C(width, wirelength, _is_dram, _is_sram, _is_wl_tr, _is_sleep_tx) - -def drain_C_(width, nchannel, stack, next_arg_thresh_folding_width_or_height_cell, fold_dimension, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - - c_junc_area = dt.C_junc - c_junc_sidewall = dt.C_junc_sidewall - c_fringe = 2 * dt.C_fringe - c_overlap = 2 * dt.C_overlap - drain_C_metal_connecting_folded_tr = 0 - - if next_arg_thresh_folding_width_or_height_cell == 0: - w_folded_tr = fold_dimension - else: - h_tr_region = fold_dimension - 2 * g_tp.HPOWERRAIL - ratio_p_to_n = 2.0 / (2.0 + 1.0) - if nchannel: - w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) - else: - w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) - - num_folded_tr = int(sp.ceiling(width / w_folded_tr)) - if num_folded_tr < 2: - w_folded_tr = width - - total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + (stack - 1) * g_tp.spacing_poly_to_poly - drain_h_for_sidewall = w_folded_tr - total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1) - if num_folded_tr > 1: - total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly) - if num_folded_tr % 2 == 0: - drain_h_for_sidewall = 0 - total_drain_height_for_cap_wrt_gate *= num_folded_tr - drain_C_metal_connecting_folded_tr = g_tp.wire_local.C_per_um * total_drain_w - - drain_C_area = c_junc_area * total_drain_w * w_folded_tr - drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w) - drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate - - return drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr - -def tr_R_on(width, nchannel, stack, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - - restrans = dt.R_nch_on if nchannel else dt.R_pch_on - return stack * restrans / width - -def R_to_w(res, nchannel, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - - restrans = dt.R_nch_on if nchannel else dt.R_pch_on - return restrans / res - -def pmos_to_nmos_sz_ratio(_is_dram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_wl_tr: - return g_tp.dram_wl.n_to_p_eff_curr_drv_ratio - elif _is_sleep_tx: - return g_tp.sleep_tx.n_to_p_eff_curr_drv_ratio - else: - return g_tp.peri_global.n_to_p_eff_curr_drv_ratio - -def horowitz(inputramptime, tf, vs1, vs2, rise): - if inputramptime == 0 and vs1 == vs2: - return tf * (-math.log(vs1) if vs1 < 1 else math.log(vs1)) - - a = inputramptime / tf - if rise == RISE: - b = 0.5 - td = tf * math.sqrt(math.log(vs1) ** 2 + 2 * a * b * (1.0 - vs1)) + tf * (math.log(vs1) - math.log(vs2)) - else: - b = 0.4 - td = tf * math.sqrt(math.log(1.0 - vs1) ** 2 + 2 * a * b * vs1) + tf * (math.log(1.0 - vs1) - math.log(1.0 - vs2)) - return td - -def cmos_Ileak(nWidth, pWidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nWidth * dt.I_off_n + pWidth * dt.I_off_p - -def simplified_nmos_Isat(nwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nwidth * dt.I_on_n - -def simplified_pmos_Isat(pwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return pwidth * dt.I_on_n / dt.n_to_p_eff_curr_drv_ratio - -def simplified_nmos_leakage(nwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nwidth * dt.I_off_n - -def simplified_pmos_leakage(pwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return pwidth * dt.I_off_p - -def cmos_Ig_n(nWidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nWidth * dt.I_g_on_n - -def cmos_Ig_p(pWidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return pWidth * dt.I_g_on_p - -def cmos_Isub_leakage(nWidth, pWidth, fanin, g_type, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False, topo=series): - assert fanin >= 1 - nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - Isub = 0 - num_states = int(math.pow(2.0, fanin)) - - if g_type == nmos: - if fanin == 1: - Isub = nmos_leak / num_states - else: - if topo == parallel: - Isub = nmos_leak * fanin / num_states - else: - for num_off_tx in range(1, fanin + 1): - Isub += nmos_leak * math.pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub /= num_states - - elif g_type == pmos: - if fanin == 1: - Isub = pmos_leak / num_states - else: - if topo == parallel: - Isub = pmos_leak * fanin / num_states - else: - for num_off_tx in range(1, fanin + 1): - Isub += pmos_leak * math.pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub /= num_states - - elif g_type == inv: - Isub = (nmos_leak + pmos_leak) / 2 - - elif g_type == nand: - Isub += fanin * pmos_leak - for num_off_tx in range(1, fanin + 1): - Isub += nmos_leak * math.pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub /= num_states - - elif g_type == nor: - for num_off_tx in range(1, fanin + 1): - Isub += pmos_leak * math.pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub += fanin * nmos_leak - Isub /= num_states - - elif g_type == tri: - Isub += (nmos_leak + pmos_leak) / 2 - Isub += nmos_leak * UNI_LEAK_STACK_FACTOR - Isub /= 2 - - elif g_type == tg: - Isub = (nmos_leak + pmos_leak) / 2 - - else: - raise ValueError("Invalid gate type") - - return Isub - -def cmos_Ig_leakage(nWidth, pWidth, fanin, g_type, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False, topo=series): - assert fanin >= 1 - nmos_leak = cmos_Ig_n(nWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - Ig_on = 0 - num_states = int(math.pow(2.0, fanin)) - - if g_type == nmos: - if fanin == 1: - Ig_on = nmos_leak / num_states - else: - if topo == parallel: - for num_on_tx in range(1, fanin + 1): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx - else: - Ig_on += nmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - Ig_on /= num_states - - elif g_type == pmos: - if fanin == 1: - Ig_on = pmos_leak / num_states - else: - if topo == parallel: - for num_on_tx in range(1, fanin + 1): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx - else: - Ig_on += pmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - Ig_on /= num_states - - elif g_type == inv: - Ig_on = (nmos_leak + pmos_leak) / 2 - - elif g_type == nand: - for num_on_tx in range(1, fanin + 1): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx - Ig_on += nmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - Ig_on /= num_states - - elif g_type == nor: - Ig_on += pmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - for num_on_tx in range(1, fanin + 1): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx - Ig_on /= num_states - - elif g_type == tri: - Ig_on += (2 * nmos_leak + 2 * pmos_leak) / 2 - Ig_on += (nmos_leak + pmos_leak) / 2 - Ig_on /= 2 - - elif g_type == tg: - Ig_on = (nmos_leak + pmos_leak) / 2 - - else: - raise ValueError("Invalid gate type") - - return Ig_on - -def shortcircuit_simple(vt, velocity_index, c_in, c_out, w_nmos, w_pmos, i_on_n, i_on_p, i_on_n_in, i_on_p_in, vdd): - fo_n = i_on_n / i_on_n_in - fo_p = i_on_p / i_on_p_in - fanout = c_out / c_in - beta_ratio = i_on_p / i_on_n - vt_to_vdd_ratio = vt / vdd - - p_short_circuit_discharge_low = (10 / 3) * (pow((vdd - vt) - vt_to_vdd_ratio, 3.0) / pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio * vt_to_vdd_ratio)) * c_in * vdd * vdd * fo_p * fo_p / fanout / beta_ratio - p_short_circuit_charge_low = (10 / 3) * (pow((vdd - vt) - vt_to_vdd_ratio, 3.0) / pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio * vt_to_vdd_ratio)) * c_in * vdd * vdd * fo_n * fo_n / fanout * beta_ratio - - p_short_circuit_discharge = p_short_circuit_discharge_low - p_short_circuit_charge = p_short_circuit_charge_low - p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge) / 2 - - return p_short_circuit - -def shortcircuit(vt, velocity_index, c_in, c_out, w_nmos, w_pmos, i_on_n, i_on_p, i_on_n_in, i_on_p_in, vdd): - fo_p = i_on_p / i_on_p_in - fanout = 1 - beta_ratio = i_on_p / i_on_n - e = 2.71828 - f_alpha = 1 / (velocity_index + 2) - velocity_index / (2 * (velocity_index + 3)) + velocity_index / (velocity_index + 4) * (velocity_index / 2 - 1) - k_v = 0.9 / 0.8 + (vdd - vt) / 0.8 * math.log(10 * (vdd - vt) / e) - g_v_alpha = (velocity_index + 1) * pow((1 - velocity_index), velocity_index) * pow((1 - velocity_index), velocity_index / 2) / f_alpha / pow((1 - velocity_index - velocity_index), (velocity_index / 2 + velocity_index + 2)) - h_v_alpha = pow(2, velocity_index) * (velocity_index + 1) * pow((1 - velocity_index), velocity_index) / pow((1 - velocity_index - velocity_index), (velocity_index + 1)) - - p_short_circuit_discharge = k_v * vdd * vdd * c_in * fo_p * fo_p / ((vdd - vt) * g_v_alpha * fanout * beta_ratio / 2 / k_v + h_v_alpha * fo_p) - return p_short_circuit_discharge - -def wire_resistance(resistivity, wire_width, wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter): - resistance = alpha_scatter * resistivity / ((wire_thickness - barrier_thickness - dishing_thickness) * (wire_width - 2 * barrier_thickness)) - return resistance - -def wire_capacitance(wire_width, wire_thickness, wire_spacing, ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, fringe_cap): - vertical_cap = 2 * PERMITTIVITY_FREE_SPACE * vert_dielectric_constant * wire_width / ild_thickness - sidewall_cap = 2 * PERMITTIVITY_FREE_SPACE * miller_value * horiz_dielectric_constant * wire_thickness / wire_spacing - total_cap = vertical_cap + sidewall_cap + fringe_cap - return total_cap - -def tsv_resistance(resistivity, tsv_len, tsv_diam, tsv_contact_resistance): - resistance = resistivity * tsv_len / (math.pi * (tsv_diam / 2) ** 2) + tsv_contact_resistance - return resistance - -def tsv_capacitance(tsv_len, tsv_diam, tsv_pitch, dielec_thickness, liner_dielectric_constant, depletion_width): - e_si = PERMITTIVITY_FREE_SPACE * 11.9 - PI = math.pi - lateral_coupling_constant = 4.1 - diagonal_coupling_constant = 5.3 - - liner_cap = 2 * PI * PERMITTIVITY_FREE_SPACE * liner_dielectric_constant * tsv_len / math.log(1 + dielec_thickness / (tsv_diam / 2)) - depletion_cap = 2 * PI * e_si * tsv_len / math.log(1 + depletion_width / (dielec_thickness + tsv_diam / 2)) - self_cap = 1 / (1 / liner_cap + 1 / depletion_cap) - - lateral_coupling_cap = 0.4 * (0.225 * math.log(0.97 * tsv_len / tsv_diam) + 0.53) * e_si / (tsv_pitch - tsv_diam) * PI * tsv_diam * tsv_len - diagonal_coupling_cap = 0.4 * (0.225 * math.log(0.97 * tsv_len / tsv_diam) + 0.53) * e_si / (1.414 * tsv_pitch - tsv_diam) * PI * tsv_diam * tsv_len - - total_cap = self_cap + lateral_coupling_constant * lateral_coupling_cap + diagonal_coupling_constant * diagonal_coupling_cap - return total_cap - -def tsv_area(tsv_pitch): - return tsv_pitch ** 2 diff --git a/cacti-main/cacti_python/cacti_interface.py b/cacti-main/cacti_python/cacti_interface.py index 30ce2f0..cf24a4b 100644 --- a/cacti-main/cacti_python/cacti_interface.py +++ b/cacti-main/cacti_python/cacti_interface.py @@ -230,29 +230,56 @@ def __init__(self): def find_delay(self): data_arr = self.data_array2 tag_arr = self.tag_array2 - - print("uca_org_t find_delay 0") - if g_ip.pure_ram or g_ip.pure_cam or g_ip.fully_assoc: - print("pure ram") self.access_time = data_arr.access_time - elif g_ip.fast_access: - print("fast_access") - self.access_time = symbolic_convex_max(tag_arr.access_time, data_arr.access_time) - elif g_ip.is_seq_acc: - print("seq_acc") - self.access_time = tag_arr.access_time + data_arr.access_time + if(g_ip.pure_ram): + if (g_ip.is_main_mem): + self.access_time *= 10e6 / 2 + else: + self.access_time *= 10e6 / 4 + else: + self.access_time *= 2 else: - print("else") - self.access_time = symbolic_convex_max(tag_arr.access_time + data_arr.delay_senseamp_mux_decoder, - data_arr.delay_before_subarray_output_driver) + data_arr.delay_from_subarray_output_driver_to_output - print("uca_org_t find_delay 1") + if g_ip.fast_access: + self.access_time = symbolic_convex_max(tag_arr.access_time, data_arr.access_time) + elif g_ip.is_seq_acc: + self.access_time = tag_arr.access_time + data_arr.access_time + else: + self.access_time = symbolic_convex_max(tag_arr.access_time + data_arr.delay_senseamp_mux_decoder, + data_arr.delay_before_subarray_output_driver) + data_arr.delay_from_subarray_output_driver_to_output + + if (g_ip.is_main_mem): + self.access_time *= 10e6 / 2 + else: + self.access_time *= 10e6 / 4 + + def find_energy(self): if not (g_ip.pure_ram or g_ip.pure_cam or g_ip.fully_assoc): self.power = self.data_array2.power + self.tag_array2.power + # self.power.readOp.dynamic *= 3e-1 + # self.power.writeOp.dynamic *= 3e-1 + # self.power.readOp.leakage *= 1e-3 else: self.power = self.data_array2.power + if g_ip.pure_ram: + self.power.readOp.dynamic *= 5e-4 + self.power.writeOp.dynamic *= 5e-4 + self.power.readOp.leakage *= 5 + elif g_ip.fully_assoc: + self.power.readOp.dynamic *= 15e-5 + self.power.writeOp.dynamic *= 15e-5 + self.power.readOp.leakage *= 5e-3 + + if g_ip.is_main_mem: + self.power.readOp.dynamic *= 3 + self.power.writeOp.dynamic *= 3 + self.power.readOp.leakage /= 2 + + self.power.readOp.dynamic *= 1e9 + self.power.writeOp.dynamic *= 1e9 + self.power.readOp.leakage *= 1e3 def find_area(self): if g_ip.pure_ram or g_ip.pure_cam or g_ip.fully_assoc: diff --git a/cacti-main/cacti_python/component.py b/cacti-main/cacti_python/component.py index 894f62d..91c7380 100644 --- a/cacti-main/cacti_python/component.py +++ b/cacti-main/cacti_python/component.py @@ -23,16 +23,21 @@ def compute_diffusion_width(num_stacked_in, num_folded_tr): w_poly = g_ip.F_sz_um spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact - # TODO RECENTLY COMMENTED - total_diff_w = sp.Piecewise( - (2 * spacing_poly_to_poly + num_stacked_in * w_poly + (num_stacked_in - 1) * g_tp.spacing_poly_to_poly, num_folded_tr <= 1), - (2 * spacing_poly_to_poly + num_stacked_in * w_poly + (num_stacked_in - 1) * g_tp.spacing_poly_to_poly + - (num_folded_tr - 2) * 2 * spacing_poly_to_poly + - (num_folded_tr - 1) * num_stacked_in * w_poly + - (num_folded_tr - 1) * (num_stacked_in - 1) * g_tp.spacing_poly_to_poly, num_folded_tr > 1) - ) + # Change: Relational - set to one option to reduce expression size + # total_diff_w = sp.Piecewise( + # (2 * spacing_poly_to_poly + num_stacked_in * w_poly + (num_stacked_in - 1) * g_tp.spacing_poly_to_poly, num_folded_tr <= 1), + # (2 * spacing_poly_to_poly + num_stacked_in * w_poly + (num_stacked_in - 1) * g_tp.spacing_poly_to_poly + + # (num_folded_tr - 2) * 2 * spacing_poly_to_poly + + # (num_folded_tr - 1) * num_stacked_in * w_poly + + # (num_folded_tr - 1) * (num_stacked_in - 1) * g_tp.spacing_poly_to_poly, num_folded_tr > 1) + # ) + + total_diff_w = 2 * spacing_poly_to_poly + num_stacked_in * w_poly + (num_stacked_in - 1) * g_tp.spacing_poly_to_poly + \ + (num_folded_tr - 2) * 2 * spacing_poly_to_poly + \ + (num_folded_tr - 1) * num_stacked_in * w_poly + \ + (num_folded_tr - 1) * (num_stacked_in - 1) * g_tp.spacing_poly_to_poly + # total_diff_w = 2 * spacing_poly_to_poly + num_stacked_in * w_poly + (num_stacked_in - 1) * g_tp.spacing_poly_to_poly - # TODO Important can't do this symbolically # total_diff_w = (2 * spacing_poly_to_poly + # for both source and drain # num_stacked_in * w_poly + # (num_stacked_in - 1) * g_tp.spacing_poly_to_poly) @@ -44,75 +49,22 @@ def compute_diffusion_width(num_stacked_in, num_folded_tr): return total_diff_w def compute_gate_area(gate_type, num_inputs, w_pmos, w_nmos, h_gate): - #TODO IMPORTANT this can't be done synbolically - - # TODO inverstiage Why is w_pmos and w_nmos 0 - # Traceback (most recent call last): - # File "/Users/dw/Documents/codesign/cacti/diff/second/main.py", line 44, in - # mat = Mat(dyn_p) - # ^^^^^^^^^^ - # File "/Users/dw/Documents/codesign/cacti/diff/second/mat.py", line 164, in __init__ - # self.r_predec_blk1 = PredecBlk(num_dec_signals, self.row_dec, C_wire_predec_blk_out, R_wire_predec_blk_out, self.num_subarrays_per_mat, self.is_dram, True) - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - # File "/Users/dw/Documents/codesign/cacti/diff/second/decoder.py", line 271, in __init__ - # self.compute_area() - # File "/Users/dw/Documents/codesign/cacti/diff/second/decoder.py", line 396, in compute_area - # tot_area_L1_nand2 = compute_gate_area(NAND, 2, self.w_L1_nand2_p[0], self.w_L1_nand2_n[0], g_tp.cell_h_def) - # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - # File "/Users/dw/Documents/codesign/cacti/diff/second/component.py", line 39, in compute_gate_area - # if w_pmos <= 0.0 or w_nmos <= 0.0: - # ^^^^^^^^^^^^^ - # File "/Users/dw/miniconda3/lib/python3.11/site-packages/sympy/core/relational.py", line 510, in __bool__ - # raise TypeError("cannot determine truth value of Relational") - - # if w_pmos <= 0.0 or w_nmos <= 0.0: - # return 0.0 - - if isinstance(w_pmos, (int, float)) and isinstance(w_nmos, (int, float)): - if w_pmos <= 0.0 or w_nmos <= 0.0: + # Relational + if w_pmos <= 0.0 or w_nmos <= 0.0: return 0.0 - - print("compute_gate_area CHECKPINT 0") - # TODO RELATIONAL - # simplify_w_pmos = sp.simplify(w_pmos) - # simplify_w_nmos = sp.simplify(w_nmos) - # if simplify_w_pmos.is_zero or simplify_w_pmos.is_negative or simplify_w_nmos.is_zero or simplify_w_nmos.is_negative: - # return 0.0 - - print("compute_gate_area CHECKPINT 1") - - # print(f"w_pmos {w_pmos} and w_nmos {w_nmos}") h_tr_region = h_gate - 2 * g_tp.HPOWERRAIL ratio_p_to_n = w_pmos / (w_pmos + w_nmos) - # TODO IMPORTANT this can't be done synbolically - # simplify_ratio_p_to_n = sp.simplify(ratio_p_to_n) + # Relational resolved with 'result' below # if ratio_p_to_n >= 1 or ratio_p_to_n <= 0: - # return 0.0 - # if sp.Or(ratio_p_to_n >= 1 or ratio_p_to_n <= 0): - # return 0.0 - # if simplify_ratio_p_to_n.is_integer and (simplify_ratio_p_to_n >= 1 or simplify_ratio_p_to_n <= 0): - # return 0.0 - if isinstance(ratio_p_to_n, (int, float)): - if ratio_p_to_n <= 0 or ratio_p_to_n >= 1: - return 0.0 - - - - print("compute_gate_area CHECKPINT 2") + # return 0.0 - w_folded_pmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * ratio_p_to_n w_folded_nmos = (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) * (1 - ratio_p_to_n) - # TODO IMPORTANT this can't be done synbolically + # Relational # assert w_folded_pmos > 0 - if(w_folded_pmos == 0): - return 0 - if isinstance(w_folded_pmos, (int, float)): - if w_folded_pmos <= 0: - return 0 num_folded_pmos = sp.ceiling(w_pmos / w_folded_pmos) num_folded_nmos = sp.ceiling(w_nmos / w_folded_nmos) @@ -131,21 +83,20 @@ def compute_gate_area(gate_type, num_inputs, w_pmos, w_nmos, h_gate): sys.exit(1) gate_w = symbolic_convex_max(total_ndiff_w, total_pdiff_w) - - # TODO Important can't do this symbolically - # if w_folded_nmos > w_nmos: - # gate_h = (w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL) - # else: - # gate_h = h_gate - - # TODO RECENTLY COMMENTED - gate_h = sp.Piecewise( - ((w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL), w_folded_nmos > w_nmos), - (h_gate, True) # TODO CHECK Else case + + # Change: Relational - set to one option to reduce expression size + # gate_h = sp.Piecewise( + # ((w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL), w_folded_nmos > w_nmos), + # (h_gate, True) + # ) + gate_h = (w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL) + + result = sp.Piecewise( + (0, sp.Or(ratio_p_to_n >= 1, ratio_p_to_n <= 0)), + (gate_w * gate_h, True ) ) - # gate_h = (w_nmos + w_pmos + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + 2 * g_tp.HPOWERRAIL) - return gate_w * gate_h # Assuming area is width * height + return result def compute_tr_width_after_folding(input_width, threshold_folding_width): if input_width <= 0: @@ -170,66 +121,49 @@ def height_sense_amplifier(pitch_sense_amp): return h_pmos_tr + h_nmos_tr + g_tp.MIN_GAP_BET_P_AND_N_DIFFS + def logical_effort(num_gates_min, g, F, w_n, w_p, C_load, p_to_n_sz_ratio, is_dram_, is_wl_tr_, max_w_nmos): - #TODO deleted int - # print(f'F is this {F}') - # print(f'F is this {fopt}') - num_gates = sp.log(F) / sp.log(fopt) - if(F == 0): - num_gates = 2 - # print(f'num_gates is this {num_gates}') - # print("End") - # print("") - - # TODO MOD Important - # num_gates += (num_gates % 2) - num_gates += (num_gates + 2) - num_gates = symbolic_convex_max(num_gates, num_gates_min) + # num_gates = sp.log(F) / sp.log(fopt) + # if(F == 0): + # num_gates = 4 + # else: + # num_gates = 4 + num_gates = 4 f = sp.Pow(F, 1.0 / num_gates) - num_gates = 4 # TODO IMPORTANT this can't be done synbolically i = num_gates - 1 - #TODO IMPORTANT this can't be done synbolically - # i = 2 - #print(f'OH NOES! {i}') + if (f == 0): + f = 1 C_in = C_load / f - # print(f'I is {i}') + w_n[i] = (1.0 / (1.0 + p_to_n_sz_ratio)) * C_in / gate_C(1, 0, is_dram_, False, is_wl_tr_) - # print(f'w_n[i] is this {w_n[i]}') - # print(f'min_w_nmos_ is this {g_tp.min_w_nmos_}') - # print("End") - # print("") - #TODO important nan shortcut - if not contains_any_symbol(w_n[i]) and math.isnan(w_n[i]): - w_n[i] = 0 + + # RECENT CHANGE: Max - ignore to reduce expression length w_n[i] = symbolic_convex_max(w_n[i], g_tp.min_w_nmos_) + w_p[i] = p_to_n_sz_ratio * w_n[i] - #TODO IMPORTANT SINCE RELATIONAL + # CHANGE: ARRAY LOGIC + # #TODO IMPORTANT SINCE RELATIONAL # if w_n[i] > max_w_nmos: - # print(f'OH NOES p_to_n_sz_ratio! {p_to_n_sz_ratio}') - # print(f'OH NOES max_w_nmos! {max_w_nmos}') # C_ld = gate_C((1 + p_to_n_sz_ratio) * max_w_nmos, 0, is_dram_, False, is_wl_tr_) - # print(f'OH NOES C_ld! {C_ld}') # F = g * C_ld / gate_C(w_n[0] + w_p[0], 0, is_dram_, False, is_wl_tr_) - # print(f'OH NOES F! {F}') - # #TODO deleted int - # num_gates = sp.log(F) / sp.log(fopt) + 1 - # num_gates += (num_gates % 2) - # print(f'OH NOES num_gates! {num_gates}') - # num_gates = symbolic_convex_max(num_gates, num_gates_min) + + # num_gates += 2 # f = sp.Pow(F, 1.0 / (num_gates - 1)) # i = num_gates - 1 # w_n[i] = max_w_nmos # w_p[i] = p_to_n_sz_ratio * w_n[i] for i in range(num_gates - 2, 0, -1): - #TODO important zoo shortcut w_item = w_n[i + 1] / f if w_item == sp.zoo: w_item = 0 - - w_n[i] = symbolic_convex_max(w_item, g_tp.min_w_nmos_) + + # RECENT CHANGE: Max - ignore to reduce expression length + # w_n[i] = symbolic_convex_max(w_item, g_tp.min_w_nmos_) + w_n[i] = w_item + w_p[i] = p_to_n_sz_ratio * w_n[i] assert num_gates <= MAX_NUMBER_GATES_STAGE @@ -237,16 +171,13 @@ def logical_effort(num_gates_min, g, F, w_n, w_p, C_load, p_to_n_sz_ratio, is_dr def compute_tr_width_after_folding(input_width, threshold_folding_width): - # TODO can't do relational - # if input_width <= 0: - # return 0 + # CHANGE: RELATIONAL: this function either returns 0 or result if isinstance(input_width, (int, float)): if input_width <= 0: return 0 - # print(f"input_widht {input_width}") - # print(f"thresh {threshold_folding_width}") + # CHANGE: RELATIONAL # num_folded_tr = sp.ceiling(input_width / threshold_folding_width) # spacing_poly_to_poly = g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact # width_poly = g_ip.F_sz_um @@ -255,10 +186,10 @@ def compute_tr_width_after_folding(input_width, threshold_folding_width): # return total_diff_width result = sp.Piecewise( - (0, input_width <= 0), # Return 0 if input_width <= 0 + (0, input_width <= 0), (sp.ceiling(input_width / threshold_folding_width) * g_ip.F_sz_um + (sp.ceiling(input_width / threshold_folding_width) + 1) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact), - True) # TODO CHECKCalculate total_diff_width otherwise + True) ) return result \ No newline at end of file diff --git a/cacti-main/cacti_python/const.py b/cacti-main/cacti_python/const.py index b56e42b..86f6b6a 100644 --- a/cacti-main/cacti_python/const.py +++ b/cacti-main/cacti_python/const.py @@ -45,9 +45,9 @@ MINSUBARRAYCOLS = 2 MAXSUBARRAYCOLS = 262144 -INV = 0 -NOR = 1 -NAND = 2 +INV = "INV" +NOR = "NOR" +NAND = "NAND" NUMBER_TECH_FLAVORS = 4 NUMBER_INTERCONNECT_PROJECTION_TYPES = 2 diff --git a/cacti-main/cacti_python/decoder.py b/cacti-main/cacti_python/decoder.py index 190a4b8..d02148c 100644 --- a/cacti-main/cacti_python/decoder.py +++ b/cacti-main/cacti_python/decoder.py @@ -8,6 +8,7 @@ from .powergating import SleepTx from .parameter import g_tp from .parameter import g_ip +import time class Decoder(Component): def __init__(self, _num_dec_signals, flag_way_select, _C_ld_dec_out, _R_wire_dec_out, fully_assoc_, is_dram_, is_wl_tr_, cell_): @@ -29,10 +30,9 @@ def __init__(self, _num_dec_signals, flag_way_select, _C_ld_dec_out, _R_wire_dec self.w_dec_n = [0] * MAX_NUMBER_GATES_STAGE self.w_dec_p = [0] * MAX_NUMBER_GATES_STAGE - # TODO RELATIONAL - _num_dec_signals = _num_dec_signals - num_addr_bits_dec = sp.log(_num_dec_signals, 2) + num_addr_bits_dec = _log2(_num_dec_signals) + # Relational # if num_addr_bits_dec < 4: # if flag_way_select: # self.exist = True @@ -46,22 +46,13 @@ def __init__(self, _num_dec_signals, flag_way_select, _C_ld_dec_out, _R_wire_dec # else: # self.num_in_signals = 2 - # TODO increases length - self.exist = sp.Piecewise( - (True, num_addr_bits_dec < 4), # self.exist is True if num_addr_bits_dec < 4 - (self.exist, True) # self.exist is True otherwise - ) - self.num_in_signals = sp.Piecewise( - (2, sp.And(num_addr_bits_dec < 4, flag_way_select)), # self.num_in_signals = 2 if num_addr_bits_dec < 4 and flag_way_select - (0, sp.And(num_addr_bits_dec < 4, not flag_way_select)), # self.num_in_signals = 0 if num_addr_bits_dec < 4 and not flag_way_select - (3, sp.And(num_addr_bits_dec >= 4, flag_way_select)), # self.num_in_signals = 3 if num_addr_bits_dec >= 4 and flag_way_select - (2, num_addr_bits_dec >= 4, True) # self.num_in_signals = 2 if num_addr_bits_dec >= 4 and not flag_way_select + (2, sp.And(num_addr_bits_dec < 4, flag_way_select != 0)), # self.num_in_signals = 2 if num_addr_bits_dec < 4 and flag_way_select + (0, sp.And(num_addr_bits_dec < 4, flag_way_select == 0)), # self.num_in_signals = 0 if num_addr_bits_dec < 4 and not flag_way_select + (3, sp.And(num_addr_bits_dec >= 4, flag_way_select != 0)), # self.num_in_signals = 3 if num_addr_bits_dec >= 4 and flag_way_select + (2, True) # self.num_in_signals = 2 if num_addr_bits_dec >= 4 and not flag_way_select ) - # self.exist = True - # self.num_in_signals = 3 - # assert self.cell.h > 0 # assert self.cell.w > 0 self.area.h = g_tp.h_dec * self.cell.h @@ -86,7 +77,8 @@ def compute_widths(self): F *= self.C_ld_dec_out / (gate_C(self.w_dec_n[0], 0, self.is_dram, False, self.is_wl_tr) + gate_C(self.w_dec_p[0], 0, self.is_dram, False, self.is_wl_tr)) - #print(f'BEORE CALL logical effort {g_tp.max_w_nmos_dec}') + + print("Made it to Decoder Logical Effort") self.num_gates = logical_effort( self.num_gates_min, gnand2 if self.num_in_signals == 2 else gnand3, @@ -99,6 +91,7 @@ def compute_widths(self): self.is_wl_tr, g_tp.max_w_nmos_dec ) + print("Made it past Decoder Logical Effort") def compute_area(self): cumulative_area = 0 @@ -256,8 +249,7 @@ def __init__(self, num_dec_signals, dec_, C_wire_predec_blk_out, R_wire_predec_b self.w_L2_n = [0] * MAX_NUMBER_GATES_STAGE self.w_L2_p = [0] * MAX_NUMBER_GATES_STAGE - print("PRE CHECKPOINT 0") - # TODO CHECK RELATIONAL + # CHANGE: RELATIONAL: set to default values, otherwise, expression will be too long # if is_blk1: # if num_addr_bits_dec <= 0: # return @@ -275,6 +267,7 @@ def __init__(self, num_dec_signals, dec_, C_wire_predec_blk_out, R_wire_predec_b # self.C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out # else: # if num_addr_bits_dec >= 4: + self.exist = True self.number_input_addr_bits = blk2_num_input_addr_bits branch_effort_predec_out = sp.Pow(2, blk1_num_input_addr_bits) #(1 << blk1_num_input_addr_bits) @@ -282,49 +275,45 @@ def __init__(self, num_dec_signals, dec_, C_wire_predec_blk_out, R_wire_predec_b self.R_wire_predec_blk_out = R_wire_predec_blk_out_ self.C_ld_predec_blk_out = branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out - self.exist = sp.Piecewise( - (self.exist, sp.And(is_blk1, num_addr_bits_dec <= 0)), - (True, True) - ) + # self.exist = sp.Piecewise( + # (self.exist, sp.And(is_blk1, num_addr_bits_dec <= 0)), + # (True, True) + # ) - self.number_input_addr_bits = sp.Piecewise( - (num_addr_bits_dec, sp.And(is_blk1, num_addr_bits_dec < 4)), # self.number_input_addr_bits = num_addr_bits_dec if is_blk1 and 0 < num_addr_bits_dec < 4 - (blk1_num_input_addr_bits, sp.And(is_blk1, num_addr_bits_dec >= 4)), # self.number_input_addr_bits = blk1_num_input_addr_bits if is_blk1 and num_addr_bits_dec >= 4 - (blk2_num_input_addr_bits, True) # self.number_input_addr_bits = blk2_num_input_addr_bits if not is_blk1 - ) + # self.number_input_addr_bits = sp.Piecewise( + # (num_addr_bits_dec, sp.And(is_blk1, num_addr_bits_dec < 4)), # self.number_input_addr_bits = num_addr_bits_dec if is_blk1 and 0 < num_addr_bits_dec < 4 + # (blk1_num_input_addr_bits, sp.And(is_blk1, num_addr_bits_dec >= 4)), # self.number_input_addr_bits = blk1_num_input_addr_bits if is_blk1 and num_addr_bits_dec >= 4 + # (blk2_num_input_addr_bits, True) # self.number_input_addr_bits = blk2_num_input_addr_bits if not is_blk1 + # ) - branch_effort_predec_out = sp.Piecewise( - (sp.Pow(2, blk2_num_input_addr_bits), sp.And(is_blk1, num_addr_bits_dec >= 4)), # branch_effort_predec_out = 2^blk2_num_input_addr_bits if is_blk1 and num_addr_bits_dec >= 4 - (sp.Pow(2, blk1_num_input_addr_bits), True) - ) + # branch_effort_predec_out = sp.Piecewise( + # (sp.Pow(2, blk2_num_input_addr_bits), sp.And(is_blk1, num_addr_bits_dec >= 4)), # branch_effort_predec_out = 2^blk2_num_input_addr_bits if is_blk1 and num_addr_bits_dec >= 4 + # (sp.Pow(2, blk1_num_input_addr_bits), True) + # ) - C_ld_dec_gate = sp.Piecewise( - (num_dec_per_predec * gate_C(self.dec.w_dec_n[0] + self.dec.w_dec_p[0], 0, self.is_dram_, False, False), - num_addr_bits_dec >= 4), # C_ld_dec_gate calculation based on conditions - (1, True) # C_ld_dec_gate = 13/10 if num_addr_bits_dec <= 0 - ) + # C_ld_dec_gate = sp.Piecewise( + # (num_dec_per_predec * gate_C(self.dec.w_dec_n[0] + self.dec.w_dec_p[0], 0, self.is_dram_, False, False), + # num_addr_bits_dec >= 4), # C_ld_dec_gate calculation based on conditions + # (1, True) # C_ld_dec_gate = 13/10 if num_addr_bits_dec <= 0 + # ) - self.R_wire_predec_blk_out = sp.Piecewise( - (self.dec.R_wire_dec_out, num_addr_bits_dec < 4), # self.R_wire_predec_blk_out based on conditions - (R_wire_predec_blk_out_, True), # self.R_wire_predec_blk_out = 3/2 if num_addr_bits_dec <= 0 - ) + # self.R_wire_predec_blk_out = sp.Piecewise( + # (self.dec.R_wire_dec_out, num_addr_bits_dec < 4), # self.R_wire_predec_blk_out based on conditions + # (R_wire_predec_blk_out_, True), # self.R_wire_predec_blk_out = 3/2 if num_addr_bits_dec <= 0 + # ) - self.C_ld_predec_blk_out = sp.Piecewise( - (self.dec.C_ld_dec_out, num_addr_bits_dec < 4), # self.C_ld_predec_blk_out based on conditions - (branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out, True) # self.C_ld_predec_blk_out = 13/10 if num_addr_bits_dec <= 0 - ) + # self.C_ld_predec_blk_out = sp.Piecewise( + # (self.dec.C_ld_dec_out, num_addr_bits_dec < 4), # self.C_ld_predec_blk_out based on conditions + # (branch_effort_predec_out * C_ld_dec_gate + C_wire_predec_blk_out, True) # self.C_ld_predec_blk_out = 13/10 if num_addr_bits_dec <= 0 + # ) - print("PRE CHECKPOINT 1") self.compute_widths() - print("PRE CHECKPOINT 2") self.compute_area() - print("PRE CHECKPOINT 3") def compute_widths(self): - print("huh?") if not self.exist: return - print("huh1?") + p_to_n_sz_ratio = pmos_to_nmos_sz_ratio(self.is_dram_) gnand2 = (2 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio) gnand3 = (3 + p_to_n_sz_ratio) / (1 + p_to_n_sz_ratio) @@ -332,7 +321,6 @@ def compute_widths(self): flag_L2_gate = 0 number_inputs_L1_gate = 0 - print(f'number input addr_bits {self.number_input_addr_bits}') if self.number_input_addr_bits == 1: flag_two_unique_paths = False number_inputs_L1_gate = 2 @@ -376,7 +364,6 @@ def compute_widths(self): flag_L2_gate = 3 branch_effort_nand3_gate_output = 64 else: - # TODO this is being reached but why? flag_two_unique_paths = False number_inputs_L1_gate = 2 flag_L2_gate = 2 @@ -386,11 +373,7 @@ def compute_widths(self): self.number_inputs_L1_gate = number_inputs_L1_gate self.flag_L2_gate = flag_L2_gate - print(f'PREDEC Compute widths: end') - if flag_L2_gate: - print(f'PREDEC Compute widths: flagL2_gate') - print(f'PREDEC Compute widths: {g_tp.min_w_nmos_}, {p_to_n_sz_ratio}') if flag_L2_gate == 2: self.w_L2_n[0] = 2 * g_tp.min_w_nmos_ F = gnand2 @@ -398,10 +381,7 @@ def compute_widths(self): self.w_L2_n[0] = 3 * g_tp.min_w_nmos_ F = gnand3 self.w_L2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_ - print(f"F0 before call to logical_effort {F}") - print(f"self.C_ld_predec_blk_out before call to logical_effort {self.C_ld_predec_blk_out}") F *= self.C_ld_predec_blk_out / (gate_C(self.w_L2_n[0], 0, self.is_dram_) + gate_C(self.w_L2_p[0], 0, self.is_dram_)) - print(f"F1 before call to logical_effort {F}") self.number_gates_L2 = logical_effort( self.min_number_gates_L2, gnand2 if flag_L2_gate == 2 else gnand3, @@ -450,8 +430,6 @@ def compute_widths(self): g_tp.max_w_nmos_ ) else: - print(f'PREDEC Compute widths: else flagL2_gate') - print(f'PREDEC Compute widths: {g_tp.min_w_nmos_}, {p_to_n_sz_ratio}') if self.number_inputs_L1_gate == 2: self.w_L1_nand2_n[0] = 2 * g_tp.min_w_nmos_ self.w_L1_nand2_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_ @@ -467,7 +445,6 @@ def compute_widths(self): self.is_dram_, False, g_tp.max_w_nmos_ ) - print(f'PREDEC In Input L1 gate 2: {self.w_L1_nand2_n[0]}, {self.w_L1_nand2_p[0]}') elif self.number_inputs_L1_gate == 3: self.w_L1_nand3_n[0] = 3 * g_tp.min_w_nmos_ self.w_L1_nand3_p[0] = p_to_n_sz_ratio * g_tp.min_w_nmos_ @@ -483,7 +460,6 @@ def compute_widths(self): self.is_dram_, False, g_tp.max_w_nmos_ ) - print(f'PREDEC In Input L1 gate 3: {self.w_L1_nand2_n[0]}, {self.w_L1_nand2_p[0]}') def compute_area(self): if self.exist: @@ -494,14 +470,10 @@ def compute_area(self): leak_L1_nand3 = 0 gate_leak_L1_nand3 = 0 - print("compute_area CHECKPINT 0") - tot_area_L1_nand2 = compute_gate_area(NAND, 2, self.w_L1_nand2_p[0], self.w_L1_nand2_n[0], g_tp.cell_h_def) leak_L1_nand2 = cmos_Isub_leakage(self.w_L1_nand2_n[0], self.w_L1_nand2_p[0], 2, nand, self.is_dram_) gate_leak_L1_nand2 = cmos_Ig_leakage(self.w_L1_nand2_n[0], self.w_L1_nand2_p[0], 2, nand, self.is_dram_) - print("compute_area CHECKPINT 1") - if self.number_inputs_L1_gate != 3: tot_area_L1_nand3 = 0 leak_L1_nand3 = 0 @@ -560,19 +532,10 @@ def compute_area(self): self.num_L1_active_nand2_path = 0 self.num_L1_active_nand3_path = 3 - print("compute_area CHECKPINT 2") - - print(self.number_gates_L1_nand2_path) for i in range(1, self.number_gates_L1_nand2_path): - print("compute_area CHECKPINT 2.1") tot_area_L1_nand2 += compute_gate_area(INV, 1, self.w_L1_nand2_p[i], self.w_L1_nand2_n[i], g_tp.cell_h_def) - print("compute_area CHECKPINT 2.2") leak_L1_nand2 += cmos_Isub_leakage(self.w_L1_nand2_n[i], self.w_L1_nand2_p[i], 2, nand, self.is_dram_) - print("compute_area CHECKPINT 2.3") gate_leak_L1_nand2 += cmos_Ig_leakage(self.w_L1_nand2_n[i], self.w_L1_nand2_p[i], 2, nand, self.is_dram_) - print("compute_area CHECKPINT 2.4") - - print("compute_area CHECKPINT 3") tot_area_L1_nand2 *= num_L1_nand2 leak_L1_nand2 *= num_L1_nand2 @@ -587,8 +550,6 @@ def compute_area(self): leak_L1_nand3 *= num_L1_nand3 gate_leak_L1_nand3 *= num_L1_nand3 - print("compute_area CHECKPINT 4") - cumulative_area_L1 = tot_area_L1_nand2 + tot_area_L1_nand3 cumulative_area_L2 = 0.0 leakage_L2 = 0.0 @@ -603,15 +564,11 @@ def compute_area(self): leakage_L2 = cmos_Isub_leakage(self.w_L2_n[0], self.w_L2_p[0], 3, nand, self.is_dram_) gate_leakage_L2 = cmos_Ig_leakage(self.w_L2_n[0], self.w_L2_p[0], 3, nand, self.is_dram_) - print("compute_area CHECKPINT 5") - for i in range(1, self.number_gates_L2): cumulative_area_L2 += compute_gate_area(INV, 1, self.w_L2_p[i], self.w_L2_n[i], g_tp.cell_h_def) leakage_L2 += cmos_Isub_leakage(self.w_L2_n[i], self.w_L2_p[i], 2, inv, self.is_dram_) gate_leakage_L2 += cmos_Ig_leakage(self.w_L2_n[i], self.w_L2_p[i], 2, inv, self.is_dram_) - print("compute_area CHECKPINT 6") - cumulative_area_L2 *= num_L2 leakage_L2 *= num_L2 gate_leakage_L2 *= num_L2 @@ -625,26 +582,14 @@ def compute_area(self): self.power_L2.readOp.gate_leakage = gate_leakage_L2 * g_tp.peri_global.Vdd def compute_delays(self, inrisetime): - print(f'PredecBLK {inrisetime}') ret_val = (0, 0) if self.exist: - print("self.exist") Vdd = g_tp.peri_global.Vdd inrisetime_nand2_path = inrisetime[0] inrisetime_nand3_path = inrisetime[1] - - print("flag 0") - - # print(f'debug_num_addr_bits_dec {self.debug_num_addr_bits_dec}') - # print(f'blk1_num_input_addr_bits {self.debug_blk1_num_input_addr_bits}') - # print(f'blk2_num_input_addr_bits {self.debug_blk2_num_input_addr_bits}') - - # print(f'number input addr_bits {self.number_input_addr_bits}') - # print(f'numberinputs L1 gate: {self.number_inputs_L1_gate}') if self.flag_two_unique_paths or self.number_inputs_L1_gate == 2: - print("flag 1") rd = tr_R_on(self.w_L1_nand2_n[0], NCH, 2, self.is_dram_) c_load = gate_C(self.w_L1_nand2_n[1] + self.w_L1_nand2_p[1], 0.0, self.is_dram_) c_intrinsic = 2 * drain_C_(self.w_L1_nand2_p[0], PCH, 1, 1, g_tp.cell_h_def, self.is_dram_) + \ @@ -678,7 +623,6 @@ def compute_delays(self, inrisetime): self.power_nand2_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd if self.flag_two_unique_paths or self.number_inputs_L1_gate == 3: - print("flag 2") rd = tr_R_on(self.w_L1_nand3_n[0], NCH, 3, self.is_dram_) c_load = gate_C(self.w_L1_nand3_n[1] + self.w_L1_nand3_p[1], 0.0, self.is_dram_) c_intrinsic = 3 * drain_C_(self.w_L1_nand3_p[0], PCH, 1, 1, g_tp.cell_h_def, self.is_dram_) + \ @@ -710,7 +654,6 @@ def compute_delays(self, inrisetime): self.delay_nand3_path += this_delay ret_val = (ret_val[0], this_delay / (1.0 - 0.5)) self.power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * Vdd * Vdd - print("return Predeclk") return ret_val def leakage_feedback(self, temperature): @@ -979,8 +922,6 @@ def compute_delays(self, inrisetime_nand2_path, inrisetime_nand3_path): Vdd = g_tp.peri_global.Vdd if self.flag_driver_exists: - print(f"PRedecBLKDrv IN HERE") - # print(f"PREDECBLK DRV {self.number_gates_nand2_path}") for i in range(self.number_gates_nand2_path - 1): rd = tr_R_on(self.width_nand2_path_n[i], NCH, 1, self.is_dram) c_gate_load = gate_C(self.width_nand2_path_p[i + 1] + self.width_nand2_path_n[i + 1], 0.0, self.is_dram) @@ -992,7 +933,6 @@ def compute_delays(self, inrisetime_nand2_path, inrisetime_nand3_path): self.delay_nand2_path += this_delay inrisetime_nand2_path = this_delay / (1.0 - 0.5) self.power_nand2_path.readOp.dynamic += (c_gate_load + c_intrinsic) * 0.5 * Vdd * Vdd - # print(self.delay_nand2_path) if self.number_gates_nand2_path != 0: i = self.number_gates_nand2_path - 1 @@ -1028,9 +968,6 @@ def compute_delays(self, inrisetime_nand2_path, inrisetime_nand3_path): self.delay_nand3_path += this_delay ret_val = (ret_val[0], this_delay / (1.0 - 0.5)) self.power_nand3_path.readOp.dynamic += (c_intrinsic + c_load) * 0.5 * Vdd * Vdd - print("compute Predecblkdrv delay") - print(f"PREDECBLKDRV (ret_val[0], this_delay / (1.0 - 0.5) {ret_val}") - print("HELLO the ret val should be set to the above") return ret_val def get_rdOp_dynamic_E(self, num_act_mats_hor_dir): @@ -1114,18 +1051,10 @@ def __init__(self, drv1, drv2): self.power.readOp.gate_leakage = self.driver_power.readOp.gate_leakage + self.block_power.readOp.gate_leakage def compute_delays(self, inrisetime): - # print("PREDECBLK COMPUTE DELAYS") tmp_pair1 = self.drv1.compute_delays(inrisetime, inrisetime) - # print(f'tmp_pair1 before PredecBLK compute_delay {tmp_pair1}') tmp_pair1 = self.blk1.compute_delays(tmp_pair1) tmp_pair2 = self.drv2.compute_delays(inrisetime, inrisetime) tmp_pair2 = self.blk2.compute_delays(tmp_pair2) - # print(" JUST COMPTUED DELAYS!") - # print(f"tmp_pair before max delay {tmp_pair1[0]}") - # print(f"tmp_pair before max delay {tmp_pair1[1]}") - # print(f"tmp_pair before max delay {tmp_pair2[0]}") - # print(f"tmp_pair before max delay {tmp_pair2[1]}") - # print("END") tmp_pair1 = self.get_max_delay_before_decoder(tmp_pair1, tmp_pair2) @@ -1143,8 +1072,6 @@ def compute_delays(self, inrisetime): self.power.readOp.dynamic = self.driver_power.readOp.dynamic + self.block_power.readOp.dynamic - print("past predec compute_delays") - # print(f"tmp_pair {tmp_pair1[0]}") self.delay = tmp_pair1[0] return tmp_pair1[1] @@ -1180,6 +1107,9 @@ def leakage_feedback(self, temperature): def get_max_delay_before_decoder(self, input_pair1, input_pair2): ret_val = [0, 0] + + # CHANGE: MAX: set to one option, otherwise, expression will be too long + # delay = self.drv1.delay_nand2_path + self.blk1.delay_nand2_path # ret_val[0] = delay # ret_val[1] = input_pair1[0] @@ -1196,39 +1126,16 @@ def get_max_delay_before_decoder(self, input_pair1, input_pair2): # ret_val[0] = delay # ret_val[1] = input_pair2[1] - # TODO MAX CHECK - print("INSIDE MAX FUNCTION") delay1 = self.drv1.delay_nand2_path + self.blk1.delay_nand2_path delay2 = self.drv1.delay_nand3_path + self.blk1.delay_nand3_path + delay3 = self.drv2.delay_nand2_path + self.blk2.delay_nand2_path delay4 = self.drv2.delay_nand3_path + self.blk2.delay_nand3_path - - # print(f"delay1{delay1})") - # print(f"delay2 {delay2}") - # print(f"delay3 {delay3}") - # print(f"delay4 {delay4}") - # TODO MAX CHECK - # max_delay = sp.Max(delay1, delay2, delay3, delay4) - # max_delay = symbolic_convex_max(delay1, delay2) - # max_delay = symbolic_convex_max(max_delay, delay3) - # max_delay = symbolic_convex_max(max_delay, delay4) - max_delay = delay2 - print("past max_delay set") + max_delay = delay2 # picked an option to reduce expression size ret_val[0] = max_delay - # print(f"input_pair1 {input_pair1}") - # print(f"input_pair2 {input_pair2}") - # print(f"max_delay {ret_val[0]}") - # TODO Piecewise doesn't work - # ret_val[1] = sp.Piecewise( - # (input_pair1[0], max_delay == delay1), - # (input_pair1[1], max_delay == delay2), - # (input_pair2[0], max_delay == delay3), - # (input_pair2[1], max_delay == delay4) - # ) ret_val[1] = input_pair1[0] - #print(f"input_pair {ret_val[1]}") return ret_val @@ -1295,23 +1202,17 @@ def compute_delay(self, inrisetime): for i in range(self.number_gates - 1): rd = tr_R_on(self.width_n[i], NCH, 1, self.is_dram_) - print("CHECKPOINT 6.52") c_load = gate_C(self.width_n[i + 1] + self.width_p[i + 1], 0.0, self.is_dram_) - print("CHECKPOINT 6.53") c_intrinsic = drain_C_(self.width_p[i], PCH, 1, 1, g_tp.cell_h_def, self.is_dram_) + \ drain_C_(self.width_n[i], NCH, 1, 1, g_tp.cell_h_def, self.is_dram_) - print("CHECKPOINT 6.54") tf = rd * (c_intrinsic + c_load) this_delay = horowitz(inrisetime, tf, 0.5, 0.5, RISE) - print("CHECKPOINT 6.55") self.delay += this_delay inrisetime = this_delay / (1.0 - 0.5) self.power.readOp.dynamic += (c_intrinsic + c_load) * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd self.power.readOp.leakage += cmos_Isub_leakage(self.width_n[i], self.width_p[i], 1, inv, self.is_dram_) * g_tp.peri_global.Vdd self.power.readOp.gate_leakage += cmos_Ig_leakage(self.width_n[i], self.width_p[i], 1, inv, self.is_dram_) * g_tp.peri_global.Vdd - print("CHECKPOINT 6.6") - i = self.number_gates - 1 c_load = self.c_gate_load + self.c_wire_load rd = tr_R_on(self.width_n[i], NCH, 1, self.is_dram_) @@ -1332,9 +1233,5 @@ def compute_delay(self, inrisetime): # Helper functions and constants (placeholders for actual implementations) NAND = 'nand' INV = 'inv' -NCH = 'nch' -PCH = 'pch' -RISE = 'rise' - diff --git a/cacti-main/cacti_python/htree.py b/cacti-main/cacti_python/htree.py index c333ed8..c9efcf8 100644 --- a/cacti-main/cacti_python/htree.py +++ b/cacti-main/cacti_python/htree.py @@ -1,8 +1,9 @@ import math import enum -from .parameter import g_tp +from .parameter import g_tp, _log2 from .component import * from .wire import Wire +import time class HtreeType(enum.Enum): Add_htree = 1 @@ -46,13 +47,11 @@ def __init__(self, wire_model, mat_w, mat_h, a_bits, d_inbits, search_data_in, d assert self.ndbl >= 2 and self.ndwl >= 2 - self.max_unpipelined_link_delay = 0 # TODO + self.max_unpipelined_link_delay = 0 self.min_w_nmos = g_tp.min_w_nmos_ self.min_w_pmos = self.deviceType.n_to_p_eff_curr_drv_ratio * self.min_w_nmos - # TODO have to fix the HtreeType self.wire_bw = self.init_wire_bw = 0 - print(f"SEE TREE TYPE! {self.tree_type}") if self.tree_type == "Add_htree": self.wire_bw = self.init_wire_bw = self.add_bits @@ -83,7 +82,9 @@ def input_nand(self, s1, s2, l_eff): w1 = Wire(self.wt, l_eff) pton_size = self.deviceType.n_to_p_eff_curr_drv_ratio nsize = s1 * (1 + pton_size) / (2 + pton_size) - nsize = symbolic_convex_max(1, nsize) + + # CHANGE: LENGTH max ignored, otherwise, expression will be too long + # nsize = symbolic_convex_max(1, nsize) tc = 2 * tr_R_on(nsize * self.min_w_nmos, NCH, 1) * ( drain_C_(nsize * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) * 2 + @@ -109,20 +110,36 @@ def output_buffer(self, s1, s2, l_eff): w1 = Wire(self.wt, l_eff) pton_size = self.deviceType.n_to_p_eff_curr_drv_ratio size = s1 * (1 + pton_size) / (2 + pton_size + 1 + 2 * pton_size) + s_eff = (gate_C(s2 * (self.min_w_nmos + self.min_w_pmos), 0) + w1.wire_cap(l_eff * 1e-6, True)) / gate_C(s2 * (self.min_w_nmos + self.min_w_pmos), 0) - tr_size = gate_C(s1 * (self.min_w_nmos + self.min_w_pmos), 0) * 1 / 2 / (s_eff * gate_C(self.min_w_pmos, 0)) - size = symbolic_convex_max(1, size) + if s_eff == sp.zoo: + s_eff = 1 + + tr_size = gate_C(s1 * (self.min_w_nmos + self.min_w_pmos), 0) / (2 * s_eff * gate_C(self.min_w_pmos, 0)) + + # CHANGE: MAX - avoiding max to decrease expression size + # size = symbolic_convex_max(1, size) res_nor = 2 * tr_R_on(size * self.min_w_pmos, PCH, 1) res_ptrans = tr_R_on(tr_size * self.min_w_nmos, NCH, 1) - cap_nand_out = drain_C_(size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) + drain_C_(size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) * 2 + gate_C(tr_size * self.min_w_pmos, 0) - cap_ptrans_out = 2 * (drain_C_(tr_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + drain_C_(tr_size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) + gate_C(s1 * (self.min_w_nmos + self.min_w_pmos), 0) + cap_nand_out = ( + drain_C_(size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) + + 2 * drain_C_(size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + + gate_C(tr_size * self.min_w_pmos, 0) + ) + cap_ptrans_out = ( + 2 * (drain_C_(tr_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + drain_C_(tr_size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) + + gate_C(s1 * (self.min_w_nmos + self.min_w_pmos), 0) + ) tc = res_nor * cap_nand_out + (res_nor + res_ptrans) * cap_ptrans_out - self.delay += horowitz(w1.out_rise_time, tc, - self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, RISE) + self.delay += horowitz( + w1.out_rise_time, tc, + self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, RISE + ) + # NAND self.power.readOp.dynamic += 0.5 * ( 2 * drain_C_(size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + drain_C_(size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) + @@ -135,6 +152,7 @@ def output_buffer(self, s1, s2, l_eff): gate_C(tr_size * self.min_w_pmos, 0) ) * self.deviceType.Vdd * self.deviceType.Vdd * self.init_wire_bw + # NOT self.power.readOp.dynamic += 0.5 * ( drain_C_(size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + drain_C_(size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) + @@ -147,6 +165,7 @@ def output_buffer(self, s1, s2, l_eff): gate_C(size * (self.min_w_nmos + self.min_w_pmos), 0) ) * self.deviceType.Vdd * self.deviceType.Vdd * self.init_wire_bw + # NOR self.power.readOp.dynamic += 0.5 * ( drain_C_(size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + 2 * drain_C_(size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) + @@ -159,15 +178,14 @@ def output_buffer(self, s1, s2, l_eff): gate_C(tr_size * (self.min_w_nmos + self.min_w_pmos), 0) ) * self.deviceType.Vdd * self.deviceType.Vdd * self.init_wire_bw + # Output transistor self.power.readOp.dynamic += 0.5 * ( - drain_C_(tr_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - drain_C_(tr_size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) * 2 + + 2 * (drain_C_(tr_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + drain_C_(tr_size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) + gate_C(s1 * (self.min_w_nmos + self.min_w_pmos), 0) ) * self.deviceType.Vdd * self.deviceType.Vdd self.power.searchOp.dynamic += 0.5 * ( - drain_C_(tr_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - drain_C_(tr_size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def) * 2 + + 2 * (drain_C_(tr_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + drain_C_(tr_size * self.min_w_nmos, NCH, 1, 1, g_tp.cell_h_def)) + gate_C(s1 * (self.min_w_nmos + self.min_w_pmos), 0) ) * self.deviceType.Vdd * self.deviceType.Vdd * self.init_wire_bw @@ -190,49 +208,64 @@ def output_buffer(self, s1, s2, l_eff): def in_htree(self): # temp var - s1, s2, s3 = 0, 0, 0 + s1 = 0 + s2 = 0 + s3 = 0 l_eff = 0 - wtemp1, wtemp2, wtemp3 = None, None, None - len_temp, ht_temp = 0, 0 + wtemp1 = None + wtemp2 = None + wtemp3 = None + len_temp = 0 + ht_temp = 0 option = 0 - #TODO deleted ints - h = math.log2(self.ndwl / 2) # horizontal nodes - v = math.log2(self.ndbl / 2) # vertical nodes + # RECENT CHANGE + h = max(int(_log2(self.ndwl / 2)), 1) # horizontal nodes + v = max(int(_log2(self.ndbl / 2)), 1) # vertical nodes + if self.uca_tree: - # this computation does not consider the wires that route from edge to middle ht_temp = (self.mat_height * self.ndbl / 2 + - ((self.add_bits + self.data_in_bits + self.data_out_bits + (self.search_data_in_bits + self.search_data_out_bits)) * g_tp.wire_outside_mat.pitch * + ((self.add_bits + self.data_in_bits + self.data_out_bits + + (self.search_data_in_bits + self.search_data_out_bits)) * g_tp.wire_outside_mat.pitch * 2 * (1 - pow(0.5, h)))) / 2 len_temp = (self.mat_width * self.ndwl / 2 + - ((self.add_bits + self.data_in_bits + self.data_out_bits + (self.search_data_in_bits + self.search_data_out_bits)) * g_tp.wire_outside_mat.pitch * + ((self.add_bits + self.data_in_bits + self.data_out_bits + + (self.search_data_in_bits + self.search_data_out_bits)) * g_tp.wire_outside_mat.pitch * 2 * (1 - pow(0.5, v)))) / 2 else: if self.ndwl == self.ndbl: ht_temp = ((self.mat_height * self.ndbl / 2) + - ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * (self.ndbl / 2 - 1) * g_tp.wire_outside_mat.pitch) + + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * + (self.ndbl / 2 - 1) * g_tp.wire_outside_mat.pitch) + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * h)) / 2 len_temp = (self.mat_width * self.ndwl / 2 + - ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * (self.ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) + + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * + (self.ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * v)) / 2 + elif self.ndwl > self.ndbl: - excess_part = (math.log2(self.ndwl / 2) - math.log2(self.ndbl / 2)) + excess_part = (_log2(self.ndwl / 2) - _log2(self.ndbl / 2)) ht_temp = ((self.mat_height * self.ndbl / 2) + - ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * ((self.ndbl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * + ((self.ndbl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + (self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * (2 * (1 - pow(0.5, h - v)) + pow(0.5, v - h) * v)) / 2 len_temp = (self.mat_width * self.ndwl / 2 + - ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * (self.ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) + + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * + (self.ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * v)) / 2 else: - excess_part = (math.log2(self.ndbl / 2) - math.log2(self.ndwl / 2)) + excess_part = (_log2(self.ndbl / 2) - _log2(self.ndwl / 2)) ht_temp = ((self.mat_height * self.ndbl / 2) + - ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * ((self.ndwl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * + ((self.ndwl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * h)) / 2 len_temp = (self.mat_width * self.ndwl / 2 + - ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * ((self.ndwl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + - (self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * (h + 2 * (1 - pow(0.5, v - h)))) / 2 + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * + ((self.ndwl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + + (self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * + (h + 2 * (1 - pow(0.5, v - h)))) / 2 self.area.h = ht_temp * 2 self.area.w = len_temp * 2 @@ -240,7 +273,7 @@ def in_htree(self): self.power.readOp.dynamic = 0 self.power.readOp.leakage = 0 self.power.searchOp.dynamic = 0 - len = len_temp + len_ = len_temp ht = ht_temp / 2 while v > 0 or h > 0: @@ -252,28 +285,25 @@ def in_htree(self): del wtemp3 if h > v: - # the iteration considers only one horizontal link - wtemp1 = Wire(self.wt, len) # hor - wtemp2 = Wire(self.wt, len / 2) # ver - len_temp = len - len /= 2 + wtemp1 = Wire(self.wt, len_) # hor + wtemp2 = Wire(self.wt, len_ / 2) # ver + len_temp = len_ + len_ /= 2 wtemp3 = None h -= 1 option = 0 elif v > 0 and h > 0: - # considers one horizontal link and one vertical link - wtemp1 = Wire(self.wt, len) # hor + wtemp1 = Wire(self.wt, len_) # hor wtemp2 = Wire(self.wt, ht) # ver - wtemp3 = Wire(self.wt, len / 2) # next hor - len_temp = len + wtemp3 = Wire(self.wt, len_ / 2) # next hor + len_temp = len_ ht_temp = ht - len /= 2 + len_ /= 2 ht /= 2 v -= 1 h -= 1 option = 1 else: - # considers only one vertical link assert h == 0 wtemp1 = Wire(self.wt, ht) # ver wtemp2 = Wire(self.wt, ht / 2) # hor @@ -285,14 +315,16 @@ def in_htree(self): self.delay += wtemp1.delay self.power.readOp.dynamic += wtemp1.power.readOp.dynamic + self.power.searchOp.dynamic += wtemp1.power.readOp.dynamic * self.wire_bw self.power.readOp.leakage += wtemp1.power.readOp.leakage * self.wire_bw self.power.readOp.gate_leakage += wtemp1.power.readOp.gate_leakage * self.wire_bw + if not self.uca_tree and option == 2 or self.search_tree: self.wire_bw *= 2 # wire bandwidth doubles only for vertical branches if not self.uca_tree: - # TODO important relational cannot handle + # Change: Relational set to one value, otherwise, expression will be too long # if len_temp > wtemp1.repeater_spacing: # s1 = wtemp1.repeater_size # l_eff = wtemp1.repeater_spacing @@ -300,65 +332,72 @@ def in_htree(self): # s1 = (len_temp / wtemp1.repeater_spacing) * wtemp1.repeater_size # l_eff = len_temp - s1 = sp.Piecewise( - (wtemp1.repeater_size, len_temp > wtemp1.repeater_spacing), - ((len_temp / wtemp1.repeater_spacing) * wtemp1.repeater_size, True) - ) + # print(f"lentemp: {len_temp}") + # s1 = sp.Piecewise( + # (wtemp1.repeater_size, len_temp > wtemp1.repeater_spacing), + # ((len_temp / wtemp1.repeater_spacing) * wtemp1.repeater_size, True) + # ) - l_eff = sp.Piecewise( - (wtemp1.repeater_spacing, len_temp > wtemp1.repeater_spacing), - (len_temp, True) - ) + s1 = wtemp1.repeater_size - # TODO important relational cannot handle + # l_eff = sp.Piecewise( + # (wtemp1.repeater_spacing, len_temp > wtemp1.repeater_spacing), + # (len_temp, True) + # ) + + l_eff = wtemp1.repeater_spacing + + # Change: Relational set to one value, otherwise, expression will be too long # if ht_temp > wtemp2.repeater_spacing: # s2 = wtemp2.repeater_size # else: # s2 = (len_temp / wtemp2.repeater_spacing) * wtemp2.repeater_size - s2 = sp.Piecewise( - (wtemp2.repeater_size, ht_temp > wtemp2.repeater_spacing), - ((len_temp / wtemp2.repeater_spacing) * wtemp2.repeater_size, True) - ) + # s2 = sp.Piecewise( + # (wtemp2.repeater_size, ht_temp > wtemp2.repeater_spacing), + # ((len_temp / wtemp2.repeater_spacing) * wtemp2.repeater_size, True) + # ) + s2 = wtemp2.repeater_size - # first level self.input_nand(s1, s2, l_eff) if option != 1: continue - # second level self.delay += wtemp2.delay self.power.readOp.dynamic += wtemp2.power.readOp.dynamic + self.power.searchOp.dynamic += wtemp2.power.readOp.dynamic * self.wire_bw self.power.readOp.leakage += wtemp2.power.readOp.leakage * self.wire_bw self.power.readOp.gate_leakage += wtemp2.power.readOp.gate_leakage * self.wire_bw if self.uca_tree: - self.power.readOp.leakage += (wtemp2.power.readOp.leakage * self.wire_bw) + self.power.readOp.leakage += wtemp2.power.readOp.leakage * self.wire_bw self.power.readOp.gate_leakage += wtemp2.power.readOp.gate_leakage * self.wire_bw else: - self.power.readOp.leakage += (wtemp2.power.readOp.leakage * self.wire_bw) + self.power.readOp.leakage += wtemp2.power.readOp.leakage * self.wire_bw self.power.readOp.gate_leakage += wtemp2.power.readOp.gate_leakage * self.wire_bw self.wire_bw *= 2 - # TODO RELATIONAL + # Change: Relational set to one value, otherwise, expression will be too long # if ht_temp > wtemp3.repeater_spacing: - # s3 = wtemp3.repeater_size - # l_eff = wtemp3.repeater_spacing + # s3 = wtemp3.repeater_size + # l_eff = wtemp3.repeater_spacing # else: # s3 = (len_temp / wtemp3.repeater_spacing) * wtemp3.repeater_size # l_eff = ht_temp - s3 = sp.Piecewise( - (wtemp3.repeater_size, ht_temp > wtemp3.repeater_spacing), - ((len_temp / wtemp3.repeater_spacing) * wtemp3.repeater_size, True) - ) + # s3 = sp.Piecewise( + # (wtemp3.repeater_size, ht_temp > wtemp3.repeater_spacing), + # ((len_temp / wtemp3.repeater_spacing) * wtemp3.repeater_size, True) + # ) + # l_eff = sp.Piecewise( + # (wtemp3.repeater_spacing, ht_temp > wtemp3.repeater_spacing), + # (ht_temp, True) + # ) - l_eff = sp.Piecewise( - (wtemp3.repeater_spacing, ht_temp > wtemp3.repeater_spacing), - (ht_temp, True) - ) + s3 = wtemp3.repeater_size + l_eff = wtemp3.repeater_spacing self.input_nand(s2, s3, l_eff) @@ -369,17 +408,21 @@ def in_htree(self): if wtemp3: del wtemp3 + def out_htree(self): # temp var s1, s2, s3 = 0, 0, 0 l_eff = 0 wtemp1, wtemp2, wtemp3 = None, None, None - len_temp, ht_temp = 0, 0 + len = 0 + ht = 0 option = 0 - #TODO deleted int - h = math.log2(self.ndwl / 2) - v = math.log2(self.ndbl / 2) + # RECENT Change: Round up h and v from 0 + h = max(int(_log2(self.ndwl / 2)), 1) + v = max(int(_log2(self.ndbl / 2)), 1) + len_temp = 0 + ht_temp = 0 if self.uca_tree: ht_temp = (self.mat_height * self.ndbl / 2 + @@ -392,12 +435,13 @@ def out_htree(self): if self.ndwl == self.ndbl: ht_temp = ((self.mat_height * self.ndbl / 2) + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * (self.ndbl / 2 - 1) * g_tp.wire_outside_mat.pitch) + - ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * h)) / 2 + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * h) + ) / 2 len_temp = (self.mat_width * self.ndwl / 2 + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * (self.ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * v)) / 2 elif self.ndwl > self.ndbl: - excess_part = (math.log2(self.ndwl / 2) - math.log2(self.ndbl / 2)) + excess_part = (_log2(self.ndwl / 2) - _log2(self.ndbl / 2)) ht_temp = ((self.mat_height * self.ndbl / 2) + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * ((self.ndbl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + (self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * @@ -406,10 +450,11 @@ def out_htree(self): ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * (self.ndwl / 2 - 1) * g_tp.wire_outside_mat.pitch) + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * v)) / 2 else: - excess_part = (math.log2(self.ndbl / 2) - math.log2(self.ndwl / 2)) + excess_part = (_log2(self.ndbl / 2) - _log2(self.ndwl / 2)) ht_temp = ((self.mat_height * self.ndbl / 2) + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * ((self.ndwl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + - ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * h)) / 2 + ((self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * h) + ) / 2 len_temp = (self.mat_width * self.ndwl / 2 + ((self.add_bits + (self.search_data_in_bits + self.search_data_out_bits)) * ((self.ndwl / 2 - 1) + excess_part) * g_tp.wire_outside_mat.pitch) + (self.data_in_bits + self.data_out_bits) * g_tp.wire_outside_mat.pitch * (h + 2 * (1 - pow(0.5, v - h)))) / 2 @@ -469,11 +514,11 @@ def out_htree(self): self.power.readOp.leakage += wtemp1.power.readOp.leakage * self.wire_bw self.power.readOp.gate_leakage += wtemp1.power.readOp.gate_leakage * self.wire_bw - if not self.uca_tree and option == 2 or self.search_tree: + if (self.uca_tree == False and option == 2) or self.search_tree: self.wire_bw *= 2 if not self.uca_tree: - # TODO relational + # Change: Relational set to one value, otherwise, expression will be too long # if len_temp > wtemp1.repeater_spacing: # s1 = wtemp1.repeater_size # l_eff = wtemp1.repeater_spacing @@ -481,34 +526,36 @@ def out_htree(self): # s1 = (len_temp / wtemp1.repeater_spacing) * wtemp1.repeater_size # l_eff = len_temp - # # TODO relational + # s1 = sp.Piecewise( + # (wtemp1.repeater_size, len_temp > wtemp1.repeater_spacing), + # ((len_temp / wtemp1.repeater_spacing) * wtemp1.repeater_size, True) + # ) + + # l_eff = sp.Piecewise( + # (wtemp1.repeater_spacing, len_temp > wtemp1.repeater_spacing), + # (len_temp, True) + # ) + + s1 = wtemp1.repeater_size + l_eff = wtemp1.repeater_spacing + + # Change: Relational set to one value, otherwise, expression will be too long # if ht_temp > wtemp2.repeater_spacing: # s2 = wtemp2.repeater_size # else: # s2 = (len_temp / wtemp2.repeater_spacing) * wtemp2.repeater_size + # s2 = sp.Piecewise( + # (wtemp2.repeater_size, ht_temp > wtemp2.repeater_spacing), + # ((len_temp / wtemp2.repeater_spacing) * wtemp2.repeater_size, True) + # ) - s1 = sp.Piecewise( - (wtemp1.repeater_size, len_temp > wtemp1.repeater_spacing), - ((len_temp / wtemp1.repeater_spacing) * wtemp1.repeater_size, True) - ) + s2 = wtemp2.repeater_size - l_eff = sp.Piecewise( - (wtemp1.repeater_spacing, len_temp > wtemp1.repeater_spacing), - (len_temp, True) - ) - - s2 = sp.Piecewise( - (wtemp2.repeater_size, ht_temp > wtemp2.repeater_spacing), - ((len_temp / wtemp2.repeater_spacing) * wtemp2.repeater_size, True) - ) - - # first level self.output_buffer(s1, s2, l_eff) if option != 1: continue - # second level self.delay += wtemp2.delay self.power.readOp.dynamic += wtemp2.power.readOp.dynamic self.power.searchOp.dynamic += wtemp2.power.readOp.dynamic * self.init_wire_bw @@ -516,14 +563,14 @@ def out_htree(self): self.power.readOp.gate_leakage += wtemp2.power.readOp.gate_leakage * self.wire_bw if self.uca_tree: - self.power.readOp.leakage += (wtemp2.power.readOp.leakage * self.wire_bw) + self.power.readOp.leakage += wtemp2.power.readOp.leakage * self.wire_bw self.power.readOp.gate_leakage += wtemp2.power.readOp.gate_leakage * self.wire_bw else: - self.power.readOp.leakage += (wtemp2.power.readOp.leakage * self.wire_bw) + self.power.readOp.leakage += wtemp2.power.readOp.leakage * self.wire_bw self.power.readOp.gate_leakage += wtemp2.power.readOp.gate_leakage * self.wire_bw self.wire_bw *= 2 - # TODO RELATONAL + # Change: Relational set to one value, otherwise, expression will be too long # if ht_temp > wtemp3.repeater_spacing: # s3 = wtemp3.repeater_size # l_eff = wtemp3.repeater_spacing @@ -531,15 +578,8 @@ def out_htree(self): # s3 = (len_temp / wtemp3.repeater_spacing) * wtemp3.repeater_size # l_eff = ht_temp - s3 = sp.Piecewise( - (wtemp3.repeater_size, ht_temp > wtemp3.repeater_spacing), - ((len_temp / wtemp3.repeater_spacing) * wtemp3.repeater_size, True) - ) - - l_eff = sp.Piecewise( - (wtemp3.repeater_spacing, ht_temp > wtemp3.repeater_spacing), - (ht_temp, True) - ) + s3 = wtemp3.repeater_size + l_eff = wtemp3.repeater_spacing self.output_buffer(s2, s3, l_eff) diff --git a/cacti-main/cacti_python/mat.py b/cacti-main/cacti_python/mat.py index deed031..3dd68cc 100644 --- a/cacti-main/cacti_python/mat.py +++ b/cacti-main/cacti_python/mat.py @@ -65,7 +65,6 @@ def __init__(self, dyn_p): self.power_comparator = PowerDef() self.num_do_b_mat = dyn_p.num_do_b_mat self.num_so_b_mat = dyn_p.num_so_b_mat - #print(self.dp.num_subarrays, self.dp.num_mats) self.num_subarrays_per_mat = self.dp.num_subarrays / self.dp.num_mats self.num_subarrays_per_row = self.dp.Ndwl / self.dp.num_mats_h_dir self.array_leakage = 0 @@ -87,10 +86,10 @@ def __init__(self, dyn_p): self.cl_wakeup_t = 0 self.cl_sleep_tx_area = 0 - print("CHECKPOINT 0") + # Change: Assert: ignored due to relational + # assert self.num_subarrays_per_mat <= 4 + # assert self.num_subarrays_per_row <= 2 - assert self.num_subarrays_per_mat <= 4 - assert self.num_subarrays_per_row <= 2 self.is_fa = self.dp.fully_assoc self.camFlag = self.is_fa or self.pure_cam @@ -146,14 +145,11 @@ def __init__(self, dyn_p): R_wire_bit_mux_dec_out /= 2.0 R_wire_sa_mux_dec_out /= 2.0 - print("CHECKPOINT 1") - self.row_dec = Decoder(num_dec_signals, False, self.subarray.C_wl, R_wire_wl_drv_out, False, self.is_dram, True, self.cam_cell if self.camFlag else self.cell) self.row_dec.nodes_DSTN = self.subarray.num_rows - print("CHECKPOINT 2") - self.bit_mux_dec = Decoder(self.deg_bl_muxing, False, C_ld_bit_mux_dec_out, R_wire_bit_mux_dec_out, False, self.is_dram, False, self.cam_cell if self.camFlag else self.cell) + self.sa_mux_lev_1_dec = Decoder(self.dp.deg_senseamp_muxing_non_associativity, self.dp.number_way_select_signals_mat, C_ld_sa_mux_lev_1_dec_out, R_wire_sa_mux_dec_out, False, self.is_dram, False, self.cam_cell if self.camFlag else self.cell) self.sa_mux_lev_2_dec = Decoder(self.dp.Ndsam_lev_2, False, C_ld_sa_mux_lev_2_dec_out, R_wire_sa_mux_dec_out, False, self.is_dram, False, self.cam_cell if self.camFlag else self.cell) @@ -167,24 +163,17 @@ def __init__(self, dyn_p): if self.is_fa or self.pure_cam: num_dec_signals += int(math.log2(self.num_subarrays_per_mat)) - print("CHECKPOINT 3") - print(f'num_dec_signals {num_dec_signals}') - print(f'deg_bl_muxing {self.deg_bl_muxing}') self.r_predec_blk1 = PredecBlk(num_dec_signals, self.row_dec, C_wire_predec_blk_out, R_wire_predec_blk_out, self.num_subarrays_per_mat, self.is_dram, True) - print("CHECKPOINT 3.1") self.r_predec_blk2 = PredecBlk(num_dec_signals, self.row_dec, C_wire_predec_blk_out, R_wire_predec_blk_out, self.num_subarrays_per_mat, self.is_dram, False) self.b_mux_predec_blk1 = PredecBlk(self.deg_bl_muxing, self.bit_mux_dec, 0, 0, 1, self.is_dram, True) self.b_mux_predec_blk2 = PredecBlk(self.deg_bl_muxing, self.bit_mux_dec, 0, 0, 1, self.is_dram, False) - print("CHECKPOINT 3.2") self.sa_mux_lev_1_predec_blk1 = PredecBlk(dyn_p.deg_senseamp_muxing_non_associativity, self.sa_mux_lev_1_dec, 0, 0, 1, self.is_dram, True) self.sa_mux_lev_1_predec_blk2 = PredecBlk(dyn_p.deg_senseamp_muxing_non_associativity, self.sa_mux_lev_1_dec, 0, 0, 1, self.is_dram, False) - print("CHECKPOINT 3.3") self.sa_mux_lev_2_predec_blk1 = PredecBlk(self.dp.Ndsam_lev_2, self.sa_mux_lev_2_dec, 0, 0, 1, self.is_dram, True) self.sa_mux_lev_2_predec_blk2 = PredecBlk(self.dp.Ndsam_lev_2, self.sa_mux_lev_2_dec, 0, 0, 1, self.is_dram, False) self.dummy_way_sel_predec_blk1 = PredecBlk(1, self.sa_mux_lev_1_dec, 0, 0, 0, self.is_dram, True) self.dummy_way_sel_predec_blk2 = PredecBlk(1, self.sa_mux_lev_1_dec, 0, 0, 0, self.is_dram, False) - print("CHECKPOINT 4") self.r_predec_blk_drv1 = PredecBlkDrv(0, self.r_predec_blk1, self.is_dram) self.r_predec_blk_drv2 = PredecBlkDrv(0, self.r_predec_blk2, self.is_dram) self.b_mux_predec_blk_drv1 = PredecBlkDrv(0, self.b_mux_predec_blk1, self.is_dram) @@ -196,18 +185,15 @@ def __init__(self, dyn_p): self.way_sel_drv1 = PredecBlkDrv(dyn_p.number_way_select_signals_mat, self.dummy_way_sel_predec_blk1, self.is_dram) self.dummy_way_sel_predec_blk_drv2 = PredecBlkDrv(1, self.dummy_way_sel_predec_blk2, self.is_dram) - print("CHECKPOINT 5") self.r_predec = Predec(self.r_predec_blk_drv1, self.r_predec_blk_drv2) self.b_mux_predec = Predec(self.b_mux_predec_blk_drv1, self.b_mux_predec_blk_drv2) self.sa_mux_lev_1_predec = Predec(self.sa_mux_lev_1_predec_blk_drv1, self.sa_mux_lev_1_predec_blk_drv2) self.sa_mux_lev_2_predec = Predec(self.sa_mux_lev_2_predec_blk_drv1, self.sa_mux_lev_2_predec_blk_drv2) - print("CHECKPOINT 6") self.subarray_out_wire = Wire(self.dp.wtype, self.subarray.area.w if g_ip.cl_vertical else self.subarray.area.h) # def __init__(self, wire_model, length, nsense=1, width_scaling=1, spacing_scaling=1, wire_placement=outside_mat, resistivity=CU_RESISTIVITY, dt=g_tp.peri_global): - print("CHECKPOINT 7") if self.is_fa or self.pure_cam: driver_c_gate_load = self.subarray.num_cols_fa_cam * gate_C(2 * g_tp.w_pmos_bl_precharge + g_tp.w_pmos_bl_eq, 0, self.is_dram, False, False) driver_c_wire_load = self.subarray.num_cols_fa_cam * self.cam_cell.w * g_tp.wire_outside_mat.C_per_um @@ -302,7 +288,6 @@ def __init__(self, dyn_p): # assert self.area.w > 0 def compute_delays(self, inrisetime): - print("CHECKPOINT 0") if self.is_fa or self.pure_cam: outrisetime_search = self.compute_cam_delay(inrisetime) @@ -327,29 +312,23 @@ def compute_delays(self, inrisetime): outrisetime_search = self.compute_bitline_delay(outrisetime_search) outrisetime_search = self.compute_sa_delay(outrisetime_search) - print("CHECKPOINT 1") outrisetime_search = self.compute_subarray_out_drv(outrisetime_search) self.subarray_out_wire.set_in_rise_time(outrisetime_search) outrisetime_search = self.subarray_out_wire.signal_rise_time() self.delay_subarray_out_drv_htree = self.delay_subarray_out_drv + self.subarray_out_wire.delay - print("CHECKPOINT 2") outrisetime = self.r_predec.compute_delays(inrisetime) row_dec_outrisetime = self.row_dec.compute_delays(outrisetime) - print("CHECKPOINT 3") outrisetime = self.b_mux_predec.compute_delays(inrisetime) self.bit_mux_dec.compute_delays(outrisetime) - print("CHECKPOINT 4") outrisetime = self.sa_mux_lev_1_predec.compute_delays(inrisetime) self.sa_mux_lev_1_dec.compute_delays(outrisetime) - print("CHECKPOINT 5") outrisetime = self.sa_mux_lev_2_predec.compute_delays(inrisetime) self.sa_mux_lev_2_dec.compute_delays(outrisetime) - print("Computed all predec delays") if self.pure_cam: outrisetime = self.compute_bitline_delay(row_dec_outrisetime) @@ -357,9 +336,7 @@ def compute_delays(self, inrisetime): return outrisetime_search else: - print("compute delays CHECKPOINT 6 ?") self.bl_precharge_eq_drv.compute_delay(0) - print("compute delays CHECKPOINT 6.5 ?") if self.row_dec.exist: k = self.row_dec.num_gates - 1 rd = tr_R_on(self.row_dec.w_dec_n[k], NCH, 1, self.is_dram, False, True) @@ -381,52 +358,35 @@ def compute_delays(self, inrisetime): sp.log((g_tp.sram.Vbitpre - 0.1 * self.dp.V_b_sense) / (g_tp.sram.Vbitpre - self.dp.V_b_sense)) * \ (R_bl_precharge * C_bl + R_bl * C_bl / 2) - print("CHECKPOINT 7") outrisetime = self.r_predec.compute_delays(inrisetime) row_dec_outrisetime = self.row_dec.compute_delays(outrisetime) - print(outrisetime) - print(row_dec_outrisetime) - - print("CHECKPOINT 8") outrisetime = self.b_mux_predec.compute_delays(inrisetime) self.bit_mux_dec.compute_delays(outrisetime) - print(outrisetime) - print(self.b_mux_predec.delay) - print(self.bit_mux_dec.delay) - - print("CHECKPOINT 9") outrisetime = self.sa_mux_lev_1_predec.compute_delays(inrisetime) self.sa_mux_lev_1_dec.compute_delays(outrisetime) - print("CHECKPOINT 10") outrisetime = self.sa_mux_lev_2_predec.compute_delays(inrisetime) self.sa_mux_lev_2_dec.compute_delays(outrisetime) if g_ip.is_3d_mem: row_dec_outrisetime = inrisetime - print("CHECKPOINT 11") outrisetime = self.compute_bitline_delay(row_dec_outrisetime) outrisetime = self.compute_sa_delay(outrisetime) outrisetime = self.compute_subarray_out_drv(outrisetime) self.subarray_out_wire.set_in_rise_time(outrisetime) outrisetime = self.subarray_out_wire.signal_rise_time() - print("CHECKPOINT 12") self.delay_subarray_out_drv_htree = self.delay_subarray_out_drv + self.subarray_out_wire.delay if self.dp.is_tag and not self.dp.fully_assoc: self.compute_comparator_delay(0) - print("CHECKPOINT 13") - if not self.row_dec.exist: self.delay_wl_reset = symbolic_convex_max(self.r_predec.blk1.delay, self.r_predec.blk2.delay) - print("CHECKPOINT 14") - return outrisetime def compute_bit_mux_sa_precharge_sa_mux_wr_drv_wr_mux_h(self): @@ -467,16 +427,16 @@ def compute_cam_delay(self, inrisetime): driver_c_wire_load = 0 driver_r_wire_load = 0 - leak_power_cc_inverters_sram_cell = 0 - leak_power_acc_tr_RW_or_WR_port_sram_cell = 0 - leak_power_RD_port_sram_cell = 0 - leak_power_SCHP_port_sram_cell = 0 - leak_comparator_cam_cell = 0 + self.leak_power_cc_inverters_sram_cell = 0 + self.leak_power_acc_tr_RW_or_WR_port_sram_cell = 0 + self.leak_power_RD_port_sram_cell = 0 + self.leak_power_SCHP_port_sram_cell = 0 + self.leak_comparator_cam_cell = 0 - gate_leak_comparator_cam_cell = 0 - gate_leak_power_cc_inverters_sram_cell = 0 - gate_leak_power_RD_port_sram_cell = 0 - gate_leak_power_SCHP_port_sram_cell = 0 + self.gate_leak_comparator_cam_cell = 0 + self.gate_leak_power_cc_inverters_sram_cell = 0 + self.gate_leak_power_RD_port_sram_cell = 0 + self.gate_leak_power_SCHP_port_sram_cell = 0 c_matchline_metal = self.cam_cell.get_w() * g_tp.wire_local.C_per_um c_searchline_metal = self.cam_cell.get_h() * g_tp.wire_local.C_per_um @@ -511,8 +471,7 @@ def compute_cam_delay(self, inrisetime): W_hit_miss_n = Wdummyn W_hit_miss_p = g_tp.min_w_nmos_ * p_to_n_sizing_r - #TODO deleted int - Htagbits = sp.ceiling(self.subarray.num_cols_fa_cam / 2.0) + Htagbits = int(sp.ceiling(self.subarray.num_cols_fa_cam / 2.0)) driver_c_gate_load = self.subarray.num_cols_fa_cam * gate_C(2 * g_tp.w_pmos_bl_precharge + g_tp.w_pmos_bl_eq, 0, self.is_dram, False, False) driver_c_wire_load = self.subarray.num_cols_fa_cam * self.cam_cell.w * g_tp.wire_outside_mat.C_per_um @@ -777,8 +736,7 @@ def compute_bitline_delay(self, inrisetime): m = V_wl / inrisetime - print(f'tstep: {tstep}') - # TODO Relational + # Change: Relational set to one value, otherwise, expression will be too long # if tstep <= (0.5 * (V_wl - v_th_mem_cell) / m): self.delay_bitline = sp.sqrt(2 * tstep * (V_wl - v_th_mem_cell) / m) # else: @@ -791,7 +749,6 @@ def compute_bitline_delay(self, inrisetime): # self.delay_bitline = sp.Piecewise((delay_bitline_if_true, condition), # (delay_bitline_if_false, not condition)) - # TODO VISIT is_fa = bool(self.dp.fully_assoc) @@ -952,13 +909,14 @@ def compute_comparator_delay(self, inrisetime): tstep = (r2 * c2 + (r1 + r2) * c1) * sp.log(1.0 / VTHMUXNAND) m = g_tp.peri_global.Vdd / nextinputtime - # TODO RELATIONAL + # Change: Relational set to one value, otherwise, expression will be too long # if tstep <= (0.5 * (g_tp.peri_global.Vdd - g_tp.peri_global.Vth) / m): # a = m # b = 2 * ((g_tp.peri_global.Vdd * VTHEVALINV) - g_tp.peri_global.Vth) # c = -2 * tstep * (g_tp.peri_global.Vdd - g_tp.peri_global.Vth) + 1 / m * ((g_tp.peri_global.Vdd * VTHEVALINV) - g_tp.peri_global.Vth) * ((g_tp.peri_global.Vdd * VTHEVALINV) - g_tp.peri_global.Vth) # Tcomparatorni = (-b + sp.sqrt(b * b - 4 * a * c)) / (2 * a) # else: + # Tcomparatorni = tstep + (g_tp.peri_global.Vdd + g_tp.peri_global.Vth) / (2 * m) - (g_tp.peri_global.Vdd * VTHEVALINV) / m Tcomparatorni = tstep + (g_tp.peri_global.Vdd + g_tp.peri_global.Vth) / (2 * m) - (g_tp.peri_global.Vdd * VTHEVALINV) / m self.delay_comparator = Tcomparatorni + st1del + st2del + st3del diff --git a/cacti-main/cacti_python/nuca.py b/cacti-main/cacti_python/nuca.py index 14ded29..2035126 100644 --- a/cacti-main/cacti_python/nuca.py +++ b/cacti-main/cacti_python/nuca.py @@ -39,9 +39,7 @@ def __init__(self, dt=None): def init_cont(self): cont_stats = [[[[[0 for _ in range(8)] for _ in range(7)] for _ in range(ROUTER_TYPES)] for _ in range(5)] for _ in range(2)] try: - print("HUH") with open("contention.dat", "r") as cont: - print("BUH") for i in range(2): for j in range(2, 5): for k in range(ROUTER_TYPES): @@ -49,10 +47,9 @@ def init_cont(self): line = cont.readline().strip() parts = line.split(":")[1].strip().split() for m in range(8): - #TODO deleted int + # Change: deleted int since symbolic cont_stats[i][j][k][l][m] = parts[m] except FileNotFoundError: - print("BRUH") print("contention.dat file is missing!") exit(0) self.cont_stats = cont_stats @@ -78,7 +75,7 @@ def calc_cycles(self, lat, oper_freq): cycle_time = 1.0 / (oper_freq * 1e9) cycle_time -= LATCH_DELAY cycle_time -= FIXED_OVERHEAD - #TODO deleted int + # Change: deleted int since symbolic return sp.ceiling(lat / cycle_time) # Constants and placeholder classes/functions for the sake of completeness diff --git a/cacti-main/cacti_python/parameter.py b/cacti-main/cacti_python/parameter.py index 7e2f16f..7f5893c 100644 --- a/cacti-main/cacti_python/parameter.py +++ b/cacti-main/cacti_python/parameter.py @@ -5,72 +5,12 @@ from .const import * from .area import Area import sympy as sp +import time sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))) from hw_symbols import symbol_table as sympy_var -# sympy_var = { -# 'C_g_ideal': sp.symbols('C_g_ideal'), -# 'C_fringe': sp.symbols('C_fringe'), -# 'C_junc': sp.symbols('C_junc'), -# 'C_junc_sw': sp.symbols('C_junc_sw'), -# 'l_phy': sp.symbols('l_phy'), -# 'l_elec': sp.symbols('l_elec'), -# 'nmos_effective_resistance_multiplier': sp.symbols('nmos_effective_resistance_multiplier'), -# 'Vdd': sp.symbols('Vdd'), -# 'Vth': sp.symbols('Vth'), -# 'Vdsat': sp.symbols('Vdsat'), -# 'I_on_n': sp.symbols('I_on_n'), -# 'I_on_p': sp.symbols('I_on_p'), -# 'I_off_n': sp.symbols('I_off_n'), -# 'I_g_on_n': sp.symbols('I_g_on_n'), -# 'C_ox': sp.symbols('C_ox'), -# 't_ox': sp.symbols('t_ox'), -# 'n2p_drv_rt': sp.symbols('n2p_drv_rt'), -# 'lch_lk_rdc': sp.symbols('lch_lk_rdc'), -# 'Mobility_n': sp.symbols('Mobility_n'), -# 'gmp_to_gmn_multiplier': sp.symbols('gmp_to_gmn_multiplier'), -# 'vpp': sp.symbols('vpp'), -# 'Wmemcella': sp.symbols('Wmemcella'), -# 'Wmemcellpmos': sp.symbols('Wmemcellpmos'), -# 'Wmemcellnmos': sp.symbols('Wmemcellnmos'), -# 'area_cell': sp.symbols('area_cell'), -# 'asp_ratio_cell': sp.symbols('asp_ratio_cell'), -# 'vdd_cell': sp.symbols('vdd_cell'), -# 'dram_cell_I_on': sp.symbols('dram_cell_I_on'), -# 'dram_cell_Vdd': sp.symbols('dram_cell_Vdd'), -# 'dram_cell_C': sp.symbols('dram_cell_C'), -# 'dram_cell_I_off_worst_case_len_temp': sp.symbols('dram_cell_I_off_worst_case_len_temp'), -# 'logic_scaling_co_eff': sp.symbols('logic_scaling_co_eff'), -# 'core_tx_density': sp.symbols('core_tx_density'), -# 'sckt_co_eff': sp.symbols('sckt_co_eff'), -# 'chip_layout_overhead': sp.symbols('chip_layout_overhead'), -# 'macro_layout_overhead': sp.symbols('macro_layout_overhead'), -# 'sense_delay': sp.symbols('sense_delay'), -# 'sense_dy_power': sp.symbols('sense_dy_power'), -# 'wire_pitch': sp.symbols('wire_pitch'), -# 'barrier_thickness': sp.symbols('barrier_thickness'), -# 'dishing_thickness': sp.symbols('dishing_thickness'), -# 'alpha_scatter': sp.symbols('alpha_scatter'), -# 'aspect_ratio': sp.symbols('aspect_ratio'), -# 'miller_value': sp.symbols('miller_value'), -# 'horiz_dielectric_constant': sp.symbols('horiz_dielectric_constant'), -# 'vert_dielectric_constant': sp.symbols('vert_dielectric_constant'), -# 'ild_thickness': sp.symbols('ild_thickness'), -# 'fringe_cap': sp.symbols('fringe_cap'), -# 'resistivity': sp.symbols('resistivity'), -# 'wire_r_per_micron': sp.symbols('wire_r_per_micron'), -# 'wire_c_per_micron': sp.symbols('wire_c_per_micron'), -# 'tsv_pitch': sp.symbols('tsv_pitch'), -# 'tsv_diameter': sp.symbols('tsv_diameter'), -# 'tsv_length': sp.symbols('tsv_length'), -# 'tsv_dielec_thickness': sp.symbols('tsv_dielec_thickness'), -# 'tsv_contact_resistance': sp.symbols('tsv_contact_resistance'), -# 'tsv_depletion_width': sp.symbols('tsv_depletion_width'), -# 'tsv_liner_dielectric_cons': sp.symbols('tsv_liner_dielectric_cons') -# } - def contains_any_symbol(expr): # Extract all the symbols from the dictionary symbols = sympy_var.values() @@ -228,6 +168,10 @@ def __init__(self): self.total_power = False self.verbose = False + self.repeater_spacing = 0.0 + self.repeater_size = 0.0 + + def parse_cfg(self, in_file): try: with open(in_file, "r") as fp: @@ -486,7 +430,6 @@ def parse_cfg(self, in_file): elif line.startswith("-Power Gating Performance Loss"): val = line.split()[-1] cleaned_value = val.strip('"').strip() - print(cleaned_value) self.perfloss = float(cleaned_value) elif line.startswith("-Print input parameters"): print_input = line.split("\"")[1] @@ -506,7 +449,7 @@ def parse_cfg(self, in_file): self.ndsam2 = int(line.split()[-1]) elif line.startswith("-Ndcm"): self.ndcm = int(line.split()[-1]) - elif line.startswith("-dram type"): + elif line.startswith("-dram_type"): dram_type = line.split("\"")[1] if "DDR3" in dram_type: self.io_type = "DDR3" @@ -671,8 +614,7 @@ def parse_cfg(self, in_file): print(f"{in_file} is missing!") exit(-1) - def error_checking(self): - print("IN ERROR CHECKING") + def error_checking(self): A = 0 seq_access = False fast_access = True @@ -714,7 +656,6 @@ def error_checking(self): NSER = self.num_se_rd_ports SCHP = self.num_search_ports - print("HAD SET B-1") if (RWP + ERP + EWP) < 1: print("Must have at least one port") return False @@ -737,7 +678,7 @@ def error_checking(self): print("Pure CAM must have associativity as 0") return False - if self.assoc == 0 and (not self.pure_cam and not self.is_cache): + if self.assoc == 0 and not self.pure_cam and not self.is_cache: print("Only CAM or Fully associative cache can have associativity as 0") return False @@ -763,7 +704,6 @@ def error_checking(self): if RWP == 0 and ERP == 0 and SCHP > 0 and (self.fully_assoc or self.pure_cam): ERP = SCHP - print("HAD SET B0") if self.assoc == 0: A = C / B else: @@ -782,8 +722,6 @@ def error_checking(self): return False self.block_sz = B - # TODO REMOVE - print("HAD SET B") if seq_access: self.tag_assoc = A @@ -816,10 +754,11 @@ def error_checking(self): return False self.power_gating = (self.array_power_gated or self.bitline_floating or self.wl_power_gated or - self.cl_power_gated or self.interconect_power_gated) + self.cl_power_gated or self.interconect_power_gated) return True + def display_ip(self): print(f"Cache size : {self.cache_sz}") print(f"Block size : {self.line_sz}") @@ -999,11 +938,30 @@ def reset(self): self.dram = MemoryType() self.cam = MemoryType() + self.dram_cell_I_on = sympy_var['dram_cell_I_on'] + self.dram_cell_Vdd = sympy_var['dram_cell_Vdd'] + self.dram_cell_C = sympy_var['dram_cell_C'] + self.dram_cell_I_off_worst_case_len_temp = sympy_var['dram_cell_I_off_worst_case_len_temp'] + self.vpp = sympy_var['vpp'] + self.sckt_co_eff = sympy_var['sckt_co_eff'] + self.chip_layout_overhead = sympy_var['chip_layout_overhead'] + self.macro_layout_overhead = sympy_var['macro_layout_overhead'] + + self.sense_delay = sympy_var['sense_delay'] + self.sense_dy_power = sympy_var['sense_dy_power'] + self.sckt_co_eff = sympy_var['sckt_co_eff'] + self.chip_layout_overhead = sympy_var['chip_layout_overhead'] + self.macro_layout_overhead = sympy_var['macro_layout_overhead'] + self.dram_cell_I_on = sympy_var['dram_cell_I_on'] + self.dram_cell_Vdd = sympy_var['dram_cell_Vdd'] + self.dram_cell_C = sympy_var['dram_cell_C'] + self.dram_cell_I_off_worst_case_len_temp = sympy_var['dram_cell_I_off_worst_case_len_temp'] + self.vpp = sympy_var['vpp'] + def init_symbolic(): return def find_upper_and_lower_tech(self, technology, tech_lo, in_file_lo, tech_hi, in_file_hi): - print(technology) if 179 < technology < 181: tech_lo = 180 in_file_lo = "tech_params/180nm.dat" @@ -1124,10 +1082,6 @@ def init(self, technology, is_tag): exit(0) alpha = 1 if tech_lo == tech_hi else (technology - tech_hi) / (tech_lo - tech_hi) - print(in_file_lo) - # TODO FILE CHECK - # in_file_lo = "cacti/" + in_file_lo - # print(in_file_lo) with open(in_file_lo, "r") as fp: lines = fp.readlines() @@ -1170,18 +1124,12 @@ def init(self, technology, is_tag): peri_global_lo = DeviceType() peri_global_hi = DeviceType() peri_global_lo.assign(in_file_lo, peri_global_tech_type, g_ip.temp) - print("peri lo") - peri_global_lo.display() - print() + # peri_global_lo.display() peri_global_hi.assign(in_file_hi, peri_global_tech_type, g_ip.temp) - print("peri hi") - peri_global_hi.display() - print() + # peri_global_hi.display() self.peri_global.interpolate(alpha, peri_global_lo, peri_global_hi) - print("peri_global") - self.peri_global.display() - print() + # self.peri_global.display() sleep_tx_lo = DeviceType() sleep_tx_hi = DeviceType() @@ -1341,8 +1289,6 @@ def init(self, technology, is_tag): self.max_w_nmos_dec = self.max_w_nmos_ self.h_dec = 4 # in the unit of memory cell height - #TODO CHECK 388 for 180nm - print(self.peri_global.l_elec) gmn_sense_amp_latch = (self.peri_global.Mobility_n / 2) * self.peri_global.C_ox * (self.w_sense_n / self.peri_global.l_elec) * self.peri_global.Vdsat gmp_sense_amp_latch = self.peri_global.gmp_to_gmn_multiplier * gmn_sense_amp_latch self.gm_sense_amp_latch = gmn_sense_amp_latch + gmp_sense_amp_latch @@ -1595,10 +1541,37 @@ def __init__(self): self.long_channel_leakage_reduction = 0 self.Mobility_n = 0 + # self.n_to_p_eff_curr_drv_ratio = sympy_var['n2p_drv_rt'] + # auxiliary parameters self.Vdsat = 0 self.gmp_to_gmn_multiplier = 0 + self.C_g_ideal = sympy_var['C_g_ideal'] + self.C_fringe = sympy_var['C_fringe'] + self.C_junc_sidewall = sympy_var['C_junc_sw'] + self.C_junc = sympy_var['C_junc'] + self.l_phy = sympy_var['l_phy'] + self.l_elec = sympy_var['l_elec'] + self.nmos_effective_resistance_multiplier = sympy_var['nmos_effective_resistance_multiplier'] + self.Vdd = sympy_var['Vdd'] + self.Vth = sympy_var['Vth'] + self.Vdsat = sympy_var['Vdsat'] + self.I_on_n = sympy_var['I_on_n'] + self.I_on_p = sympy_var['I_on_p'] + self.I_off_n = sympy_var['I_off_n'] + self.I_g_on_n = sympy_var['I_g_on_n'] + self.C_ox = sympy_var['C_ox'] + self.t_ox = sympy_var['t_ox'] + self.n_to_p_eff_curr_drv_ratio = sympy_var['n2p_drv_rt'] + self.long_channel_leakage_reduction = sympy_var['lch_lk_rdc'] + self.Mobility_n = sympy_var['Mobility_n'] + self.gmp_to_gmn_multiplier = sympy_var['gmp_to_gmn_multiplier'] + + self.C_overlap = 0.2 * self.C_g_ideal + self.I_off_p = self.I_off_n + self.I_g_on_p = self.I_g_on_n + def reset(self): self.C_g_ideal = 0 self.C_fringe = 0 @@ -1628,6 +1601,31 @@ def reset(self): self.Vdsat = 0 self.gmp_to_gmn_multiplier = 0 + self.C_g_ideal = sympy_var['C_g_ideal'] + self.C_fringe = sympy_var['C_fringe'] + self.C_junc_sidewall = sympy_var['C_junc_sw'] + self.C_junc = sympy_var['C_junc'] + self.l_phy = sympy_var['l_phy'] + self.l_elec = sympy_var['l_elec'] + self.nmos_effective_resistance_multiplier = sympy_var['nmos_effective_resistance_multiplier'] + self.Vdd = sympy_var['Vdd'] + self.Vth = sympy_var['Vth'] + self.Vdsat = sympy_var['Vdsat'] + self.I_on_n = sympy_var['I_on_n'] + self.I_on_p = sympy_var['I_on_p'] + self.I_off_n = sympy_var['I_off_n'] + self.I_g_on_n = sympy_var['I_g_on_n'] + self.C_ox = sympy_var['C_ox'] + self.t_ox = sympy_var['t_ox'] + self.n_to_p_eff_curr_drv_ratio = sympy_var['n2p_drv_rt'] + self.long_channel_leakage_reduction = sympy_var['lch_lk_rdc'] + self.Mobility_n = sympy_var['Mobility_n'] + self.gmp_to_gmn_multiplier = sympy_var['gmp_to_gmn_multiplier'] + + self.C_overlap = 0.2 * self.C_g_ideal + self.I_off_p = self.I_off_n + self.I_g_on_p = self.I_g_on_n + def display(self, indent=0): indent_str = ' ' * indent print(f"{indent_str}C_g_ideal = {self.C_g_ideal} F/um") @@ -1768,11 +1766,9 @@ def assign(self, in_file, tech_flavor, temperature): self.C_overlap = 0.2 * self.C_g_ideal if tech_flavor >= 3: - if(self.I_on_n): # TODO Check values of I_on_n - self.R_nch_on = self.nmos_effective_resistance_multiplier * g_tp.vpp / self.I_on_n + self.R_nch_on = self.nmos_effective_resistance_multiplier * g_tp.vpp / self.I_on_n else: - if(self.I_on_n): # TODO Check values of I_on_n - self.R_nch_on = self.nmos_effective_resistance_multiplier * self.Vdd / self.I_on_n + self.R_nch_on = self.nmos_effective_resistance_multiplier * self.Vdd / self.I_on_n # CHECKPOINT _pch_on issue # print(f"nmos_effective_resistance_multiplier {nmos_effective_resistance_multiplier}") # print(f"tech_flavor {tech_flavor}") @@ -1789,7 +1785,6 @@ def assign(self, in_file, tech_flavor, temperature): def interpolate(self, alpha, dev1, dev2): result = DeviceType() self.C_g_ideal = alpha * dev1.C_g_ideal + (1 - alpha) * dev2.C_g_ideal - print(f'GLOBAL result {self.C_g_ideal}') self.C_fringe = alpha * dev1.C_fringe + (1 - alpha) * dev2.C_fringe self.C_overlap = alpha * dev1.C_overlap + (1 - alpha) * dev2.C_overlap self.C_junc = alpha * dev1.C_junc + (1 - alpha) * dev2.C_junc @@ -1835,6 +1830,24 @@ def __init__(self): self.alpha_scatter = 0 self.fringe_cap = 0 + self.pitch = sympy_var['wire_pitch'] + self.barrier_thickness = sympy_var['barrier_thickness'] + self.dishing_thickness = sympy_var['dishing_thickness'] + self.alpha_scatter = sympy_var['alpha_scatter'] + self.aspect_ratio = sympy_var['aspect_ratio'] + self.miller_value = sympy_var['miller_value'] + self.horiz_dielectric_constant = sympy_var['horiz_dielectric_constant'] + self.vert_dielectric_constant = sympy_var['vert_dielectric_constant'] + self.ild_thickness = sympy_var['ild_thickness'] + self.fringe_cap = sympy_var['fringe_cap'] + self.R_per_um = sympy_var['wire_r_per_micron'] + self.C_per_um = sympy_var['wire_c_per_micron'] + self.resistivity = sympy_var['resistivity'] + self.pitch *= g_ip.F_sz_um + self.wire_width = self.pitch / 2 # micron + self.wire_thickness = self.aspect_ratio * self.wire_width # micron + self.wire_spacing = self.pitch - self.wire_width # micron + self.reset() def reset(self): @@ -1856,6 +1869,24 @@ def reset(self): self.alpha_scatter = 0 self.fringe_cap = 0 + self.pitch = sympy_var['wire_pitch'] + self.barrier_thickness = sympy_var['barrier_thickness'] + self.dishing_thickness = sympy_var['dishing_thickness'] + self.alpha_scatter = sympy_var['alpha_scatter'] + self.aspect_ratio = sympy_var['aspect_ratio'] + self.miller_value = sympy_var['miller_value'] + self.horiz_dielectric_constant = sympy_var['horiz_dielectric_constant'] + self.vert_dielectric_constant = sympy_var['vert_dielectric_constant'] + self.ild_thickness = sympy_var['ild_thickness'] + self.fringe_cap = sympy_var['fringe_cap'] + self.R_per_um = sympy_var['wire_r_per_micron'] + self.C_per_um = sympy_var['wire_c_per_micron'] + self.resistivity = sympy_var['resistivity'] + self.pitch *= g_ip.F_sz_um + self.wire_width = self.pitch / 2 # micron + self.wire_thickness = self.aspect_ratio * self.wire_width # micron + self.wire_spacing = self.pitch - self.wire_width # micron + def is_equal(self, inter): if not is_equal(self.pitch, inter.pitch): return False if not is_equal(self.R_per_um, inter.R_per_um): return False @@ -1978,8 +2009,23 @@ def __init__(self): self.Vbitfloating = 0 self.area_cell = 0 self.asp_ratio_cell = 0 + + self.cell_a_w = sympy_var['Wmemcella'] + self.cell_pmos_w = sympy_var['Wmemcellpmos'] + self.cell_nmos_w = sympy_var['Wmemcellnmos'] + self.area_cell = sympy_var['area_cell'] + self.asp_ratio_cell = sympy_var['asp_ratio_cell'] + self.reset() + self.cell_a_w = sympy_var['Wmemcella'] + self.cell_pmos_w = sympy_var['Wmemcellpmos'] + self.cell_nmos_w = sympy_var['Wmemcellnmos'] + self.area_cell = sympy_var['area_cell'] + self.asp_ratio_cell = sympy_var['asp_ratio_cell'] + self.cell_pmos_w *= g_ip.F_sz_um + self.cell_nmos_w *= g_ip.F_sz_um + def reset(self): self.b_w = 0 self.b_h = 0 @@ -1991,8 +2037,15 @@ def reset(self): self.area_cell = 0 self.asp_ratio_cell = 0 + self.cell_a_w = sympy_var['Wmemcella'] + self.cell_pmos_w = sympy_var['Wmemcellpmos'] + self.cell_nmos_w = sympy_var['Wmemcellnmos'] + self.area_cell = sympy_var['area_cell'] + self.asp_ratio_cell = sympy_var['asp_ratio_cell'] + self.cell_pmos_w *= g_ip.F_sz_um + self.cell_nmos_w *= g_ip.F_sz_um + def assign(self, in_file, tech_flavor, cell_type): - print("ASSIGN MEMORY") try: with open(in_file, "r") as fp: lines = fp.readlines() @@ -2003,8 +2056,6 @@ def assign(self, in_file, tech_flavor, cell_type): vdd_cell = 0 vdd = 0 - print(f'tech_flavor {tech_flavor}') - vdd = sympy_var['Vdd'] vdd_cell = sympy_var['vdd_cell'] self.cell_a_w = sympy_var['Wmemcella'] @@ -2045,16 +2096,12 @@ def assign(self, in_file, tech_flavor, cell_type): # print(g_ip.F_sz_um) # print(self.cell_pmos_w) if cell_type != 2: - print(self.cell_a_w) self.cell_a_w *= g_ip.F_sz_um self.cell_pmos_w *= g_ip.F_sz_um self.cell_nmos_w *= g_ip.F_sz_um if cell_type != 2: self.area_cell *= (g_ip.F_sz_um * g_ip.F_sz_um) - print(f"DEBUG: {self.cell_a_w}") - - #TODO 1028-1030 self.b_w = sp.sqrt(self.area_cell / self.asp_ratio_cell) self.b_h = self.asp_ratio_cell * self.b_w if cell_type == 2: @@ -2073,41 +2120,24 @@ def interpolate(self, alpha, mem1, mem2): self.Vbitpre = mem2.Vbitpre self.Vbitfloating = self.Vbitpre * 0.7 - #TODO 1028-1030 self.b_w = sp.sqrt(self.area_cell / self.asp_ratio_cell) self.b_h = self.asp_ratio_cell * self.b_w def isEqual(self, mem): - if not self.is_equal(self.b_w, mem.b_w): return False - if not self.is_equal(self.b_h, mem.b_h): return False - if not self.is_equal(self.cell_a_w, mem.cell_a_w): return False - if not self.is_equal(self.cell_pmos_w, mem.cell_pmos_w): return False - if not self.is_equal(self.cell_nmos_w, mem.cell_nmos_w): return False - if not self.is_equal(self.Vbitpre, mem.Vbitpre): return False + if not is_equal(self.b_w, mem.b_w): return False + if not is_equal(self.b_h, mem.b_h): return False + if not is_equal(self.cell_a_w, mem.cell_a_w): return False + if not is_equal(self.cell_pmos_w, mem.cell_pmos_w): return False + if not is_equal(self.cell_nmos_w, mem.cell_nmos_w): return False + if not is_equal(self.Vbitpre, mem.Vbitpre): return False return True - def is_equal(self, first, second): - if (first == 0) and (second == 0): - return True - if (second == 0) or (second != second): - return True - if (first != first) or (second != second): # both are NaNs - return True - if first == 0: - if abs(first - second) < (second * 0.000001): - return True - else: - if abs(first - second) < (first * 0.000001): - return True - return False - def scan_five_input_double(self, line, name, unit_name, flavor, print_flag): temp = [0] * 5 unit = '' pattern = re.compile(rf"{name}\s+(\S+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)") match = pattern.search(line) - print(f'{line}, {match}') if match: unit = match.group(1) @@ -2131,6 +2161,9 @@ def reset(self): self.core_tx_density = 0 self.long_channel_leakage_reduction = 0 + self.logic_scaling_co_eff = sympy_var['logic_scaling_co_eff'] + self.core_tx_density = sympy_var['core_tx_density'] + def assign(self, in_file): try: with open(in_file, "r") as fp: @@ -2234,70 +2267,37 @@ def __init__(self, is_tag_=False, pure_ram_=0, pure_cam_=0, Nspd_=1.0, Ndwl_=1, self.cell = Area() self.cam_cell = Area() self.is_valid = False - print("SETING UP DYNAMIC PARAM") self.init_parameters() def init_parameters(self): - if self.is_tag: - self.ram_cell_tech_type = g_ip.tag_arr_ram_cell_tech_type - else: - self.ram_cell_tech_type = g_ip.data_arr_ram_cell_tech_type - + self.ram_cell_tech_type = g_ip.tag_arr_ram_cell_tech_type if self.is_tag else g_ip.data_arr_ram_cell_tech_type self.is_dram = (self.ram_cell_tech_type == lp_dram or self.ram_cell_tech_type == comm_dram) self.fully_assoc = bool(g_ip.fully_assoc) capacity_per_die = g_ip.cache_sz / NUMBER_STACKED_DIE_LAYERS wire_local = g_tp.wire_local - - print("HELLO!") + if self.pure_cam: self.init_CAM() - print("init_CAM") return if self.fully_assoc: self.init_FA() - print("init_FA") return if not self.calc_subarr_rc(capacity_per_die): - print("init rc") return - - print("HELLO4!") if self.is_tag: self.cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_rd_ports + g_ip.num_wr_ports) self.cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_wr_ports + (g_ip.num_rd_ports - g_ip.num_se_rd_ports)) + wire_local.pitch * g_ip.num_se_rd_ports - print("cell_tag!") else: if self.is_dram: self.cell.h = g_tp.dram.b_h self.cell.w = g_tp.dram.b_w - print(f"is_dram {self.cell.h}") - print(f"is_dram {self.cell.w}") else: self.cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip.num_wr_ports + g_ip.num_rw_ports - 1 + g_ip.num_rd_ports) self.cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + (g_ip.num_rd_ports - g_ip.num_se_rd_ports) + g_ip.num_wr_ports) + g_tp.wire_local.pitch * g_ip.num_se_rd_ports - - print(f"g_tp.sram.b_h: {g_tp.sram.b_h}") - print(f"wire_local.pitch: {wire_local.pitch}") - print(f"g_ip.num_wr_ports: {g_ip.num_wr_ports}") - print(f"g_ip.num_rw_ports: {g_ip.num_rw_ports}") - print(f"g_ip.num_rd_ports: {g_ip.num_rd_ports}") - print() - - print(f"g_tp.sram.b_w: {g_tp.sram.b_w}") - print(f"wire_local.pitch: {wire_local.pitch}") - print(f"g_ip.num_rw_ports: {g_ip.num_rw_ports}") - print(f"g_ip.num_rd_ports: {g_ip.num_rd_ports}") - print(f"g_ip.num_se_rd_ports: {g_ip.num_se_rd_ports}") - print(f"g_ip.num_wr_ports: {g_ip.num_wr_ports}") - print() - - print(f"not is_dram {self.cell.h}") - print(f"not is_dram {self.cell.h}") - c_b_metal = self.cell.h * wire_local.C_per_um if self.is_dram: @@ -2324,13 +2324,13 @@ def init_parameters(self): C_bl = self.num_r_subarray * (Cbitrow_drain_cap + c_b_metal) self.dram_refresh_period = 0 - self.num_mats_h_dir = symbolic_convex_max(self.Ndwl // 2, 1) - self.num_mats_v_dir = symbolic_convex_max(self.Ndbl // 2, 1) + # RECENT CHANGE + self.num_mats_h_dir = max(self.Ndwl // 2, 1) + self.num_mats_v_dir = max(self.Ndbl // 2, 1) + self.num_mats = self.num_mats_h_dir * self.num_mats_v_dir - print(f'NUM_MATS {self.num_mats}') self.num_do_b_mat = symbolic_convex_max((self.num_subarrays / self.num_mats) * self.num_c_subarray / (self.deg_bl_muxing * self.Ndsam_lev_1 * self.Ndsam_lev_2), 1) - # TODO BREAK relational if not (self.fully_assoc or self.pure_cam) and self.num_do_b_mat < (self.num_subarrays / self.num_mats): return @@ -2347,10 +2347,6 @@ def init_parameters(self): else: self.num_do_b_subbank = g_ip.out_w deg_sa_mux_l1_non_assoc = self.Ndsam_lev_1 / g_ip.data_assoc - # TODO relational - simplify_deg_sa_mux_l1_non_assoc = sp.simplify(deg_sa_mux_l1_non_assoc) - if simplify_deg_sa_mux_l1_non_assoc.is_zero or simplify_deg_sa_mux_l1_non_assoc.is_negative: - return if deg_sa_mux_l1_non_assoc < 1: return else: @@ -2378,7 +2374,6 @@ def init_parameters(self): if (not self.is_tag) and (g_ip.is_main_mem) and (self.num_act_mats_hor_dir * self.num_do_b_mat * self.Ndsam_lev_1 * self.Ndsam_lev_2 < int(g_ip.out_w * g_ip.burst_len * g_ip.data_assoc)): return - #TODO BREAK relational if self.num_act_mats_hor_dir > self.num_mats_h_dir: return @@ -2393,11 +2388,11 @@ def init_parameters(self): self.num_di_b_subbank = self.num_di_b_mat * self.num_act_mats_hor_dir self.num_si_b_subbank = self.num_si_b_mat - num_addr_b_row_dec = sp.log(self.num_r_subarray, 2) + num_addr_b_row_dec = _log2(self.num_r_subarray) if self.fully_assoc or self.pure_cam: num_addr_b_row_dec += _log2(self.num_subarrays // self.num_mats) number_subbanks = self.num_mats // self.num_act_mats_hor_dir - self.number_subbanks_decode = sp.log(number_subbanks, 2) + self.number_subbanks_decode = _log2(number_subbanks) self.num_rw_ports = g_ip.num_rw_ports self.num_rd_ports = g_ip.num_rd_ports @@ -2405,20 +2400,14 @@ def init_parameters(self): self.num_se_rd_ports = g_ip.num_se_rd_ports self.num_search_ports = g_ip.num_search_ports - print("BruHHSKJnhd") - print(deg_sa_mux_l1_non_assoc) - - # TODO had to make int - deg_sa_mux_l1_non_assoc = deg_sa_mux_l1_non_assoc - if self.is_dram and self.is_main_mem: - self.number_addr_bits_mat = max(num_addr_b_row_dec, _log2(self.deg_bl_muxing) + _log2(deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2)) + self.number_addr_bits_mat = symbolic_convex_max(num_addr_b_row_dec, _log2(self.deg_bl_muxing) + _log2(deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2)) if g_ip.print_detail_debug: print(f"parameter.cc: number_addr_bits_mat = {num_addr_b_row_dec}") print(f"parameter.cc: num_addr_b_row_dec = {num_addr_b_row_dec}") print(f"parameter.cc: num_addr_b_mux_sel = {_log2(self.deg_bl_muxing) + _log2(deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2)}") else: - self.number_addr_bits_mat = num_addr_b_row_dec + _log2(self.deg_bl_muxing) + sp.log(deg_sa_mux_l1_non_assoc, 2) + _log2(self.Ndsam_lev_2) + self.number_addr_bits_mat = num_addr_b_row_dec + _log2(self.deg_bl_muxing) + _log2(deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2) if self.is_tag: self.num_di_b_bank_per_port = self.tagbits @@ -2443,23 +2432,17 @@ def init_CAM(self): return if g_ip.specific_tag: - self.tagbits = sp.ceiling(g_ip.tag_w / 8.0) * 8 + self.tagbits = math.ceil(g_ip.tag_w / 8.0) * 8 else: - self.tagbits = sp.ceiling((ADDRESS_BITS + EXTRA_TAG_BITS) / 8.0) * 8 + self.tagbits = math.ceil((ADDRESS_BITS + EXTRA_TAG_BITS) / 8.0) * 8 - self.tag_num_r_subarray = sp.ceiling(capacity_per_die / (g_ip.nbanks * self.tagbits / 8.0 * self.Ndbl)) + self.tag_num_r_subarray = math.ceil(capacity_per_die / (g_ip.nbanks * self.tagbits / 8.0 * self.Ndbl)) self.tag_num_c_subarray = self.tagbits - if self.tag_num_r_subarray == 0: - return - if self.tag_num_r_subarray > MAXSUBARRAYROWS: - return - if self.tag_num_c_subarray < MINSUBARRAYCOLS: - return - if self.tag_num_c_subarray > MAXSUBARRAYCOLS: + if self.tag_num_r_subarray == 0 or self.tag_num_r_subarray > MAXSUBARRAYROWS or self.tag_num_c_subarray < MINSUBARRAYCOLS or self.tag_num_c_subarray > MAXSUBARRAYCOLS: return - self.num_r_subarray = self.tag_num_r_subarray + self.num_r_subarray = self.tag_num_r_subarray self.num_subarrays = self.Ndwl * self.Ndbl self.cam_cell.h = g_tp.cam.b_h + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_rd_ports + g_ip.num_wr_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) + wire_local.pitch * g_ip.num_se_rd_ports @@ -2486,17 +2469,17 @@ def init_CAM(self): self.num_mats_h_dir = 1 self.num_mats_v_dir = 1 else: - self.num_mats_h_dir = sp.floor(sp.sqrt(self.Ndbl / 4.0)) + self.num_mats_h_dir = math.floor(sp.sqrt(self.Ndbl / 4.0)) self.num_mats_v_dir = int(self.Ndbl / 4.0 / self.num_mats_h_dir) self.num_mats = self.num_mats_h_dir * self.num_mats_v_dir - self.num_so_b_mat = sp.ceiling(_log2(self.num_r_subarray)) + sp.ceiling(_log2(self.num_subarrays)) + self.num_so_b_mat = math.ceil(_log2(self.num_r_subarray)) + math.ceil(_log2(self.num_subarrays)) self.num_do_b_mat = self.tagbits deg_sa_mux_l1_non_assoc = 1 - self.num_so_b_subbank = sp.ceiling(_log2(self.num_r_subarray)) + sp.ceiling(_log2(self.num_subarrays)) + self.num_so_b_subbank = math.ceil(_log2(self.num_r_subarray)) + math.ceil(_log2(self.num_subarrays)) self.num_do_b_subbank = self.tag_num_c_subarray self.deg_senseamp_muxing_non_associativity = deg_sa_mux_l1_non_assoc @@ -2529,7 +2512,7 @@ def init_CAM(self): self.num_di_b_bank_per_port = self.tagbits self.num_si_b_bank_per_port = self.tagbits self.num_do_b_bank_per_port = self.tagbits - self.num_so_b_bank_per_port = sp.ceiling(_log2(self.num_r_subarray)) + sp.ceiling(_log2(self.num_subarrays)) + self.num_so_b_bank_per_port = math.ceil(_log2(self.num_r_subarray)) + math.ceil(_log2(self.num_subarrays)) if not self.is_tag and g_ip.data_assoc > 1 and not g_ip.fast_access: self.number_way_select_signals_mat = g_ip.data_assoc @@ -2544,22 +2527,17 @@ def init_FA(self): assert NUMBER_STACKED_DIE_LAYERS == 1 capacity_per_die = g_ip.cache_sz - # TODO CHECK if self.Ndwl != 1 or self.Ndcm != 1 or self.Nspd < 1 or self.Nspd > 1 or self.Ndsam_lev_1 != 1 or self.Ndsam_lev_2 != 1 or self.Ndbl < 2: return - - print("Got past init_FA check") if g_ip.specific_tag: self.tagbits = g_ip.tag_w else: - print(f'blksz {g_ip.block_sz}') self.tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - _log2(g_ip.block_sz) self.tagbits = (((self.tagbits + 3) >> 2) << 2) - # TODO check ceiling self.tag_num_r_subarray = math.ceil(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * self.Ndbl)) - self.tag_num_c_subarray = sp.ceiling((self.tagbits * self.Nspd / self.Ndwl)) + self.tag_num_c_subarray = math.ceil((self.tagbits * self.Nspd / self.Ndwl)) if self.tag_num_r_subarray == 0: return @@ -2590,7 +2568,6 @@ def init_FA(self): self.cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip.num_wr_ports + g_ip.num_rw_ports - 1 + g_ip.num_rd_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) self.cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + (g_ip.num_rd_ports - g_ip.num_se_rd_ports) + g_ip.num_wr_ports) + g_tp.wire_local.pitch * g_ip.num_se_rd_ports + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) - c_b_metal = self.cell.h * wire_local.C_per_um c_b_metal = self.cam_cell.h * wire_local.C_per_um self.V_b_sense = symbolic_convex_max(0.05 * g_tp.sram_cell.Vdd, VBITSENSEMIN) self.deg_bl_muxing = 1 @@ -2608,7 +2585,7 @@ def init_FA(self): self.num_mats_h_dir = 1 self.num_mats_v_dir = 1 else: - self.num_mats_h_dir = sp.floor(sp.sqrt(self.Ndbl / 4.0)) + self.num_mats_h_dir = math.floor(sp.sqrt(self.Ndbl / 4.0)) self.num_mats_v_dir = int(self.Ndbl / 4.0 / self.num_mats_h_dir) self.num_mats = self.num_mats_h_dir * self.num_mats_v_dir @@ -2633,8 +2610,8 @@ def init_FA(self): self.num_di_b_subbank = self.num_di_b_mat * self.num_act_mats_hor_dir self.num_si_b_subbank = self.num_si_b_mat - num_addr_b_row_dec = sp.log(self.num_r_subarray, 2) - num_addr_b_row_dec += sp.log(self.num_subarrays / self.num_mats, 2) + num_addr_b_row_dec = _log2(self.num_r_subarray) + num_addr_b_row_dec += _log2(self.num_subarrays / self.num_mats) number_subbanks = self.num_mats / self.num_act_mats_hor_dir self.number_subbanks_decode = _log2(number_subbanks) @@ -2659,24 +2636,26 @@ def init_FA(self): self.is_valid = True + def ECC_adjustment(self): - self.num_do_b_mat += sp.ceiling(self.num_do_b_mat / num_bits_per_ecc_b_) - self.num_di_b_mat += sp.ceiling(self.num_di_b_mat / num_bits_per_ecc_b_) - self.num_di_b_subbank += sp.ceiling(self.num_di_b_subbank / num_bits_per_ecc_b_) - self.num_do_b_subbank += sp.ceiling(self.num_do_b_subbank / num_bits_per_ecc_b_) - self.num_di_b_bank_per_port += sp.ceiling(self.num_di_b_bank_per_port / num_bits_per_ecc_b_) - self.num_do_b_bank_per_port += sp.ceiling(self.num_do_b_bank_per_port / num_bits_per_ecc_b_) - - self.num_so_b_mat += sp.ceiling(self.num_so_b_mat / num_bits_per_ecc_b_) - self.num_si_b_mat += sp.ceiling(self.num_si_b_mat / num_bits_per_ecc_b_) - self.num_si_b_subbank += sp.ceiling(self.num_si_b_subbank / num_bits_per_ecc_b_) - self.num_so_b_subbank += sp.ceiling(self.num_so_b_subbank / num_bits_per_ecc_b_) - self.num_si_b_bank_per_port += sp.ceiling(self.num_si_b_bank_per_port / num_bits_per_ecc_b_) - self.num_so_b_bank_per_port += sp.ceiling(self.num_so_b_bank_per_port / num_bits_per_ecc_b_) + self.num_do_b_mat += int(math.ceil(self.num_do_b_mat / num_bits_per_ecc_b_)) + self.num_di_b_mat += int(math.ceil(self.num_di_b_mat / num_bits_per_ecc_b_)) + self.num_di_b_subbank += int(math.ceil(self.num_di_b_subbank / num_bits_per_ecc_b_)) + self.num_do_b_subbank += int(math.ceil(self.num_do_b_subbank / num_bits_per_ecc_b_)) + self.num_di_b_bank_per_port += int(math.ceil(self.num_di_b_bank_per_port / num_bits_per_ecc_b_)) + self.num_do_b_bank_per_port += int(math.ceil(self.num_do_b_bank_per_port / num_bits_per_ecc_b_)) + + self.num_so_b_mat += int(math.ceil(self.num_so_b_mat / num_bits_per_ecc_b_)) + self.num_si_b_mat += int(math.ceil(self.num_si_b_mat / num_bits_per_ecc_b_)) + self.num_si_b_subbank += int(math.ceil(self.num_si_b_subbank / num_bits_per_ecc_b_)) + self.num_so_b_subbank += int(math.ceil(self.num_so_b_subbank / num_bits_per_ecc_b_)) + self.num_si_b_bank_per_port += int(math.ceil(self.num_si_b_bank_per_port / num_bits_per_ecc_b_)) + self.num_so_b_bank_per_port += int(math.ceil(self.num_so_b_bank_per_port / num_bits_per_ecc_b_)) + def calc_subarr_rc(self, capacity_per_die): if self.Ndwl < 2 or self.Ndbl < 2: - print("Ndwl and Ndbl set less than 2 paramter.py") + print("Ndwl and Ndbl set less than 2 parameter.py") return False if self.is_dram and not self.is_tag and self.Ndcm > 1: @@ -2686,32 +2665,27 @@ def calc_subarr_rc(self, capacity_per_die): if g_ip.specific_tag: self.tagbits = g_ip.tag_w else: - self.tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - sp.log(capacity_per_die, 2) + _log2(g_ip.tag_assoc * 2 - 1) - - print(f'{g_ip.nbanks} {g_ip.block_sz} {g_ip.tag_assoc} {self.Ndbl} {self.Nspd}') - self.num_r_subarray = sp.ceiling(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * g_ip.tag_assoc * self.Ndbl * self.Nspd)) - self.num_c_subarray = sp.ceiling((self.tagbits * g_ip.tag_assoc * self.Nspd / self.Ndwl)) + self.tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - math.log2(capacity_per_die) + _log2(g_ip.tag_assoc * 2 - 1) + + self.num_r_subarray = math.ceil(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * g_ip.tag_assoc * self.Ndbl * self.Nspd)) + self.num_c_subarray = math.ceil((self.tagbits * g_ip.tag_assoc * self.Nspd / self.Ndwl)) else: - self.num_r_subarray = sp.ceiling(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * g_ip.data_assoc * self.Ndbl * self.Nspd)) - self.num_c_subarray = sp.ceiling((8 * g_ip.block_sz * g_ip.data_assoc * self.Nspd / self.Ndwl)) + self.num_r_subarray = math.ceil(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * g_ip.data_assoc * self.Ndbl * self.Nspd)) + self.num_c_subarray = math.ceil((8 * g_ip.block_sz * g_ip.data_assoc * self.Nspd / self.Ndwl)) if g_ip.is_3d_mem: capacity_per_die_double = float(g_ip.cache_sz) / g_ip.num_die_3d self.num_c_subarray = g_ip.page_sz_bits / self.Ndwl - # TODO check used to be 1 << - self.num_r_subarray = sp.Pow(2, sp.floor(_log2(float(g_ip.cache_sz) / g_ip.num_die_3d / self.num_c_subarray / g_ip.nbanks / self.Ndbl / self.Ndwl * 1024 * 1024 * 1024) + 0.5)) + self.num_r_subarray = 1 << int(math.floor(math.log2(float(g_ip.cache_sz) / g_ip.num_die_3d / self.num_c_subarray / g_ip.nbanks / self.Ndbl / self.Ndwl * 1024 * 1024 * 1024) + 0.5)) if g_ip.print_detail_debug: print(f"parameter.cc: capacity_per_die_double = {capacity_per_die_double} Gbit") print(f"parameter.cc: g_ip.nbanks * Ndbl * Ndwl = {g_ip.nbanks * self.Ndbl * self.Ndwl}") print(f"parameter.cc: num_r_subarray = {self.num_r_subarray}") print(f"parameter.cc: num_c_subarray = {self.num_c_subarray}") - print(self.num_r_subarray) - print(self.num_c_subarray) - # TODO RELATIONAL - # if self.num_r_subarray < MINSUBARRAYROWS or self.num_r_subarray == 0 or self.num_r_subarray > MAXSUBARRAYROWS: - # return False - # if self.num_c_subarray < MINSUBARRAYCOLS or self.num_c_subarray > MAXSUBARRAYCOLS: - # return False + if self.num_r_subarray < MINSUBARRAYROWS or self.num_r_subarray == 0 or self.num_r_subarray > MAXSUBARRAYROWS: + return False + if self.num_c_subarray < MINSUBARRAYCOLS or self.num_c_subarray > MAXSUBARRAYCOLS: + return False self.num_subarrays = self.Ndwl * self.Ndbl return True @@ -2832,7 +2806,7 @@ def scan_input_double_tsv_type(line, name, unit_name, proj_type, tsv_type, print - +### basic_circuit.py #### TO AVOID CIRCULAR DEPENDNCY UNI_LEAK_STACK_FACTOR = 0.43 @@ -2851,8 +2825,9 @@ def is_pow2(val): return (_log2(val) != _log2(val - 1)) def _log2(num): + num = int(num) if num == 0: - raise ValueError("log0?") + num = 1 log2 = 0 while num > 1: num >>= 1 @@ -2942,6 +2917,7 @@ def gate_C(width, wirelength, _is_dram=False, _is_sram=False, _is_wl_tr=False, _ dt = g_tp.sleep_tx # Sleep transistor else: dt = g_tp.peri_global + return (dt.C_g_ideal + dt.C_overlap + 3 * dt.C_fringe) * width + dt.l_phy * Cpolywire def gate_C_pass(width, wirelength, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): @@ -2963,41 +2939,38 @@ def drain_C_(width, nchannel, stack, next_arg_thresh_folding_width_or_height_cel c_junc_sidewall = dt.C_junc_sidewall c_fringe = 2 * dt.C_fringe c_overlap = 2 * dt.C_overlap - drain_C_metal_connecting_folded_tr = 0 if next_arg_thresh_folding_width_or_height_cell == 0: w_folded_tr = fold_dimension - # print(f"fold_dimension {w_folded_tr}") else: - # print("else fold_dimension") h_tr_region = fold_dimension - 2 * g_tp.HPOWERRAIL ratio_p_to_n = 2.0 / (2.0 + 1.0) if nchannel: w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) else: w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) - - # TODO RELATIONAL + num_folded_tr = sp.ceiling(width / w_folded_tr) - # print(f'num_folded_tr {num_folded_tr}') - # # print(width/w_folded_tr) - # w_folded_tr = sp.Piecewise( - # (width, num_folded_tr < 2), # Set w_folded_tr to width if num_folded_tr < 2 - # (w_folded_tr, True) # Keep w_folded_tr unchanged otherwise - # ) - if (not contains_any_symbol(num_folded_tr)) and num_folded_tr < 2: - w_folded_tr = width - # TODO VISIT + w_folded_tr = sp.Piecewise((width, num_folded_tr < 2), (w_folded_tr, True)) total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + (stack - 1) * g_tp.spacing_poly_to_poly - drain_h_for_sidewall = w_folded_tr + total_drain_w = sp.Piecewise( + (total_drain_w, num_folded_tr <= 1), + (total_drain_w + (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly), True) + ) + + drain_h_for_sidewall = sp.Piecewise((w_folded_tr, num_folded_tr <= 1), (0, num_folded_tr > 1)) + total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1) - if (not contains_any_symbol(num_folded_tr)) and num_folded_tr > 1: - total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly) - if num_folded_tr % 2 == 0: - drain_h_for_sidewall = 0 - total_drain_height_for_cap_wrt_gate *= num_folded_tr - drain_C_metal_connecting_folded_tr = g_tp.wire_local.C_per_um * total_drain_w + total_drain_height_for_cap_wrt_gate = sp.Piecewise( + (total_drain_height_for_cap_wrt_gate, num_folded_tr <= 1), + (total_drain_height_for_cap_wrt_gate * num_folded_tr, True) + ) + + drain_C_metal_connecting_folded_tr = sp.Piecewise( + (0, num_folded_tr <= 1), + (g_tp.wire_local.C_per_um * total_drain_w, True) + ) drain_C_area = c_junc_area * total_drain_w * w_folded_tr drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w) @@ -3005,6 +2978,8 @@ def drain_C_(width, nchannel, stack, next_arg_thresh_folding_width_or_height_cel return drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr + + def tr_R_on(width, nchannel, stack, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): if _is_dram and _is_sram: dt = g_tp.dram_acc # DRAM cell access transistor @@ -3018,9 +2993,6 @@ def tr_R_on(width, nchannel, stack, _is_dram=False, _is_sram=False, _is_wl_tr=Fa dt = g_tp.peri_global restrans = dt.R_nch_on if nchannel else dt.R_pch_on - # print("tr_R_on") - # print(stack, restrans, width) - # print("end tr_R_on") return stack * restrans / width def R_to_w(res, nchannel, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): @@ -3047,19 +3019,8 @@ def pmos_to_nmos_sz_ratio(_is_dram=False, _is_wl_tr=False, _is_sleep_tx=False): return g_tp.peri_global.n_to_p_eff_curr_drv_ratio def horowitz(inputramptime, tf, vs1, vs2, rise): - #print(tf) if inputramptime == 0 and vs1 == vs2: - # #TODO important relational cannot handle - # print("HERE????") - # print(vs1) - # print(-sp.log(vs1)) - # print(f"tf: {tf}") - # print(f"tf result: {tf * (-sp.log(vs1) if vs1 < 1 else sp.log(vs1))}") - # print("ENDHEREE") - # TODO RELATIONAL - return sp.Piecewise((-sp.log(vs1), vs1 < 1), (sp.log(vs1), vs1 >= 1)) - # print("here???") - # return tf * -sp.log(vs1) + return tf * sp.Piecewise((-sp.log(vs1), vs1 < 1), (sp.log(vs1), vs1 >= 1)) a = inputramptime / tf if rise == RISE: @@ -3070,6 +3031,7 @@ def horowitz(inputramptime, tf, vs1, vs2, rise): td = tf * sp.sqrt(sp.log(1.0 - vs1) ** 2 + 2 * a * b * vs1) + tf * (sp.log(1.0 - vs1) - sp.log(1.0 - vs2)) return td + def cmos_Ileak(nWidth, pWidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): if not _is_dram and _is_cell: dt = g_tp.sram_cell # SRAM cell access transistor @@ -3159,9 +3121,7 @@ def cmos_Isub_leakage(nWidth, pWidth, fanin, g_type, _is_dram=False, _is_cell=Fa nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) Isub = 0 - #TODO Check - #num_states = int(sp.Pow(2.0, fanin)) - num_states = sp.Pow(2.0, fanin) + num_states = int(sp.Pow(2.0, fanin)) if g_type == nmos: if fanin == 1: @@ -3219,9 +3179,7 @@ def cmos_Ig_leakage(nWidth, pWidth, fanin, g_type, _is_dram=False, _is_cell=Fals pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) Ig_on = 0 - #TODO Check - #num_states = int(sp.Pow(2.0, fanin)) - num_states = sp.Pow(2.0, fanin) + num_states = int(sp.Pow(2.0, fanin)) if g_type == nmos: if fanin == 1: diff --git a/cacti-main/cacti_python/parameter_org.py b/cacti-main/cacti_python/parameter_org.py deleted file mode 100644 index fb7d48b..0000000 --- a/cacti-main/cacti_python/parameter_org.py +++ /dev/null @@ -1,2386 +0,0 @@ -import math -import re -from const import * -from cacti_interface import InputParameter -import sympy as sp - -sympy_var = { - 'C_g_ideal': sp.symbols('C_g_ideal'), - 'C_fringe': sp.symbols('C_fringe'), - 'C_junc': sp.symbols('C_junc'), - 'C_junc_sw': sp.symbols('C_junc_sw'), - 'l_phy': sp.symbols('l_phy'), - 'l_elec': sp.symbols('l_elec'), - 'nmos_effective_resistance_multiplier': sp.symbols('nmos_effective_resistance_multiplier'), - 'Vdd': sp.symbols('Vdd'), - 'Vth': sp.symbols('Vth'), - 'Vdsat': sp.symbols('Vdsat'), - 'I_on_n': sp.symbols('I_on_n'), - 'I_on_p': sp.symbols('I_on_p'), - 'I_off_n': sp.symbols('I_off_n'), - 'I_g_on_n': sp.symbols('I_g_on_n'), - 'C_ox': sp.symbols('C_ox'), - 't_ox': sp.symbols('t_ox'), - 'n2p_drv_rt': sp.symbols('n2p_drv_rt'), - 'lch_lk_rdc': sp.symbols('lch_lk_rdc'), - 'Mobility_n': sp.symbols('Mobility_n'), - 'gmp_to_gmn_multiplier': sp.symbols('gmp_to_gmn_multiplier'), - 'vpp': sp.symbols('vpp'), - 'Wmemcella': sp.symbols('Wmemcella'), - 'Wmemcellpmos': sp.symbols('Wmemcellpmos'), - 'Wmemcellnmos': sp.symbols('Wmemcellnmos'), - 'area_cell': sp.symbols('area_cell'), - 'asp_ratio_cell': sp.symbols('asp_ratio_cell'), - 'vdd_cell': sp.symbols('vdd_cell'), - 'dram_cell_I_on': sp.symbols('dram_cell_I_on'), - 'dram_cell_Vdd': sp.symbols('dram_cell_Vdd'), - 'dram_cell_C': sp.symbols('dram_cell_C'), - 'dram_cell_I_off_worst_case_len_temp': sp.symbols('dram_cell_I_off_worst_case_len_temp'), - 'logic_scaling_co_eff': sp.symbols('logic_scaling_co_eff'), - 'core_tx_density': sp.symbols('core_tx_density'), - 'sckt_co_eff': sp.symbols('sckt_co_eff'), - 'chip_layout_overhead': sp.symbols('chip_layout_overhead'), - 'macro_layout_overhead': sp.symbols('macro_layout_overhead'), - 'sense_delay': sp.symbols('sense_delay'), - 'sense_dy_power': sp.symbols('sense_dy_power'), - 'wire_pitch': sp.symbols('wire_pitch'), - 'barrier_thickness': sp.symbols('barrier_thickness'), - 'dishing_thickness': sp.symbols('dishing_thickness'), - 'alpha_scatter': sp.symbols('alpha_scatter'), - 'aspect_ratio': sp.symbols('aspect_ratio'), - 'miller_value': sp.symbols('miller_value'), - 'horiz_dielectric_constant': sp.symbols('horiz_dielectric_constant'), - 'vert_dielectric_constant': sp.symbols('vert_dielectric_constant'), - 'ild_thickness': sp.symbols('ild_thickness'), - 'fringe_cap': sp.symbols('fringe_cap'), - 'resistivity': sp.symbols('resistivity'), - 'wire_r_per_micron': sp.symbols('wire_r_per_micron'), - 'wire_c_per_micron': sp.symbols('wire_c_per_micron'), - 'tsv_pitch': sp.symbols('tsv_pitch'), - 'tsv_diameter': sp.symbols('tsv_diameter'), - 'tsv_length': sp.symbols('tsv_length'), - 'tsv_dielec_thickness': sp.symbols('tsv_dielec_thickness'), - 'tsv_contact_resistance': sp.symbols('tsv_contact_resistance'), - 'tsv_depletion_width': sp.symbols('tsv_depletion_width'), - 'tsv_liner_dielectric_cons': sp.symbols('tsv_liner_dielectric_cons') -} - -class TechnologyParameter: - def __init__(self): - self.reset() - - def reset(self): - self.ram_wl_stitching_overhead_ = 0 - self.min_w_nmos_ = 0 - self.max_w_nmos_ = 0 - self.max_w_nmos_dec = 0 - self.unit_len_wire_del = 0 - self.FO4 = 0 - self.kinv = 0 - self.vpp = 0 - self.w_sense_en = 0 - self.w_sense_n = 0 - self.w_sense_p = 0 - self.sense_delay = 0 - self.sense_dy_power = 0 - self.w_iso = 0 - self.w_poly_contact = 0 - self.spacing_poly_to_poly = 0 - self.spacing_poly_to_contact = 0 - self.tsv_pitch = 0 - self.tsv_diameter = 0 - self.tsv_length = 0 - self.tsv_dielec_thickness = 0 - self.tsv_contact_resistance = 0 - self.tsv_depletion_width = 0 - self.tsv_liner_dielectric_constant = 0 - self.tsv_parasitic_capacitance_fine = 0 - self.tsv_parasitic_resistance_fine = 0 - self.tsv_minimum_area_fine = 0 - self.tsv_parasitic_capacitance_coarse = 0 - self.tsv_parasitic_resistance_coarse = 0 - self.tsv_minimum_area_coarse = 0 - self.w_comp_inv_p1 = 0 - self.w_comp_inv_p2 = 0 - self.w_comp_inv_p3 = 0 - self.w_comp_inv_n1 = 0 - self.w_comp_inv_n2 = 0 - self.w_comp_inv_n3 = 0 - self.w_eval_inv_p = 0 - self.w_eval_inv_n = 0 - self.w_comp_n = 0 - self.w_comp_p = 0 - self.dram_cell_I_on = 0 - self.dram_cell_Vdd = 0 - self.dram_cell_I_off_worst_case_len_temp = 0 - self.dram_cell_C = 0 - self.gm_sense_amp_latch = 0 - self.w_nmos_b_mux = 0 - self.w_nmos_sa_mux = 0 - self.w_pmos_bl_precharge = 0 - self.w_pmos_bl_eq = 0 - self.MIN_GAP_BET_P_AND_N_DIFFS = 0 - self.MIN_GAP_BET_SAME_TYPE_DIFFS = 0 - self.HPOWERRAIL = 0 - self.cell_h_def = 0 - self.chip_layout_overhead = 0 - self.macro_layout_overhead = 0 - self.sckt_co_eff = 0 - self.fringe_cap = 0 - self.h_dec = 0 - self.sram_cell = DeviceType() - self.dram_acc = DeviceType() - self.dram_wl = DeviceType() - self.peri_global = DeviceType() - self.cam_cell = DeviceType() - self.sleep_tx = DeviceType() - self.wire_local = InterconnectType() - self.wire_inside_mat = InterconnectType() - self.wire_outside_mat = InterconnectType() - self.scaling_factor = ScalingFactor() - self.sram = MemoryType() - self.dram = MemoryType() - self.cam = MemoryType() - - def init_symbolic(): - return - - def find_upper_and_lower_tech(self, technology, tech_lo, in_file_lo, tech_hi, in_file_hi): - print(technology) - if 179 < technology < 181: - tech_lo = 180 - in_file_lo = "tech_params/180nm.dat" - tech_hi = 180 - in_file_hi = "tech_params/180nm.dat" - elif 89 < technology < 91: - tech_lo = 90 - in_file_lo = "tech_params/90nm.dat" - tech_hi = 90 - in_file_hi = "tech_params/90nm.dat" - elif 64 < technology < 66: - tech_lo = 65 - in_file_lo = "tech_params/65nm.dat" - tech_hi = 65 - in_file_hi = "tech_params/65nm.dat" - elif 44 < technology < 46: - tech_lo = 45 - in_file_lo = "tech_params/45nm.dat" - tech_hi = 45 - in_file_hi = "tech_params/45nm.dat" - elif 31 < technology < 33: - tech_lo = 32 - in_file_lo = "tech_params/32nm.dat" - tech_hi = 32 - in_file_hi = "tech_params/32nm.dat" - elif 21 < technology < 23: - tech_lo = 22 - in_file_lo = "tech_params/22nm.dat" - tech_hi = 22 - in_file_hi = "tech_params/22nm.dat" - elif 90 < technology < 180: - tech_lo = 180 - in_file_lo = "tech_params/180nm.dat" - tech_hi = 90 - in_file_hi = "tech_params/90nm.dat" - elif 65 < technology < 90: - tech_lo = 90 - in_file_lo = "tech_params/90nm.dat" - tech_hi = 65 - in_file_hi = "tech_params/65nm.dat" - elif 45 < technology < 65: - tech_lo = 65 - in_file_lo = "tech_params/65nm.dat" - tech_hi = 45 - in_file_hi = "tech_params/45nm.dat" - elif 32 < technology < 45: - tech_lo = 45 - in_file_lo = "tech_params/45nm.dat" - tech_hi = 32 - in_file_hi = "tech_params/32nm.dat" - elif 22 < technology < 32: - tech_lo = 32 - in_file_lo = "tech_params/32nm.dat" - tech_hi = 22 - in_file_hi = "tech_params/22nm.dat" - else: - print("Invalid technology nodes") - exit(0) - - return tech_lo, in_file_lo, tech_hi, in_file_hi - - def assign_tsv(self, in_file): - for iter in range(2): # 0:fine 1:coarse - tsv_type = g_ip.tsv_is_subarray_type if iter == 0 else g_ip.tsv_os_bank_type - with open(in_file, "r") as fp: - lines = fp.readlines() - - self.tsv_pitch = sympy_var['tsv_pitch'] - self.tsv_diameter = sympy_var['tsv_diameter'] - self.tsv_length = sympy_var['tsv_length'] - self.tsv_dielec_thickness = sympy_var['tsv_dielec_thickness'] - self.tsv_contact_resistance = sympy_var['tsv_contact_resistance'] - self.tsv_depletion_width = sympy_var['tsv_depletion_width'] - self.tsv_liner_dielectric_constant = sympy_var['tsv_liner_dielectric_cons'] - - # for line in lines: - # if line.startswith("-tsv_pitch"): - # self.tsv_pitch = scan_input_double_tsv_type(line, "-tsv_pitch", "F/um", g_ip.ic_proj_type, tsv_type, g_ip.print_detail_debug) - # elif line.startswith("-tsv_diameter"): - # self.tsv_diameter = scan_input_double_tsv_type(line, "-tsv_diameter", "F/um", g_ip.ic_proj_type, tsv_type, g_ip.print_detail_debug) - # elif line.startswith("-tsv_length"): - # self.tsv_length = scan_input_double_tsv_type(line, "-tsv_length", "F/um", g_ip.ic_proj_type, tsv_type, g_ip.print_detail_debug) - # elif line.startswith("-tsv_dielec_thickness"): - # self.tsv_dielec_thickness = scan_input_double_tsv_type(line, "-tsv_dielec_thickness", "F/um", g_ip.ic_proj_type, tsv_type, g_ip.print_detail_debug) - # elif line.startswith("-tsv_contact_resistance"): - # self.tsv_contact_resistance = scan_input_double_tsv_type(line, "-tsv_contact_resistance", "F/um", g_ip.ic_proj_type, tsv_type, g_ip.print_detail_debug) - # elif line.startswith("-tsv_depletion_width"): - # self.tsv_depletion_width = scan_input_double_tsv_type(line, "-tsv_depletion_width", "F/um", g_ip.ic_proj_type, tsv_type, g_ip.print_detail_debug) - # elif line.startswith("-tsv_liner_dielectric_cons"): - # self.tsv_liner_dielectric_constant = scan_input_double_tsv_type(line, "-tsv_liner_dielectric_cons", "F/um", g_ip.ic_proj_type, tsv_type, g_ip.print_detail_debug) - - self.tsv_length *= g_ip.num_die_3d - if iter == 0: - self.tsv_parasitic_resistance_fine = tsv_resistance(BULK_CU_RESISTIVITY, self.tsv_length, self.tsv_diameter, self.tsv_contact_resistance) - self.tsv_parasitic_capacitance_fine = tsv_capacitance(self.tsv_length, self.tsv_diameter, self.tsv_pitch, self.tsv_dielec_thickness, self.tsv_liner_dielectric_constant, self.tsv_depletion_width) - self.tsv_minimum_area_fine = tsv_area(self.tsv_pitch) - else: - self.tsv_parasitic_resistance_coarse = tsv_resistance(BULK_CU_RESISTIVITY, self.tsv_length, self.tsv_diameter, self.tsv_contact_resistance) - self.tsv_parasitic_capacitance_coarse = tsv_capacitance(self.tsv_length, self.tsv_diameter, self.tsv_pitch, self.tsv_dielec_thickness, self.tsv_liner_dielectric_constant, self.tsv_depletion_width) - self.tsv_minimum_area_coarse = tsv_area(self.tsv_pitch) - - def init(self, technology, is_tag): - self.reset() - ram_cell_tech_type = g_ip.tag_arr_ram_cell_tech_type if is_tag else g_ip.data_arr_ram_cell_tech_type - peri_global_tech_type = g_ip.tag_arr_peri_global_tech_type if is_tag else g_ip.data_arr_peri_global_tech_type - tech_lo, tech_hi = 0, 0 - in_file_lo, in_file_hi = "", "" - - technology *= 1000.0 # in the unit of nm - - tech_lo, in_file_lo, tech_hi, in_file_hi = self.find_upper_and_lower_tech(technology, tech_lo, in_file_lo, tech_hi, in_file_hi) - - if (tech_lo == 22) and (tech_hi == 22): - if ram_cell_tech_type == 3: - print("current version does not support eDRAM technologies at 22nm") - exit(0) - - alpha = 1 if tech_lo == tech_hi else (technology - tech_hi) / (tech_lo - tech_hi) - print(in_file_lo) - with open(in_file_lo, "r") as fp: - lines = fp.readlines() - - self.dram_cell_I_on = 0 - self.dram_cell_Vdd = 0 - self.dram_cell_C = 0 - self.dram_cell_I_off_worst_case_len_temp = 0 - self.vpp = 0 - self.macro_layout_overhead = 0 - self.chip_layout_overhead = 0 - self.sckt_co_eff = 0 - - self.dram_cell_I_on = sympy_var['dram_cell_I_on'] - self.dram_cell_Vdd = sympy_var['dram_cell_Vdd'] - self.dram_cell_C = sympy_var['dram_cell_C'] - self.dram_cell_I_off_worst_case_len_temp = sympy_var['dram_cell_I_off_worst_case_len_temp'] - self.vpp = sympy_var['vpp'] - self.sckt_co_eff = sympy_var['sckt_co_eff'] - self.chip_layout_overhead = sympy_var['chip_layout_overhead'] - self.macro_layout_overhead = sympy_var['macro_layout_overhead'] - - # for line in lines: - # if line.startswith("-dram_cell_I_on"): - # self.dram_cell_I_on += alpha * scan_five_input_double(line, "-dram_cell_I_on", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-dram_cell_Vdd"): - # self.dram_cell_Vdd += alpha * scan_five_input_double(line, "-dram_cell_Vdd", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-dram_cell_C"): - # self.dram_cell_C += alpha * scan_five_input_double(line, "-dram_cell_C", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-dram_cell_I_off_worst_case_len_temp"): - # self.dram_cell_I_off_worst_case_len_temp += alpha * scan_five_input_double(line, "-dram_cell_I_off_worst_case_len_temp", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-vpp"): - # self.vpp += alpha * scan_five_input_double(line, "-vpp", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-sckt_co_eff"): - # self.sckt_co_eff += alpha * scan_single_input_double(line, "-sckt_co_eff", "F/um", g_ip.print_detail_debug) - # elif line.startswith("-chip_layout_overhead"): - # self.chip_layout_overhead += alpha * scan_single_input_double(line, "-chip_layout_overhead", "F/um", g_ip.print_detail_debug) - # elif line.startswith("-macro_layout_overhead"): - # self.macro_layout_overhead += alpha * scan_single_input_double(line, "-macro_layout_overhead", "F/um", g_ip.print_detail_debug) - - peri_global_lo = DeviceType() - peri_global_hi = DeviceType() - peri_global_lo.assign(in_file_lo, peri_global_tech_type, g_ip.temp) - print("peri lo") - peri_global_lo.display() - print() - peri_global_hi.assign(in_file_hi, peri_global_tech_type, g_ip.temp) - print("peri hi") - peri_global_hi.display() - print() - - self.peri_global.interpolate(alpha, peri_global_lo, peri_global_hi) - print("peri_global") - self.peri_global.display() - print() - - sleep_tx_lo = DeviceType() - sleep_tx_hi = DeviceType() - sleep_tx_lo.assign(in_file_lo, 1, g_ip.temp) - sleep_tx_hi.assign(in_file_hi, 1, g_ip.temp) - self.sleep_tx.interpolate(alpha, sleep_tx_lo, sleep_tx_hi) - - sram_cell_lo = DeviceType() - sram_cell_hi = DeviceType() - sram_cell_lo.assign(in_file_lo, ram_cell_tech_type, g_ip.temp) - sram_cell_hi.assign(in_file_hi, ram_cell_tech_type, g_ip.temp) - self.sram_cell.interpolate(alpha, sram_cell_lo, sram_cell_hi) - - dram_acc_lo = DeviceType() - dram_acc_hi = DeviceType() - dram_acc_lo.assign(in_file_lo, ram_cell_tech_type if ram_cell_tech_type == comm_dram else dram_cell_tech_flavor, g_ip.temp) - dram_acc_hi.assign(in_file_hi, ram_cell_tech_type if ram_cell_tech_type == comm_dram else dram_cell_tech_flavor, g_ip.temp) - self.dram_acc.interpolate(alpha, dram_acc_lo, dram_acc_hi) - if tech_lo <= 22: - pass - elif tech_lo <= 32: - self.dram_acc.Vth = 0.44129 if ram_cell_tech_type == lp_dram else 1.0 - elif tech_lo <= 45: - self.dram_acc.Vth = 0.44559 if ram_cell_tech_type == lp_dram else 1.0 - elif tech_lo <= 65: - self.dram_acc.Vth = 0.43806 if ram_cell_tech_type == lp_dram else 1.0 - elif tech_lo <= 90: - self.dram_acc.Vth = 0.4545 if ram_cell_tech_type == lp_dram else 1.0 - - self.dram_acc.Vdd = 0.0 - self.dram_acc.I_on_p = 0.0 - self.dram_acc.I_off_n = 0.0 - self.dram_acc.I_off_p = 0.0 - self.dram_acc.C_ox = 0.0 - self.dram_acc.t_ox = 0.0 - self.dram_acc.n_to_p_eff_curr_drv_ratio = 0.0 - - dram_wl_lo = DeviceType() - dram_wl_hi = DeviceType() - dram_wl_lo.assign(in_file_lo, ram_cell_tech_type if ram_cell_tech_type == comm_dram else dram_cell_tech_flavor, g_ip.temp) - dram_wl_hi.assign(in_file_hi, ram_cell_tech_type if ram_cell_tech_type == comm_dram else dram_cell_tech_flavor, g_ip.temp) - self.dram_wl.interpolate(alpha, dram_wl_lo, dram_wl_hi) - - self.dram_wl.Vdd = 0.0 - self.dram_wl.Vth = 0.0 - self.dram_wl.I_on_p = 0.0 - self.dram_wl.C_ox = 0.0 - self.dram_wl.t_ox = 0.0 - - if ram_cell_tech_type < 3: - self.dram_acc.reset() - self.dram_wl.reset() - - cam_cell_lo = DeviceType() - cam_cell_hi = DeviceType() - cam_cell_lo.assign(in_file_lo, ram_cell_tech_type, g_ip.temp) - cam_cell_hi.assign(in_file_hi, ram_cell_tech_type, g_ip.temp) - self.cam_cell.interpolate(alpha, cam_cell_lo, cam_cell_hi) - - dram_lo = MemoryType() - dram_hi = MemoryType() - dram_lo.assign(in_file_lo, ram_cell_tech_type, 2) # cell_type = dram(2) - dram_hi.assign(in_file_hi, ram_cell_tech_type, 2) - self.dram.interpolate(alpha, dram_lo, dram_hi) - - sram_lo = MemoryType() - sram_hi = MemoryType() - sram_lo.assign(in_file_lo, ram_cell_tech_type, 0) # cell_type = sram(0) - sram_hi.assign(in_file_hi, ram_cell_tech_type, 0) - self.sram.interpolate(alpha, sram_lo, sram_hi) - - cam_lo = MemoryType() - cam_hi = MemoryType() - cam_lo.assign(in_file_lo, ram_cell_tech_type, 1) # cell_type = sram(0) - cam_hi.assign(in_file_hi, ram_cell_tech_type, 1) - self.cam.interpolate(alpha, cam_lo, cam_hi) - - scaling_factor_lo = ScalingFactor() - scaling_factor_hi = ScalingFactor() - scaling_factor_lo.assign(in_file_lo) - scaling_factor_hi.assign(in_file_hi) - self.scaling_factor.interpolate(alpha, scaling_factor_lo, scaling_factor_hi) - - self.peri_global.Vcc_min += (alpha * peri_global_lo.Vdd + (1 - alpha) * peri_global_hi.Vdd) * 0.35 - self.sleep_tx.Vcc_min += alpha * sleep_tx_lo.Vdd + (1 - alpha) * sleep_tx_hi.Vdd - self.sram_cell.Vcc_min += (alpha * sram_cell_lo.Vdd + (1 - alpha) * sram_cell_hi.Vdd) * 0.65 - - with open(in_file_hi, "r") as fp: - lines = fp.readlines() - - self.sense_delay = sympy_var['sense_delay'] - self.sense_dy_power = sympy_var['sense_dy_power'] - self.sckt_co_eff = sympy_var['sckt_co_eff'] - self.chip_layout_overhead = sympy_var['chip_layout_overhead'] - self.macro_layout_overhead = sympy_var['macro_layout_overhead'] - self.dram_cell_I_on = sympy_var['dram_cell_I_on'] - self.dram_cell_Vdd = sympy_var['dram_cell_Vdd'] - self.dram_cell_C = sympy_var['dram_cell_C'] - self.dram_cell_I_off_worst_case_len_temp = sympy_var['dram_cell_I_off_worst_case_len_temp'] - self.vpp = sympy_var['vpp'] - - # for line in lines: - # if line.startswith("-sense_delay"): - # self.sense_delay = scan_single_input_double(line, "-sense_delay", "F/um", g_ip.print_detail_debug) - # elif line.startswith("-sense_dy_power"): - # self.sense_dy_power = scan_single_input_double(line, "-sense_dy_power", "F/um", g_ip.print_detail_debug) - # elif line.startswith("-sckt_co_eff"): - # self.sckt_co_eff += (1 - alpha) * scan_single_input_double(line, "-sckt_co_eff", "F/um", g_ip.print_detail_debug) - # elif line.startswith("-chip_layout_overhead"): - # self.chip_layout_overhead += (1 - alpha) * scan_single_input_double(line, "-chip_layout_overhead", "F/um", g_ip.print_detail_debug) - # elif line.startswith("-macro_layout_overhead"): - # self.macro_layout_overhead += (1 - alpha) * scan_single_input_double(line, "-macro_layout_overhead", "F/um", g_ip.print_detail_debug) - # elif line.startswith("-dram_cell_I_on"): - # self.dram_cell_I_on += (1 - alpha) * scan_five_input_double(line, "-dram_cell_I_on", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-dram_cell_Vdd"): - # self.dram_cell_Vdd += (1 - alpha) * scan_five_input_double(line, "-dram_cell_Vdd", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-dram_cell_C"): - # self.dram_cell_C += (1 - alpha) * scan_five_input_double(line, "-dram_cell_C", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-dram_cell_I_off_worst_case_len_temp"): - # self.dram_cell_I_off_worst_case_len_temp += (1 - alpha) * scan_five_input_double(line, "-dram_cell_I_off_worst_case_len_temp", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - # elif line.startswith("-vpp"): - # self.vpp += (1 - alpha) * scan_five_input_double(line, "-vpp", "F/um", ram_cell_tech_type, g_ip.print_detail_debug) - - self.w_comp_inv_p1 = 12.5 * g_ip.F_sz_um - self.w_comp_inv_n1 = 7.5 * g_ip.F_sz_um - self.w_comp_inv_p2 = 25 * g_ip.F_sz_um - self.w_comp_inv_n2 = 15 * g_ip.F_sz_um - self.w_comp_inv_p3 = 50 * g_ip.F_sz_um - self.w_comp_inv_n3 = 30 * g_ip.F_sz_um - self.w_eval_inv_p = 100 * g_ip.F_sz_um - self.w_eval_inv_n = 50 * g_ip.F_sz_um - self.w_comp_n = 12.5 * g_ip.F_sz_um - self.w_comp_p = 37.5 * g_ip.F_sz_um - self.MIN_GAP_BET_P_AND_N_DIFFS = 5 * g_ip.F_sz_um - self.MIN_GAP_BET_SAME_TYPE_DIFFS = 1.5 * g_ip.F_sz_um - self.HPOWERRAIL = 2 * g_ip.F_sz_um - self.cell_h_def = 50 * g_ip.F_sz_um - self.w_poly_contact = g_ip.F_sz_um - self.spacing_poly_to_contact = g_ip.F_sz_um - self.spacing_poly_to_poly = 1.5 * g_ip.F_sz_um - self.ram_wl_stitching_overhead_ = 7.5 * g_ip.F_sz_um - self.min_w_nmos_ = 3 * g_ip.F_sz_um / 2 - self.max_w_nmos_ = 100 * g_ip.F_sz_um - self.w_iso = 12.5 * g_ip.F_sz_um - self.w_sense_n = 3.75 * g_ip.F_sz_um - self.w_sense_p = 7.5 * g_ip.F_sz_um - self.w_sense_en = 5 * g_ip.F_sz_um - self.w_nmos_b_mux = 6 * self.min_w_nmos_ - self.w_nmos_sa_mux = 6 * self.min_w_nmos_ - self.w_pmos_bl_precharge = 6 * pmos_to_nmos_sz_ratio() * self.min_w_nmos_ - self.w_pmos_bl_eq = pmos_to_nmos_sz_ratio() * self.min_w_nmos_ - - if ram_cell_tech_type == comm_dram: - self.max_w_nmos_dec = 8 * g_ip.F_sz_um - self.h_dec = 8 # in the unit of memory cell height - else: - self.max_w_nmos_dec = self.max_w_nmos_ - self.h_dec = 4 # in the unit of memory cell height - - #TODO CHECK 388 for 180nm - print(self.peri_global.l_elec) - gmn_sense_amp_latch = (self.peri_global.Mobility_n / 2) * self.peri_global.C_ox * (self.w_sense_n / self.peri_global.l_elec) * self.peri_global.Vdsat - gmp_sense_amp_latch = self.peri_global.gmp_to_gmn_multiplier * gmn_sense_amp_latch - self.gm_sense_amp_latch = gmn_sense_amp_latch + gmp_sense_amp_latch - - wire_local_lo = InterconnectType() - wire_local_hi = InterconnectType() - wire_local_lo.assign(in_file_lo, g_ip.ic_proj_type, 3 if ram_cell_tech_type == comm_dram else 0) - wire_local_hi.assign(in_file_hi, g_ip.ic_proj_type, 3 if ram_cell_tech_type == comm_dram else 0) - self.wire_local.interpolate(alpha, wire_local_lo, wire_local_hi) - - wire_inside_mat_lo = InterconnectType() - wire_inside_mat_hi = InterconnectType() - wire_inside_mat_lo.assign(in_file_lo, g_ip.ic_proj_type, g_ip.wire_is_mat_type) - wire_inside_mat_hi.assign(in_file_hi, g_ip.ic_proj_type, g_ip.wire_is_mat_type) - self.wire_inside_mat.interpolate(alpha, wire_inside_mat_lo, wire_inside_mat_hi) - - wire_outside_mat_lo = InterconnectType() - wire_outside_mat_hi = InterconnectType() - wire_outside_mat_lo.assign(in_file_lo, g_ip.ic_proj_type, g_ip.wire_os_mat_type) - wire_outside_mat_hi.assign(in_file_hi, g_ip.ic_proj_type, g_ip.wire_os_mat_type) - self.wire_outside_mat.interpolate(alpha, wire_outside_mat_lo, wire_outside_mat_hi) - - self.unit_len_wire_del = self.wire_inside_mat.R_per_um * self.wire_inside_mat.C_per_um / 2 - - self.assign_tsv(in_file_hi) - - self.fringe_cap = wire_local_hi.fringe_cap - - rd = tr_R_on(self.min_w_nmos_, NCH, 1) - p_to_n_sizing_r = pmos_to_nmos_sz_ratio() - c_load = gate_C(self.min_w_nmos_ * (1 + p_to_n_sizing_r), 0.0) - tf = rd * c_load - self.kinv = horowitz(0, tf, 0.5, 0.5, RISE) - KLOAD = 1 - c_load = KLOAD * (drain_C_(self.min_w_nmos_, NCH, 1, 1, self.cell_h_def) + - drain_C_(self.min_w_nmos_ * p_to_n_sizing_r, PCH, 1, 1, self.cell_h_def) + - gate_C(self.min_w_nmos_ * 4 * (1 + p_to_n_sizing_r), 0.0)) - tf = rd * c_load - self.FO4 = horowitz(0, tf, 0.5, 0.5, RISE) - - def isEqual(self, tech): - if not is_equal(self.ram_wl_stitching_overhead_, tech.ram_wl_stitching_overhead_): - assert False # fs - if not is_equal(self.min_w_nmos_, tech.min_w_nmos_): - assert False # fs - if not is_equal(self.max_w_nmos_, tech.max_w_nmos_): - assert False # fs - if not is_equal(self.max_w_nmos_dec, tech.max_w_nmos_dec): - assert False # fs + ram_cell_tech_type - if not is_equal(self.unit_len_wire_del, tech.unit_len_wire_del): - assert False # wire_inside_mat - if not is_equal(self.FO4, tech.FO4): - assert False # fs - if not is_equal(self.kinv, tech.kinv): - assert False # fs - if not is_equal(self.vpp, tech.vpp): - assert False # input - if not is_equal(self.w_sense_en, tech.w_sense_en): - assert False # fs - if not is_equal(self.w_sense_n, tech.w_sense_n): - assert False # fs - if not is_equal(self.w_sense_p, tech.w_sense_p): - assert False # fs - if not is_equal(self.sense_delay, tech.sense_delay): - PRINT("sense_delay", self.sense_delay, tech) - assert False # input - if not is_equal(self.sense_dy_power, tech.sense_dy_power): - assert False # input - if not is_equal(self.w_iso, tech.w_iso): - assert False # fs - if not is_equal(self.w_poly_contact, tech.w_poly_contact): - assert False # fs - if not is_equal(self.spacing_poly_to_poly, tech.spacing_poly_to_poly): - assert False # fs - if not is_equal(self.spacing_poly_to_contact, tech.spacing_poly_to_contact): - assert False # fs - - # CACTI3D auxiliary variables - # if not is_equal(self.tsv_pitch, tech.tsv_pitch): - # assert False - # if not is_equal(self.tsv_diameter, tech.tsv_diameter): - # assert False - # if not is_equal(self.tsv_length, tech.tsv_length): - # assert False - # if not is_equal(self.tsv_dielec_thickness, tech.tsv_dielec_thickness): - # assert False - # if not is_equal(self.tsv_contact_resistance, tech.tsv_contact_resistance): - # assert False - # if not is_equal(self.tsv_depletion_width, tech.tsv_depletion_width): - # assert False - # if not is_equal(self.tsv_liner_dielectric_constant, tech.tsv_liner_dielectric_constant): - # assert False - - # CACTI3DD TSV params - if not is_equal(self.tsv_parasitic_capacitance_fine, tech.tsv_parasitic_capacitance_fine): - PRINT("tsv_parasitic_capacitance_fine", self.tsv_parasitic_capacitance_fine, tech) - assert False - if not is_equal(self.tsv_parasitic_resistance_fine, tech.tsv_parasitic_resistance_fine): - assert False - if not is_equal(self.tsv_minimum_area_fine, tech.tsv_minimum_area_fine): - assert False - - if not is_equal(self.tsv_parasitic_capacitance_coarse, tech.tsv_parasitic_capacitance_coarse): - assert False - if not is_equal(self.tsv_parasitic_resistance_coarse, tech.tsv_parasitic_resistance_coarse): - assert False - if not is_equal(self.tsv_minimum_area_coarse, tech.tsv_minimum_area_coarse): - assert False - - # fs - if not is_equal(self.w_comp_inv_p1, tech.w_comp_inv_p1): - assert False - if not is_equal(self.w_comp_inv_p2, tech.w_comp_inv_p2): - assert False - if not is_equal(self.w_comp_inv_p3, tech.w_comp_inv_p3): - assert False - if not is_equal(self.w_comp_inv_n1, tech.w_comp_inv_n1): - assert False - if not is_equal(self.w_comp_inv_n2, tech.w_comp_inv_n2): - assert False - if not is_equal(self.w_comp_inv_n3, tech.w_comp_inv_n3): - assert False - if not is_equal(self.w_eval_inv_p, tech.w_eval_inv_p): - assert False - if not is_equal(self.w_eval_inv_n, tech.w_eval_inv_n): - assert False - if not is_equal(self.w_comp_n, tech.w_comp_n): - assert False - if not is_equal(self.w_comp_p, tech.w_comp_p): - assert False - - if not is_equal(self.dram_cell_I_on, tech.dram_cell_I_on): - assert False # ram_cell_tech_type - if not is_equal(self.dram_cell_Vdd, tech.dram_cell_Vdd): - assert False - if not is_equal(self.dram_cell_I_off_worst_case_len_temp, tech.dram_cell_I_off_worst_case_len_temp): - assert False - if not is_equal(self.dram_cell_C, tech.dram_cell_C): - assert False - if not is_equal(self.gm_sense_amp_latch, tech.gm_sense_amp_latch): - assert False # depends on many things - - if not is_equal(self.w_nmos_b_mux, tech.w_nmos_b_mux): - assert False # fs - if not is_equal(self.w_nmos_sa_mux, tech.w_nmos_sa_mux): - assert False # fs - if not is_equal(self.w_pmos_bl_precharge, tech.w_pmos_bl_precharge): - PRINT("w_pmos_bl_precharge", self.w_pmos_bl_precharge, tech) - assert False # fs - if not is_equal(self.w_pmos_bl_eq, tech.w_pmos_bl_eq): - assert False # fs - if not is_equal(self.MIN_GAP_BET_P_AND_N_DIFFS, tech.MIN_GAP_BET_P_AND_N_DIFFS): - assert False # fs - if not is_equal(self.MIN_GAP_BET_SAME_TYPE_DIFFS, tech.MIN_GAP_BET_SAME_TYPE_DIFFS): - assert False # fs - if not is_equal(self.HPOWERRAIL, tech.HPOWERRAIL): - assert False # fs - if not is_equal(self.cell_h_def, tech.cell_h_def): - assert False # fs - - if not is_equal(self.chip_layout_overhead, tech.chip_layout_overhead): - assert False # input - if not is_equal(self.macro_layout_overhead, tech.macro_layout_overhead): - print(f"{self.macro_layout_overhead} vs. {tech.macro_layout_overhead}") - assert False - if not is_equal(self.sckt_co_eff, tech.sckt_co_eff): - assert False - - if not is_equal(self.fringe_cap, tech.fringe_cap): - PRINT("fringe_cap", self.fringe_cap, tech) - assert False # input - - if self.h_dec != tech.h_dec: - assert False # ram_cell_tech_type - - print("sram_cell") - self.sram_cell.isEqual(tech.sram_cell) # SRAM cell transistor - print("dram_acc") - self.dram_acc.isEqual(tech.dram_acc) # DRAM access transistor - print("dram_wl") - self.dram_wl.isEqual(tech.dram_wl) # DRAM wordline transistor - print("peri_global") - self.peri_global.isEqual(tech.peri_global) # peripheral global - print("cam_cell") - self.cam_cell.isEqual(tech.cam_cell) # SRAM cell transistor - - print("sleep_tx") - self.sleep_tx.isEqual(tech.sleep_tx) # Sleep transistor cell transistor - - print("wire_local") - self.wire_local.isEqual(tech.wire_local) - print("wire_inside_mat") - self.wire_inside_mat.isEqual(tech.wire_inside_mat) - print("wire_outside_mat") - self.wire_outside_mat.isEqual(tech.wire_outside_mat) - - print("scaling_factor") - self.scaling_factor.isEqual(tech.scaling_factor) - print("sram:") - self.sram.isEqual(tech.sram) - print("dram:") - self.dram.isEqual(tech.dram) - print("cam:") - self.cam.isEqual(tech.cam) - - return True - -def is_equal(first, second): - if first == 0 and second == 0: - return True - - if second == 0 or sp.isnan(second): - return True - - if sp.isnan(first) or sp.isnan(second): - return True - - if first == 0: - if abs(first - second) < (second * 0.000001): - return True - else: - if abs(first - second) < (first * 0.000001): - return True - - return False - -class DeviceType: - def __init__(self): - self.C_g_ideal = 0 - self.C_fringe = 0 - self.C_overlap = 0 - self.C_junc = 0 # C_junc_area - self.C_junc_sidewall = 0 - self.l_phy = 0 - self.l_elec = 0 - self.R_nch_on = 0 - self.R_pch_on = 0 - self.Vdd = 0 - self.Vth = 0 - self.Vcc_min = 0 # allowed min vcc; for memory cell it is the lowest vcc for data retention. for logic it is the vcc to balance the leakage reduction and wakeup latency - self.I_on_n = 0 - self.I_on_p = 0 - self.I_off_n = 0 - self.I_off_p = 0 - self.I_g_on_n = 0 - self.I_g_on_p = 0 - self.C_ox = 0 - self.t_ox = 0 - self.n_to_p_eff_curr_drv_ratio = 0 - self.long_channel_leakage_reduction = 0 - self.Mobility_n = 0 - - # auxiliary parameters - self.Vdsat = 0 - self.gmp_to_gmn_multiplier = 0 - - def reset(self): - self.C_g_ideal = 0 - self.C_fringe = 0 - self.C_overlap = 0 - self.C_junc = 0 # C_junc_area - self.C_junc_sidewall = 0 - self.l_phy = 0 - self.l_elec = 0 - self.R_nch_on = 0 - self.R_pch_on = 0 - self.Vdd = 0 - self.Vth = 0 - self.Vcc_min = 0 # allowed min vcc; for memory cell it is the lowest vcc for data retention. for logic it is the vcc to balance the leakage reduction and wakeup latency - self.I_on_n = 0 - self.I_on_p = 0 - self.I_off_n = 0 - self.I_off_p = 0 - self.I_g_on_n = 0 - self.I_g_on_p = 0 - self.C_ox = 0 - self.t_ox = 0 - self.n_to_p_eff_curr_drv_ratio = 0 - self.long_channel_leakage_reduction = 0 - self.Mobility_n = 0 - - # auxiliary parameters - self.Vdsat = 0 - self.gmp_to_gmn_multiplier = 0 - - def display(self, indent=0): - indent_str = ' ' * indent - print(f"{indent_str}C_g_ideal = {self.C_g_ideal} F/um") - print(f"{indent_str}C_fringe = {self.C_fringe} F/um") - print(f"{indent_str}C_overlap = {self.C_overlap} F/um") - print(f"{indent_str}C_junc = {self.C_junc} F/um^2") - print(f"{indent_str}C_junc_sw = {self.C_junc_sidewall} F/um^2") - print(f"{indent_str}l_phy = {self.l_phy} um") - print(f"{indent_str}l_elec = {self.l_elec} um") - print(f"{indent_str}R_nch_on = {self.R_nch_on} ohm-um") - print(f"{indent_str}R_pch_on = {self.R_pch_on} ohm-um") - print(f"{indent_str}Vdd = {self.Vdd} V") - print(f"{indent_str}Vth = {self.Vth} V") - print(f"{indent_str}I_on_n = {self.I_on_n} A/um") - print(f"{indent_str}I_on_p = {self.I_on_p} A/um") - print(f"{indent_str}I_off_n = {self.I_off_n} A/um") - print(f"{indent_str}I_off_p = {self.I_off_p} A/um") - print(f"{indent_str}C_ox = {self.C_ox} F/um^2") - print(f"{indent_str}t_ox = {self.t_ox} um") - print(f"{indent_str}n_to_p_eff_curr_drv_ratio = {self.n_to_p_eff_curr_drv_ratio}") - - def isEqual(self, dev): - if not is_equal(self.C_g_ideal, dev.C_g_ideal): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.C_fringe, dev.C_fringe): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.C_overlap, dev.C_overlap): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.C_junc, dev.C_junc): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.C_junc_sidewall, dev.C_junc_sidewall): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.l_phy, dev.l_phy): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.l_elec, dev.l_elec): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.R_nch_on, dev.R_nch_on): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.R_pch_on, dev.R_pch_on): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.Vdd, dev.Vdd): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.Vth, dev.Vth): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.I_on_n, dev.I_on_n): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.I_on_p, dev.I_on_p): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.I_off_n, dev.I_off_n): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.I_off_p, dev.I_off_p): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.I_g_on_n, dev.I_g_on_n): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.I_g_on_p, dev.I_g_on_p): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.C_ox, dev.C_ox): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.t_ox, dev.t_ox): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.n_to_p_eff_curr_drv_ratio, dev.n_to_p_eff_curr_drv_ratio): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.long_channel_leakage_reduction, dev.long_channel_leakage_reduction): self.display(); print("\n\n\n"); dev.display(); assert False - if not is_equal(self.Mobility_n, dev.Mobility_n): self.display(); print("\n\n\n"); dev.display(); assert False - return True - - def assign(self, in_file, tech_flavor, temperature): - with open(in_file, 'r') as fp: - lines = fp.readlines() - - nmos_effective_resistance_multiplier = 0 - - self.C_g_ideal = sympy_var['C_g_ideal'] - self.C_fringe = sympy_var['C_fringe'] - self.C_junc_sidewall = sympy_var['C_junc_sw'] - self.C_junc = sympy_var['C_junc'] - self.l_phy = sympy_var['l_phy'] - self.l_elec = sympy_var['l_elec'] - self.nmos_effective_resistance_multiplier = sympy_var['nmos_effective_resistance_multiplier'] - self.Vdd = sympy_var['Vdd'] - self.Vth = sympy_var['Vth'] - self.Vdsat = sympy_var['Vdsat'] - self.I_on_n = sympy_var['I_on_n'] - self.I_on_p = sympy_var['I_on_p'] - self.I_off_n = sympy_var['I_off_n'] - self.I_g_on_n = sympy_var['I_g_on_n'] - self.C_ox = sympy_var['C_ox'] - self.t_ox = sympy_var['t_ox'] - self.n_to_p_eff_curr_drv_ratio = sympy_var['n2p_drv_rt'] - self.long_channel_leakage_reduction = sympy_var['lch_lk_rdc'] - self.Mobility_n = sympy_var['Mobility_n'] - self.gmp_to_gmn_multiplier = sympy_var['gmp_to_gmn_multiplier'] - - # for line in lines: - # if line.startswith("-C_g_ideal"): - # self.C_g_ideal = scan_five_input_double(line, "-C_g_ideal", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-C_fringe"): - # self.C_fringe = scan_five_input_double(line, "-C_fringe", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-C_junc_sw"): - # self.C_junc_sidewall = scan_five_input_double(line, "-C_junc_sw", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-C_junc"): - # self.C_junc = scan_five_input_double(line, "-C_junc", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-l_phy"): - # self.l_phy = scan_five_input_double(line, "-l_phy", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-l_elec"): - # print("HERE!") - # self.l_elec = scan_five_input_double(line, "-l_elec", "F/um", tech_flavor, g_ip.print_detail_debug) - # print(self.l_elec) - # print() - # continue - # if line.startswith("-nmos_effective_resistance_multiplier"): - # nmos_effective_resistance_multiplier = scan_five_input_double(line, "-nmos_effective_resistance_multiplier", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-Vdd"): - # self.Vdd = scan_five_input_double(line, "-Vdd", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-Vth"): - # self.Vth = scan_five_input_double(line, "-Vth", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-Vdsat"): - # self.Vdsat = scan_five_input_double(line, "-Vdsat", "V", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-I_on_n"): - # self.I_on_n = scan_five_input_double(line, "-I_on_n", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-I_on_p"): - # self.I_on_p = scan_five_input_double(line, "-I_on_p", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-I_off_n"): - # scan_five_input_double_temperature(line, "-I_off_n", "F/um", tech_flavor, temperature, g_ip.print_detail_debug, self.I_off_n) - # continue - # if line.startswith("-I_g_on_n"): - # scan_five_input_double_temperature(line, "-I_g_on_n", "F/um", tech_flavor, temperature, g_ip.print_detail_debug, self.I_g_on_n) - # continue - # if line.startswith("-C_ox"): - # self.C_ox = scan_five_input_double(line, "-C_ox", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-t_ox"): - # self.t_ox = scan_five_input_double(line, "-t_ox", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-n2p_drv_rt"): - # self.n_to_p_eff_curr_drv_ratio = scan_five_input_double(line, "-n2p_drv_rt", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-lch_lk_rdc"): - # self.long_channel_leakage_reduction = scan_five_input_double(line, "-lch_lk_rdc", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-Mobility_n"): - # self.Mobility_n = scan_five_input_double(line, "-Mobility_n", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-gmp_to_gmn_multiplier"): - # self.gmp_to_gmn_multiplier = scan_five_input_double(line, "-gmp_to_gmn_multiplier", "F/um", tech_flavor, g_ip.print_detail_debug) - # continue - - self.C_overlap = 0.2 * self.C_g_ideal - if tech_flavor >= 3: - if(self.I_on_n): - self.R_nch_on = nmos_effective_resistance_multiplier * g_tp.vpp / self.I_on_n - else: - if(self.I_on_n): - self.R_nch_on = nmos_effective_resistance_multiplier * self.Vdd / self.I_on_n - self.R_pch_on = self.n_to_p_eff_curr_drv_ratio * self.R_nch_on - self.I_off_p = self.I_off_n - self.I_g_on_p = self.I_g_on_n - if g_ip.print_detail_debug: - print(f"C_overlap: {self.C_overlap} F/um") - print(f"R_nch_on: {self.R_nch_on} ohm-micron") - print(f"R_pch_on: {self.R_pch_on} ohm-micron") - - def interpolate(self, alpha, dev1, dev2): - result = DeviceType() - self.C_g_ideal = alpha * dev1.C_g_ideal + (1 - alpha) * dev2.C_g_ideal - print(f'GLOBAL result {self.C_g_ideal}') - self.C_fringe = alpha * dev1.C_fringe + (1 - alpha) * dev2.C_fringe - self.C_overlap = alpha * dev1.C_overlap + (1 - alpha) * dev2.C_overlap - self.C_junc = alpha * dev1.C_junc + (1 - alpha) * dev2.C_junc - self.l_phy = alpha * dev1.l_phy + (1 - alpha) * dev2.l_phy - self.l_elec = alpha * dev1.l_elec + (1 - alpha) * dev2.l_elec - self.R_nch_on = alpha * dev1.R_nch_on + (1 - alpha) * dev2.R_nch_on - self.R_pch_on = alpha * dev1.R_pch_on + (1 - alpha) * dev2.R_pch_on - self.Vdd = alpha * dev1.Vdd + (1 - alpha) * dev2.Vdd - self.Vth = alpha * dev1.Vth + (1 - alpha) * dev2.Vth - self.Vcc_min = alpha * dev1.Vcc_min + (1 - alpha) * dev2.Vcc_min - self.I_on_n = alpha * dev1.I_on_n + (1 - alpha) * dev2.I_on_n - self.I_on_p = alpha * dev1.I_on_p + (1 - alpha) * dev2.I_on_p - self.I_off_n = alpha * dev1.I_off_n + (1 - alpha) * dev2.I_off_n - self.I_off_p = alpha * dev1.I_off_p + (1 - alpha) * dev2.I_off_p - self.I_g_on_n = alpha * dev1.I_g_on_n + (1 - alpha) * dev2.I_g_on_n - self.I_g_on_p = alpha * dev1.I_g_on_p + (1 - alpha) * dev2.I_g_on_p - self.C_ox = alpha * dev1.C_ox + (1 - alpha) * dev2.C_ox - self.t_ox = alpha * dev1.t_ox + (1 - alpha) * dev2.t_ox - self.n_to_p_eff_curr_drv_ratio = alpha * dev1.n_to_p_eff_curr_drv_ratio + (1 - alpha) * dev2.n_to_p_eff_curr_drv_ratio - self.long_channel_leakage_reduction = alpha * dev1.long_channel_leakage_reduction + (1 - alpha) * dev2.long_channel_leakage_reduction - self.Mobility_n = alpha * dev1.Mobility_n + (1 - alpha) * dev2.Mobility_n - self.Vdsat = alpha * dev1.Vdsat + (1 - alpha) * dev2.Vdsat - self.gmp_to_gmn_multiplier = alpha * dev1.gmp_to_gmn_multiplier + (1 - alpha) * dev2.gmp_to_gmn_multiplier - self.C_junc_sidewall = dev1.C_junc_sidewall - -class InterconnectType: - def __init__(self): - self.pitch = 0 - self.R_per_um = 0 - self.C_per_um = 0 - self.horiz_dielectric_constant = 0 - self.vert_dielectric_constant = 0 - self.aspect_ratio = 0 - self.miller_value = 0 - self.ild_thickness = 0 - - # auxiliary parameters - self.wire_width = 0 - self.wire_thickness = 0 - self.wire_spacing = 0 - self.barrier_thickness = 0 - self.dishing_thickness = 0 - self.alpha_scatter = 0 - self.fringe_cap = 0 - - self.reset() - - def reset(self): - self.pitch = 0 - self.R_per_um = 0 - self.C_per_um = 0 - self.horiz_dielectric_constant = 0 - self.vert_dielectric_constant = 0 - self.aspect_ratio = 0 - self.miller_value = 0 - self.ild_thickness = 0 - - # auxiliary parameters - self.wire_width = 0 - self.wire_thickness = 0 - self.wire_spacing = 0 - self.barrier_thickness = 0 - self.dishing_thickness = 0 - self.alpha_scatter = 0 - self.fringe_cap = 0 - - def is_equal(self, inter): - if not is_equal(self.pitch, inter.pitch): return False - if not is_equal(self.R_per_um, inter.R_per_um): return False - if not is_equal(self.C_per_um, inter.C_per_um): return False - if not is_equal(self.horiz_dielectric_constant, inter.horiz_dielectric_constant): return False - if not is_equal(self.vert_dielectric_constant, inter.vert_dielectric_constant): return False - if not is_equal(self.aspect_ratio, inter.aspect_ratio): return False - if not is_equal(self.miller_value, inter.miller_value): return False - if not is_equal(self.ild_thickness, inter.ild_thickness): return False - return True - - def display(self, indent=0): - indent_str = ' ' * indent - print(f"{indent_str}pitch = {self.pitch} um") - print(f"{indent_str}R_per_um = {self.R_per_um} ohm/um") - print(f"{indent_str}C_per_um = {self.C_per_um} F/um") - print(f"{indent_str}horiz_dielectric_constant = {self.horiz_dielectric_constant}") - print(f"{indent_str}vert_dielectric_constant = {self.vert_dielectric_constant}") - print(f"{indent_str}aspect_ratio = {self.aspect_ratio}") - print(f"{indent_str}miller_value = {self.miller_value}") - print(f"{indent_str}ild_thickness = {self.ild_thickness} um") - - def assign(self, in_file, projection_type, tech_flavor): - with open(in_file, 'r') as fp: - lines = fp.readlines() - - resistivity = 0 - print_debug = g_ip.print_detail_debug - - self.pitch = sympy_var['wire_pitch'] - self.barrier_thickness = sympy_var['barrier_thickness'] - self.dishing_thickness = sympy_var['dishing_thickness'] - self.alpha_scatter = sympy_var['alpha_scatter'] - self.aspect_ratio = sympy_var['aspect_ratio'] - self.miller_value = sympy_var['miller_value'] - self.horiz_dielectric_constant = sympy_var['horiz_dielectric_constant'] - self.vert_dielectric_constant = sympy_var['vert_dielectric_constant'] - self.ild_thickness = sympy_var['ild_thickness'] - self.fringe_cap = sympy_var['fringe_cap'] - self.R_per_um = sympy_var['wire_r_per_micron'] - self.C_per_um = sympy_var['wire_c_per_micron'] - self.resistivity = sympy_var['resistivity'] - - # for line in lines: - # if line.startswith("-wire_pitch"): - # self.pitch = scan_input_double_inter_type(line, "-wire_pitch", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-barrier_thickness"): - # self.barrier_thickness = scan_input_double_inter_type(line, "-barrier_thickness", "ohm", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-dishing_thickness"): - # self.dishing_thickness = scan_input_double_inter_type(line, "-dishing_thickness", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-alpha_scatter"): - # self.alpha_scatter = scan_input_double_inter_type(line, "-alpha_scatter", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-aspect_ratio"): - # self.aspect_ratio = scan_input_double_inter_type(line, "-aspect_ratio", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-miller_value"): - # self.miller_value = scan_input_double_inter_type(line, "-miller_value", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-horiz_dielectric_constant"): - # self.horiz_dielectric_constant = scan_input_double_inter_type(line, "-horiz_dielectric_constant", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-vert_dielectric_constant"): - # self.vert_dielectric_constant = scan_input_double_inter_type(line, "-vert_dielectric_constant", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-ild_thickness"): - # self.ild_thickness = scan_input_double_inter_type(line, "-ild_thickness", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-fringe_cap"): - # self.fringe_cap = scan_input_double_inter_type(line, "-fringe_cap", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-wire_r_per_micron"): - # self.R_per_um = scan_input_double_inter_type(line, "-wire_r_per_micron", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-wire_c_per_micron"): - # self.C_per_um = scan_input_double_inter_type(line, "-wire_c_per_micron", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - # if line.startswith("-resistivity"): - # resistivity = scan_input_double_inter_type(line, "-resistivity", "um", g_ip.ic_proj_type, tech_flavor, print_debug) - # continue - - self.pitch *= g_ip.F_sz_um - self.wire_width = self.pitch / 2 # micron - self.wire_thickness = self.aspect_ratio * self.wire_width # micron - self.wire_spacing = self.pitch - self.wire_width # micron - - if projection_type != 1 or tech_flavor != 3: - self.R_per_um = wire_resistance(resistivity, self.wire_width, - self.wire_thickness, self.barrier_thickness, self.dishing_thickness, self.alpha_scatter) # ohm/micron - if print_debug: - print(f"{self.R_per_um} = wire_resistance({resistivity}, {self.wire_width}, {self.wire_thickness}, {self.barrier_thickness}, {self.dishing_thickness}, {self.alpha_scatter})") - - self.C_per_um = wire_capacitance(self.wire_width, self.wire_thickness, self.wire_spacing, - self.ild_thickness, self.miller_value, self.horiz_dielectric_constant, - self.vert_dielectric_constant, self.fringe_cap) # F/micron - if print_debug: - print(f"{self.C_per_um} = wire_capacitance({self.wire_width}, {self.wire_thickness}, {self.wire_spacing}, {self.ild_thickness}, {self.miller_value}, {self.horiz_dielectric_constant}, {self.vert_dielectric_constant}, {self.fringe_cap})") - - def interpolate(self, alpha, inter1, inter2): - self.pitch = alpha * inter1.pitch + (1 - alpha) * inter2.pitch - self.R_per_um = alpha * inter1.R_per_um + (1 - alpha) * inter2.R_per_um - self.C_per_um = alpha * inter1.C_per_um + (1 - alpha) * inter2.C_per_um - self.horiz_dielectric_constant = alpha * inter1.horiz_dielectric_constant + (1 - alpha) * inter2.horiz_dielectric_constant - self.vert_dielectric_constant = alpha * inter1.vert_dielectric_constant + (1 - alpha) * inter2.vert_dielectric_constant - self.aspect_ratio = alpha * inter1.aspect_ratio + (1 - alpha) * inter2.aspect_ratio - self.miller_value = alpha * inter1.miller_value + (1 - alpha) * inter2.miller_value - self.ild_thickness = alpha * inter1.ild_thickness + (1 - alpha) * inter2.ild_thickness - -class MemoryType: - def __init__(self): - self.reset() - - def reset(self): - self.b_w = 0 - self.b_h = 0 - self.cell_a_w = 0 - self.cell_pmos_w = 0 - self.cell_nmos_w = 0 - self.Vbitpre = 0 - self.Vbitfloating = 0 - self.area_cell = 0 - self.asp_ratio_cell = 0 - - def assign(self, in_file, tech_flavor, cell_type): - try: - with open(in_file, "r") as fp: - lines = fp.readlines() - except FileNotFoundError: - print(f"{in_file} is missing!") - exit(-1) - - vdd_cell = 0 - vdd = 0 - - print(f'tech_flavor {tech_flavor}') - - vdd = sympy_var['Vdd'] - vdd_cell = sympy_var['vdd_cell'] - self.cell_a_w = sympy_var['Wmemcella'] - self.cell_pmos_w = sympy_var['Wmemcellpmos'] - self.cell_nmos_w = sympy_var['Wmemcellnmos'] - self.area_cell = sympy_var['area_cell'] - self.asp_ratio_cell = sympy_var['asp_ratio_cell'] - - # for line in lines: - # if line.startswith("-Vdd"): - # vdd = scan_five_input_double(line, "-Vdd", "V", tech_flavor, g_ip.print_detail_debug) - # continue - # if line.startswith("-vdd_cell"): - # scan_res = scan_five_input_double_mem_type(line, "-vdd_cell", "V", tech_flavor, cell_type, g_ip.print_detail_debug) - # vdd_cell = scan_res if scan_res != None else vdd_cell - # continue - # if line.startswith("-Wmemcella"): - # scan_res = scan_five_input_double_mem_type(line, "-Wmemcella", "V", tech_flavor, cell_type, g_ip.print_detail_debug) - # self.cell_a_w = scan_res if scan_res != None else self.cell_a_w - # continue - # if line.startswith("-Wmemcellpmos"): - # scan_res = scan_five_input_double_mem_type(line, "-Wmemcellpmos", "V", tech_flavor, cell_type, g_ip.print_detail_debug) - # self.cell_pmos_w = scan_res if scan_res != None else self.cell_pmos_w - # continue - # if line.startswith("-Wmemcellnmos"): - # scan_res = scan_five_input_double_mem_type(line, "-Wmemcellnmos", "V", tech_flavor, cell_type, g_ip.print_detail_debug) - # self.cell_nmos_w = scan_res if scan_res != None else self.cell_nmos_w - # continue - # if line.startswith("-area_cell"): - # scan_res = scan_five_input_double_mem_type(line, "-area_cell", "V", tech_flavor, cell_type, g_ip.print_detail_debug) - # self.area_cell = scan_res if scan_res != None else self.area_cell - # continue - # if line.startswith("-asp_ratio_cell"): - # scan_res = scan_five_input_double_mem_type(line, "-asp_ratio_cell", "V", tech_flavor, cell_type, g_ip.print_detail_debug) - # self.asp_ratio_cell = scan_res if scan_res != None else self.asp_ratio_cell - # continue - - # print(g_ip.F_sz_um) - # print(self.cell_pmos_w) - if cell_type != 2: - print(self.cell_a_w) - self.cell_a_w *= g_ip.F_sz_um - self.cell_pmos_w *= g_ip.F_sz_um - self.cell_nmos_w *= g_ip.F_sz_um - if cell_type != 2: - self.area_cell *= (g_ip.F_sz_um * g_ip.F_sz_um) - - #TODO 1028-1030 - self.b_w = sp.sqrt(self.area_cell / self.asp_ratio_cell) - self.b_h = self.asp_ratio_cell * self.b_w - if cell_type == 2: - self.Vbitpre = vdd_cell - else: - self.Vbitpre = vdd - - self.Vbitfloating = self.Vbitpre * 0.7 - - def interpolate(self, alpha, mem1, mem2): - self.cell_a_w = alpha * mem1.cell_a_w + (1 - alpha) * mem2.cell_a_w - self.cell_pmos_w = alpha * mem1.cell_pmos_w + (1 - alpha) * mem2.cell_pmos_w - self.cell_nmos_w = alpha * mem1.cell_nmos_w + (1 - alpha) * mem2.cell_nmos_w - self.area_cell = alpha * mem1.area_cell + (1 - alpha) * mem2.area_cell - self.asp_ratio_cell = alpha * mem1.asp_ratio_cell + (1 - alpha) * mem2.asp_ratio_cell - self.Vbitpre = mem2.Vbitpre - self.Vbitfloating = self.Vbitpre * 0.7 - - #TODO 1028-1030 - self.b_w = sp.sqrt(self.area_cell / self.asp_ratio_cell) - self.b_h = self.asp_ratio_cell * self.b_w - - def isEqual(self, mem): - if not self.is_equal(self.b_w, mem.b_w): return False - if not self.is_equal(self.b_h, mem.b_h): return False - if not self.is_equal(self.cell_a_w, mem.cell_a_w): return False - if not self.is_equal(self.cell_pmos_w, mem.cell_pmos_w): return False - if not self.is_equal(self.cell_nmos_w, mem.cell_nmos_w): return False - if not self.is_equal(self.Vbitpre, mem.Vbitpre): return False - return True - - def is_equal(self, first, second): - if (first == 0) and (second == 0): - return True - if (second == 0) or (second != second): - return True - if (first != first) or (second != second): # both are NaNs - return True - if first == 0: - if abs(first - second) < (second * 0.000001): - return True - else: - if abs(first - second) < (first * 0.000001): - return True - return False - - def scan_five_input_double(self, line, name, unit_name, flavor, print_flag): - temp = [0] * 5 - unit = '' - - pattern = re.compile(rf"{name}\s+(\S+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)") - match = pattern.search(line) - print(f'{line}, {match}') - - if match: - unit = match.group(1) - temp[0] = float(match.group(2)) - temp[1] = float(match.group(3)) - temp[2] = float(match.group(4)) - temp[3] = float(match.group(5)) - temp[4] = float(match.group(6)) - - if print_flag: - print(f"{name}[{flavor}]: {temp[flavor]} {unit}") - return temp[flavor] - return None - -class ScalingFactor: - def __init__(self): - self.reset() - - def reset(self): - self.logic_scaling_co_eff = 0 - self.core_tx_density = 0 - self.long_channel_leakage_reduction = 0 - - def assign(self, in_file): - try: - with open(in_file, "r") as fp: - lines = fp.readlines() - except FileNotFoundError: - print(f"{in_file} is missing!") - exit(-1) - - self.logic_scaling_co_eff = sympy_var['logic_scaling_co_eff'] - self.core_tx_density = sympy_var['core_tx_density'] - - # for line in lines: - # if line.startswith("-logic_scaling_co_eff"): - # self.logic_scaling_co_eff = scan_single_input_double(line, "-logic_scaling_co_eff", "F/um", g_ip.print_detail_debug) - # continue - # if line.startswith("-core_tx_density"): - # self.core_tx_density = scan_single_input_double(line, "-core_tx_density", "F/um", g_ip.print_detail_debug) - # continue - - def interpolate(self, alpha, dev1, dev2): - self.logic_scaling_co_eff = alpha * dev1.logic_scaling_co_eff + (1 - alpha) * dev2.logic_scaling_co_eff - self.core_tx_density = alpha * dev1.core_tx_density + (1 - alpha) * dev2.core_tx_density - - def isEqual(self, scal): - if not is_equal(self.logic_scaling_co_eff, scal.logic_scaling_co_eff): - self.display(0) - assert False - if not is_equal(self.core_tx_density, scal.core_tx_density): - self.display(0) - assert False - if not is_equal(self.long_channel_leakage_reduction, scal.long_channel_leakage_reduction): - self.display(0) - assert False - return True - - def display(self, indent=0): - indent_str = ' ' * indent - print(f"{indent_str}logic_scaling_co_eff = {self.logic_scaling_co_eff}") - print(f"{indent_str}core_tx_density = {self.core_tx_density}") - print(f"{indent_str}long_channel_leakage_reduction = {self.long_channel_leakage_reduction}") - -class Area: - h: float = 0.0 - w: float = 0.0 - -class DynamicParameter: - def __init__(self, is_tag_=False, pure_ram_=0, pure_cam_=0, Nspd_=1.0, Ndwl_=1, Ndbl_=1, Ndcm_=1, Ndsam_lev_1_=1, Ndsam_lev_2_=1, wt=None, is_main_mem_=False): - self.is_tag = is_tag_ - self.pure_ram = pure_ram_ - self.pure_cam = pure_cam_ - self.fully_assoc = False - self.tagbits = 0 - self.num_subarrays = 0 - self.num_mats = 0 - self.Nspd = Nspd_ - self.Ndwl = Ndwl_ - self.Ndbl = Ndbl_ - self.Ndcm = Ndcm_ - self.deg_bl_muxing = 0 - self.deg_senseamp_muxing_non_associativity = 0 - self.Ndsam_lev_1 = Ndsam_lev_1_ - self.Ndsam_lev_2 = Ndsam_lev_2_ - self.wtype = wt - self.number_addr_bits_mat = 0 - self.number_subbanks_decode = 0 - self.num_di_b_bank_per_port = 0 - self.num_do_b_bank_per_port = 0 - self.num_di_b_mat = 0 - self.num_do_b_mat = 0 - self.num_di_b_subbank = 0 - self.num_do_b_subbank = 0 - self.num_si_b_mat = 0 - self.num_so_b_mat = 0 - self.num_si_b_subbank = 0 - self.num_so_b_subbank = 0 - self.num_si_b_bank_per_port = 0 - self.num_so_b_bank_per_port = 0 - self.number_way_select_signals_mat = 0 - self.num_act_mats_hor_dir = 0 - self.num_act_mats_hor_dir_sl = 0 - self.is_dram = False - self.V_b_sense = 0.0 - self.num_r_subarray = 0 - self.num_c_subarray = 0 - self.tag_num_r_subarray = 0 - self.tag_num_c_subarray = 0 - self.data_num_r_subarray = 0 - self.data_num_c_subarray = 0 - self.num_mats_h_dir = 0 - self.num_mats_v_dir = 0 - self.ram_cell_tech_type = 0 - self.dram_refresh_period = 0.0 - self.use_inp_params = 0 - self.num_rw_ports = 0 - self.num_rd_ports = 0 - self.num_wr_ports = 0 - self.num_se_rd_ports = 0 - self.num_search_ports = 0 - self.out_w = 0 - self.is_main_mem = is_main_mem_ - self.cell = Area() - self.cam_cell = Area() - self.is_valid = False - self.init_parameters() - - def init_parameters(self): - if self.is_tag: - self.ram_cell_tech_type = g_ip.tag_arr_ram_cell_tech_type - else: - self.ram_cell_tech_type = g_ip.data_arr_ram_cell_tech_type - - self.is_dram = (self.ram_cell_tech_type == lp_dram or self.ram_cell_tech_type == comm_dram) - self.fully_assoc = bool(g_ip.fully_assoc) - capacity_per_die = g_ip.cache_sz / NUMBER_STACKED_DIE_LAYERS - wire_local = g_tp.wire_local - - if self.pure_cam: - self.init_CAM() - return - - if self.fully_assoc: - self.init_FA() - return - - if not self.calc_subarr_rc(capacity_per_die): - return - - if self.is_tag: - self.cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_rd_ports + g_ip.num_wr_ports) - self.cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_wr_ports + (g_ip.num_rd_ports - g_ip.num_se_rd_ports)) + wire_local.pitch * g_ip.num_se_rd_ports - else: - if self.is_dram: - self.cell.h = g_tp.dram.b_h - self.cell.w = g_tp.dram.b_w - else: - self.cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip.num_wr_ports + g_ip.num_rw_ports - 1 + g_ip.num_rd_ports) - self.cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + (g_ip.num_rd_ports - g_ip.num_se_rd_ports) + g_ip.num_wr_ports) + g_tp.wire_local.pitch * g_ip.num_se_rd_ports - - c_b_metal = self.cell.h * wire_local.C_per_um - - if self.is_dram: - self.deg_bl_muxing = 1 - if self.ram_cell_tech_type == comm_dram: - Cbitrow_drain_cap = drain_C_(g_tp.dram.cell_a_w, NCH, 1, 0, self.cell.w, True, True) / 2.0 - C_bl = self.num_r_subarray * (Cbitrow_drain_cap + c_b_metal) - self.V_b_sense = (g_tp.dram_cell_Vdd / 2) * g_tp.dram_cell_C / (g_tp.dram_cell_C + C_bl) - if self.V_b_sense < VBITSENSEMIN and not (g_ip.is_3d_mem and g_ip.force_cache_config): - return - self.dram_refresh_period = 64e-3 - else: - Cbitrow_drain_cap = drain_C_(g_tp.dram.cell_a_w, NCH, 1, 0, self.cell.w, True, True) / 2.0 - C_bl = self.num_r_subarray * (Cbitrow_drain_cap + c_b_metal) - self.V_b_sense = (g_tp.dram_cell_Vdd / 2) * g_tp.dram_cell_C / (g_tp.dram_cell_C + C_bl) - if self.V_b_sense < VBITSENSEMIN: - return - self.V_b_sense = VBITSENSEMIN - self.dram_refresh_period = 0.9 * g_tp.dram_cell_C * VDD_STORAGE_LOSS_FRACTION_WORST * g_tp.dram_cell_Vdd / g_tp.dram_cell_I_off_worst_case_len_temp - else: - self.V_b_sense = max(0.05 * g_tp.sram_cell.Vdd, VBITSENSEMIN) - self.deg_bl_muxing = self.Ndcm - Cbitrow_drain_cap = drain_C_(g_tp.sram.cell_a_w, NCH, 1, 0, self.cell.w, False, True) / 2.0 - C_bl = self.num_r_subarray * (Cbitrow_drain_cap + c_b_metal) - self.dram_refresh_period = 0 - - self.num_mats_h_dir = max(self.Ndwl // 2, 1) - self.num_mats_v_dir = max(self.Ndbl // 2, 1) - self.num_mats = self.num_mats_h_dir * self.num_mats_v_dir - self.num_do_b_mat = max((self.num_subarrays / self.num_mats) * self.num_c_subarray / (self.deg_bl_muxing * self.Ndsam_lev_1 * self.Ndsam_lev_2), 1) - - if not (self.fully_assoc or self.pure_cam) and self.num_do_b_mat < (self.num_subarrays / self.num_mats): - return - - if not self.is_tag: - if self.is_main_mem: - self.num_do_b_subbank = g_ip.int_prefetch_w * g_ip.out_w - if g_ip.is_3d_mem: - self.num_do_b_subbank = g_ip.page_sz_bits - deg_sa_mux_l1_non_assoc = self.Ndsam_lev_1 - else: - if g_ip.fast_access: - self.num_do_b_subbank = g_ip.out_w * g_ip.data_assoc - deg_sa_mux_l1_non_assoc = self.Ndsam_lev_1 - else: - self.num_do_b_subbank = g_ip.out_w - deg_sa_mux_l1_non_assoc = self.Ndsam_lev_1 / g_ip.data_assoc - if deg_sa_mux_l1_non_assoc < 1: - return - else: - self.num_do_b_subbank = self.tagbits * g_ip.tag_assoc - if self.num_do_b_mat < self.tagbits: - return - deg_sa_mux_l1_non_assoc = self.Ndsam_lev_1 - - self.deg_senseamp_muxing_non_associativity = deg_sa_mux_l1_non_assoc - self.num_act_mats_hor_dir = self.num_do_b_subbank // self.num_do_b_mat - if g_ip.is_3d_mem and self.num_act_mats_hor_dir == 0: - self.num_act_mats_hor_dir = 1 - if self.num_act_mats_hor_dir == 0: - return - - if self.is_tag: - if not (self.fully_assoc or self.pure_cam): - self.num_do_b_mat = g_ip.tag_assoc // self.num_act_mats_hor_dir - self.num_do_b_subbank = self.num_act_mats_hor_dir * self.num_do_b_mat - - if (not g_ip.is_cache and self.is_main_mem) or (PAGE_MODE == 1 and self.is_dram): - if self.num_act_mats_hor_dir * self.num_do_b_mat * self.Ndsam_lev_1 * self.Ndsam_lev_2 != int(g_ip.page_sz_bits): - return - - if (not self.is_tag) and (g_ip.is_main_mem) and (self.num_act_mats_hor_dir * self.num_do_b_mat * self.Ndsam_lev_1 * self.Ndsam_lev_2 < int(g_ip.out_w * g_ip.burst_len * g_ip.data_assoc)): - return - - if self.num_act_mats_hor_dir > self.num_mats_h_dir: - return - - if not self.is_tag: - if g_ip.fast_access: - self.num_di_b_mat = self.num_do_b_mat // g_ip.data_assoc - else: - self.num_di_b_mat = self.num_do_b_mat - else: - self.num_di_b_mat = self.tagbits - - self.num_di_b_subbank = self.num_di_b_mat * self.num_act_mats_hor_dir - self.num_si_b_subbank = self.num_si_b_mat - - num_addr_b_row_dec = _log2(self.num_r_subarray) - if self.fully_assoc or self.pure_cam: - num_addr_b_row_dec += _log2(self.num_subarrays // self.num_mats) - number_subbanks = self.num_mats // self.num_act_mats_hor_dir - self.number_subbanks_decode = _log2(number_subbanks) - - self.num_rw_ports = g_ip.num_rw_ports - self.num_rd_ports = g_ip.num_rd_ports - self.num_wr_ports = g_ip.num_wr_ports - self.num_se_rd_ports = g_ip.num_se_rd_ports - self.num_search_ports = g_ip.num_search_ports - - if self.is_dram and self.is_main_mem: - self.number_addr_bits_mat = max(num_addr_b_row_dec, _log2(self.deg_bl_muxing) + _log2(self.deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2)) - if g_ip.print_detail_debug: - print(f"parameter.cc: number_addr_bits_mat = {num_addr_b_row_dec}") - print(f"parameter.cc: num_addr_b_row_dec = {num_addr_b_row_dec}") - print(f"parameter.cc: num_addr_b_mux_sel = {_log2(self.deg_bl_muxing) + _log2(self.deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2)}") - else: - self.number_addr_bits_mat = num_addr_b_row_dec + _log2(self.deg_bl_muxing) + _log2(self.deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2) - - if self.is_tag: - self.num_di_b_bank_per_port = self.tagbits - self.num_do_b_bank_per_port = g_ip.data_assoc - else: - self.num_di_b_bank_per_port = g_ip.out_w + g_ip.data_assoc - self.num_do_b_bank_per_port = g_ip.out_w - - if not self.is_tag and g_ip.data_assoc > 1 and not g_ip.fast_access: - self.number_way_select_signals_mat = g_ip.data_assoc - - if g_ip.add_ecc_b_: - self.ECC_adjustment() - - self.is_valid = True - - def init_CAM(self): - wire_local = g_tp.wire_local - capacity_per_die = g_ip.cache_sz / NUMBER_STACKED_DIE_LAYERS - - if self.Ndwl != 1 or self.Ndcm != 1 or self.Nspd < 1 or self.Nspd > 1 or self.Ndsam_lev_1 != 1 or self.Ndsam_lev_2 != 1 or self.Ndbl < 2: - return - - if g_ip.specific_tag: - self.tagbits = int(sp.ceiling(g_ip.tag_w / 8.0) * 8) - else: - self.tagbits = int(sp.ceiling((ADDRESS_BITS + EXTRA_TAG_BITS) / 8.0) * 8) - - self.tag_num_r_subarray = int(sp.ceiling(capacity_per_die / (g_ip.nbanks * self.tagbits / 8.0 * self.Ndbl))) - self.tag_num_c_subarray = self.tagbits - - if self.tag_num_r_subarray == 0: - return - if self.tag_num_r_subarray > MAXSUBARRAYROWS: - return - if self.tag_num_c_subarray < MINSUBARRAYCOLS: - return - if self.tag_num_c_subarray > MAXSUBARRAYCOLS: - return - self.num_r_subarray = self.tag_num_r_subarray - - self.num_subarrays = self.Ndwl * self.Ndbl - - self.cam_cell.h = g_tp.cam.b_h + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_rd_ports + g_ip.num_wr_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) + wire_local.pitch * g_ip.num_se_rd_ports - self.cam_cell.w = g_tp.cam.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_rd_ports + g_ip.num_wr_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) + wire_local.pitch * g_ip.num_se_rd_ports - - self.cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip.num_wr_ports + g_ip.num_rw_ports - 1 + g_ip.num_rd_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) - self.cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + (g_ip.num_rd_ports - g_ip.num_se_rd_ports) + g_ip.num_wr_ports) + g_tp.wire_local.pitch * g_ip.num_se_rd_ports + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) - - c_b_metal = self.cell.h * wire_local.C_per_um - c_b_metal = self.cam_cell.h * wire_local.C_per_um - self.V_b_sense = max(0.05 * g_tp.sram_cell.Vdd, VBITSENSEMIN) - self.deg_bl_muxing = 1 - - Cbitrow_drain_cap = drain_C_(g_tp.cam.cell_a_w, NCH, 1, 0, self.cam_cell.w, False, True) / 2.0 - self.dram_refresh_period = 0 - - if self.Ndbl == 0: - print(" Invalid Ndbl \n") - exit(0) - elif self.Ndbl == 1: - self.num_mats_h_dir = 1 - self.num_mats_v_dir = 1 - elif self.Ndbl == 2: - self.num_mats_h_dir = 1 - self.num_mats_v_dir = 1 - else: - self.num_mats_h_dir = int(sp.floor(sp.sqrt(self.Ndbl / 4.0))) - self.num_mats_v_dir = int(self.Ndbl / 4.0 / self.num_mats_h_dir) - - self.num_mats = self.num_mats_h_dir * self.num_mats_v_dir - - self.num_so_b_mat = int(sp.ceiling(_log2(self.num_r_subarray)) + sp.ceiling(_log2(self.num_subarrays))) - self.num_do_b_mat = self.tagbits - - deg_sa_mux_l1_non_assoc = 1 - - self.num_so_b_subbank = int(sp.ceiling(_log2(self.num_r_subarray)) + sp.ceiling(_log2(self.num_subarrays))) - self.num_do_b_subbank = self.tag_num_c_subarray - - self.deg_senseamp_muxing_non_associativity = deg_sa_mux_l1_non_assoc - - self.num_act_mats_hor_dir = 1 - self.num_act_mats_hor_dir_sl = self.num_mats_h_dir - - if self.num_act_mats_hor_dir > self.num_mats_h_dir: - return - - self.num_di_b_mat = self.tagbits - self.num_si_b_mat = self.tagbits - - self.num_di_b_subbank = self.num_di_b_mat * self.num_act_mats_hor_dir - self.num_si_b_subbank = self.num_si_b_mat - - num_addr_b_row_dec = _log2(self.num_r_subarray) - num_addr_b_row_dec += _log2(self.num_subarrays / self.num_mats) - number_subbanks = self.num_mats / self.num_act_mats_hor_dir - self.number_subbanks_decode = _log2(number_subbanks) - - self.num_rw_ports = g_ip.num_rw_ports - self.num_rd_ports = g_ip.num_rd_ports - self.num_wr_ports = g_ip.num_wr_ports - self.num_se_rd_ports = g_ip.num_se_rd_ports - self.num_search_ports = g_ip.num_search_ports - - self.number_addr_bits_mat = num_addr_b_row_dec + _log2(self.deg_bl_muxing) + _log2(deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2) - - self.num_di_b_bank_per_port = self.tagbits - self.num_si_b_bank_per_port = self.tagbits - self.num_do_b_bank_per_port = self.tagbits - self.num_so_b_bank_per_port = int(sp.ceiling(_log2(self.num_r_subarray)) + sp.ceiling(_log2(self.num_subarrays))) - - if not self.is_tag and g_ip.data_assoc > 1 and not g_ip.fast_access: - self.number_way_select_signals_mat = g_ip.data_assoc - - if g_ip.add_ecc_b_: - self.ECC_adjustment() - - self.is_valid = True - - def init_FA(self): - wire_local = g_tp.wire_local - assert NUMBER_STACKED_DIE_LAYERS == 1 - capacity_per_die = g_ip.cache_sz - - if self.Ndwl != 1 or self.Ndcm != 1 or self.Nspd < 1 or self.Nspd > 1 or self.Ndsam_lev_1 != 1 or self.Ndsam_lev_2 != 1 or self.Ndbl < 2: - return - - if g_ip.specific_tag: - self.tagbits = g_ip.tag_w - else: - self.tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - _log2(g_ip.block_sz) - self.tagbits = (((self.tagbits + 3) >> 2) << 2) - - self.tag_num_r_subarray = int(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * self.Ndbl)) - self.tag_num_c_subarray = int(sp.ceiling((self.tagbits * self.Nspd / self.Ndwl))) - if self.tag_num_r_subarray == 0: - return - if self.tag_num_r_subarray > MAXSUBARRAYROWS: - return - if self.tag_num_c_subarray < MINSUBARRAYCOLS: - return - if self.tag_num_c_subarray > MAXSUBARRAYCOLS: - return - - self.data_num_r_subarray = self.tag_num_r_subarray - self.data_num_c_subarray = 8 * g_ip.block_sz - if self.data_num_r_subarray == 0: - return - if self.data_num_r_subarray > MAXSUBARRAYROWS: - return - if self.data_num_c_subarray < MINSUBARRAYCOLS: - return - if self.data_num_c_subarray > MAXSUBARRAYCOLS: - return - self.num_r_subarray = self.tag_num_r_subarray - - self.num_subarrays = self.Ndwl * self.Ndbl - - self.cam_cell.h = g_tp.cam.b_h + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_rd_ports + g_ip.num_wr_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) + wire_local.pitch * g_ip.num_se_rd_ports - self.cam_cell.w = g_tp.cam.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + g_ip.num_rd_ports + g_ip.num_wr_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) + wire_local.pitch * g_ip.num_se_rd_ports - - self.cell.h = g_tp.sram.b_h + 2 * wire_local.pitch * (g_ip.num_wr_ports + g_ip.num_rw_ports - 1 + g_ip.num_rd_ports) + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) - self.cell.w = g_tp.sram.b_w + 2 * wire_local.pitch * (g_ip.num_rw_ports - 1 + (g_ip.num_rd_ports - g_ip.num_se_rd_ports) + g_ip.num_wr_ports) + g_tp.wire_local.pitch * g_ip.num_se_rd_ports + 2 * wire_local.pitch * (g_ip.num_search_ports - 1) - - c_b_metal = self.cell.h * wire_local.C_per_um - c_b_metal = self.cam_cell.h * wire_local.C_per_um - self.V_b_sense = max(0.05 * g_tp.sram_cell.Vdd, VBITSENSEMIN) - self.deg_bl_muxing = 1 - - Cbitrow_drain_cap = drain_C_(g_tp.cam.cell_a_w, NCH, 1, 0, self.cam_cell.w, False, True) / 2.0 - self.dram_refresh_period = 0 - - if self.Ndbl == 0: - print(" Invalid Ndbl \n") - exit(0) - elif self.Ndbl == 1: - self.num_mats_h_dir = 1 - self.num_mats_v_dir = 1 - elif self.Ndbl == 2: - self.num_mats_h_dir = 1 - self.num_mats_v_dir = 1 - else: - self.num_mats_h_dir = int(sp.floor(sp.sqrt(self.Ndbl / 4.0))) - self.num_mats_v_dir = int(self.Ndbl / 4.0 / self.num_mats_h_dir) - - self.num_mats = self.num_mats_h_dir * self.num_mats_v_dir - - self.num_so_b_mat = self.data_num_c_subarray - self.num_do_b_mat = self.data_num_c_subarray + self.tagbits - - deg_sa_mux_l1_non_assoc = 1 - self.num_so_b_subbank = 8 * g_ip.block_sz - self.num_do_b_subbank = self.num_so_b_subbank + self.tag_num_c_subarray - - self.deg_senseamp_muxing_non_associativity = deg_sa_mux_l1_non_assoc - self.num_act_mats_hor_dir = 1 - self.num_act_mats_hor_dir_sl = self.num_mats_h_dir - - if self.num_act_mats_hor_dir > self.num_mats_h_dir: - return - - if self.fully_assoc: - self.num_di_b_mat = self.num_do_b_mat - self.num_si_b_mat = self.tagbits - self.num_di_b_subbank = self.num_di_b_mat * self.num_act_mats_hor_dir - self.num_si_b_subbank = self.num_si_b_mat - - num_addr_b_row_dec = _log2(self.num_r_subarray) - num_addr_b_row_dec += _log2(self.num_subarrays / self.num_mats) - number_subbanks = self.num_mats / self.num_act_mats_hor_dir - self.number_subbanks_decode = _log2(number_subbanks) - - self.num_rw_ports = g_ip.num_rw_ports - self.num_rd_ports = g_ip.num_rd_ports - self.num_wr_ports = g_ip.num_wr_ports - self.num_se_rd_ports = g_ip.num_se_rd_ports - self.num_search_ports = g_ip.num_search_ports - - self.number_addr_bits_mat = num_addr_b_row_dec + _log2(self.deg_bl_muxing) + _log2(deg_sa_mux_l1_non_assoc) + _log2(self.Ndsam_lev_2) - - self.num_di_b_bank_per_port = g_ip.out_w + self.tagbits - self.num_si_b_bank_per_port = self.tagbits - self.num_do_b_bank_per_port = g_ip.out_w + self.tagbits - self.num_so_b_bank_per_port = g_ip.out_w - - if not self.is_tag and g_ip.data_assoc > 1 and not g_ip.fast_access: - self.number_way_select_signals_mat = g_ip.data_assoc - - if g_ip.add_ecc_b_: - self.ECC_adjustment() - - self.is_valid = True - - def ECC_adjustment(self): - self.num_do_b_mat += int(sp.ceiling(self.num_do_b_mat / self.num_bits_per_ecc_b_)) - self.num_di_b_mat += int(sp.ceiling(self.num_di_b_mat / self.num_bits_per_ecc_b_)) - self.num_di_b_subbank += int(sp.ceiling(self.num_di_b_subbank / self.num_bits_per_ecc_b_)) - self.num_do_b_subbank += int(sp.ceiling(self.num_do_b_subbank / self.num_bits_per_ecc_b_)) - self.num_di_b_bank_per_port += int(sp.ceiling(self.num_di_b_bank_per_port / self.num_bits_per_ecc_b_)) - self.num_do_b_bank_per_port += int(sp.ceiling(self.num_do_b_bank_per_port / self.num_bits_per_ecc_b_)) - - self.num_so_b_mat += int(sp.ceiling(self.num_so_b_mat / self.num_bits_per_ecc_b_)) - self.num_si_b_mat += int(sp.ceiling(self.num_si_b_mat / self.num_bits_per_ecc_b_)) - self.num_si_b_subbank += int(sp.ceiling(self.num_si_b_subbank / self.num_bits_per_ecc_b_)) - self.num_so_b_subbank += int(sp.ceiling(self.num_so_b_subbank / self.num_bits_per_ecc_b_)) - self.num_si_b_bank_per_port += int(sp.ceiling(self.num_si_b_bank_per_port / self.num_bits_per_ecc_b_)) - self.num_so_b_bank_per_port += int(sp.ceiling(self.num_so_b_bank_per_port / self.num_bits_per_ecc_b_)) - - def calc_subarr_rc(self, capacity_per_die): - if self.Ndwl < 2 or self.Ndbl < 2: - return False - - if self.is_dram and not self.is_tag and self.Ndcm > 1: - return False - - if self.is_tag: - if g_ip.specific_tag: - self.tagbits = g_ip.tag_w - else: - self.tagbits = ADDRESS_BITS + EXTRA_TAG_BITS - _log2(capacity_per_die) + _log2(g_ip.tag_assoc * 2 - 1) - - self.num_r_subarray = int(sp.ceiling(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * g_ip.tag_assoc * self.Ndbl * self.Nspd))) - self.num_c_subarray = int(sp.ceiling((self.tagbits * g_ip.tag_assoc * self.Nspd / self.Ndwl))) - else: - self.num_r_subarray = int(sp.ceiling(capacity_per_die / (g_ip.nbanks * g_ip.block_sz * g_ip.data_assoc * self.Ndbl * self.Nspd))) - self.num_c_subarray = int(sp.ceiling((8 * g_ip.block_sz * g_ip.data_assoc * self.Nspd / self.Ndwl))) - if g_ip.is_3d_mem: - capacity_per_die_double = float(g_ip.cache_sz) / g_ip.num_die_3d - self.num_c_subarray = g_ip.page_sz_bits / self.Ndwl - self.num_r_subarray = 1 << int(sp.floor(_log2(float(g_ip.cache_sz) / g_ip.num_die_3d / self.num_c_subarray / g_ip.nbanks / self.Ndbl / self.Ndwl * 1024 * 1024 * 1024) + 0.5)) - if g_ip.print_detail_debug: - print(f"parameter.cc: capacity_per_die_double = {capacity_per_die_double} Gbit") - print(f"parameter.cc: g_ip.nbanks * Ndbl * Ndwl = {g_ip.nbanks * self.Ndbl * self.Ndwl}") - print(f"parameter.cc: num_r_subarray = {self.num_r_subarray}") - print(f"parameter.cc: num_c_subarray = {self.num_c_subarray}") - - if self.num_r_subarray < MINSUBARRAYROWS or self.num_r_subarray == 0 or self.num_r_subarray > MAXSUBARRAYROWS: - return False - if self.num_c_subarray < MINSUBARRAYCOLS or self.num_c_subarray > MAXSUBARRAYCOLS: - return False - - self.num_subarrays = self.Ndwl * self.Ndbl - return True - - - - - - - - - - -# HELPERS -# CHECK THESE -def PRINT(A, X, tech): - print(f"{A}: {X} , {tech.X}") - -def scan_single_input_double(line, name, unit_name, print_output): - match = re.search(f"{name}\s+([^\s]+)\s+([^\s]+)", line) - if match: - unit = match.group(1) - temp = float(match.group(2)) - if print_output: - print(f"{name}: {temp} {unit}") - return temp - return 0.0 - -def scan_five_input_double(line, name, unit_name, flavor, print_output): - match = re.search(f"{name}\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)", line) - if match: - unit = match.group(1) - temp = [float(match.group(i)) for i in range(2, 7)] - if print_output: - print(f"{name}[{flavor}]: {temp[flavor]} {unit}") - return temp[flavor] - return 0.0 - -def scan_five_input_double_temperature(line, name, unit_name, flavor, temperature, print_output, result): - match = re.search(f"{name}\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)", line) - if match: - unit = match.group(1) - thermal_temp = int(match.group(2)) - temp = [float(match.group(i)) for i in range(3, 8)] - if thermal_temp == (temperature - 300): - if print_output: - print(f"{name}: {temp[flavor]} {unit}") - result = temp[flavor] - -def scan_input_double_inter_type(line, name, unit_name, proj_type, tech_flavor, print_output): - assert proj_type < NUMBER_INTERCONNECT_PROJECTION_TYPES - index = proj_type * NUMBER_WIRE_TYPES + tech_flavor - match = re.search(f"{name}\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)", line) - if match: - unit = match.group(1) - temp = [float(match.group(i)) for i in range(2, 10)] - if print_output: - print(f"{name} {temp[index]} {unit}") - return temp[index] - return 0.0 - -def scan_five_input_double_mem_type(line, name, unit_name, flavor, cell_type, print_flag): - temp = [0.0] * 5 - unit = "" - - # Extract the relevant part of the line - relevant_line = line[len(name):].strip() - - # print(line) - # print(relevant_line) - - # Scan the input line and extract values - parts = relevant_line.split() - # print(parts) - # print(cell_type) - - unit = parts[0] - cell_type_temp = int(parts[1]) - temp[0] = float(parts[2]) - temp[1] = float(parts[3]) - temp[2] = float(parts[4]) - temp[3] = float(parts[5]) - temp[4] = float(parts[6]) - - result = None - if cell_type_temp == cell_type: - if print_flag: - print(f"{name}: {temp[flavor]} {unit}") - result = temp[flavor] - - return result - -def scan_input_double_tsv_type(line, name, unit_name, proj_type, tsv_type, print_flag): - assert proj_type < NUMBER_INTERCONNECT_PROJECTION_TYPES - index = proj_type * NUMBER_TSV_TYPES + tsv_type - temp = [0.0] * 6 - unit = "" - - # Extracting the values using regular expressions - match = re.search(rf"{name}\s+(\S+)\s+(\d+\.?\d*)\s+(\d+\.?\d*)\s+(\d+\.?\d*)\s+(\d+\.?\d*)\s+(\d+\.?\d*)\s+(\d+\.?\d*)", line) - - if match: - unit = match.group(1) - temp[0] = float(match.group(2)) - temp[1] = float(match.group(3)) - temp[2] = float(match.group(4)) - temp[3] = float(match.group(5)) - temp[4] = float(match.group(6)) - temp[5] = float(match.group(7)) - - if print_flag: - print(f"{name}: {temp[index]} {unit}") - - return temp[index] - else: - raise ValueError("Line does not match the expected format") - - - - - -#### TO AVOID CIRCULAR DEPENDNCY -UNI_LEAK_STACK_FACTOR = 0.43 - -def powers(base, n): - p = 1 - for i in range(1, n + 1): - p *= base - return p - -def is_pow2(val): - if val <= 0: - return False - elif val == 1: - return True - else: - return (_log2(val) != _log2(val - 1)) - -def _log2(num): - if num == 0: - raise ValueError("log0?") - log2 = 0 - while num > 1: - num >>= 1 - log2 += 1 - return log2 - -def factorial(n, m=1): - fa = m - for i in range(m + 1, n + 1): - fa *= i - return fa - -def combination(n, m): - return factorial(n, m + 1) // factorial(n - m) - - -outside_mat = "outside_mat" -inside_mat = "inside_mat" -local_wires = "local_wires" - - -Add_htree = "Add_htree" -Data_in_htree = "Data_in_htree" -Data_out_htree = "Data_out_htree" -Search_in_htree = "Search_in_htree" -Search_out_htree = "Search_out_htree" - - -Row_add_path = "Row_add_path" -Col_add_path = "Col_add_path" -Data_path = "Data_path" - - -nmos = "nmos" -pmos = "pmos" -inv = "inv" -nand = "nand" -nor = "nor" -tri = "tri" -tg = "tg" - -parallel = "parallel" -series = "series" - -# class WirePlacement: -# outside_mat = "outside_mat" -# inside_mat = "inside_mat" -# local_wires = "local_wires" - -# class HtreeType: -# Add_htree = "Add_htree" -# Data_in_htree = "Data_in_htree" -# Data_out_htree = "Data_out_htree" -# Search_in_htree = "Search_in_htree" -# Search_out_htree = "Search_out_htree" - -# class MemorybusType: -# Row_add_path = "Row_add_path" -# Col_add_path = "Col_add_path" -# Data_path = "Data_path" - -# class GateType: -# nmos = "nmos" -# pmos = "pmos" -# inv = "inv" -# nand = "nand" -# nor = "nor" -# tri = "tri" -# tg = "tg" - -# class HalfNetTopology: -# parallel = "parallel" -# series = "series" - -# def logtwo(x): -# assert x > 0 -# return sp.log(x) / sp.log(2.0) - -def gate_C(width, wirelength, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - return (dt.C_g_ideal + dt.C_overlap + 3 * dt.C_fringe) * width + dt.l_phy * Cpolywire - -def gate_C_pass(width, wirelength, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - return gate_C(width, wirelength, _is_dram, _is_sram, _is_wl_tr, _is_sleep_tx) - -def drain_C_(width, nchannel, stack, next_arg_thresh_folding_width_or_height_cell, fold_dimension, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - - c_junc_area = dt.C_junc - c_junc_sidewall = dt.C_junc_sidewall - c_fringe = 2 * dt.C_fringe - c_overlap = 2 * dt.C_overlap - drain_C_metal_connecting_folded_tr = 0 - - if next_arg_thresh_folding_width_or_height_cell == 0: - w_folded_tr = fold_dimension - else: - h_tr_region = fold_dimension - 2 * g_tp.HPOWERRAIL - ratio_p_to_n = 2.0 / (2.0 + 1.0) - if nchannel: - w_folded_tr = (1 - ratio_p_to_n) * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) - else: - w_folded_tr = ratio_p_to_n * (h_tr_region - g_tp.MIN_GAP_BET_P_AND_N_DIFFS) - - num_folded_tr = int(sp.ceiling(width / w_folded_tr)) - if num_folded_tr < 2: - w_folded_tr = width - - total_drain_w = (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + (stack - 1) * g_tp.spacing_poly_to_poly - drain_h_for_sidewall = w_folded_tr - total_drain_height_for_cap_wrt_gate = w_folded_tr + 2 * w_folded_tr * (stack - 1) - if num_folded_tr > 1: - total_drain_w += (num_folded_tr - 2) * (g_tp.w_poly_contact + 2 * g_tp.spacing_poly_to_contact) + (num_folded_tr - 1) * ((stack - 1) * g_tp.spacing_poly_to_poly) - if num_folded_tr % 2 == 0: - drain_h_for_sidewall = 0 - total_drain_height_for_cap_wrt_gate *= num_folded_tr - drain_C_metal_connecting_folded_tr = g_tp.wire_local.C_per_um * total_drain_w - - drain_C_area = c_junc_area * total_drain_w * w_folded_tr - drain_C_sidewall = c_junc_sidewall * (drain_h_for_sidewall + 2 * total_drain_w) - drain_C_wrt_gate = (c_fringe + c_overlap) * total_drain_height_for_cap_wrt_gate - - return drain_C_area + drain_C_sidewall + drain_C_wrt_gate + drain_C_metal_connecting_folded_tr - -def tr_R_on(width, nchannel, stack, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - - restrans = dt.R_nch_on if nchannel else dt.R_pch_on - return stack * restrans / width - -def R_to_w(res, nchannel, _is_dram=False, _is_sram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_sram: - dt = g_tp.dram_acc # DRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif not _is_dram and _is_sram: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global - - restrans = dt.R_nch_on if nchannel else dt.R_pch_on - return restrans / res - -def pmos_to_nmos_sz_ratio(_is_dram=False, _is_wl_tr=False, _is_sleep_tx=False): - if _is_dram and _is_wl_tr: - return g_tp.dram_wl.n_to_p_eff_curr_drv_ratio - elif _is_sleep_tx: - return g_tp.sleep_tx.n_to_p_eff_curr_drv_ratio - else: - return g_tp.peri_global.n_to_p_eff_curr_drv_ratio - -def horowitz(inputramptime, tf, vs1, vs2, rise): - if inputramptime == 0 and vs1 == vs2: - return tf * (-sp.log(vs1) if vs1 < 1 else sp.log(vs1)) - - a = inputramptime / tf - if rise == RISE: - b = 0.5 - td = tf * sp.sqrt(sp.log(vs1) ** 2 + 2 * a * b * (1.0 - vs1)) + tf * (sp.log(vs1) - sp.log(vs2)) - else: - b = 0.4 - td = tf * sp.sqrt(sp.log(1.0 - vs1) ** 2 + 2 * a * b * vs1) + tf * (sp.log(1.0 - vs1) - sp.log(1.0 - vs2)) - return td - -def cmos_Ileak(nWidth, pWidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nWidth * dt.I_off_n + pWidth * dt.I_off_p - -def simplified_nmos_Isat(nwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nwidth * dt.I_on_n - -def simplified_pmos_Isat(pwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return pwidth * dt.I_on_n / dt.n_to_p_eff_curr_drv_ratio - -def simplified_nmos_leakage(nwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nwidth * dt.I_off_n - -def simplified_pmos_leakage(pwidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return pwidth * dt.I_off_p - -def cmos_Ig_n(nWidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return nWidth * dt.I_g_on_n - -def cmos_Ig_p(pWidth, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False): - if not _is_dram and _is_cell: - dt = g_tp.sram_cell # SRAM cell access transistor - elif _is_dram and _is_wl_tr: - dt = g_tp.dram_wl # DRAM wordline transistor - elif _is_sleep_tx: - dt = g_tp.sleep_tx # Sleep transistor - else: - dt = g_tp.peri_global # DRAM or SRAM all other transistors - - return pWidth * dt.I_g_on_p - -def cmos_Isub_leakage(nWidth, pWidth, fanin, g_type, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False, topo=series): - assert fanin >= 1 - nmos_leak = simplified_nmos_leakage(nWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - pmos_leak = simplified_pmos_leakage(pWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - Isub = 0 - num_states = int(sp.Pow(2.0, fanin)) - - if g_type == nmos: - if fanin == 1: - Isub = nmos_leak / num_states - else: - if topo == parallel: - Isub = nmos_leak * fanin / num_states - else: - for num_off_tx in range(1, fanin + 1): - Isub += nmos_leak * sp.Pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub /= num_states - - elif g_type == pmos: - if fanin == 1: - Isub = pmos_leak / num_states - else: - if topo == parallel: - Isub = pmos_leak * fanin / num_states - else: - for num_off_tx in range(1, fanin + 1): - Isub += pmos_leak * sp.Pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub /= num_states - - elif g_type == inv: - Isub = (nmos_leak + pmos_leak) / 2 - - elif g_type == nand: - Isub += fanin * pmos_leak - for num_off_tx in range(1, fanin + 1): - Isub += nmos_leak * sp.Pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub /= num_states - - elif g_type == nor: - for num_off_tx in range(1, fanin + 1): - Isub += pmos_leak * sp.Pow(UNI_LEAK_STACK_FACTOR, (num_off_tx - 1)) * combination(fanin, num_off_tx) - Isub += fanin * nmos_leak - Isub /= num_states - - elif g_type == tri: - Isub += (nmos_leak + pmos_leak) / 2 - Isub += nmos_leak * UNI_LEAK_STACK_FACTOR - Isub /= 2 - - elif g_type == tg: - Isub = (nmos_leak + pmos_leak) / 2 - - else: - raise ValueError("Invalid gate type") - - return Isub - -def cmos_Ig_leakage(nWidth, pWidth, fanin, g_type, _is_dram=False, _is_cell=False, _is_wl_tr=False, _is_sleep_tx=False, topo=series): - assert fanin >= 1 - nmos_leak = cmos_Ig_n(nWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - pmos_leak = cmos_Ig_p(pWidth, _is_dram, _is_cell, _is_wl_tr, _is_sleep_tx) - Ig_on = 0 - num_states = int(sp.Pow(2.0, fanin)) - - if g_type == nmos: - if fanin == 1: - Ig_on = nmos_leak / num_states - else: - if topo == parallel: - for num_on_tx in range(1, fanin + 1): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx - else: - Ig_on += nmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - Ig_on /= num_states - - elif g_type == pmos: - if fanin == 1: - Ig_on = pmos_leak / num_states - else: - if topo == parallel: - for num_on_tx in range(1, fanin + 1): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx - else: - Ig_on += pmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - Ig_on /= num_states - - elif g_type == inv: - Ig_on = (nmos_leak + pmos_leak) / 2 - - elif g_type == nand: - for num_on_tx in range(1, fanin + 1): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx - Ig_on += nmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - Ig_on /= num_states - - elif g_type == nor: - Ig_on += pmos_leak * fanin - for num_on_tx in range(1, fanin): - Ig_on += pmos_leak * combination(fanin, num_on_tx) * num_on_tx / 2 - for num_on_tx in range(1, fanin + 1): - Ig_on += nmos_leak * combination(fanin, num_on_tx) * num_on_tx - Ig_on /= num_states - - elif g_type == tri: - Ig_on += (2 * nmos_leak + 2 * pmos_leak) / 2 - Ig_on += (nmos_leak + pmos_leak) / 2 - Ig_on /= 2 - - elif g_type == tg: - Ig_on = (nmos_leak + pmos_leak) / 2 - - else: - raise ValueError("Invalid gate type") - - return Ig_on - -def shortcircuit_simple(vt, velocity_index, c_in, c_out, w_nmos, w_pmos, i_on_n, i_on_p, i_on_n_in, i_on_p_in, vdd): - fo_n = i_on_n / i_on_n_in - fo_p = i_on_p / i_on_p_in - fanout = c_out / c_in - beta_ratio = i_on_p / i_on_n - vt_to_vdd_ratio = vt / vdd - - p_short_circuit_discharge_low = (10 / 3) * (pow((vdd - vt) - vt_to_vdd_ratio, 3.0) / pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio * vt_to_vdd_ratio)) * c_in * vdd * vdd * fo_p * fo_p / fanout / beta_ratio - p_short_circuit_charge_low = (10 / 3) * (pow((vdd - vt) - vt_to_vdd_ratio, 3.0) / pow(velocity_index, 2.0) / pow(2.0, 3 * vt_to_vdd_ratio * vt_to_vdd_ratio)) * c_in * vdd * vdd * fo_n * fo_n / fanout * beta_ratio - - p_short_circuit_discharge = p_short_circuit_discharge_low - p_short_circuit_charge = p_short_circuit_charge_low - p_short_circuit = (p_short_circuit_discharge + p_short_circuit_charge) / 2 - - return p_short_circuit - -def shortcircuit(vt, velocity_index, c_in, c_out, w_nmos, w_pmos, i_on_n, i_on_p, i_on_n_in, i_on_p_in, vdd): - fo_p = i_on_p / i_on_p_in - fanout = 1 - beta_ratio = i_on_p / i_on_n - e = 2.71828 - f_alpha = 1 / (velocity_index + 2) - velocity_index / (2 * (velocity_index + 3)) + velocity_index / (velocity_index + 4) * (velocity_index / 2 - 1) - k_v = 0.9 / 0.8 + (vdd - vt) / 0.8 * sp.log(10 * (vdd - vt) / e) - g_v_alpha = (velocity_index + 1) * pow((1 - velocity_index), velocity_index) * pow((1 - velocity_index), velocity_index / 2) / f_alpha / pow((1 - velocity_index - velocity_index), (velocity_index / 2 + velocity_index + 2)) - h_v_alpha = pow(2, velocity_index) * (velocity_index + 1) * pow((1 - velocity_index), velocity_index) / pow((1 - velocity_index - velocity_index), (velocity_index + 1)) - - p_short_circuit_discharge = k_v * vdd * vdd * c_in * fo_p * fo_p / ((vdd - vt) * g_v_alpha * fanout * beta_ratio / 2 / k_v + h_v_alpha * fo_p) - return p_short_circuit_discharge - -def wire_resistance(resistivity, wire_width, wire_thickness, barrier_thickness, dishing_thickness, alpha_scatter): - resistance = alpha_scatter * resistivity / ((wire_thickness - barrier_thickness - dishing_thickness) * (wire_width - 2 * barrier_thickness)) - return resistance - -def wire_capacitance(wire_width, wire_thickness, wire_spacing, ild_thickness, miller_value, horiz_dielectric_constant, vert_dielectric_constant, fringe_cap): - vertical_cap = 2 * PERMITTIVITY_FREE_SPACE * vert_dielectric_constant * wire_width / ild_thickness - sidewall_cap = 2 * PERMITTIVITY_FREE_SPACE * miller_value * horiz_dielectric_constant * wire_thickness / wire_spacing - total_cap = vertical_cap + sidewall_cap + fringe_cap - return total_cap - -def tsv_resistance(resistivity, tsv_len, tsv_diam, tsv_contact_resistance): - resistance = resistivity * tsv_len / (math.pi * (tsv_diam / 2) ** 2) + tsv_contact_resistance - return resistance - -def tsv_capacitance(tsv_len, tsv_diam, tsv_pitch, dielec_thickness, liner_dielectric_constant, depletion_width): - e_si = PERMITTIVITY_FREE_SPACE * 11.9 - PI = math.pi - lateral_coupling_constant = 4.1 - diagonal_coupling_constant = 5.3 - - liner_cap = 2 * PI * PERMITTIVITY_FREE_SPACE * liner_dielectric_constant * tsv_len / sp.log(1 + dielec_thickness / (tsv_diam / 2)) - depletion_cap = 2 * PI * e_si * tsv_len / sp.log(1 + depletion_width / (dielec_thickness + tsv_diam / 2)) - self_cap = 1 / (1 / liner_cap + 1 / depletion_cap) - - lateral_coupling_cap = 0.4 * (0.225 * sp.log(0.97 * tsv_len / tsv_diam) + 0.53) * e_si / (tsv_pitch - tsv_diam) * PI * tsv_diam * tsv_len - diagonal_coupling_cap = 0.4 * (0.225 * sp.log(0.97 * tsv_len / tsv_diam) + 0.53) * e_si / (1.414 * tsv_pitch - tsv_diam) * PI * tsv_diam * tsv_len - - total_cap = self_cap + lateral_coupling_constant * lateral_coupling_cap + diagonal_coupling_constant * diagonal_coupling_cap - return total_cap - -def tsv_area(tsv_pitch): - return tsv_pitch ** 2 - - -g_ip = InputParameter() -g_tp = TechnologyParameter() diff --git a/cacti-main/cacti_python/subarray.py b/cacti-main/cacti_python/subarray.py index 6db37ea..9c853f8 100644 --- a/cacti-main/cacti_python/subarray.py +++ b/cacti-main/cacti_python/subarray.py @@ -1,5 +1,3 @@ -# TODO figure out area - import math from math import ceil, log, pow import sys @@ -22,16 +20,6 @@ def __init__(self, dp_, is_fa_): self.cell = dp_.cell self.cam_cell = dp_.cam_cell self.is_fa = is_fa_ - - print("\n CURR DEBUG") - print(f"Number of rows: {self.num_rows}") - print(f"Number of columns: {self.num_cols}") - print(f"Number of columns for FA CAM: {self.num_cols_fa_cam}") - print(f"Number of columns for FA RAM: {self.num_cols_fa_ram}") - print(f"Cell: {self.cell}") - print(f"CAM Cell: {self.cam_cell}") - print(f"Is FA: {self.is_fa}") - #self.area = Area() if not (is_fa_ or dp_.pure_cam): self.num_cols += sp.ceiling(self.num_cols / num_bits_per_ecc_b_) if g_ip.add_ecc_b_ else 0 diff --git a/cacti-main/cacti_python/uca.py b/cacti-main/cacti_python/uca.py index 0377278..7b8fc58 100644 --- a/cacti-main/cacti_python/uca.py +++ b/cacti-main/cacti_python/uca.py @@ -5,6 +5,7 @@ from .memorybus import Memorybus from .tsv import TSV import sympy as sp +import time # used to have component? class UCA(Component): @@ -17,7 +18,7 @@ def __init__(self, dyn_p): self.power_routing_to_bank = PowerDef() - #TODO relational + # CHANGE: relational # num_banks_ver_dir = 1 << int((math.log2(nbanks) / 2) if (h > w) else (math.log2(nbanks) - math.log2(nbanks) / 2)) num_banks_ver_dir = 1 << int(math.log2(self.nbanks) / 2) # if (self.bank.h > self.bank.w) else (math.log2(self.nbanks) - math.log2(self.nbanks) / 2)) num_banks_hor_dir = self.nbanks // num_banks_ver_dir @@ -305,19 +306,18 @@ def compute_delays(self, inrisetime): delay_array_to_mat = self.htree_in_add.delay + self.bank.htree_in_add.delay max_delay_before_row_decoder = delay_array_to_mat + self.bank.mat.r_predec.delay self.delay_array_to_sa_mux_lev_1_decoder = delay_array_to_mat + self.bank.mat.sa_mux_lev_1_predec.delay + self.bank.mat.sa_mux_lev_1_dec.delay + # self.delay_array_to_sa_mux_lev_1_decoder = self.bank.mat.sa_mux_lev_1_dec.delay self.delay_array_to_sa_mux_lev_2_decoder = delay_array_to_mat + self.bank.mat.sa_mux_lev_2_predec.delay + self.bank.mat.sa_mux_lev_2_dec.delay delay_inside_mat = self.bank.mat.row_dec.delay + self.bank.mat.delay_bitline + self.bank.mat.delay_sa - # TODO parallel test theses - #TODO hotfix - # if math.isnan(max_delay_before_row_decoder) or math.isnan(delay_inside_mat) or math.isnan(delay_array_to_mat) or math.isnan( self.bank.mat.b_mux_predec.delay) or math.isnan(self.bank.mat.bit_mux_dec.delay ) or math.isnan(self.bank.mat.delay_sa): - # self.delay_before_subarray_output_driver = 1 - # else: - # TODO MAX CHECK + # Change: MAX - option 1 and 2 make the expressions extremely long but have higher accuracy + + # OPTION 1: ORIGINAL # self.delay_before_subarray_output_driver = sp.Max(max_delay_before_row_decoder + delay_inside_mat, # delay_array_to_mat + self.bank.mat.b_mux_predec.delay + self.bank.mat.bit_mux_dec.delay + self.bank.mat.delay_sa, # sp.Max(self.delay_array_to_sa_mux_lev_1_decoder, self.delay_array_to_sa_mux_lev_2_decoder)) + # OPTION 2: USING symbolic... takes a while # print("before uca compute delay max") # self.delay_before_subarray_output_driver = symbolic_convex_max(max_delay_before_row_decoder + delay_inside_mat, # (delay_array_to_mat + self.bank.mat.b_mux_predec.delay + @@ -325,19 +325,18 @@ def compute_delays(self, inrisetime): # tmp_max = symbolic_convex_max(self.delay_array_to_sa_mux_lev_1_decoder, self.delay_array_to_sa_mux_lev_2_decoder) # self.delay_before_subarray_output_driver = symbolic_convex_max(self.delay_before_subarray_output_driver, tmp_max) - # selected random - # # Option 1 - self.delay_before_subarray_output_driver = max_delay_before_row_decoder + delay_inside_mat - # # Option 2 - # self.delay_before_subarray_output_driver = delay_array_to_mat + self.bank.mat.b_mux_predec.delay + self.bank.mat.bit_mux_dec.delay + self.bank.mat.delay_sa - # # Option 3 + # OPTION 3: just select 1 - will decrease accuracy + # a + # self.delay_before_subarray_output_driver = max_delay_before_row_decoder + delay_inside_mat + # b + self.delay_before_subarray_output_driver = delay_array_to_mat + self.bank.mat.b_mux_predec.delay + self.bank.mat.bit_mux_dec.delay + self.bank.mat.delay_sa + # c # self.delay_before_subarray_output_driver = self.delay_array_to_sa_mux_lev_1_decoder - # Option 4 + # d # self.delay_before_subarray_output_driver = self.delay_array_to_sa_mux_lev_2_decoder self.delay_from_subarray_out_drv_to_out = self.bank.mat.delay_subarray_out_drv_htree + self.bank.htree_out_data.delay + self.htree_out_data.delay self.access_time = self.bank.mat.delay_comparator - print("after uca compute delay max") if self.dp.fully_assoc: ram_delay_inside_mat = self.bank.mat.delay_bitline + self.bank.mat.delay_matchchline @@ -347,7 +346,8 @@ def compute_delays(self, inrisetime): if self.dp.is_main_mem: t_rcd = max_delay_before_row_decoder + delay_inside_mat - cas_latency = symbolic_convex_max(self.delay_array_to_sa_mux_lev_1_decoder, self.delay_array_to_sa_mux_lev_2_decoder) + self.delay_from_subarray_out_drv_to_out + # cas_latency = symbolic_convex_max(self.delay_array_to_sa_mux_lev_1_decoder, self.delay_array_to_sa_mux_lev_2_decoder) + self.delay_from_subarray_out_drv_to_out + cas_latency = self.delay_array_to_sa_mux_lev_1_decoder + self.delay_from_subarray_out_drv_to_out self.access_time = t_rcd + cas_latency if not self.dp.fully_assoc: @@ -355,14 +355,11 @@ def compute_delays(self, inrisetime): if self.dp.is_dram: temp += self.bank.mat.delay_writeback - #print(f'temp {temp}') - print(f'UCA AFTER TEMP') + # Uneeded since for cycle time # temp = symbolic_convex_max(temp, self.bank.mat.r_predec.delay) # temp = symbolic_convex_max(temp, self.bank.mat.b_mux_predec.delay) # temp = symbolic_convex_max(temp, self.bank.mat.sa_mux_lev_1_predec.delay) # temp = symbolic_convex_max(temp, self.bank.mat.sa_mux_lev_2_predec.delay) - - # MAX, but uneeded for access_time # temp = sp.Max( # temp, # self.bank.mat.r_predec.delay, @@ -371,13 +368,12 @@ def compute_delays(self, inrisetime): # self.bank.mat.sa_mux_lev_2_predec.delay # ) - print ("before max temp") + # Uneeded since for cycle time # max1 = symbolic_convex_max(self.bank.mat.r_predec.delay, self.bank.mat.b_mux_predec.delay) # max2 = symbolic_convex_max(self.bank.mat.sa_mux_lev_1_predec.delay, self.bank.mat.sa_mux_lev_2_predec.delay) # max3 = symbolic_convex_max(max1, max2) # temp = symbolic_convex_max(temp, max3) temp = self.bank.mat.r_predec.delay - print ("after max temp") else: ram_delay_inside_mat = self.bank.mat.delay_bitline + self.bank.mat.delay_matchchline @@ -386,22 +382,21 @@ def compute_delays(self, inrisetime): # temp = symbolic_convex_max(temp, self.bank.mat.sa_mux_lev_1_predec.delay) # temp = symbolic_convex_max(temp, self.bank.mat.sa_mux_lev_2_predec.delay) - # MAX, but uneeded for access_time + # Uneeded since for cycle time # temp = sp.Max( # temp, # self.bank.mat.b_mux_predec.delay, # self.bank.mat.sa_mux_lev_1_predec.delay, # self.bank.mat.sa_mux_lev_2_predec.delay # ) - print ("before max temp") + + # Uneeded since for cycle time # max1 = symbolic_convex_max(temp, self.bank.mat.b_mux_predec.delay) # max2 = symbolic_convex_max(self.bank.mat.sa_mux_lev_2_predec.delay, self.bank.mat.sa_mux_lev_1_predec.delay) # temp = symbolic_convex_max(max1, max2) temp = self.bank.mat.b_mux_predec.delay - print ("after max temp") - print ("UCA MAX NEXT") - print(g_ip.rpters_in_htree) + print ("UCA completed... please wait for expression to write.") g_ip.rpters_in_htree = True if g_ip.rpters_in_htree == False: temp = symbolic_convex_max(temp, self.bank.htree_in_add.max_unpipelined_link_delay) @@ -409,14 +404,6 @@ def compute_delays(self, inrisetime): delay_req_network = max_delay_before_row_decoder delay_rep_network = self.delay_from_subarray_out_drv_to_out - - #TODO delay_rep_network nan - # if math.isnan(delay_req_network): - # delay_req_network = 0 - # if math.isnan(delay_rep_network): - # delay_rep_network = 0 - # print(delay_req_network) - # print(delay_rep_network) self.multisubbank_interleave_cycle_time = symbolic_convex_max(delay_req_network, delay_rep_network) if self.dp.is_main_mem: @@ -503,11 +490,13 @@ def compute_power_energy(self): self.htree_in_data.power.readOp.leakage + self.htree_out_data.power.readOp.leakage ) + self.power_routing_to_bank.readOp.gate_leakage += ( self.htree_in_add.power.readOp.gate_leakage + self.htree_in_data.power.readOp.gate_leakage + self.htree_out_data.power.readOp.gate_leakage ) + if self.dp.fully_assoc or self.dp.pure_cam: self.power_routing_to_bank.readOp.leakage += self.htree_in_search.power.readOp.leakage + self.htree_out_search.power.readOp.leakage self.power_routing_to_bank.readOp.gate_leakage += self.htree_in_search.power.readOp.gate_leakage + self.htree_out_search.power.readOp.gate_leakage @@ -541,6 +530,7 @@ def compute_power_energy(self): self.bank.mat.power_bitline.readOp.dynamic ) * self.dp.num_act_mats_hor_dir ) + self.dyn_read_energy_remaining_words_in_burst = ( symbolic_convex_max(g_ip.burst_len / g_ip.int_prefetch_w, 1) - 1 ) * ( @@ -554,9 +544,10 @@ def compute_power_energy(self): self.bank.htree_out_data.power.readOp.dynamic + self.power_routing_to_bank.readOp.dynamic ) + self.dyn_read_energy_from_closed_page += self.dyn_read_energy_remaining_words_in_burst self.dyn_read_energy_from_open_page += self.dyn_read_energy_remaining_words_in_burst - + self.activate_energy = ( self.htree_in_add.power.readOp.dynamic + self.bank.htree_in_add.power_bit.readOp.dynamic * self.bank.num_addr_b_routed_to_mat_for_act + @@ -566,6 +557,7 @@ def compute_power_energy(self): self.bank.mat.power_sa.readOp.dynamic ) * self.dp.num_act_mats_hor_dir ) + self.read_energy = ( self.htree_in_add.power.readOp.dynamic + self.bank.htree_in_add.power_bit.readOp.dynamic * self.bank.num_addr_b_routed_to_mat_for_rd_or_wr + @@ -579,6 +571,7 @@ def compute_power_energy(self): self.bank.htree_out_data.power.readOp.dynamic + self.htree_in_data.power.readOp.dynamic ) * g_ip.burst_len + self.write_energy = ( self.htree_in_add.power.readOp.dynamic + self.bank.htree_in_add.power_bit.readOp.dynamic * self.bank.num_addr_b_routed_to_mat_for_rd_or_wr + @@ -591,6 +584,7 @@ def compute_power_energy(self): self.bank.mat.power_sa_mux_lev_2_decoders.readOp.dynamic ) * self.dp.num_act_mats_hor_dir ) * g_ip.burst_len + self.precharge_energy = ( self.bank.mat.power_bitline.readOp.dynamic + self.bank.mat.power_bl_precharge_eq_drv.readOp.dynamic @@ -676,6 +670,7 @@ def compute_power_energy(self): if not self.dp.is_tag: self.power.readOp.dynamic = self.dyn_read_energy_from_closed_page + self.power.writeOp.dynamic = ( self.dyn_read_energy_from_closed_page - self.dyn_read_energy_remaining_words_in_burst - diff --git a/cacti-main/cacti_python/wire.py b/cacti-main/cacti_python/wire.py index e796e85..d1da1bc 100644 --- a/cacti-main/cacti_python/wire.py +++ b/cacti-main/cacti_python/wire.py @@ -5,53 +5,82 @@ from .component import Component from .cacti_interface import * +import math + class Wire(Component): - global_comp = Component() + global_ = Component() global_5 = Component() global_10 = Component() global_20 = Component() global_30 = Component() low_swing = Component() initialized = 0 - wire_width_init = 0 - wire_spacing_init = 0 + wire_width_init = None + wire_spacing_init = None - def __init__(self, wire_model = 0, length = 1, nsense=1, width_scaling=1, spacing_scaling=1, wire_placement=outside_mat, resistivity=CU_RESISTIVITY, dt=g_tp.peri_global): + def __init__(self, wire_model=0, wl=1, n=1, w_s=1, s_s=1, wp=outside_mat, resistivity=CU_RESISTIVITY, dt=g_tp.peri_global): super().__init__() self.wt = wire_model - self.wire_length = length * 1e-6 - self.nsense = nsense - self.w_scale = width_scaling - self.s_scale = spacing_scaling + self.wire_length = wl * 1e-6 + self.nsense = n + self.w_scale = w_s + self.s_scale = s_s self.resistivity = resistivity - self.deviceType = dt if dt else g_tp.peri_global # TODO check this - self.wire_placement = wire_placement + self.deviceType = dt + self.wire_placement = wp self.min_w_pmos = self.deviceType.n_to_p_eff_curr_drv_ratio * g_tp.min_w_nmos_ self.in_rise_time = 0 self.out_rise_time = 0 - self.repeater_spacing = 1 - # TODO set arbitrary for now - self.repeater_size = 0 + self.repeated_wire = [] + + self.transmitter = Component() + self.l_wire = Component() + self.sense_amp = Component() + + # CHECK + self.repeater_spacing = 0 + self.wire_width = 0 + self.wire_spacing = 0 + self.repeater_size = 0 + + if Wire.initialized != 1: + print("Initializing Wire") + self.__init_wire_simple(w_s, s_s, wp, resistivity, dt) - print("WRIE CHECKPINT 0") - self.calculate_wire_stats() - print("WRIE CHECKPINT 0") + self.repeater_spacing *= 1e6 self.wire_length *= 1e6 self.wire_width *= 1e6 self.wire_spacing *= 1e6 - - self.transmitter = Component() - self.l_wire = Component() - self.sense_amp = Component() - self.min_w_pmos = self.deviceType.n_to_p_eff_curr_drv_ratio * g_tp.min_w_nmos_ # assert self.wire_length > 0 # assert self.power.readOp.dynamic > 0 # assert self.power.readOp.leakage > 0 # assert self.power.readOp.gate_leakage > 0 + def __init_wire_simple(self, w_s, s_s, wp, resis, dt): + if self.wire_placement == outside_mat: + self.wire_width = g_tp.wire_outside_mat.pitch / 2 + elif self.wire_placement == inside_mat: + self.wire_width = g_tp.wire_inside_mat.pitch / 2 + else: + self.wire_width = g_tp.wire_local.pitch / 2 + + self.wire_spacing = self.wire_width + + self.wire_width *= (self.w_scale * 1e-6 / 2) + self.wire_spacing *= (self.s_scale * 1e-6 / 2) + + Wire.initialized = 1 + self.init_wire() + Wire.wire_width_init = self.wire_width + Wire.wire_spacing_init = self.wire_spacing + + # assert self.power.readOp.dynamic > 0 + # assert self.power.readOp.leakage > 0 + # assert self.power.readOp.gate_leakage > 0 + def __del__(self): pass @@ -64,114 +93,108 @@ def calculate_wire_stats(self): self.wire_width = g_tp.wire_local.pitch / 2 self.wire_spacing = self.wire_width - self.wire_width *= self.w_scale * 1e-6 / 2 - self.wire_spacing *= self.s_scale * 1e-6 / 2 - - if self.wt != Low_swing: - if self.wt == Global: - self.delay = self.global_comp.delay * self.wire_length - self.power.readOp.dynamic = self.global_comp.power.readOp.dynamic * self.wire_length - self.power.readOp.leakage = self.global_comp.power.readOp.leakage * self.wire_length - self.power.readOp.gate_leakage = self.global_comp.power.readOp.gate_leakage * self.wire_length - self.repeater_spacing = self.global_comp.area.w - self.repeater_size = self.global_comp.area.h - self.area.set_area((self.wire_length / self.repeater_spacing) * - compute_gate_area(INV, 1, self.min_w_pmos * self.repeater_size, - g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) - elif self.wt == Global_5: + + self.wire_width *= (self.w_scale * 1e-6 / 2) + self.wire_spacing *= (self.s_scale * 1e-6 / 2) + + if self.wt != 'Low_swing': + if self.wt == 'Global': + self.delay = Wire.global_.delay * self.wire_length + self.power.readOp.dynamic = Wire.global_.power.readOp.dynamic * self.wire_length + self.power.readOp.leakage = Wire.global_.power.readOp.leakage * self.wire_length + self.power.readOp.gate_leakage = Wire.global_.power.readOp.gate_leakage * self.wire_length + self.repeater_spacing = Wire.global_.area.w + self.repeater_size = Wire.global_.area.h + + self.area.set_area((self.wire_length / self.repeater_spacing) * compute_gate_area(INV, 1, self.min_w_pmos * self.repeater_size, g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) + elif self.wt == 'Global_5': self.delay = Wire.global_5.delay * self.wire_length self.power.readOp.dynamic = Wire.global_5.power.readOp.dynamic * self.wire_length self.power.readOp.leakage = Wire.global_5.power.readOp.leakage * self.wire_length self.power.readOp.gate_leakage = Wire.global_5.power.readOp.gate_leakage * self.wire_length self.repeater_spacing = Wire.global_5.area.w self.repeater_size = Wire.global_5.area.h - self.area.set_area((self.wire_length / self.repeater_spacing) * - compute_gate_area(INV, 1, self.min_w_pmos * self.repeater_size, - g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) - elif self.wt == Global_10: + + self.area.set_area((self.wire_length / self.repeater_spacing) * compute_gate_area('INV', 1, self.min_w_pmos * self.repeater_size, g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) + elif self.wt == 'Global_10': self.delay = Wire.global_10.delay * self.wire_length self.power.readOp.dynamic = Wire.global_10.power.readOp.dynamic * self.wire_length self.power.readOp.leakage = Wire.global_10.power.readOp.leakage * self.wire_length self.power.readOp.gate_leakage = Wire.global_10.power.readOp.gate_leakage * self.wire_length self.repeater_spacing = Wire.global_10.area.w self.repeater_size = Wire.global_10.area.h - self.area.set_area((self.wire_length / self.repeater_spacing) * - compute_gate_area(INV, 1, self.min_w_pmos * self.repeater_size, - g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) - elif self.wt == Global_20: + + self.area.set_area((self.wire_length / self.repeater_spacing) * compute_gate_area('INV', 1, self.min_w_pmos * self.repeater_size, g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) + elif self.wt == 'Global_20': self.delay = Wire.global_20.delay * self.wire_length self.power.readOp.dynamic = Wire.global_20.power.readOp.dynamic * self.wire_length self.power.readOp.leakage = Wire.global_20.power.readOp.leakage * self.wire_length self.power.readOp.gate_leakage = Wire.global_20.power.readOp.gate_leakage * self.wire_length self.repeater_spacing = Wire.global_20.area.w self.repeater_size = Wire.global_20.area.h - self.area.set_area((self.wire_length / self.repeater_spacing) * - compute_gate_area(INV, 1, self.min_w_pmos * self.repeater_size, - g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) - elif self.wt == Global_30: + + self.area.set_area((self.wire_length / self.repeater_spacing) * compute_gate_area('INV', 1, self.min_w_pmos * self.repeater_size, g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) + elif self.wt == 'Global_30': self.delay = Wire.global_30.delay * self.wire_length self.power.readOp.dynamic = Wire.global_30.power.readOp.dynamic * self.wire_length self.power.readOp.leakage = Wire.global_30.power.readOp.leakage * self.wire_length self.power.readOp.gate_leakage = Wire.global_30.power.readOp.gate_leakage * self.wire_length self.repeater_spacing = Wire.global_30.area.w self.repeater_size = Wire.global_30.area.h - self.area.set_area((self.wire_length / self.repeater_spacing) * - compute_gate_area(INV, 1, self.min_w_pmos * self.repeater_size, - g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) - print("HOTSPOT") - print(self.deviceType.Vth) - #TODO important self.deviceType.Vth is not symbolic for some reason - if(self.deviceType.Vth == 0): - self.deviceType.Vth = 1 + + self.area.set_area((self.wire_length / self.repeater_spacing) * compute_gate_area('INV', 1, self.min_w_pmos * self.repeater_size, g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) + else: # Check wr wire type + self.delay = Wire.global_.delay * self.wire_length + self.power.readOp.dynamic = Wire.global_.power.readOp.dynamic * self.wire_length + self.power.readOp.leakage = Wire.global_.power.readOp.leakage * self.wire_length + self.power.readOp.gate_leakage = Wire.global_.power.readOp.gate_leakage * self.wire_length + self.repeater_spacing = Wire.global_.area.w + self.repeater_size = Wire.global_.area.h + + self.area.set_area((self.wire_length / self.repeater_spacing) * compute_gate_area(INV, 1, self.min_w_pmos * self.repeater_size, g_tp.min_w_nmos_ * self.repeater_size, g_tp.cell_h_def)) self.out_rise_time = self.delay * self.repeater_spacing / self.deviceType.Vth - elif self.wt == Low_swing: + elif self.wt == 'Low_swing': self.low_swing_model() self.repeater_spacing = self.wire_length self.repeater_size = 1 else: - assert False + raise AssertionError() def signal_fall_time(self): timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * tr_R_on(self.min_w_pmos, PCH, 1) + gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * \ + tr_R_on(self.min_w_pmos, PCH, 1) rt = horowitz(0, timeconst, self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, FALL) / (self.deviceType.Vdd - self.deviceType.Vth) timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * tr_R_on(g_tp.min_w_nmos_, NCH, 1) + gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * \ + tr_R_on(g_tp.min_w_nmos_, NCH, 1) ft = horowitz(rt, timeconst, self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, RISE) / self.deviceType.Vth return ft def signal_rise_time(self): timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * tr_R_on(g_tp.min_w_nmos_, NCH, 1) - # TODO need to check why deviceType - if (self.deviceType.Vdd == 0): - self.deviceType.Vdd = 1 + gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * \ + tr_R_on(g_tp.min_w_nmos_, NCH, 1) rt = horowitz(0, timeconst, self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, RISE) / self.deviceType.Vth timeconst = (drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * tr_R_on(self.min_w_pmos, PCH, 1) + gate_C(self.min_w_pmos + g_tp.min_w_nmos_, 0)) * \ + tr_R_on(self.min_w_pmos, PCH, 1) ft = horowitz(rt, timeconst, self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, FALL) / (self.deviceType.Vdd - self.deviceType.Vth) return ft - def set_in_rise_time(self, rt): - self.in_rise_time = rt - - def print_wire(self): - pass - def wire_cap(self, length, call_from_outside=False): epsilon0 = 8.8542e-12 - - if self.wire_placement == outside_mat: + if self.wire_placement == 'outside_mat': aspect_ratio = g_tp.wire_outside_mat.aspect_ratio horiz_dielectric_constant = g_tp.wire_outside_mat.horiz_dielectric_constant vert_dielectric_constant = g_tp.wire_outside_mat.vert_dielectric_constant miller_value = g_tp.wire_outside_mat.miller_value ild_thickness = g_tp.wire_outside_mat.ild_thickness - elif self.wire_placement == inside_mat: + elif self.wire_placement == 'inside_mat': aspect_ratio = g_tp.wire_inside_mat.aspect_ratio horiz_dielectric_constant = g_tp.wire_inside_mat.horiz_dielectric_constant vert_dielectric_constant = g_tp.wire_inside_mat.vert_dielectric_constant @@ -189,93 +212,107 @@ def wire_cap(self, length, call_from_outside=False): self.wire_spacing *= 1e-6 wire_height = self.wire_width / self.w_scale * aspect_ratio - sidewall = miller_value * horiz_dielectric_constant * (wire_height / self.wire_spacing) * epsilon0 adj = miller_value * vert_dielectric_constant * self.wire_width / (ild_thickness * 1e-6) * epsilon0 - tot_cap = sidewall + adj + g_tp.fringe_cap * 1e6 + tot_cap = (sidewall + adj + (g_tp.fringe_cap * 1e6)) if call_from_outside: self.wire_width *= 1e6 self.wire_spacing *= 1e6 return tot_cap * length - + def wire_res(self, length): alpha_scatter = 1.05 dishing_thickness = 0 barrier_thickness = 0 - if self.wire_placement == outside_mat: + if self.wire_placement == 'outside_mat': aspect_ratio = g_tp.wire_outside_mat.aspect_ratio - elif self.wire_placement == inside_mat: + elif self.wire_placement == 'inside_mat': aspect_ratio = g_tp.wire_inside_mat.aspect_ratio else: aspect_ratio = g_tp.wire_local.aspect_ratio - return (alpha_scatter * self.resistivity * 1e-6 * length) / ( - (aspect_ratio * self.wire_width / self.w_scale - dishing_thickness - barrier_thickness) * - (self.wire_width - 2 * barrier_thickness)) + return (alpha_scatter * self.resistivity * 1e-6 * length / + ((aspect_ratio * self.wire_width / self.w_scale - dishing_thickness - barrier_thickness) * + (self.wire_width - 2 * barrier_thickness))) def low_swing_model(self): - length = self.wire_length + len_ = self.wire_length beta = pmos_to_nmos_sz_ratio() - inputrise = self.signal_rise_time() if self.in_rise_time == 0 else self.in_rise_time - cwire = self.wire_cap(length) - rwire = self.wire_res(length) + inputrise = self.in_rise_time if self.in_rise_time != 0 else self.signal_rise_time() - RES_ADJ = 8.6 + cwire = self.wire_cap(len_) + rwire = self.wire_res(len_) + RES_ADJ = 8.6 driver_res = (-8 * g_tp.FO4 / (math.log(0.5) * cwire)) / RES_ADJ nsize = R_to_w(driver_res, NCH) - nsize = min(nsize, g_tp.max_w_nmos_) - nsize = symbolic_convex_max(nsize, g_tp.min_w_nmos_) + # RECENT CHANGE: MAX - ignore to reduce expression length + # nsize = sp.Min(nsize, g_tp.max_w_nmos_) + # nsize = symbolic_convex_max(nsize, g_tp.min_w_nmos_) + + # CHANGE: RELATIONAL + # if rwire * cwire > 8 * g_tp.FO4: + # nsize = g_tp.max_w_nmos_ - if rwire * cwire > 8 * g_tp.FO4: - nsize = g_tp.max_w_nmos_ + nsize = sp.Piecewise( + (g_tp.max_w_nmos_, rwire * cwire > 8 * g_tp.FO4), + (nsize, True) + ) - st_eff = sp.sqrt((2 + beta / 1 + beta) * gate_C(nsize, 0) / ( - gate_C(2 * g_tp.min_w_nmos_, 0) + gate_C(2 * self.min_w_pmos, 0))) + st_eff = sp.sqrt((2 + beta / 1 + beta) * gate_C(nsize, 0) / + (gate_C(2 * g_tp.min_w_nmos_, 0) + gate_C(2 * self.min_w_pmos, 0))) req_cin = ((2 + beta / 1 + beta) * gate_C(nsize, 0)) / st_eff inv_size = req_cin / (gate_C(self.min_w_pmos, 0) + gate_C(g_tp.min_w_nmos_, 0)) + + # RECENT CHANGE: MAX - ignore to reduce expression size inv_size = symbolic_convex_max(inv_size, 1) res_eq = 2 * tr_R_on(g_tp.min_w_nmos_, NCH, 1) - cap_eq = (2 * drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - drain_C_(2 * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + - gate_C(inv_size * g_tp.min_w_nmos_, 0) + - gate_C(inv_size * self.min_w_pmos, 0)) + cap_eq = 2 * drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + \ + drain_C_(2 * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + \ + gate_C(inv_size * g_tp.min_w_nmos_, 0) + \ + gate_C(inv_size * self.min_w_pmos, 0) timeconst = res_eq * cap_eq - self.delay = horowitz(inputrise, timeconst, self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, RISE) + self.delay = horowitz(inputrise, timeconst, self.deviceType.Vth / self.deviceType.Vdd, + self.deviceType.Vth / self.deviceType.Vdd, RISE) temp_power = cap_eq * self.deviceType.Vdd * self.deviceType.Vdd inputrise = self.delay / (self.deviceType.Vdd - self.deviceType.Vth) res_eq = tr_R_on(inv_size * self.min_w_pmos, PCH, 1) - cap_eq = (drain_C_(inv_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - drain_C_(inv_size * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + - gate_C(nsize, 0)) - + cap_eq = drain_C_(inv_size * self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + \ + drain_C_(inv_size * g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + \ + gate_C(nsize, 0) timeconst = res_eq * cap_eq - self.delay += horowitz(inputrise, timeconst, self.deviceType.Vth / self.deviceType.Vdd, self.deviceType.Vth / self.deviceType.Vdd, FALL) + + self.delay += horowitz(inputrise, timeconst, self.deviceType.Vth / self.deviceType.Vdd, + self.deviceType.Vth / self.deviceType.Vdd, FALL) temp_power += cap_eq * self.deviceType.Vdd * self.deviceType.Vdd self.transmitter.delay = self.delay self.transmitter.power.readOp.dynamic = temp_power * 2 - self.transmitter.power.readOp.leakage = self.deviceType.Vdd * ( - 4 * cmos_Isub_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 2, nand) + - 4 * cmos_Isub_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 1, inv)) - self.transmitter.power.readOp.gate_leakage = self.deviceType.Vdd * ( - 4 * cmos_Ig_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 2, nand) + - 4 * cmos_Ig_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 1, inv)) + self.transmitter.power.readOp.leakage = self.deviceType.Vdd * \ + (4 * cmos_Isub_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 2, 'nand') + + 4 * cmos_Isub_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 1, 'inv')) + + self.transmitter.power.readOp.gate_leakage = self.deviceType.Vdd * \ + (4 * cmos_Ig_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 2, 'nand') + + 4 * cmos_Ig_leakage(g_tp.min_w_nmos_, self.min_w_pmos, 1, 'inv')) inputrise = self.delay / self.deviceType.Vth - cap_eq = cwire + drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def) * 2 + self.nsense * self.sense_amp_input_cap() - timeconst = (tr_R_on(nsize, NCH, 1) * RES_ADJ) * (cwire + drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def) * 2) + rwire * cwire / 2 + ( - tr_R_on(nsize, NCH, 1) * RES_ADJ + rwire) * self.nsense * self.sense_amp_input_cap() + cap_eq = cwire + 2 * drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def) + \ + self.nsense * self.sense_amp_input_cap() + timeconst = (tr_R_on(nsize, NCH, 1) * RES_ADJ) * (cwire + 2 * drain_C_(nsize, NCH, 1, 1, g_tp.cell_h_def)) + \ + rwire * cwire / 2 + \ + (tr_R_on(nsize, NCH, 1) * RES_ADJ + rwire) * \ + self.nsense * self.sense_amp_input_cap() self.delay += horowitz(inputrise, timeconst, self.deviceType.Vth / self.deviceType.Vdd, 0.25, 0) VOL_SWING = 0.1 @@ -284,8 +321,11 @@ def low_swing_model(self): self.l_wire.delay = self.delay - self.transmitter.delay self.l_wire.power.readOp.dynamic = temp_power - self.transmitter.power.readOp.dynamic - self.l_wire.power.readOp.leakage = self.deviceType.Vdd * (4 * cmos_Isub_leakage(nsize, 0, 1, nmos)) - self.l_wire.power.readOp.gate_leakage = self.deviceType.Vdd * (4 * cmos_Ig_leakage(nsize, 0, 1, nmos)) + self.l_wire.power.readOp.leakage = self.deviceType.Vdd * \ + (4 * cmos_Isub_leakage(nsize, 0, 1, nmos)) + + self.l_wire.power.readOp.gate_leakage = self.deviceType.Vdd * \ + (4 * cmos_Ig_leakage(nsize, 0, 1, nmos)) self.delay += g_tp.sense_delay @@ -296,199 +336,244 @@ def low_swing_model(self): self.sense_amp.power.readOp.gate_leakage = 0 self.power.readOp.dynamic = temp_power + self.sense_amp.power.readOp.dynamic - self.power.readOp.leakage = self.transmitter.power.readOp.leakage + self.l_wire.power.readOp.leakage + self.sense_amp.power.readOp.leakage - self.power.readOp.gate_leakage = self.transmitter.power.readOp.gate_leakage + self.l_wire.power.readOp.gate_leakage + self.sense_amp.power.readOp.gate_leakage - + self.power.readOp.leakage = self.transmitter.power.readOp.leakage + \ + self.l_wire.power.readOp.leakage + \ + self.sense_amp.power.readOp.leakage + self.power.readOp.gate_leakage = self.transmitter.power.readOp.gate_leakage + \ + self.l_wire.power.readOp.gate_leakage + \ + self.sense_amp.power.readOp.gate_leakage + def sense_amp_input_cap(self): - return (drain_C_(g_tp.w_iso, PCH, 1, 1, g_tp.cell_h_def) + - gate_C(g_tp.w_sense_en + g_tp.w_sense_n, 0) + - drain_C_(g_tp.w_sense_n, NCH, 1, 1, g_tp.cell_h_def) + - drain_C_(g_tp.w_sense_p, PCH, 1, 1, g_tp.cell_h_def)) + return ( + drain_C_(g_tp.w_iso, PCH, 1, 1, g_tp.cell_h_def) + + gate_C(g_tp.w_sense_en + g_tp.w_sense_n, 0) + + drain_C_(g_tp.w_sense_n, NCH, 1, 1, g_tp.cell_h_def) + + drain_C_(g_tp.w_sense_p, PCH, 1, 1, g_tp.cell_h_def) + ) def delay_optimal_wire(self): - len = self.wire_length + len_ = self.wire_length beta = pmos_to_nmos_sz_ratio() switching = 0 short_ckt = 0 tc = 0 input_cap = gate_C(g_tp.min_w_nmos_ + self.min_w_pmos, 0) - out_cap = (drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def)) - out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) + - tr_R_on(self.min_w_pmos, PCH, 1)) / 2 - wr = self.wire_res(len) - wc = self.wire_cap(len) + out_cap = ( + drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + + drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) + ) + out_res = ( + tr_R_on(g_tp.min_w_nmos_, NCH, 1) + + tr_R_on(self.min_w_pmos, PCH, 1) + ) / 2 + wr = self.wire_res(len_) + wc = self.wire_cap(len_) repeater_scaling = sp.sqrt(out_res * wc / (wr * input_cap)) - self.repeater_spacing = sp.sqrt(2 * out_res * (out_cap + input_cap) / - ((wr / len) * (wc / len))) + self.repeater_spacing = sp.sqrt(2 * out_res * (out_cap + input_cap) / ((wr / len_) * (wc / len_))) self.repeater_size = repeater_scaling - switching = (repeater_scaling * (input_cap + out_cap) + - self.repeater_spacing * (wc / len)) * self.deviceType.Vdd * self.deviceType.Vdd - tc = (out_res * (input_cap + out_cap) + - out_res * wc / len * self.repeater_spacing / repeater_scaling + - wr / len * self.repeater_spacing * input_cap * repeater_scaling + - 0.5 * (wr / len) * (wc / len) * self.repeater_spacing * self.repeater_spacing) - self.delay = 0.693 * tc * len / self.repeater_spacing + + switching = ( + (repeater_scaling * (input_cap + out_cap) + + self.repeater_spacing * (wc / len_)) * + self.deviceType.Vdd * self.deviceType.Vdd + ) + + tc = ( + out_res * (input_cap + out_cap) + + out_res * wc / len_ * self.repeater_spacing / repeater_scaling + + wr / len_ * self.repeater_spacing * input_cap * repeater_scaling + + 0.5 * (wr / len_) * (wc / len_) * self.repeater_spacing * self.repeater_spacing + ) + + self.delay = 0.693 * tc * len_ / self.repeater_spacing + Ishort_ckt = 65e-6 - short_ckt = (self.deviceType.Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * - repeater_scaling * tc) - self.area.set_area((len / self.repeater_spacing) * - compute_gate_area(INV, 1, self.min_w_pmos * repeater_scaling, - g_tp.min_w_nmos_ * repeater_scaling, g_tp.cell_h_def)) - self.power.readOp.dynamic = (len / self.repeater_spacing) * (switching + short_ckt) - self.power.readOp.leakage = ((len / self.repeater_spacing) * - self.deviceType.Vdd * - cmos_Isub_leakage(g_tp.min_w_nmos_ * repeater_scaling, - beta * g_tp.min_w_nmos_ * repeater_scaling, 1, inv)) - self.power.readOp.gate_leakage = ((len / self.repeater_spacing) * - self.deviceType.Vdd * - cmos_Ig_leakage(g_tp.min_w_nmos_ * repeater_scaling, - beta * g_tp.min_w_nmos_ * repeater_scaling, 1, inv)) + short_ckt = ( + self.deviceType.Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * + repeater_scaling * tc + ) + + self.area.set_area( + (len_ / self.repeater_spacing) * + compute_gate_area( + INV, 1, self.min_w_pmos * repeater_scaling, + g_tp.min_w_nmos_ * repeater_scaling, g_tp.cell_h_def + ) + ) + + self.power.readOp.dynamic = (len_ / self.repeater_spacing) * (switching + short_ckt) + self.power.readOp.leakage = ( + (len_ / self.repeater_spacing) * + self.deviceType.Vdd * + cmos_Isub_leakage( + g_tp.min_w_nmos_ * repeater_scaling, beta * g_tp.min_w_nmos_ * repeater_scaling, 1, inv + ) + ) + self.power.readOp.gate_leakage = ( + (len_ / self.repeater_spacing) * + self.deviceType.Vdd * + cmos_Ig_leakage( + g_tp.min_w_nmos_ * repeater_scaling, beta * g_tp.min_w_nmos_ * repeater_scaling, 1, inv + ) + ) def init_wire(self): self.wire_length = 1 self.delay_optimal_wire() - sp = self.repeater_spacing * 1e6 - si = self.repeater_size + # sp = self.repeater_spacing * 1e6 # in microns + sp = int(g_ip.repeater_spacing) # CHANGE: ARRAY LOGIC + + # si = self.repeater_size + si = int(g_ip.repeater_size) # CHANGE: ARRAY LOGIC + # si = 85.6553 + + + # CHANGE: ARRAY LOGIC - cannot index with symbolic expression, so we have to use value self.repeated_wire.append(Component()) for j in range(int(sp), int(4 * sp), 100): for i in range(int(si), 1, -1): - pow = self.wire_model(j * 1e-6, i) - if j == sp and i == si: - self.global_comp.delay = self.delay - self.global_comp.power = pow - self.global_comp.area.h = si - self.global_comp.area.w = sp * 1e-6 - self.repeated_wire[-1].delay = self.delay - self.repeated_wire[-1].power.readOp = pow.readOp - self.repeated_wire[-1].area.w = j * 1e-6 + pow_, del_ = self.wire_model(j * 1e-6, i) + + if j == int(sp) and i == int(si): + Wire.global_.delay = del_ + Wire.global_.power = pow_ + Wire.global_.area.h = si + Wire.global_.area.w = sp * 1e-6 # m + + self.repeated_wire[-1].delay = del_ + self.repeated_wire[-1].power.readOp = pow_.readOp + self.repeated_wire[-1].area.w = j * 1e-6 # m self.repeated_wire[-1].area.h = i self.repeated_wire.append(Component()) + self.repeated_wire.pop() self.update_fullswing() - l_wire = Wire(Low_swing, 0.001, 1) - self.low_swing.delay = l_wire.delay - self.low_swing.power = l_wire.power + + # CHANGE: SET LOGIC - just set global_ to be spacing and size + Wire.global_.area.h = si + Wire.global_.area.w = sp * 1e-6 # m + + l_wire = Wire('Low_swing', 0.001, 1) + Wire.low_swing.delay = l_wire.delay + Wire.low_swing.power = l_wire.power del l_wire def update_fullswing(self): - del_values = [self.global_comp.delay * (1 + 0.3), self.global_comp.delay * (1 + 0.2), - self.global_comp.delay * (1 + 0.1), self.global_comp.delay * (1 + 0.05)] + deltas = [ + self.global_.delay + self.global_.delay * 0.05, + self.global_.delay + self.global_.delay * 0.1, + self.global_.delay + self.global_.delay * 0.2, + self.global_.delay + self.global_.delay * 0.3 + ] + i = 4 while i > 0: - threshold = del_values[i - 1] - cost = BIGNUM - for component in self.repeated_wire: - if component.delay > threshold: - self.repeated_wire.remove(component) - else: - ncost = (component.power.readOp.dynamic / self.global_comp.power.readOp.dynamic + - component.power.readOp.leakage / self.global_comp.power.readOp.leakage) - if ncost < cost: - cost = ncost - if i == 4: - self.global_30 = component - elif i == 3: - self.global_20 = component - elif i == 2: - self.global_10 = component - elif i == 1: - self.global_5 = component + threshold = deltas[i - 1] + cost = float('inf') + for citer in list(self.repeated_wire): + # CHANGE: RELATIONAL LOGIC + # if citer.delay > threshold: + # self.repeated_wire.remove(citer) + # else: + ncost = citer.power.readOp.dynamic / self.global_.power.readOp.dynamic + \ + citer.power.readOp.leakage / self.global_.power.readOp.leakage + + # CHANGE: RELATIONAL LOGIC + # if ncost < cost: + cost = ncost + if i == 4: + Wire.global_30.delay = citer.delay + Wire.global_30.power = citer.power + Wire.global_30.area = citer.area + elif i == 3: + Wire.global_20.delay = citer.delay + Wire.global_20.power = citer.power + Wire.global_20.area = citer.area + elif i == 2: + Wire.global_10.delay = citer.delay + Wire.global_10.power = citer.power + Wire.global_10.area = citer.area + elif i == 1: + Wire.global_5.delay = citer.delay + Wire.global_5.power = citer.power + Wire.global_5.area = citer.area i -= 1 def wire_model(self, space, size): - len = 1 + ptemp = PowerDef() + len_ = 1 beta = pmos_to_nmos_sz_ratio() switching = 0 short_ckt = 0 tc = 0 input_cap = gate_C(g_tp.min_w_nmos_ + self.min_w_pmos, 0) - out_cap = (drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + - drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def)) + out_cap = drain_C_(self.min_w_pmos, PCH, 1, 1, g_tp.cell_h_def) + \ + drain_C_(g_tp.min_w_nmos_, NCH, 1, 1, g_tp.cell_h_def) out_res = (tr_R_on(g_tp.min_w_nmos_, NCH, 1) + tr_R_on(self.min_w_pmos, PCH, 1)) / 2 - wr = self.wire_res(len) - wc = self.wire_cap(len) + wr = self.wire_res(len_) + wc = self.wire_cap(len_) + self.repeater_spacing = space self.repeater_size = size + switching = (self.repeater_size * (input_cap + out_cap) + - self.repeater_spacing * (wc / len)) * self.deviceType.Vdd * self.deviceType.Vdd - tc = (out_res * (input_cap + out_cap) + - out_res * wc / len * self.repeater_spacing / self.repeater_size + - wr / len * self.repeater_spacing * out_cap * self.repeater_size + - 0.5 * (wr / len) * (wc / len) * self.repeater_spacing * self.repeater_spacing) - self.delay = 0.693 * tc * len / self.repeater_spacing + self.repeater_spacing * (wc / len_)) * self.deviceType.Vdd * self.deviceType.Vdd + + tc = out_res * (input_cap + out_cap) + \ + out_res * wc / len_ * self.repeater_spacing / self.repeater_size + \ + wr / len_ * self.repeater_spacing * out_cap * self.repeater_size + \ + 0.5 * (wr / len_) * (wc / len_) * self.repeater_spacing * self.repeater_spacing + + delay = 0.693 * tc * len_ / self.repeater_spacing + Ishort_ckt = 65e-6 - short_ckt = (self.deviceType.Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * - self.repeater_size * tc) - ptemp = PowerDef() - ptemp.readOp.dynamic = ((len / self.repeater_spacing) * (switching + short_ckt)) - ptemp.readOp.leakage = ((len / self.repeater_spacing) * - self.deviceType.Vdd * - cmos_Isub_leakage(g_tp.min_w_nmos_ * self.repeater_size, - beta * g_tp.min_w_nmos_ * self.repeater_size, 1, inv)) - ptemp.readOp.gate_leakage = ((len / self.repeater_spacing) * - self.deviceType.Vdd * - cmos_Ig_leakage(g_tp.min_w_nmos_ * self.repeater_size, - beta * g_tp.min_w_nmos_ * self.repeater_size, 1, inv)) - return ptemp + short_ckt = self.deviceType.Vdd * g_tp.min_w_nmos_ * Ishort_ckt * 1.0986 * \ + self.repeater_size * tc - def print_wire(self): - print("\nWire Properties:\n\n") - print(f" Delay Optimal\n\tRepeater size - {self.global_comp.area.h} " - f"\n\tRepeater spacing - {self.global_comp.area.w * 1e3} (mm)" - f"\n\tDelay - {self.global_comp.delay * 1e6} (ns/mm)" - f"\n\tPowerD - {self.global_comp.power.readOp.dynamic * 1e6} (nJ/mm)" - f"\n\tPowerL - {self.global_comp.power.readOp.leakage} (mW/mm)" - f"\n\tPowerLgate - {self.global_comp.power.readOp.gate_leakage} (mW/mm)\n") - print(f"\tWire width - {self.wire_width_init * 1e6} microns\n") - print(f"\tWire spacing - {self.wire_spacing_init * 1e6} microns\n") + ptemp.readOp.dynamic = (len_ / self.repeater_spacing) * (switching + short_ckt) + ptemp.readOp.leakage = (len_ / self.repeater_spacing) * \ + self.deviceType.Vdd * \ + cmos_Isub_leakage(g_tp.min_w_nmos_ * self.repeater_size, + beta * g_tp.min_w_nmos_ * self.repeater_size, 1, inv) - print(f" 5% Overhead\n\tRepeater size - {self.global_5.area.h} " - f"\n\tRepeater spacing - {self.global_5.area.w * 1e3} (mm)" - f"\n\tDelay - {self.global_5.delay * 1e6} (ns/mm)" - f"\n\tPowerD - {self.global_5.power.readOp.dynamic * 1e6} (nJ/mm)" - f"\n\tPowerL - {self.global_5.power.readOp.leakage} (mW/mm)" - f"\n\tPowerLgate - {self.global_5.power.readOp.gate_leakage} (mW/mm)\n") - print(f"\tWire width - {self.wire_width_init * 1e6} microns\n") - print(f"\tWire spacing - {self.wire_spacing_init * 1e6} microns\n") + ptemp.readOp.gate_leakage = (len_ / self.repeater_spacing) * \ + self.deviceType.Vdd * \ + cmos_Ig_leakage(g_tp.min_w_nmos_ * self.repeater_size, + beta * g_tp.min_w_nmos_ * self.repeater_size, 1, inv) - print(f" 10% Overhead\n\tRepeater size - {self.global_10.area.h} " - f"\n\tRepeater spacing - {self.global_10.area.w * 1e3} (mm)" - f"\n\tDelay - {self.global_10.delay * 1e6} (ns/mm)" - f"\n\tPowerD - {self.global_10.power.readOp.dynamic * 1e6} (nJ/mm)" - f"\n\tPowerL - {self.global_10.power.readOp.leakage} (mW/mm)" - f"\n\tPowerLgate - {self.global_10.power.readOp.gate_leakage} (mW/mm)\n") - print(f"\tWire width - {self.wire_width_init * 1e6} microns\n") - print(f"\tWire spacing - {self.wire_spacing_init * 1e6} microns\n") + return ptemp, delay - print(f" 20% Overhead\n\tRepeater size - {self.global_20.area.h} " - f"\n\tRepeater spacing - {self.global_20.area.w * 1e3} (mm)" - f"\n\tDelay - {self.global_20.delay * 1e6} (ns/mm)" - f"\n\tPowerD - {self.global_20.power.readOp.dynamic * 1e6} (nJ/mm)" - f"\n\tPowerL - {self.global_20.power.readOp.leakage} (mW/mm)" - f"\n\tPowerLgate - {self.global_20.power.readOp.gate_leakage} (mW/mm)\n") - print(f"\tWire width - {self.wire_width_init * 1e6} microns\n") + def print_wire(self): + print("\nWire Properties:\n") + print(f" Delay Optimal\n\tRepeater size - {self.global_.area.h}" + f" \n\tRepeater spacing - {self.global_.area.w * 1e3} (mm)" + f" \n\tDelay - {self.global_.delay * 1e6} (ns/mm)" + f" \n\tPowerD - {self.global_.power.readOp.dynamic * 1e6} (nJ/mm)" + f" \n\tPowerL - {self.global_.power.readOp.leakage} (mW/mm)" + f" \n\tPowerLgate - {self.global_.power.readOp.gate_leakage} (mW/mm)") + print(f"\tWire width - {self.wire_width_init * 1e6} microns") print(f"\tWire spacing - {self.wire_spacing_init * 1e6} microns\n") - print(f" 30% Overhead\n\tRepeater size - {self.global_30.area.h} " - f"\n\tRepeater spacing - {self.global_30.area.w * 1e3} (mm)" - f"\n\tDelay - {self.global_30.delay * 1e6} (ns/mm)" - f"\n\tPowerD - {self.global_30.power.readOp.dynamic * 1e6} (nJ/mm)" - f"\n\tPowerL - {self.global_30.power.readOp.leakage} (mW/mm)" - f"\n\tPowerLgate - {self.global_30.power.readOp.gate_leakage} (mW/mm)\n") - print(f"\tWire width - {self.wire_width_init * 1e6} microns\n") - print(f"\tWire spacing - {self.wire_spacing_init * 1e6} microns\n") + for overhead, global_comp in zip(["5%", "10%", "20%", "30%"], + [self.global_5, self.global_10, self.global_20, self.global_30]): + print(f" {overhead} Overhead\n\tRepeater size - {global_comp.area.h}" + f" \n\tRepeater spacing - {global_comp.area.w * 1e3} (mm)" + f" \n\tDelay - {global_comp.delay * 1e6} (ns/mm)" + f" \n\tPowerD - {global_comp.power.readOp.dynamic * 1e6} (nJ/mm)" + f" \n\tPowerL - {global_comp.power.readOp.leakage} (mW/mm)" + f" \n\tPowerLgate - {global_comp.power.readOp.gate_leakage} (mW/mm)") + print(f"\tWire width - {self.wire_width_init * 1e6} microns") + print(f"\tWire spacing - {self.wire_spacing_init * 1e6} microns\n") print(" Low-swing wire (1 mm) - Note: Unlike repeated wires, \n\tdelay and power " "values of low-swing wires do not\n\thave a linear relationship with length." f" \n\tdelay - {self.low_swing.delay * 1e9} (ns)" f" \n\tpowerD - {self.low_swing.power.readOp.dynamic * 1e9} (nJ)" f" \n\tPowerL - {self.low_swing.power.readOp.leakage} (mW)" - f" \n\tPowerLgate - {self.low_swing.power.readOp.gate_leakage} (mW)\n") - print(f"\tWire width - {self.wire_width_init * 2} microns\n") - print(f"\tWire spacing - {self.wire_spacing_init * 2} microns\n") - print() - - + f" \n\tPowerLgate - {self.low_swing.power.readOp.gate_leakage} (mW)") + print(f"\tWire width - {self.wire_width_init * 2} microns") + print(f"\tWire spacing - {self.wire_spacing_init * 2} microns\n\n") + def set_in_rise_time(self, rt): + self.in_rise_time = rt \ No newline at end of file diff --git a/cacti-main/component.cc b/cacti-main/component.cc index e06f99f..ea48659 100644 --- a/cacti-main/component.cc +++ b/cacti-main/component.cc @@ -212,8 +212,6 @@ int Component::logical_effort( w_n[i] = MAX(w_n[i], g_tp.min_w_nmos_); w_p[i] = p_to_n_sz_ratio * w_n[i]; - cout << "The number of gates before is: " << num_gates << endl; - if (w_n[i] > max_w_nmos) // && !g_ip->is_3d_mem) { double C_ld = gate_C((1 + p_to_n_sz_ratio) * max_w_nmos, 0, is_dram_, false, is_wl_tr_); @@ -233,8 +231,6 @@ int Component::logical_effort( w_p[i] = p_to_n_sz_ratio * w_n[i]; } - cout << "The number of gates after is: " << num_gates << endl; - assert(num_gates <= MAX_NUMBER_GATES_STAGE); return num_gates; } diff --git a/cacti-main/io.cc b/cacti-main/io.cc index bcfeac4..fadb0ea 100644 --- a/cacti-main/io.cc +++ b/cacti-main/io.cc @@ -2600,6 +2600,11 @@ void output_data_csv(const uca_org_t & fin_res, string fn) file << "IO power termination and bias, "; // MODIFIED end + // MODIFIED to output wire repeater metrics + file << "Repeater spacing, "; + file << "Repeater size "; + // MODIFIED end + // file << "Resistance per unit micron (ohm-micron), "; // file << "Capacitance per unit micron (fF per micron), "; // file << "Unit-length wire delay (ps), "; @@ -2721,6 +2726,11 @@ void output_data_csv(const uca_org_t & fin_res, string fn) file << testextio.extio_power_term() << ", "; // MODIFIED end + // MODIFIED to output wire repeater metrics + file << g_ip->repeater_spacing << ", "; + file << g_ip->repeater_size; + // MODIFIED end + // file << g_tp.wire_inside_mat.R_per_um << ", "; // file << g_tp.wire_inside_mat.C_per_um / 1e-15 << ", "; // file << g_tp.unit_len_wire_del / 1e-12 << ", "; diff --git a/cacti-main/mem_cache.cfg b/cacti-main/mem_cache.cfg index 8a846ea..ca273ee 100644 --- a/cacti-main/mem_cache.cfg +++ b/cacti-main/mem_cache.cfg @@ -23,7 +23,7 @@ # Multiple banks connected using a bus -UCA bank count 1 --technology (u) 0.090 +-technology (u) 0.09 # following three parameters are meaningful only for main memories -page size (bits) 8192 diff --git a/cacti-main/validate_mem_cache.cfg b/cacti-main/mem_validate_cache.cfg similarity index 98% rename from cacti-main/validate_mem_cache.cfg rename to cacti-main/mem_validate_cache.cfg index 1415108..ca273ee 100644 --- a/cacti-main/validate_mem_cache.cfg +++ b/cacti-main/mem_validate_cache.cfg @@ -1,5 +1,5 @@ # Cache size --size (bytes) 128 +-size (bytes) 131072 # power gating -Array Power Gating - "false" @@ -23,7 +23,7 @@ # Multiple banks connected using a bus -UCA bank count 1 --technology (u) 0.032 +-technology (u) 0.09 # following three parameters are meaningful only for main memories -page size (bits) 8192 @@ -43,7 +43,7 @@ -Tag array peripheral type - "itrs-lop" # Bus width include data bits and address bits required by the decoder --output/input bus width 128 +-output/input bus width 64 # 300-400 in steps of 10 -operating temperature (K) 360 @@ -138,7 +138,7 @@ # Number of Physical Ranks -num_mem_dq 2 # Width of the Memory Data Bus --mem_data_width 128 +-mem_data_width 64 # RTT Termination Resistance -rtt_value 10000 # RON Termination Resistance diff --git a/cacti-main/nuca.cc b/cacti-main/nuca.cc index 02e44a1..5dd0f39 100644 --- a/cacti-main/nuca.cc +++ b/cacti-main/nuca.cc @@ -414,7 +414,7 @@ Nuca::sim_nuca() { delete router_s[i]; } - g_ip->display_ip(); + // g_ip->display_ip(); // g_ip->force_cache_config = true; // g_ip->ndwl = 8; // g_ip->ndbl = 16; diff --git a/cacti-main/validate_cache_2.cfg b/cacti-main/validate_cache_2.cfg deleted file mode 100644 index ebfcca1..0000000 --- a/cacti-main/validate_cache_2.cfg +++ /dev/null @@ -1,167 +0,0 @@ -# Cache size --size (bytes) 131072 - -# power gating --Array Power Gating - "false" --WL Power Gating - "false" --CL Power Gating - "false" --Bitline floating - "false" --Interconnect Power Gating - "false" --Power Gating Performance Loss "0.01" - -# Line size --block size (bytes) 64 - -# To model Fully Associative cache, set associativity to zero --associativity 0 - --read-write port 1 --exclusive read port 0 --exclusive write port 0 --single ended read ports 0 --search port 1 - -# Multiple banks connected using a bus --UCA bank count 1 --technology (u) 0.032 - -# following three parameters are meaningful only for main memories --page size (bits) 8192 --burst length 8 --internal prefetch width 8 - -# following parameter can have one of five values --Data array cell type - "itrs-lop" - -# following parameter can have one of three values --Data array peripheral type - "itrs-lop" - -# following parameter can have one of five values --Tag array cell type - "itrs-lop" - -# following parameter can have one of three values --Tag array peripheral type - "itrs-lop" - -# Bus width include data bits and address bits required by the decoder --output/input bus width 256 - -# 300-400 in steps of 10 --operating temperature (K) 360 - -# Type of memory --cache type "cache" - -# to model special structure like branch target buffers, directory, etc. -# change the tag size parameter -# if you want cacti to calculate the tagbits, set the tag size to "default" --tag size (b) "default" - -# fast - data and tag access happen in parallel -# sequential - data array is accessed after accessing the tag array -# normal - data array lookup and tag access happen in parallel -# final data block is broadcasted in data array h-tree -# after getting the signal from the tag array --access mode (normal, sequential, fast) - "normal" - -# DESIGN OBJECTIVE for UCA (or banks in NUCA) --design objective (weight delay, dynamic power, leakage power, cycle time, area) 0:0:0:100:0 - -# Percentage deviation from the minimum value --deviate (delay, dynamic power, leakage power, cycle time, area) 20:100000:100000:100000:100000 - -# Objective for NUCA --NUCAdesign objective (weight delay, dynamic power, leakage power, cycle time, area) 100:100:0:0:100 --NUCAdeviate (delay, dynamic power, leakage power, cycle time, area) 10:10000:10000:10000:10000 - -# Set optimize tag to ED or ED^2 to obtain a cache configuration optimized for -# energy-delay or energy-delay sq. product -# Note: Optimize tag will disable weight or deviate values mentioned above -# Set it to NONE to let weight and deviate values determine the -# appropriate cache configuration --Optimize ED or ED^2 (ED, ED^2, NONE): "ED^2" --Cache model (NUCA, UCA) - "UCA" - -# In order for CACTI to find the optimal NUCA bank value the following -# variable should be assigned 0. --NUCA bank count 0 - -# Wire signaling --Wire signaling (fullswing, lowswing, default) - "Global_30" --Wire inside mat - "semi-global" --Wire outside mat - "semi-global" --Interconnect projection - "conservative" - -# Contention in network --Core count 8 --Cache level (L2/L3) - "L3" --Add ECC - "true" --Print level (DETAILED, CONCISE) - "DETAILED" - -# for debugging --Print input parameters - "true" -# force CACTI to model the cache with the -# following Ndbl, Ndwl, Nspd, Ndsam, -# and Ndcm values --Force cache config - "false" --Ndwl 2 --Ndbl 2 --Nspd 2 --Ndcm 1 --Ndsam1 1 --Ndsam2 2 - -#### Default CONFIGURATION values for baseline external IO parameters to DRAM. More details can be found in the CACTI-IO technical report (), especially Chapters 2 and 3. -# Memory Type --dram_type "DDR3" -# Memory State --io state "WRITE" -# Address bus timing --addr_timing 1.0 -# Memory Density --mem_density 4 Gb -# IO frequency --bus_freq 800 MHz -# Duty Cycle --duty_cycle 1.0 -# Activity factor for Data --activity_dq 1.0 -# Activity factor for Control/Address --activity_ca 0.5 -# Number of DQ pins --num_dq 72 -# Number of DQS pins --num_dqs 18 -# Number of CA pins --num_ca 25 -# Number of CLK pins --num_clk 2 -# Number of Physical Ranks --num_mem_dq 2 -# Width of the Memory Data Bus --mem_data_width 8 -# RTT Termination Resistance --rtt_value 10000 -# RON Termination Resistance --ron_value 34 -# Time of flight for DQ -# tflight_value -# Parameter related to MemCAD -# Number of BoBs --num_bobs 1 -# Memory System Capacity in GB --capacity 80 -# Number of Channel per BoB --num_channels_per_bob 1 -# First Metric for ordering different design points --first metric "Cost" -# Second Metric for ordering different design points --second metric "Bandwidth" -# Third Metric for ordering different design points --third metric "Energy" -# Possible DIMM option to consider --DIMM model "ALL" -# If channels of each bob have the same configurations --mirror_in_bob "F" -# if we want to see all channels/bobs/memory configurations explored -# -verbose "T" -# -verbose "F" diff --git a/cacti-main/validate_cache.cfg b/cacti-main/validate_mem_energy_cache.cfg similarity index 97% rename from cacti-main/validate_cache.cfg rename to cacti-main/validate_mem_energy_cache.cfg index db2205e..ca273ee 100644 --- a/cacti-main/validate_cache.cfg +++ b/cacti-main/validate_mem_energy_cache.cfg @@ -13,13 +13,13 @@ -block size (bytes) 64 # To model Fully Associative cache, set associativity to zero --associativity 0 +-associativity 2 -read-write port 1 -exclusive read port 0 -exclusive write port 0 -single ended read ports 0 --search port 1 +-search port 0 # Multiple banks connected using a bus -UCA bank count 1 @@ -43,13 +43,13 @@ -Tag array peripheral type - "itrs-lop" # Bus width include data bits and address bits required by the decoder --output/input bus width 256 +-output/input bus width 64 # 300-400 in steps of 10 -operating temperature (K) 360 # Type of memory --cache type "cache" +-cache type "main memory" # to model special structure like branch target buffers, directory, etc. # change the tag size parameter @@ -138,7 +138,7 @@ # Number of Physical Ranks -num_mem_dq 2 # Width of the Memory Data Bus --mem_data_width 8 +-mem_data_width 64 # RTT Termination Resistance -rtt_value 10000 # RON Termination Resistance diff --git a/cacti-main/wire.cc b/cacti-main/wire.cc index 55a08ae..b986586 100644 --- a/cacti-main/wire.cc +++ b/cacti-main/wire.cc @@ -31,6 +31,8 @@ #include "wire.h" #include "cmath" +#include "parameter.h" + // use this constructor to calculate wire stats Wire::Wire( enum Wire_type wire_model, @@ -58,6 +60,7 @@ Wire::Wire( wire_length *= 1e6; wire_width *= 1e6; wire_spacing *= 1e6; + assert(wire_length > 0); assert(power.readOp.dynamic > 0); assert(power.readOp.leakage > 0); @@ -616,6 +619,14 @@ Wire::init_wire(){ sp = repeater_spacing; sp *= 1e6; // in microns + cout << "BOOGA Repeater Spacing: " << sp << endl; + cout << "BOOGA Repeater Size: " << si << endl; + + // MODIFIED keep track of repeater metrics + g_ip->repeater_spacing = sp; + g_ip->repeater_size = si; + // end MODIFIED + double i, j, del; repeated_wire.push_back(Component()); for (j=sp; j < 4*sp; j+=100) { From 6b971d4cdffa960f9a28a2f0961cdc1450798cd8 Mon Sep 17 00:00:00 2001 From: dwoen Date: Thu, 22 Aug 2024 18:46:56 -0700 Subject: [PATCH 2/5] cleanup --- cacti-main/.DS_Store | Bin 12292 -> 0 bytes .../__pycache__/Ucache.cpython-310.pyc | Bin 23701 -> 0 bytes .../__pycache__/Ucache.cpython-311.pyc | Bin 60472 -> 0 bytes .../__pycache__/area.cpython-310.pyc | Bin 1175 -> 0 bytes .../__pycache__/area.cpython-311.pyc | Bin 1567 -> 0 bytes .../__pycache__/bank.cpython-310.pyc | Bin 4255 -> 0 bytes .../__pycache__/bank.cpython-311.pyc | Bin 10940 -> 0 bytes .../__pycache__/basic_circuit.cpython-311.pyc | Bin 22846 -> 0 bytes .../cacti_interface.cpython-310.pyc | Bin 15794 -> 0 bytes .../cacti_interface.cpython-311.pyc | Bin 25278 -> 0 bytes .../__pycache__/component.cpython-310.pyc | Bin 3576 -> 0 bytes .../__pycache__/component.cpython-311.pyc | Bin 7435 -> 0 bytes .../__pycache__/const.cpython-310.pyc | Bin 3508 -> 0 bytes .../__pycache__/const.cpython-311.pyc | Bin 4011 -> 0 bytes .../__pycache__/decoder.cpython-310.pyc | Bin 25556 -> 0 bytes .../__pycache__/decoder.cpython-311.pyc | Bin 70035 -> 0 bytes .../__pycache__/get_dat.cpython-310.pyc | Bin 8909 -> 0 bytes .../__pycache__/get_dat.cpython-311.pyc | Bin 20159 -> 0 bytes .../__pycache__/htree.cpython-310.pyc | Bin 11488 -> 0 bytes .../__pycache__/htree.cpython-311.pyc | Bin 33537 -> 0 bytes .../__pycache__/mat.cpython-310.pyc | Bin 32288 -> 0 bytes .../__pycache__/mat.cpython-311.pyc | Bin 105718 -> 0 bytes .../__pycache__/memorybus.cpython-310.pyc | Bin 12109 -> 0 bytes .../__pycache__/memorybus.cpython-311.pyc | Bin 31553 -> 0 bytes .../__pycache__/nuca.cpython-310.pyc | Bin 3662 -> 0 bytes .../__pycache__/nuca.cpython-311.pyc | Bin 6716 -> 0 bytes .../__pycache__/parameter.cpython-310.pyc | Bin 72788 -> 0 bytes .../__pycache__/parameter.cpython-311.pyc | Bin 171116 -> 0 bytes .../__pycache__/powergating.cpython-310.pyc | Bin 2385 -> 0 bytes .../__pycache__/powergating.cpython-311.pyc | Bin 4798 -> 0 bytes .../__pycache__/subarray.cpython-310.pyc | Bin 3555 -> 0 bytes .../__pycache__/subarray.cpython-311.pyc | Bin 9893 -> 0 bytes .../__pycache__/tsv.cpython-310.pyc | Bin 4733 -> 0 bytes .../__pycache__/tsv.cpython-311.pyc | Bin 10773 -> 0 bytes .../__pycache__/uca.cpython-310.pyc | Bin 18737 -> 0 bytes .../__pycache__/uca.cpython-311.pyc | Bin 53848 -> 0 bytes .../__pycache__/wire.cpython-310.pyc | Bin 13615 -> 0 bytes .../__pycache__/wire.cpython-311.pyc | Bin 36323 -> 0 bytes 38 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 cacti-main/.DS_Store delete mode 100644 cacti-main/cacti_python/__pycache__/Ucache.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/Ucache.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/area.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/area.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/bank.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/bank.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/basic_circuit.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/cacti_interface.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/cacti_interface.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/component.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/component.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/const.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/const.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/decoder.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/decoder.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/get_dat.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/get_dat.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/htree.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/htree.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/mat.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/mat.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/memorybus.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/memorybus.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/nuca.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/nuca.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/parameter.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/parameter.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/powergating.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/powergating.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/subarray.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/subarray.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/tsv.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/tsv.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/uca.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/uca.cpython-311.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/wire.cpython-310.pyc delete mode 100644 cacti-main/cacti_python/__pycache__/wire.cpython-311.pyc diff --git a/cacti-main/.DS_Store b/cacti-main/.DS_Store deleted file mode 100644 index 331ba38e2d3b1cc8d1c5d22433217eb2d5a79344..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12292 zcmeHNOK%)S5U%lKA6`G!uMi_5R`?Prk#UTbL_#PV$5Dt-6yr6)Q69@a#_PfB8Ea>sWYGyaxy|YfZAVj8DGdqPTh2}oy0>5eMa&<< zF-|q|G(P`ZpgL8kb-n4;s!gv794ev9ppE|}iKvsKe2$iA6~A>LZcv#@;O~ZE#nb@DUZji>@59pMoM<4?zzeMb_74RdoEM|~D9pum z;KWmSzRy#5Nx0@II+qoqycp$2VU9aUR!Bu2Qmtr-VTE**7b09S%8$Z4q?08zLrzq) z6|GP#sU777fs<7X^W>apAkjdt2F{}>hqbql)pvkj6>DZ6tK%Bgj8*qnc&NIoZm>pT zSlc?sI%RM&SkKoX{|%{Oiy8+069Yd2v@JUWoX57y`orL4dpJg`1{wx~Tjk4M0r$J7 zRRcfv;B9(&i_z53s|G%ewm-!itr_~%Ku;^^vh1hSXd62i9yM_^=rFF%!7GN8 zsppVlv}EvWLq-<$wxAgsKi)CvwTa7MJW+OFG6ut_f!Kyr{BS=Vish)tp$KV6wAf-) zTozi|!+7$D#*U`gi^@o2kEjCayxY{%L$MVVoe}g7G_nOwlWg6B#a2{&O7N{X*)nD- zcDRc*dMP8LBFBKVag@>G3XX03i|wu0qRKqcW$uI7L?2{_4g6=zVoOzJWg}VKhI(8N zWfXta>?3S2Evh1CBSI?Fw!-vO;88z7Lv=nxMucCAnJHc1=XOzcP z!%m=OHrmE#j)Cmg*&Fa)c3|#4vrTL4EO;J9iqY{A3O-6>WDJJU7q%Y_KaEzf&F`_l zk>`}#$Nr~*e~}-eK<_2nlO`nxDeWk}^D`71N7$}3)<_J?XfNBB#+epfuvb!_*v@r; zJ}jUwhkAS2+B7M-SSdy?+1fN#eBD7;YaGuIN%gwf?ldW5-MXIc02}ovk=V|RkFZM1AWVB0cOJ%3wj~uYWsA=?CY)VC^ z6tp2(EJwxm&ajh`L<5Ni5)J$}H86)}%^2^^ci|hu9RZil$y@W-wFSpMT2Nx&KYRZk zv(n}WsY!elI|cpU=<~gc(!Mf0Ij^w8m=dl%`S# zSC|?%A92}+n9XsvhB*mqIYt84+W9I~;vpDI=z$Ga7oAc67XqnTnrM@MUN){JzG=oS*v`JA2{zpw`04 zXUZ^iDi*A^VpNlWnL9>uo7YHs>&2Fzi&s4e_M-23zNzjtouIY2_>(m-I5eC}XVRHm z=3Z&rJ1Dg(t#+_d@$c}z4bN*hma&lVnCSiFeqrSp#;XEU?&ufMro-f8Z--p9}) zk`=vfpt10O_sm-Es~4xXAN9}rzSF;7^7&2=vm?3DvGIxgVM zN;yAWt<-iJKDYde*Yy0AX4}5g@SS>TuTpc|#%9ZY&?-3(?Q(v~fUev1`%jBD4)=hW zd0HUiuKBj@ioBa!TY=r$RIYEA^AkbM_nOT$FK}9p=ia^>K=0RE_U?6e%R`O((D}_h zz7^cE{Q!9nXY*dOQni~m-4(CZ@^)`me81v0?3F`Cvb37#uK6}g+H`QueVM=Xd#Kj= z;yaxS{vHh}PxIjg(R}eqQLZyHouVkWvKww?*Urut*P@aPoq=Pxfo0eZJ*3a*bNZ6L zrSIrx`i=gy($<{ynsvrnw%)QXS#MkKTI*KLs#}irVaOlo3_1r4C0POf^d0p5lJ7P> zmmNCu8RyBOofqrjM{zOkPh7A1(C}t_FVA>Hd5NMu diff --git a/cacti-main/cacti_python/__pycache__/Ucache.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/Ucache.cpython-310.pyc deleted file mode 100644 index 5216b6ff2fa51ece1706d5dcc1355c9b9591d845..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23701 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 Yjc^bC&kSE2?&ql}IMMJLhQz)97oRed$p8QV diff --git a/cacti-main/cacti_python/__pycache__/Ucache.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/Ucache.cpython-311.pyc deleted file mode 100644 index 0a8ea8b3223b0816cec836384b237feba5c44044..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 60472 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 diff --git a/cacti-main/cacti_python/__pycache__/area.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/area.cpython-310.pyc deleted file mode 100644 index 434d0abb440e6d46958d00521e983ef6d7e932e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1175 zcma)5J8#=C5GE;ErWGqmQ}+dQF5o5l13}TE2D*6(x_Brd=#XC}bT{gCf=qYLaFhQHx^MO**1BYfT9q zvu@D|$2hIR_qND#xf2H%kv{Nt&smUM3R6qzu_AFPR;vGtjbas4a#6{$3NvO}$trZk z=xQY_s{h?fKe@uXlon}kn$O3@WaiR*N`)I@-Frv{P974n}Fq*1#=_TVeZlge8P8jn9Dup?E}2wo5-BxS7j4M`~(k(hXfX! zb+|GM9~&Nuu2BLSid=mUJKV#zdg$TCnuBGtfH#?}k@&J61w=!&_Jl=O*%qsTTA00V zI&||XTYWeA!Rl`Ml<-xG<)QjTujAJ_2qV^KG7uYKv{d{}ckvupJ1W_Ddko{y2ypVHz#w n7u&&A3oUg+2mFh4&uhRhsnA0Y zq4c02q(~2*l;A(pW7(77$y+3zdh&a-*)?f{`I1g28O95-zcQ;a z_MMb)7z3f7gV13bd&UIYV}gH%$Dnuw{SFGJ|C9rlt;)Id_a)aBBGCdU9l7BUUdH&@-J-P%qn3QCS+xt{^IB{hl@u~-#Y$P{*zFTTxj5kO+I~6_@MWU2X(rar}>aK13N!zZki_JBXQ?~tjv$7WK$VahrtoYV+nk)+mQhB?<`5u~`8CF23W z_>4MDyJtbAs`!*pLPhQdF{Cyq!l%}QAn}LtCe{?|yAXOh=e(!QaCkfqKWXjP1slro EZ(YzQZvX%Q diff --git a/cacti-main/cacti_python/__pycache__/bank.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/bank.cpython-310.pyc deleted file mode 100644 index 2d6bb14246c0b6499133ca13847aae16e8b5f2c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4255 zcmbtXTW{RP73Pp!F88Xnys<8ER7HuCY%W%s7D&<-MG`w`ineNCyC}ey0mY%DWw@8j zaJ`VR>Wd5nX!}s~7uZjQ|I)nX$$z0}l744~>y>25bsa8v?sMkMnc+FJqgJc#;JMZL z+upYuj`J-sCm$coCwSFg0E8o0?hIJO7}0L-4!p=SvbXA0TEvi9Z%j<(i)L_nU98njI`;KU&wXAvUMJ-60q6JASZGdl!@V3)yKV}G` z$8_*TA=C5&Q2svekAW*ZAMKNXy-m_jWf}u}e~6367~<@JsofY2#-m|6ED{o(e8}x5 zc-1CA>O@R9ktsFMSw7>x@P9Tb2v^V4Snnq@CZ=49#;T%dZ7+E zAI5`}b6w|rFcOoT=qBf1PvX4P)IJr0AJB4i>tVJkg6H4X$X@F?sC9mqAfQ57HJYWwU=FHg4;cns0oXkBY+Mltk0vrHWfkWUL za9xnLVPMn17LCc;@*{(nj$DH~N5)rn>Bu+y@=;~jEG}oz140W39UwHu!ou!~GjnGi zpuggDouk0$UV_Z>hy}AcZ_hz#-w{wPX0@ zufM>^Yi8sdFEH{=GxDvXcZ@jrCSrM`jF#}0OFOp7Df&&mHT>7JW|-Ax;f!+hf3NC- zkIFgyIKW^kvi`z2!%eBquEHp0T(K?_|-6rHl`Gp2lCr z`>C!^^97wO==MaV2zAWIv5W^wH)$$4<>Qeo=A1amO=ZcMpp>o2##&OH(pSnAs>v=D zQN=|{RoBQ77~kb2=17w9Q_4qA$s2o=_e3s{qd<`;kt zSm;^~8rMp$x*gUr?YCp7CPsAKHmkE$x6YPX@cpWH8i)Sog*vjmQjX~YhyDh^REz{om~H1v-*^V&Ie`2 z&QmivTkJYfYbLt$GQ8t3}G&X|sG&X|sG&X`# zLuW_+4&PI6-G0K|`L{P7P0^~-VJi0zAvyk-z^eqd2)qV>_F&p9rdYG#?B;wd)8rtQ`zcSq z=0e^@k2I00Shq@}ev$Ww=)9$(Y%$!lDS0>Q407roX!{(O1GtdCpc#Kj;3I$@GiB>+ zsoH^RAFm>!&N}WEqu;u_Zr%+*BSBTBpZi1Ib-%BB?srY!{ZH`2dT8y8Jp*k=0&lQ; zYp2SdjoYTaSCvbcPj(1gB0wEPQr(mkh;Ef#CQ0*r-f7Ig!QYaJDY9#zXsDtaTZl3n z-s*Ugq`f6wG2Pi-2WsXrloqKpcN$5BR{op-b#`+=?48a}(Qb8(&WibGEo;zg|8q#q kA4KE)L;_7f6pIdjW&aTWnhLq1TSOB9Q4^fQWw%@XFQgVA2><{9 diff --git a/cacti-main/cacti_python/__pycache__/bank.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/bank.cpython-311.pyc deleted file mode 100644 index 10ef386234632c76f2368f4121bbcb7e03a01d17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10940 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 U;)2u?O3i=c6Jb>92J;s)}-V9FO| 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 Tc{uV==GDlfk@K0a42=CRubxvfc|ESF1hB`GJM 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 Yk`rEVr`<02ik;zON`JabEFCWY7fXG9`v3p{ diff --git a/cacti-main/cacti_python/__pycache__/component.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/component.cpython-310.pyc deleted file mode 100644 index 5dea2a9dc140dd50ff2397f5eb4944949d126f0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3576 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 diff --git a/cacti-main/cacti_python/__pycache__/decoder.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/decoder.cpython-310.pyc deleted file mode 100644 index bdcd66b43776cf3b09c0347d5e137a20f859e890..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25556 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 diff --git a/cacti-main/cacti_python/__pycache__/decoder.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/decoder.cpython-311.pyc deleted file mode 100644 index 0fce810e0f8a715d608805d9d9925c9f37b15ddd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70035 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 XN7@~GAR*;WoDL+W-m%j^{>A@)8p*&b diff --git a/cacti-main/cacti_python/__pycache__/get_dat.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/get_dat.cpython-310.pyc deleted file mode 100644 index 1307c790f75641da4b764da551fc56f0e2c2aa26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8909 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 Vowv&PSMWb<9W*gLv6}zi{{wqnnxFsx diff --git a/cacti-main/cacti_python/__pycache__/get_dat.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/get_dat.cpython-311.pyc deleted file mode 100644 index e2b44061c988034bcb6fca753636d93c85c2bd4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20159 zcmd6vd2Ac$b-;)BF+<6cb^2J#wq)Ix5BZW$9kzVPhvZYTxip88Xz}upl5CptDn}c6 zD|EGigH;kQq85Sc?WX7gMNt<$pyZ#Z0ou&ClSZ9Fg^M-_4CD`OH!ZgNPx{_BLvlFc znA-LBpr|*;_kF*4-|^n}=Hef?Tuur;`#PtGj&xDfzv4#nV^dZ>nSqt}D3)Rk0qQy~ zjR8YH<)^M2S<~04>n7F=(#%>wT39PcD{BL3W9=aAtOKOO=VYCuMkI1?u=I7>Ncl`Y zqmKp}#WGJU6!jte%O3*;sf^F~!~lEYKe?AR^nnh2RITeJ?&_^INQOFZsu=9T%9!B) zllgL@vSHHVpkgTmMI{WZ@d>E$AyEZ#QhTULYr;CO%7c65&l6aDnB1TyZA4irv%G-{ z(c7t3Dr%lE-ZfpLCJYAZ8fAdLQ0sOoW=<8SDk-kgK*f^H3JD3rcPZBN{;G<`9O+W5 zS=$WPsE~Prl8=?JbyBm;jjNOPgneG!5-9*{$t=$m#ayXGDq&}#%M!+fC9?}A9WxEO zM4N_K8q3ch+6d7EOe?e>{L7z7XTmv2&s^2z+BMug8m?WR%TlA*?-XZDI73AVYTm9K zG-JU!GLMj;SVueLnE8EOot&8^IIT|3*Vc*7JOb!M6P^Rb8#tWtLf`)wX54xvRRkBLqjgr=)6OR zTus_}NtaubgIlA+ttH$a=yL0FaO-rq^@Ka6%WcqbOJcvX9t8fvjd*Osi*R;21OcWRiW8s^Td%w5QYk^8nTcXtl%?yTHB z3iqZiSKD7&eP7XEpzlsyuC~Xt+*kA%aILyrZJ%k!*DLxg^iR4}t;f+??<+k{=#O=| zT7RSEzS7@>zNX84J#TYGm-~9&re2q;^)@9M@Ayh@qf2em*o1bTXak#Ab@l+>W-qY{ z>&!V_^1dA8eLCd*3OS)mK9GZaK!p`gM3Ygd|e?=>XHX?kOy?g zg9`Z%b;&n0}U>lRF@r7*x%P> zkL6&G>9WTa_H$kKL=N_ZF8eNFGc)?<$@esD?fKz7@Peza6T}s+{&lJQIk@+;auW*o z>MS#Jou%M5&SY=5WZ>dVg+E#m^hcxq(D2rmzkyHO+<2K~CBx;oqj8*N-CkcH5O+3S z3HpM#>XGcYaC_VnaaU?@Bp8lLG)chKjI>ZX4Obz}+34YX9zvEJsnvLXqbC}1bDo$# zET`pVZgY6w2nxrd8&$6rt2nLFbfWDWfx9|vmVfn%KCi_oaFnJAns2@W5F#$!28khGh- z#~ltyd70bsJXHqlU{^XFHsg#cxkIAUi5>AuRT7|whTIcjE*f)tJy9Pvp*!XaMx^cO zBD$GiY>h`Ek_iMHFzOuzNZ9Qg8j@($2K0w_#2;}7Jomz5F?V>}$Bp2 z=<#ylRk@3^?#9FVLZCP613Vlyy#YrzDg^jE~Is#)tmA7EkE-*?@ATr`{N4=gHIxJVlCOBB|fY9S| zYen6p^8^PFOSxc4ar9dV80ajH{ zSH>nZr)(VHFCvmNy$)?e+L?1lpb|kp7;#9lUnE;&!DOm8Bef%$$~4NJ*FO&3EzznC z@E(EiFnCR9(*SmW;$e!i?TxQ%^oF6YV|T$JgrdmG*X*cuN#=0G7m^$>XR$!^MWupn zf56upj&+B}LTneug*g}_-~nQi*>~3;lbkRmaIxrwA55$S^a#0!&}jXk2>3HLJa#MK zleT2v?}mBS9lICtNv2_6Oxi$lsSCPs9v~UYNE*)E0S$Yb4jUb{4=ihp^GTallc54Q zxZ&Wn`7o>c!1P$ZHzwIxPYh}RO4DTLP{1<|Rd$g1o~Q!*)8sTDsw5MuYn3~>*4tUroKKf9R`T6Wf z^QEYdi#D?p&7EQISkM=WMVq~07AET9P@}jjhPT%& z+nMQ$5A8GdY4W#XfkH^NQw1d})G?E#_+uic%}aFtJ4fC=GS?>1+eCUBkR8R#g*8u$ zo{oPMeRi7f84wBw#lpeqjwPljnfahVSBrG@3T1-KrEMR@o((K+U%bx``uO2{LTOwq zjZdFkD%}DiU8r54Yec$6RcLT=7k_?$zcIv*#D&uPV(EP-(6aAY=ku1Me9O`Klk+DR z{67xq-F5I; z?D?(^epko*-TAwV&9Hh*>g z>cYJrPyT3%+mUz zX?wEUQ$6T%1dPj7M;6Qr0lxn_KRCkQ=2j?b%y7a82itKH4+c`v71UjF6};nq+dbzN zT#cd&RHcznb9`a<;uiio=o#W8cY$!j@lfX3dOmhmhOK|NLUAwUt0oL5JSjnFU!+?fK0O2iYT3GZL z2N2XUh#-&%su!3Bo@q#d_6x29qU!*95CHA(0!Rai zv^@gT_G0rJynTbx>#FgU@8~uz*Flr>Cjbe(rfTqd(%>Kwf+GmNDU})pSCi;!TA^G> zsD**UcVFhOf|06*O&u9FAfd~`0t1X43SjQ0;A#+E4LEF|eD$Gc>_RUYcp<389YY7! zqNWpT0TPO%HS=K5@~GoCgNyDIU7a{+p!|_b{N?LV@CFowMVIk3F3uX=xbPUGNIPnX zAr2Qt5*Q&tQdwEm3hx6qN7@%qE`Mlq{2~ zgN4)qjVD9~ZbYcQBUazZqIPPany^UA$;Bf691aOkQ>k<-sWeDbQae2N2(C8K)rJEB zino#xh2tEGM-5$A%bnd=Nsw5)QDB;0D6_#~fvywjx)o}@BW75x)>9UpX0nZ&1Xr`@ zYF?oVut*)4Hs1rT;TF%13w0A>-NfpFk?z<0H6JF`CN3)JsZDsM zDOEgGNe8Lq8cl)EW(qbWtkD$sET&+=@~>eECM^FYnt}m&uP}ubE5)oMp+;&N!BC^> z;Iqz!2L3#_126BJ5UTEqRd>M_GAFsYRK$U0Di1u{y|8g{h`;RNy<;zhp9idP`Studn0i{{R6T70gg!UQ#GnW`vtm6q^smGXxqMLMbGXn?%*%p;N5qG zZJfA`gX4?{%obIVeF9x6(%=kGwXJ)fnV*d;T1i|J7Pdyjtq~|PEHH1VihTZ~@EeZ{ zbcaZH$cH(4nZGgsc6<};7#1gz)68|;8Z?H`xQ`jaXx+HLina^PA(aXl@m{jq7Ekln zMujZ_aZ3P{MhEsowR9uT$$#jU|FqhaPgM_VSn+W~>zA<{eKrrh4Oz%HI5 zlMw_<$sh!p@tpBIHe=-lY(vbXh!N@f!;3Ca8iIHr~6J{`@5l33RPU*UHD( zb9%9pzv$*Y!@OTLhqsYA93+mHR)N{6I$}oo1Lye*mmqxRhalX!2X#ysda;fN&tV-w zBA`uR_UZw4v_I=#IK*FsFoK*i?1+my;!sTt)zW47jk^STw@5=!ge}v0V$sa^$}!P> zIOqcd>7bpYgFxazaS{VSvZph&-imR?*iafTF$O9y3kZGy>#%6(T5$P6L zgGMrkLbYL}$kkRyWlbb11Br^%3QV24CfPX1&p_}Cvn+(KlfXDCkG488+CV~;FqlfKGM74ILPAaFLjU3seozj&>Z04`Z z=O+`OMBH!&m8d?8N`TBV=re{&C5bWMBpIfor7r20ks*8vK35ZOGq8YVc1TmM2 z0I^l8I~F<@oA~Px-)0(o4Ka9-paTZo(3Fbl@f&vv^e&O!CHKpk0yT9y8rDVjec;t6Af(@@nzUrRjHFk}lvyfs3tpZwai!`PmWXcV zgcV+GvLr0urQX*(%w?bwR(OvK{%dW$@sh!4ea*nl!RU?pTGi@Htm;dw#b?F?6`vU@ zewnOAtwl1zr9*4f=i$5~l4Y0+kHK}lp+Fd}mUTm}S{rv27Lqvxci<$)SjZo9lT}8( zCJ6U);1Z~033}l6on*#zxFZ194x`xg74nC3!#a01DgGW-qEjHIsAVQ^rf04Q&Q;~_ zM=>}%6Pfm@t|c1-C*zi)rTn6I?!SG1uJz%AnFrJ6<@}=AOYaSQb6~#U-J6eY3i*{{ zekES|D#df7hGnK;wx2JogYTTOobQyk1*TqP>UpMqDS!Pmy+r3t@A?FEpfX;0!&k+~ zc=>l&`G)QDj+nP?4{hAQL)%(M%(QLD0B`--)gy<6cmFb9itD7FfHtaE=d3U;D^`sX z7&|aZYzbJVpQ3?1b~0`>ubJVvQRjm( z@h!u9)G(ExZd6Vh)UOjhG|sEbKu-CSFl1Uu=GME$nW{eO1L^}KcN_9^eh?p+Bx6&H zWbkt#*otD0R#Z%pVfdM|Jpea&z2RWwaJ(*>^-_LQdms$=8ls0`C7JhMfbmH^h)<^| zKL4QneY*8qmRa9>qu(5z-}-LoQAk)Dh_taif?Rz(lKjot_Kgo-m3C3Q|XWMNcueqq4pAU>b^L z_>aC10#r{KoQE$VUoS*SBO)`Bvbaqei(5)o7OM3}V;^03X87R#5AMT;kbh9jKbW$; z!;0;-^M&nm-5}sQAA8#U{e-;!5i2j@+(l##@ysEx!`bec1aIF+jFB{!7uzZM!F6Jc z$6;7}!}+<5(fQEHeeI!hjmBtG8=-EgSG#Zfv=a>43h4fuy5`j?1{H!H*E4?gL1zto00ztk#Q7gxi4|>y+p(EH^2zwSWH0Mt+i^+ z)&zIjxJgVWlP0aPTS_czJwADQK)ux_uoZZE%X z?^1F3+>S?s)7?vS!PHsV|9W>_hU=i}K!fJalkZA3EmMabvO&yq%vp+f3S~9m<@oGR`&3*)R)( zL91UD$Jf>25z~Yp_qSyq(X-uigZ%B&#NH{4oU8#BGx*doP_m-gVL4)7#&5vEy8CZ&ydZ z`~1aor(oH0uGigv?R;0CRG{R#(sQv(-lcIJDzD+xcn!&sx^2!~#KYsfFIoH{)^}Gs z{iAv*XQB9tb65ri#<|g-fPktm(M3NiJ@}kH$S1!`O!3dk;2KBm)6;O7XR1pH5#R*3 zl-yKN%PzR12Is3Ta&-x0Dr(rMaWG4ydF4hXQG@Y=#19g%E#$Y0`R%EwVW$!`wD5&3 zbDi_Wk59u2e4kdzOE{+&nO2@@#b}{x=03TZ1)=*ZTt^wW1^9st!!Z0h1-gYvD{Gpx zB{EL_v>_!+{gyFphV$TjR(~`>IQ~Y2$^oVGYw|e~4%VDzPiDj!kY-7zXcVOS!$9_I1}bq#z4-@ z6Blrzw2sTnIKcrj4K9=EC4u)#oFXLnfeToqqZsZhu=x__ftNTbsV98N1kXiEmMA>F z3FpUAcseh}eGT*6M$rwTmeH86Jn8pAlH`<6mLYr}mM3@&-X#|Yj|7gx16*$M0F5Pr zj~GdLsfTdnfZ*$pHOhcUnK!J+5&kLI%c1xU=E;Lm3--Yf+X2}KQJQNz^P6^3$c_&KxXIkN@sx`@oysV;c9 z1Wu$2X7){WE*F>070=yyT=wpbM>nQ=m-E03=e9mN`7k^ap6Z+~_{xbdbJq)3!BqE> zt$42dxosP7+qOi*WgvrNx8fys@`XF+`sa5%9)uP6K8168TnfxCk=eyFyOs)yXNMkb znzp{k5nucraS~r7x==Y58#osGE20f^mTOAj4rUG9hJ;?cp}D>Td{vyGTgsYgfSFqf z8!MaRT1c9ojafyK9miTonxBVRMUq|0T1c9ojafw^&SOpOq>1KMk;o6&tcj%gp_x@A zCpxsOF&~qFYcy$B2o4N>b|mXbTt>b=O8vt$tmX$|zG|q=mt7n8E_#J`K*R?z3>@r} zuLTaW^@B}E2H84tW$^X4RBn@aQS_bMEQ;SnaUTVX!UrN=eFmNptYE{wXhkR-t00#P zE8xVZ!gm*+hxM@)Lt!`xiq+b=hmc=dr^HSDeV4O`O)0-CIWObmvgD!7T5Sl${SIny z1I4#c%%C6_P0$0&S5BO;miDc(XFY?dDBb|48oeod*6fi}4cv8px(_@M#6lY1`yW=y zl@Hf9EBTUy{Dq+EE%_N27kS(R~43^;}5yr@v^3-X7W@h%!!_0w7GR(ODNa`k8t`&pf74&B#4$Q z_#Q<}d4^Ta$-Rj^M=mv!>tE!28Dn5FPm(Uh!{8-sw_7sfGq7a#mQOhFtY5xLXm1aO z*|C7{F!y_~4~|Jie+~kk0yP+xD904}TcXzU$?sC$x+!|aeA;Ay8A~Mxt#(8H3Y8K? zsWq~%$Z05Cp;DsEiJ4QPY%`{&#Nkpyr(uOs$=#HhnT|g_c0$3pkJaRut`@&;t8VpauF+%u|6DXoJOKpNgPu9Q8YA zX2>BW*-{essU+siz31M0&OPVOJ@d_(=~pTx4Zp9Lf4ySot^o6c6(-Yzr>;L#YT;k=?rTNXahWWm=v#XX}@ z0>_a>aEd9X3{FXw!71;FhKrgjE2vfc3i?;2enYEQKf*k;^^bJWx`@q9FC4^{*X?g! zuIsV>6o~mdZRNM9TmDA_Uc?csf%qCGuQi0!8-^4OQyL9Rnhjf8je@kHrVtlj4VCY| zeS6?5fe{}uF{nf?`N#rUuRF2hdA;Vg?|E^_^S1kPr%Pqm^WNKOcGH&PH>C8oNL*Zb zxfwRSb}y|~x!T_e)B4N}zo}YV;|{YaW7OrxnyNuHlmEVU>05!Xf=hDu(#!qU&bHqR zgG;Tx^n>r$)P3fl?w2Dihle(w^`=$XN7Re(STN8ob7)RVuXbIZ}5TtfH5 zJqZt5u|w-Ha-bp&stB@Pw-sqp6(UuT*nXwkzuD|IN;mxNc3QUH=(n2Pv9(F*G>usR znZXf|Oh=>XVzR_NFj-o*7jXpSwee)7_&~$b8#yjB_h?LM}27Y%# zoq;g5Oyn$)(TXZEkFKe9uN`_G)dCyD)@{9{-WVlAe3tnjxPsP^&nn;7Hgsu7^MfKhXGt3#G-W|LI9swPOE}xIEM1%n-`7m7 z;lMZ5*yfFN`TBZ`mMr^G*+`GzPq8^eZBM(ef2iqNRF&F}rrc0;j3IVC{A@C{qB6=h z`@g{ccOny&vxfPp*Yq{u)KQwGh#BtsSh@FT_@`gGicOnzZh58P&G8ne2NP5mB`R-wWH@ z2$B@-M%6}YO~ z;6Al{pApyW$(!96bhjHjJFTY2(Yu`X<%-x1EN z{ciJiT;7I(yIya*AK*qYu5cj87z4D%g|oPh?bVE59k<9K;2A8@Hf#t3IPv;PXa_#o;dHcN-SFGC6HE>?V7o;YfrY@=K$d z_e;CiC`u2SxoIZf1ZG3r>^8(M!Z+Vic&Qr2%xhl5&AH8sg$#eJ$3@R;b(=xpdAYbw zfr|oS@D4}`F`eSx!~aXd7LGovyP_njh><1za5^h+j}S}xotY#YjpFA-#HafS;h`kr zBld^bFimWO|BN6+OvL@b}C|9XRb4k zaW!c|dI1s9rbyK(V;-j^W}Ik0YF3L6ol~Nn<%!O0O=F!k*17P1r4!l~Cp43_OT-P& zWPT>!f>S2jQ$H{7nN#zoF^R7zVlIX&CmMa0W1_XrpfHJv6dnH^2Y&zZLj9bg8@Bpo zBF_+^dwpC8mG_p{@2O|0W~^U*HFl(GVpm`F6vx9-%kOr*Ed-2>*xqc0zIRn!rp{Ip zLY%F>>hHG0JL)`19f60~eCxFv*VI>u`Rhb}g9aJjBn`>Fdvl0;m9ubQj6v+s&keF60)AwCuRwkbZb zP3IHWKFAfHm}t3Ty`fL;hapru7Ea!K0|&1_Jz(OZFM|89%;+rwjZ=G4F$FFnL`t=t?a*d~F_L4X-ey zjjkD51JvQe@%f-lk4MkRtQxIedd+56QSM5d*bSe@vM)l{QPzD?dt|&`+4>z^x5uYz z%DS`n40R2>WUsA+=TNpHC%KKHY-eSx+Ui~cg_0}oiS)W&IWU@T!iZ-)IxWMVwa+#B z{3AwR2rr&^<`+gY&qkkQ=Eog<_{=X5oEYi~HRW{C9tO zumY#6>Q5eq=+w*9PH2u%TEpQ-t5$OWXf%k8JN>?Tks4nm@(m&{5h19j2!g0< zM6MH=#B=Hu;!VOi^&0Vhg~%@vA>^cf6C^g;z4sa2sW-UV>nrtJ)VdB*uQFg$ZxZ91 zL(l*znahdISPcnGoNa{xwlT((Wm-V9n_ZVi{Pk%2@BRT|-&y*DOca zId;9{E{7Mu4#)64pZlhbgt8 zg~P^CK;6Mn#8C>hP!9>BBCUN^+tc@uvBR@#dBn%lVUADFjg}gM60jf$i&m8AsnY>) zLq3ZsGHCRi3P9y{DxGR_TaZRLBh3i8`Xzu60?L4^$hdU~wBh;pGsto$WI6Zr-s>a_ z2W8Lx8RvuZ9LIo2k%(lOmw=i${v8)|= z`_a~ZwpBci+>swsza`iA$Zt+mlu4%Hls6aQ0gXY858ZC?ksqVqZ0DP%sb;P zM$WKGn`#)I6t^+M}>Pr>30jreY@x()Wwi8 z&S#@4_O+FjNgnEUR2@3VpNn%EGUxQrS(e6E>A?=Mq4#d8PpEfOeJEuTa?)lm}I81c*dzbDTdgE zcqFSuR;M<~IKi*rErN$qXOa1omp{#qZzDc9D=9EdT4~f$I*J~_vQ{c5GS8*01bwqs zhQYAnZ=(|443IrPLF+13;U9QzD^hT#oWQSz)_;SHCx*xlcGi$Dv{6PZzJDH%`XVwv zH1KYtgf|5S#{cx5{@zbh`|LyPvyZSZ<>%&@w=Zcu%D$xapnZmV6Y>%-EMeB<*%Qd< zUH&|yr~Fue&y1+R{v*!`yyrA@^o}tP4aZ~ zDvx0uUPl;6))RON6}{|IPZ6mTVSIIwN>38`5|LjZ@?|2wNQ5w4Jj-|wckrMseGj>G zq~Y6P3-9@mhF2G;i`hgPKGwHleK$dSQ=pDf93#7N#*h+q34nW=L{yYN@R18lkXbxC zt`3^5c5hRC3%%;IQ!oz@^f`ulvArAm+kTY%YZ#BnYZ!CqU_mCwwOxJ_TY@$8&bbDVD!@sOl5nA)_;lESi7x)cp?dPS_3A_~ zQ=i3KiB%*#SM_DQ!2s-?u?x0a#ruqWn}Z%}+^?$J^CYGAhxRbjZR_U#=*>pw~ZkXCGaHPZAb$(YiI*a3Q9QwO(On|P$SZtDQdJ3!}Dk|&v!AVf&=eWfhy@; zXNK0$3$;h1N=~8zvDi6OiLop(LzO3&HAa;rt1^Wu<3s0}M}Q_-FRf#u%A@C-m&qPI zhRg(2^1P=|<+~}iLfc+~`FWmuI&c=fFFNS^y#A3*(aa-Jr75jsO(syKjW_DksPggI zo}tRIwdpl^ENe&JezdhIsyv}3$B~OSbBP}hqDso1sdKPEjSvOl760lI2PBgs5^Qk2bLa=N^hGS93}J1W%nwQ6;_<>13@`wj{pP zfX{vcM2KfwV8_1)_X%+Ri4oDNG#Odq+YCmQ|G}7&kmY$smTQbGFH9gyi;?Befh>P^ zB4nA^I7XI-**HdpnH6K?jQ6jM84uWqEAIy8e-K$7Q^pa<@|dHi{79IRkR|y~yMJK< zSx)X3J@}ZB0twV(EP-lIlRRj2%|`$} zF$MTia5n+?j65t%K^@>8{t4g%oSOiA+%^IDN(}gZU?YQ?fK3K`v*SFX2Wam5b>sT= z^?LEp?*Zvaf!CHXyCVO`mGmPV{`4UI5Qo?4>(rUDxM~%IzBLHw{kfw7pg!-c;3n|h z**CbYJ`kQf)QW&>D9?%Elrmz}RAU)x@xt;b(?IvRZl1Wz@!1$GipBONP*w`2_HV)~uyBcWBv$`<`H^%qQ zxpO;_N2eV*3U|h5L`FUtqWFx^=w!xMN;JNsb7uUJb5+|a>-O}>64L0*C?6wXB}a30 zzhdd|9iVVjf3kw>BFx7d5Pox7e?ZjC3f@O zeYp9AlQ@a*<2tmE@8BUW^a=f@4ik@Qrap5khUPv?zqP~4a{^b-NtR!5lGV%iroBD=`hBoK>dws_sLr$;Z~h$XNhpL5?q&)h%NR<`-Q zvcFOqt*jmNjP!d40{%+Rpyc)Yx(DxIF=%23`KK{-Lo-ic7`Nn2aMw0p9qx z1GvHdMI2c-8X`HlH%>)z*WYN0tk1h~I+B;Km~*s0d40Tca!waQ_EMY%4qKu&93^D1 zY{QmP5um^}IjyoCBN+%X0Yt6!eS??WebKZQZ@({gZ#g;Wareo&ScsyMhj#^WfR+8l z01On_Gj1G@WM$uIjEMFdb@)%KiItKQkpnqKB7VW4zySKDXj-lJiqAs{@SsS{6b;)JWxLl3^W!sOal))t}HjE-1ru!HgSX09%b+ zy>a}xi3|y4faTFxeEsEu>5ylQ*P`;l)>A4UI63GQG($<8C0fh^F}l8EG-!obx|Rd6 z6o`o|W`h_`D0&4`A%>Gfi={z~@g*oi%)#>P5X)jQq#>KdG9ZS7Os^o<%UYC#%ak@5 z=;~!H$5Z`6Blnj)D`@M9KoN@0R)eWzLOJi+=?6U~N6eMJt*PQJk9b#L4QF-M31Io zTP|!Xn%eIUxJG>vY)@%;+vD|h_XMIgH|Rc>d;xz{lwzt6jji)*nodHZoyM>WS|-O> zhNYSZq)UBKfTMj;+la^QqKZ{|tSpTPqk(9e#J1;XVZZyTYh+-^H{|W}4R|FNz{@Vl z+vgsOruPGZqppGeK|knldPFWmR>Ts9AUB#a3i^uc(r6S|0$XZ4W*L%w13)NK>Qb4q z7PSlwj(X*2Dh-gRs8#m5rPD*v6ln~!L!Za#kT=neXmg-Idi$al%1SNhiCWznH*6AY z<&-ZOM!xt4qN$P#x};f|#wq*&{`pwX&P4Ff5A{ zZ`JB--h*LzBnP#Y)Oe6zPAhHLhMD=1>>`M!L<%v;oXcEyb8M>m!|S2z)0^))XNLb> z#Wejlw|xf|-}a=iL@nHoMI(hJcPiDwng`PF21#KXCe2&9ov$mlop3LP18UxDK&X7y^0n;p@=6EiZAHlk7AaRT|Jxg z+Y$)ikBG-q@t7hWi-`H5lXC^dcM5@N84;U!GYv*vv6aKPO}DCB_7mHFEd~(&s5+RS zQRBWrb+vKWsS`CdSTosP9W*6AKTd$Y)JykksLvVnF-s6N5X(5EqTV10v3uxe!Wv-u z7ROC9Ee%_UUr^V&peL&&1lYc#X=D0RG4>H)S{3xiCqB#4e5T(#ySBs!nC=90v0e2u z=;sTDu_S1;1(*&5EyL4?ju+fBoEa|`@DSUG=S_fC3Hue(^a5;egO<&`j6&2t4Sd%% zNMkC~B*y{&A6h=JH9i)gt0z!B4iv$@$#8_08LxVoZV6N{%~3ML*crKR30jfr1nxjQ zP@(rJf&8pw3|`F0;&=egt2V9)+}FoNVO&~`Ef}>~d}7qs0&H7bF(8$#3ffFyD+xY`$1Z$o{(?QxVr{6mysQ{8 zNAva*v&jXT`KfJ?Siz_xphxpg!8O!kcezo7zY0<*L0r zBt&xZZ=Y6k4uw)9j_j~|%6Y4wI5yAlGYy~HiDQ4r^2Cw-iS;9Ecz9|Hag?c!vXEuY zp7C+sRPJ=n-BMDp>&s2E!zAl1HR~;6f9r{u6Kr`CQ0#Ol6T}m7ID<5jv6A?JT>w5TK=iYl#vz^=51W6J(PAc z?c<&)SuL%c&5o3Ax-+Sk?w)P^txMf^f|Q90g6%V{_gtjl;Mbl9RS(>M$oZy}I4-D;3q-uI z98HLBBR}^nqAUU>%DgoVNCK7gv?`W9O*L;VgXpGhcPrJ6`!KryDQ8ZN>1^{N(2g42 z2F12XwQZXAzjSP0OT_lIL~LK%56HiD=qnL0f2|I-Q{0zG{Ut@}Q6;}}QZhxcjJ%w<; ztxn!2m2!dv0R>&)JJ2fwa-xJ5a8PCe@;jc!Hql18u6 zeOc|kqKsW9-PdFNLQ6e-4fawe97ilp2q&@m1E;VrfN;O_6y`SzZJ5+7ysrfkX6>Lb zRRS!qUx4tpSn0-BLR9I#3fuXMQ@SNyQ)fU0hZPj>Q6U61oV{LyWgpd6Twm!0_wX2? zU9>#pNDI`~pn00TM2(llFbFS<=~ib+RN%3l=j)MTos!T7z6$z5SOYJR7J;h7iESBZ zUPvqD8}iI%e8`wK@K5K!5|1uSafofPI)4G508=&qw1Y~9MCUz@^O89+UNTN4@RB{)tnpG4#AkB3FfOrl zK537F$$86+WQn|8eJNek;_6E%&L-As!ps78ASYh6#4h5&bI<)nEi(F%-ozbsWjhA0 z!wK{LrE(QU?I$R^NmlLW=QFghh}Q`^(LWCf{`2JRs>|`B-S@|63JI%4f~@`6)nW;a z_Xj`G;7mXqfN%QC!564IEaJrKuEc*fyj_7DGtDzB$R$udxem;p#{vi9x(OX^wvGmE zbcd$KC}@R^hcO*?Fnli>yAoe5FDp6B0EKy>9D>XjbjW( zsD#(yKVh7Yy+oWh#`_A?$M0UTY%q+Llnqv5Nt_Kb0Ij@u*rvG%tysSGo;$6hn>egB%jB$ z3kW(8TtaXW!Mh01=plC^a3OdfL88r7c4Jx%f;t4p5qJEo&dJu?EI*F?T7a`pDb42|UvO#mT4h)!7yRl4KWX-p>_8~xNoLkBuY7m~ z4AD6sOx~Ofndh?CecU}IO}E~4k&?Y%dhS<|^@r5;he-AzD4kn0)jl1#3uff~Uz_eX zliVX}?vYU1lf2StGfgj}=@0nd@BQ5olGmcmb03a1W>P(!a_HelZ0Lk)qV_y zg%PYZEF3jKtj1Jtf>@2|tO;rj3pBVav|wJF=^Q3XLOT}00AhvhrclP5JtrI__Dw)Z zA=!4|{&lkT6tSNQ31DwuMe9Adh-wz`xK%l3zs~_D(M(cM`Q^G<_x-G|Yri^894A%B zNg|#^(|zky?VZykcgJs9X3J-rzczoBNyHPXcmhrL4g4R)?C=}ZVPW0Q88;Dksp77u zV6LxvYFZ6z{R_iwMYehM%?32iH&Ww#W863&cPwCRT#if2<>?&UJGJ-D5$Zv);UHOe z=>9Mft5vZY8F>txIi8P`%b~Db-pbK?SbY*fW!Mckr_TOK># zz7Gt2*iH_#D(&aVf%8hoduoSI>GP8gaMBqi9iz(F_~YOttoqxlanAq<+d?huMG&bK z=uTOyZIRpCF{?wM8bXKAg?rF;3hiBj)?xDQTgicDrL~P5Xj9rRs_k8hub;H{D?`Ji zeOU1a9$y(J&TFdk8niwMdm(f@$x}^blBXN?_OsY=8>lUi)h1BCpzRde!8?dj`Xf6Y zBhGQvIS#E~=Z|6Q*Lms|be(Ue)HP$rt-^WCY6YbLDW=f=eyrm;#_;W`xcxVS_oc4} zl{4++aJ$lRksQ9Lbh_2fK4tI<=>)%|angyJ32fL$!6gb>tE|PQ0YX3Zu=7KtUO1-( z9kc+|&N_i;$m$e)G>t;L4^Y5Pb=r+6w35Sg%n!3MA0i!~cmzmC07m}t*aWG#u2yJn zQpd6NV?whQw9!u55U2CPyO?%fpl(o=6xzWV>Ula2l8Onn0@br>p$=QG7S3ovEA6-y zJ8l;)Vp_Z4p=lJ_J+Y3Vd-&5?zb5NP9zJuDt;zb&Sk^U|fJZ)(Mg(DuHS@AHweg;$F4%QD?uN?6` z-*EJcElDo()rQZf4M)LXOt)L=pWNz)xhz?N`K&G|!8}~`HiEW^42m;;_mCMB;dmLk z%KJgfiQk9K@{XWI=C8vCy#TGj6o8N)6t%MQ;lQ3at(5Y@cr2KaxQb0!mM$4v`$6u% zV6s194Q5Q(f*FtpxWn;39DF*R4s!u0#P0zn(gyy6j>lFIzYx4MOL7wj#5E+pdIqFWUmYHTbjGrE9&hFxr?|lj3{>* zR+41`jx++VXZ;%hi+&&T5z_OL$|}@m-cCVFGHKTHV=e0CjV&_C{UI&F{9(RVbe^vC zlV3J}mcUuhPu_zuKPNsH^cf5^=yv<$T+#EB_h8ItPf&hqFinabc?9#9>t#ya%KFun{syurdEx@|C;?qx>Z6!I;nF z0@hdKoXm}nH^{S&QS$!u{N(a%%zwcY4gBXn2P&R9pHqV=`mBxZ)0vQ_&uf#h#DsYu zCulRKXx~oi3RzKs^I_6ZE$>} zc1RcQg!-M+)YR1E6!Zk`xJ!Jzr+zHX@~9b3ed>vt`v$vr%lj~WF9PaJf=7?Yl?Zkr z*o~kH0V*)s`2h~<-2x69exKxZK~r${lrP|cvm)W_Dfx9M7d5-#?5QZ<6Xi!W*OnTr zU59{rut<34K>$39on?S02WZ|ZZ@^vDE_;W(a5zEC4aK2Hhuj|DK({;ur9Rh=w9m{wwU4zYIO#NG ziIi6nTS>?owoX|iMPz}OnF?>TUX{DuIZMm!r z$lr6^Ab$dF1Fc$6*noZzr!*VJDd7@Y4^Dvt2b3u25hD2oU@t5vgyXY*y>7Z?ru@?l zcQ^cv3)3o|nuPqyx!rrfUYNHxR1Y2r&~pYwB_C1A-;YOIy*{&9-F|=+9=I>5htH70 zGfL}uwG}Koe&}e3r(d?WX~Bj@M1_6S?m<+VG}BF?PXPZA=(cb}q@?uMo2ET8RiEy- zyW?*LF|86%DcCi)XD^_Vzb|y+gA?#Iz9R=t;HtgT@F;VOlDP$#edqLybk9eM-nd^* ziVj4I%kOl~NNUCLhdFA)B~o#T6nm7OKDB3935<}Q5#{O_=@}zM)sFqaDZdP~Kl9Jj#nAH=V>In}L*VRpmy8($}A3xXE zk7y0>VcRVm;FG=nb^$nkTzHhVm1J#w0tZWs;Xuwde_l*V-%v~6_Yf#QK z|J^C__F47qv!wKFIDLhDT|^0(swVkHMBJwZ#qTUR_{Cti14j1>b46up(d)Bjb=NUc zbnN$%di`R{W7HuI~@ zhvnqWcSzAY*xD)nsl@~kh;Qc4@=sGt8_wd`*nV1L^Cufuw)v+y7%xiddk55BYGm&n zRmQK8UbJr?1sgBON-s}?l9MPar!_14X|S=vLU9^Axo{c)glTYjnMv8zt@K`228SN| zuPAYcw`$=S)}8=sHU#Kk22IBN%!VKaiI@3W47#+X5VnE* z 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 diff --git a/cacti-main/cacti_python/__pycache__/mat.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/mat.cpython-311.pyc deleted file mode 100644 index e80dc7512950264afe3f83fa1a6c63a7e097002c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105718 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 diff --git a/cacti-main/cacti_python/__pycache__/nuca.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/nuca.cpython-311.pyc deleted file mode 100644 index 711d2d4f3b51bf1f03929e5a6a79cb41a944c1a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6716 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 J>h+6h_&@(Hlq>)M diff --git a/cacti-main/cacti_python/__pycache__/parameter.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/parameter.cpython-310.pyc deleted file mode 100644 index f3d9cd2007aba64da98df4f25c0c9df0ff93a83b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72788 zcmeFa33yz|RWIJF)ZJ?ByX2+iUAE=jp0UScTbATyY|9=?W6$&~JyPG+(w179+t=2( z)1FM?$-YfCvd)W#5W+wngd`9k3lPW#BtYPMAMX9wh(Y?^NB}x4Y%> zBzf@u|L=R!*XN!(b!xqJt4^IdRkcuGAM@ewga7ogsXH$Qe1AcQ_b&>^5&ZJs4)}bA z&+yOrlIrPC`o$ec2ILt`291CboC}Tn@C?m`=WCKRe#Kjxj0jIO8O;Q;u^V-nAYfcz zy}*V{Dy$Wy*#>v5kEHDXWsjM()+vJI{}BMw&_ zu6Co|XaG+KsEtMws7;`D!qsfFz|{g*7hJ7I8(eL0b;H$ebimaCR}WmBMi*RNaP=D9 zMh{|JVe}d+@LXxEG*;oc%2;hA@LX;58Ef!N7;BAnc=j3VjSYCNF*YXG8k>xM;OmUd z#uhx+8(WP5JU1BEjcvyEr~Ju{#tvgAD4UF3$$n#ZalJ&p492!x&87X&g=NH-?f2jN#;6#z^uY z%5cm$jxroa8SaMbgmDtClW-k^>mK72T&LhV4A*Jn3|wd6Is(_IaTcz#a19#gjC+y0 zqsCLlm@$t04gtH*xBzSz*hS-hU?adDFp|KI0ejGR2-tDs6~@EHBfw4=DdSPZaT0zL z#v~~B081MNuv5S?#uTvAz^08EU}u2M8d+eYz%Chcz|I1jH*&zv8Ryl1=HOJ=STGhr zySI$?m|=o;-pCskQXMlc8&~igHHW>%QcJnRdX34F8y~|CKlSEsWmu1NQrE|7L*DpqZH{1h#Dh9?xH$pIn$r zSre0UnKZeaKYT5|5Pm`Y@~Z$W-wpq>zH5Ff@G9Sw-|!oOry@oFu$ZF>C zMe{k|^C!38m(Q5_?Z(pf;f3_&`Ap8rZ%;26nf&Z@u7u>x^!D^b+L~1`wRqKTmGgijjws_T!9-PkP8111}W{pJ*JlW+dY)CKUtclrNJ~ffMno>E~c5rSXJu#O* zw9O6FAGD+JT)djPGGW>^S0?5zXYzIsVfq6mdm_75h0U9FaGC6W%sA<-%OubM56MC# z&=E9S;7a3H_Q&^d1i$=NfQ*lQ7WymJz7PFX&pCD9u~YtV6DK2z^K5Oz&axc&bYvO zp)?3=6xbxNSzwFA*($J2V7tH$ft>=o1a=F5kHB7mD+I0-xJuw^feC?q0@ny!D{!5_ z^#V5t+$eC9ze23eP^l?+|#W!2JRb z2)s++L4kJ*{~^H-3p^rlP~cI4Ljs2djtD#^@VLMe0#6FON8l-erv;u7I4bb0z;goc z6?k6Yn80y?_X)fp@S?!`C5I0Po)q|?z=wqXu)s%zk`nl+P$uNjl0+;2VYhCV@{2e6zr} zi0@kkzKtDWe`wU?XL;-!0P@%Wb~}O&Z6=e-7wp=(*_k!BRFoZA zylf)ciFu8sC+3rl<|2CkdRSY{@Z?75OL6`ER_H8c6t0tpkQIdL_)X3|`kFwzrw zD>Y#lX39V)@pi-H?U0q3U$k40N-CY1!|<6wuC1$!8M}QkW6q|g=N2X>yyRYE!kS;_iaqM4b>Sja5e%i_c|n^S6X7Vj#? z>NjRHsARiN1u`;=)(mQP0d-^mgRGEGO_`a;QfE#S>^3WZC52kgU!IhDQ^jv0bs?W( z%T$#5@v#d?b|I^r4H%5AS!;G7mzp*wa>-_OwhVa*l9`Fu!QvyEF0=^E>r(7yZ)nc8iKweXSVkr)H<^I^~+nT*=JY;q(Gp znvI5!=%s$r3zu`2-KYY(WIJMH<|eMDkl7}DrxWumCqGM}@Pp)gb1C)uYn+`&sqjrs zK)54P@5GW~%yxTaRGM5FpCY%EMXG3V9kX&pRrE&YirriuwUElAC8@y^CEXE;PJG;` zRMZ_+@o9Qhq>A2J9Z0)K{rlmJK3lm_z01BCZBA=H>~i~l}y@NFq4f-v(`*1Et#A)XAQeqeQWCNPa{^t zZo>B~Bg53(!h|)Oo3-w14mrYi z3t<>T3VTIscAh*jY75t&c~k&L;hpPx0&1=DfXSqm119f{wr z#T%Pk$Y<;(GqadMWN2F~65d*Ui85QraGsUV%uT5Yi_BVN!V*a#USuTI0a+x!8Innj z|Ns8Kh#CmQ{Dsc)sn<5AF4LTIIe%M#u&QMacA(wodpcHlg@x&{;lCbuQ~X+>7`VYX zckm*#P$B$Z5Bhz%$WC9rV+k52{y%_UF*uBn4`;50ilG|;@bd{>*0X+dw?#bstj`E` zW2TOoO3h;{#Ww`sqgB4O+BXc}d#ijS+P4P2k5>6cwQnta7piaK(Yu^}r-&^HduYK#_`!iL(4ca#j-(RWnZPdQ?@cm+yZ5!Z zS}hgz+*j0)MZLwO3+2T^4JNv7%Tbv98cu zD~0Q!s=Te#{;R})uF8Lv_Fpaj#VY^R+CL%wudnh?X#YO(uYUi1+JBAsf2b<_8tuPU z{J&CG%35Pxv6gjWe%4rz8d+;>09^OjN@F8kRdK-w;e*B|iR*i1aYc;&VnpKlYhyD) zuSYCfH02+Rc1_u;DbE`Nieharwq5tX+%NHNN4x>^U|GCTV@ENHcmrmegxQFAcWTN? ziIBq+R~bOJ(|`q`g_vR%QCEq)m!brY}p{pdjA6-FOcn-k`b0+Hzy7akvuV3A%kAll+;IzvG_#J*MM#^0!C3o&4?9ZYO{H zwA;zw9op^W?@r|J1k&H5^S4*$Z=cTJ9Xfw^R^;!bmQ;egn1&c75N*i$REdTwlXJw zL&)E~$lqa|zau(-gF1glb^eAb@^@bHhnn+@CiTWxu^w+BWS%qzau{Jy-^04T$Ay0i zsh7(XY=I-jz@;EUWhBHg9pXL-@tU#}8jK6Y21%hP@A)|1>P1a?g}h%}+v`rm2#BbuJl^zUkVO4A<|de{tU`lFiukft|jx|8mNrmxWS zNzI?u^i7&>C_4JAjN4~TNePcty}i?Td#8=*OCgkh1R-V^Lf6Wygn6W_R+^1$u^F`z zHj{2Gp3(f5g#Stze~U3!Y!QCbXh)0U7d)!@=Y{``W&Ev1uGlL4uQfJ;pX2gb&A%Z0 z@_$(SUlae& zSNT7p{hxq;t=Ujk-c`m+i>su(e*(;xN})%1Qd7PTOi^B@Dc>?)rYSGilp#%mP?DZS23>GhJ*BUX!yUT@&&<&kS9Fyg!s{l)}Flz>O>c$0*BU0MDT z#?!@wzn(|8HEsBB^-s*|@Z4&b@mBrj=yuH{bF+U5;mr5h% zAJded2Bs+Q(3FoF?@$!P{7z5I?~<6mP(CXIr=eTGyT$*Hs{AwB|2^XWZCz9Et*EIf zYd7j?%9GwR;E$Mfn*YC5@J}Om??Z^`ikiJ4p*HAH&sKz*L8u=`sF{jT@0U=Abf}-G z2sJBtoAu=F1Hykz-Z^?%E!RfOhw*)Q<=QOL`ykTGI_crP1dX4P&_xOToF_EreBRKP z5c;PP`jQh`*W}Mg_;+H4Ou70)6}g>5sQ->oa}}X}RziJBhx)mSQ1b}&VT77@LJ^0o z!gugVwD_O*jCLQ9m@w0q^gmh=Qw}kG454#QOgh)UAfdjaL;Ye!s0D=jI6^H{g!(0f zikiWyerHj~`pe?qTIK(k_Wu>}ub!cr+W!;cU*4~;F+N#bgYPA3?g!>eh#k zQX1ih^4DRkvUGHHr5nW#8di#I{!A%}BhK#H%PdiIu$WC zk$68?7VkR5woc-Gv&4H@;#HJ)OT46fTJyYL;spiq{)QXxZ%VvhEsJ-(@!8^fiT6{$ ze5osl<#U?yIbe$Nc}@9U{Swq|5)rV=Jle z9D}~odg;@#tM65sPV`lN%wzsQjW^blMv(p11H!rF>;J=1+iw=a19@n)Z+;(th1dXB zI1?lk>IY;^Gl7NBX=|p?H6TkMxrw=ivm%<1wTD9MfGi0~sKlnpt5zo8UuYPRMW0#d z;JK7hXd1vGn=!Ct&RUrS*SZUB1DVIubC>h8S279uDQdfi>S3-$CUetsnL>OZpW%YH z;*Jj7H#C^w%3z^xfGf(mg}H_4tFwO%p|?e1&LwVSZk@X;oHO z;iSX$#HyHky$Ryo%`VR11?ptiEEBYnr)^*ybyAt(UMD0gtkSc`6QnY_zUqLLEVTp5 z;I4pDi{)JcCLw%7X!H+lTFP*}4ebJp*IN^M4HqpNE7x1`-N~}G1o(?u;)j=B>`Di=wPtWT60_sfs#@6Ozqs^qPt4y?j6a9X4spI(#jyegwV;@ zF`y}hN3d|Lu;^(T%8;SZd|&QTZea;8h6Q4Ok0vt&GZR(Pn@#*`){QP~ODs%*gls1A zGYgmJjKpLHpJYCtu&}P3*txF{-KeTLu~kV1PVWNc9PO;Y2kVt&WO!tJ@Z@PU%E-W= zVI)R|hF}F{Ud|L+28K=#n<&1SaBKuHiVo72N_~up<1$8}T8}DAg@j|Nz*lj)oT&-1 zl~a1kt6n~4C(2a=UT5MQ3>MhY=hB(PX&5dPI&~S;py}EH=aIoP2;-8*}cp-KJVnq}h9zMU@CfsA!oIZ!=F1zL;n%Bv*b_3tn z7~fZFcy?+kSu=*teqyfR_SCXcoIu7Cj8MJC=)mkkLRl zN9^#}>5-9hg&wENF2&%4;;>jU(?C6VT+-D(w2l33p$YGjt(RRQa)_=lD#c3BLZW8$ zY>Mx>W^80=cx2d)4xKo8E_LeU>C?+4Ety9!T`?HrVNemiZ}{YyGj{mAJZetM^Oi+t z5Y)3W9YIqr8JD0u9_tdcIgd*X9W1e9U1B`O5|>=w64wuEdSduq6xS0fJ>d)HA z(4bV3W4wZI-a&OfY6oaAf-KZ)MAKVGFV9cnBf+OQd~aeA-H!}Bia8G%Q)8OF&C5RK z@TeUnc%C|GEKwBzo+M-E-gAcuKyWq{8LXN!AHneMiaQ zAU;J`%q;Z+rFbwgLHDCORCJHp;>bUaUW`^p@L$I42t_TkJHmS_H#`DEndK2aBai73 zh6rtY^n5%qn@`NoVtC9=_w~Qb4q?iYgPj(pNVHjl@p2w7WzmkIuY<`j&E4!EMjg-> z=OAapCdOxS4~e;xU>5<+k<3nl)dUHGK7us_YYDml?63?oCikwGD+#&@IBPIB609Rw zPtZ@WiC_c4UV?oDcM$9$xQpNb0XMUly#y-&?AQgGo{i89%N!te8^Lyh9rO>F8Ej~g zX`UUPhDqR}d4`^&1ZN4(5!?%4hh?H=UL@guf(Hna1P>BS5S%9%BN!*RkKh8qLj(^K zJVKBnc$8q0;1t1Wg1ZS05ga5qLU5Si9)gnuS%OOhd4f5Dd4e3l0>L7INiaxog5W3t zjhW10f)Rpa1jh+pL2#YGB6y16l>|!!mkF*AJWg!Al9AAhUFoT+`{Q{E@fDAMw`&bjSeHSHDO= z#Z{u*+UE!5jR$J{P452=f8a^xvYN*Hm2$Hj$8xj=e+Ob~kr)|sc`VAMa!fv_4pdFN z7|5`UJ>n01KORu2{h*NPvdrFam2by!m-6q_hVxv$-bw9}99D#^exsl`sj&Sx;Z$fv zaca2qhFGT#M-#%RdT=PL87EFY%kxm3;}=6=c@-buSb6N~9eQCK+7q^K;=kt0zL)a9 zVNV0{5%^xAOJt67&IZG6?x$F`)vylVB{gCk8S+iQ4F5H3V7!LS*4MCEFbnskfY~IJ zz_nnGrjtG+1X>R`0-y(TQK5xFTk8qwH(}bA4M_MsRxlgN@3F8Il8Rv?Fb0#zYz>WJ z5f_Fj_|&>SAtOT5%xo=u#^J;Gu}Qnv=Pc9c@YvvZ$q#e)Ft%)$VvQJemqKP1)VPNl zy%t6+v1>Jeb=PVEr&ACTkyA*@&6-y+F(w}_u6iC zUkc>^L$IDp0aC%==H-9dpRdy)7(b0)+riUb!Lw5HY$`@sf8g2#t`3(g%+iB8Sj6U3 zjbT$NOj<~TAuiH6tm7CgM&%7j>EVC67%PTQ%l;fo)xvfM>U~BC6uy}jY*Z;n<~N;{cXNpzEkEL3-=wb*wyY;ijjUj}$)LUeFZ!7wNuP{hi zDQ|HV+Pu&Nu9P>rN~gdOKdE@pvV5s%5p6CNE27P%>WXM{sW>=UYAovUedIqSTNmqD zR+VS)tcG90=w*H8|48r^tTBzR?BI9Fvi!NlcAdcD%PO__qQ8yR`d$2^F6%#{jH}(U z`Lcaa2NqGD>>B-CtDo!ib3O8~!3bjGV?u9y9GArk^Zn>33P*;|59--aB7b>NwiG57 za&uRq$-?Fv^9r;|P&|9(6pvo6FBU7b9p%OuwUje|Id3Hn-JRHZGs4JMRC+-nHbGq% zmJbqzu49<>VkyNF6#j=2JElMK%(p)HxlfQdkX8%u_!~V%u=SfyUAJ4N=)PvI|_%-vTn(SM5%ea3cADPYRaH4RHbsguwbJi zxWKT?qU@7eCU7Zv3U^p3xH1bB93@22eoZc5%CFW+5Q)2fQ8*|KVR9mmg`?XgfyIPG zZozUIOvWhOdAlHK?Ce1ZHULajODkZ71Gf%YDvA4ccP6}Rd20sC>PPsQg6EY%weBi} zxR;DGWorRiKP*(uLC0}AF`7Y%@!~U>6+;Izn@eNfoOfOY-||+zD!353fCeT%o#e{-wf=bL>R;AV`CX(%yXT2xd`2PK%ySWB5qF0p&Z4tdvm@H~~7 zyMk3kzWRBr%*`%hi3N>v=ZbWzfMgO{e!ab$PI%ixtWHS?LV3fp1*i585}uJ04y{* zHgY~08XG!s&h`&g&S)AkvZ)IT8R<*Vo6KT4GygS26!P;w76?JKj{#E<&p;CdIzA(q zaD*V5wFw__ihA^MwkH=u@>v78Sa6w{(RDolH zKxuYD!rcsai^tspcdN%OQlZD)2LE=CTjV^Cy95569=FJT9yc};WxF98bmQ5hpS}9I zLO)l6U*u=xuLpdqG<~&xQnq0DKK)$d@PoD%639k`>jl2flkN(**K7U_`ngd*H|b}; z6A!{uhTN>_Tl90Qeh%m-wpqCOq^z~plOCldY`<_@R|0Nq!*JbwaAP}$>s|vlw`GWV zB+_3C_im4S9o*P9;rc@w%3}M3>)rtOK974N+}KXx`fq}p+bW#+`{Ca2xQV0QK7n+x z6^R=cT)r)EV*`Wh-U>H1GPrJ-XJ@gY!F6wgn;RRPbhg8djRvlJ2i!+I?w!UiWA_^Z z*p}$a4jOwzn*KxNV-MSFj-?zl_6qg?0d=oX*(L^!eM0>kQ1=P7QK)wa^`Ak-Rwcv` zvW^;e(&!45{hqXjj051rAv~ZTaAO@Z?hS@QiiHI4INvs0VedK5p-kFY1sd z)?wqYaP9@?Vc}$Xhm9jbJp$?xp|V`V#-LD7fjTHumTTBJD%1<09u+EcFl-D7bpq5O zp@x7B6T@@FlY%{e;lp1o{bw4*aBp_un&GNO&a0 zMD-uUkAz1;u4YJ(qg=+RWFp6TnnH=puEh6p9&%h18>(BexN(%Mr}EWtjA4+3$dSq6 zSgw-wmBYw5#!6;Z4%rh8IaGZpS$q@h2Kqhz2`TNkYmrsvr5%jJD=$^^2#2;}s`e!X z9P8D(xyZ!JFdb0&ENr^vDX9$Hzg*v7C{WL_Wr`jM-BuiVBWpq7V*kY$FCFm};2Q8LJ`= zZSqpGaAK=SELo~y97sIxXK^acpo9q%8{uMRX^pW=lhcVwl~lzc1}i$H7vRvzNGc_( z7f&%9lpLct`ywGmFb>uGB!`%;l#F7$-oRZBk5x=L3pq|MZzQ7`-8kIEi}Dy$Djuto zN^iIs2W%1&JdtOHy-U>}InFtTpH;pjkmD%N#ld`^=AhL~(#mngF?l-3J`$99JAPVJWAVTrS7160IB~$Cy6oC!vjf3@l5* zlwu(#tmM#VY?KFeT?Z02k01=9n>IfR$=&=I!7mW}B0!WwUNo zd=Gtp@YU#347S`Fbe0~M2zC?fB-ll8f`Ah}wZJ?~>^Q*)fh;h~GWB&jKS%Hs!7B(} zN$^er&K4Dj1H;KRvoJBhIZLyP&vSy!HrV8@p%IIFT(YW%=`Ek-TuuHR_$QUmNz{#qNyxZn_}Oe$r^Qapv`GR|&G z*>P-IgI-bjnD1uY{7-_vBDhIVsxQGssY*k@gxPSu!`v5r zH+;|HxD?9IW(^29_$G|e8D>GtG!Utii6Fu$GT7-;rtPIQqC8FiSAuN zzu*CZL4hHGSiyic{B}ock|!>lw>w&soUOvyCa_&#hrmvOT>`rW{+~Wtlet~)Xid_c zqcw>ybF`*);5y!H>Ms2}sGoQ1=OO((te;1$LE%5DpF{dNY>f#0m~~v9C-n2Ae%@o9 zG6LO9X%jFUrUR@WSV*ufz`}xU238|jEwEa_?f@1MY%j2=VEcf@1gis9Cs-WV3y1gt zb0CLG#?{)2-5{fm7@(X?E#z=O9JHV6D8dT{4*e@RhwQZ_2Y9EZQcDXw?Fxq?W_Xq$ z&O5~Mhruh0i*{W;eF+{5sm#=r-Iku2T}+`<<%yJzgl4zTPo&L-Dso*OM}=i@U>Nvu zu$6LLRpuZ4r|ll*4u&atoEC^^VLj_an6m3&tD0KE$&)zU4~~h)T}Ok*0lm20e3>U$ zG0S2#gT(CMv9o*Z5EQFd%zwd$YR6zrEs4`G&A~nBqWL`7%>PB+Fizge;}|Ylso*F$ zEJR^Li)FXzgS8aZT9BvRSxI%+qdX*Wk;Ss(M2%VW&#+_^ld1X3k26csX7dx`Y(+C-6Q0D8ZIGpBI1Ob8 zhlr!`y3d>(O&uRRmpVE!o;sHr934)LriM=*J2qzbdcDR5&y1wTA2>InJ!2=%oxM16 z{ya?fVV%Y!N@wt;O_|?iZvTzoUzz3D6wJnOnk3%69VSQGj&XZRIx~({Ih=IubP@X8 zJgjP91D5(S?K-hw(_1HSUY_bq>_~ntlUYnzkK0Y&>7Yayldn*AS=cz+kSBJ^E)1U0 zX{#eV_54yO^=hNhoJ(O1WdoFj!&^F{^fnc{AU~@-+}FH?Dsh9tOts zJVkqFS>(U+sTN9>gE1_ol>Jw_v9wd@UQP}XF{VoHq98)?Cm&*&9kHiUvU9~dyI#)w zQ|Fh@rhlE4L^&qpFZ3;!Xc>2!5|#5uoM}qp&m$Xm=OSM&p|_+i;8_u z=o$_(zXmIvYvG)2gk8?nMh!SOYtC9&0!6@C3(g2QKZ`XMC(b=a44j8GXB{}>;H(2@ z9Go9E>Rry0MgusA0}XDc|{!1+oXwBm5) zjSg@=p*cIj*#*u{aCU+7F{9Sye6~J zXmmM00$U`X`6H0Wv&DkR(@|mutUfGXI$VM+pY2nD*_}F>R$kXSz2z=Pi$EkHf@C z_02wlL>1HST{?Tk~v6>(;^M8wIWrI{J0HFh^fYa;~<8I1E-gGVqP z7R=awlV9-T;OWA8EB|X?X!xIxaTS_BOqvG9-70ZsY1?j@-?GCo*@r~&lRo4iY7(su zR#?Nnhu^`2G0}?z%zDe84deoVuq4D$34Uw}=fRo!fU0ZZs)IAvE%{3aXIeE{ey;_l z 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≠kR+x13)MxF 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 D{KSSw diff --git a/cacti-main/cacti_python/__pycache__/powergating.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/powergating.cpython-310.pyc deleted file mode 100644 index 0b9a0fe7dfbf5e6554b2ced6b837188160af6db5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2385 zcmb_d%Wm676rJHq)XS0`IdumU4c^InKQ$ATwb1YmABgs0@oki-v{@ag#3w} zvzG&%@8DLy0dT@;LV~KL0p%9A6YGGKtzEWG;-qfiQXF%Edx2MSJ8>5Cs`*}0OZ~uK zJgY69)fa8!fIK9;#{HLs`=WVl2Q5zbNx%LMq9A+kC}5u&`U!wDWO`DyF}ABwo=&D( zuwe)gN)bl5=`hm@D?z|*{!(Hw{>sFxz-YepepoW2% z+I}L$l;lnww%lJZ%0IrwV2G-dm zCwvw87SS8yO&nvF3V6BkrNX;PEa>UWdW%DxFybSY>-_N*?)1p9%bhLqq7LIQ@}f~J z7>qUb)nnZ48a%u9`g+lPL*d<#-zXXtfBgaGgA+)jyLa$FT9B-F2>qMJRnv)(#%CQT^mrkA@Lf4MAZ!sxPN z8b9Sv;w08{mIZ#g;Ktcu`SZYu0L}U&%@xx*%dk~POolqnrHhBx9^k+8NWZ0~&RCR$N-_49{QcwhFG@(Y&1c*9^Jtoi zOsnlE=R(E9?35@OZAbXgDrA$n9_88gB%cWhE{(I{oylBcA;Q?yX8;ZAo%=QH2CaTA z>n>fPw=AEwDBke1j=KAmAMY%s6Je29UMMfze+O>0QW_Jy4sHjtpi!uNsKJ_JTRY%= zl)XFl${F~yb_@b%XoFJd8z|^TkLV_}_L*6(Zf$|3U~XHlls4#`uF>7`>UgcR5v+yr z&iDcYB#8&H;FaD>zpn2laVA2E%EN)m0zs>CEZQ}k z8~-s%H!v-5ctrg3EK$2*VSJH2!r9@e+yEm$Hy zLiqRu`p7;6*oIqe0<@@S-K3v_ylzmhcKe?NvyL{FGCOCx2o<)xkfZugZGT~9!D9E8 z?v+O_VlYiDQm8kfo=R~p7Sl~c_%s{}HV}e838Saq;!e1&LytC>A)KG|p5pQRWeoCj z=*TY+@TL2-%EJ2zFg1qRXY2=@cMssGvpi|>r0-*8h9nE9%nioUoKF+vEyjMGhDr6L zG;*0v`6X`k6@Y0k$_9Qm#?HL&ZJbhm0Q}>`0;SNXK70cIy5H^E636>(sDzSNKN>BT*^2zH>4Q&p8uV enH>zw_+M8q`VHn&p*?)!gEXqzQ?*sUXa5T}y-|(; diff --git a/cacti-main/cacti_python/__pycache__/powergating.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/powergating.cpython-311.pyc deleted file mode 100644 index 80133e1f17116aedb2b0b97e13dd5b4ff92d0178..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4798 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 diff --git a/cacti-main/cacti_python/__pycache__/tsv.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/tsv.cpython-310.pyc deleted file mode 100644 index d4c50184e6933399bf2925230bfbf73f8d0399ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4733 zcmb_g&2JmW72j_zKSW8izAVYkCQVY)O>8s>n$&PxDY9j|NEE|Xl0t1UUGFTZU6WjT zc4*ZE1r$*3?L7!!0|knn+kYefz+4)jht{`VdPxuI@6D1l6(>dy6)|si-h1jT;8{c?LLXxrf)C6pr%Df2Rw3+OqU-@AB7i{mN58k_e zhuzrTzkZk9-QT`(J)#-2e>MhNX!(x-V&lN%#(~9aw69Oi1DiYC{nR*ciq#KX?(;In z9kcm(xnW}=$j##gotbEla^oG1A#4-jgZcpy0GVtb*8!(zTqYtc{zr-jU} z6zS7YFP-L?S!T?z`rH}?LC_JZ(h-B%E{wSOVnr)i_3#XD-pRQ37FnyQ5LuUY=~Du{%Ys) zN4VDfGC#U}EsF--xF_?=QO0p%?cTGGTtt_nFp^0DS^tqd%zBrh-lhH{l83nzF({2d&D@voxzleZj}!DxbkAKDSRy za)h+>U7Q=nv8CnhK%P6YJ~KYIXpV#IZ<&kT#9qo={fzXSDuI#W*7ILyMimFLpHTojyNycLtCLMJ525sePoY4N7 z$=XR2cE~3)Aw``i=Lno9a7@C`Ao_j*Po0=#C?4RW|xDQ_cO27`Vevp~YEhqXXQsT@{&CHTq- z2Hm&XfBNUmOJBcS-g-(V+I&e{v9dqrTsbsdRo^S(8wIo?wN#?G(_x3O)Rr<2l`Fzt zJJv?07AMA`ZC}Sg`_|sa+Jp;Z{sC4IZxDDB023&Y+{y>{SSJqeQwX(_-a~EKYQ7-0 zrzHP&b`*phGMA+rcdi>fihq4VUewlb4%`d0v9@1ficwG1sd7!7~`>52&j>{=RY~+tD#3#fr+$AjJ1zNp8m)WGMEhK22_$!<*&2uyBJ9-xTp}q z%WvFMG%&fNODnf1tw8mFwK!fz$ejKZi+53KPm3voQyg%3Rddy*T;$De>ZPSIr9P!l zkwp}LEO}u{q5Mmf@|e4Z0s5c8A}?ti3_^UM#4-Eb?oxa|q*}V z%|b%_#TVOr#Wm`~{Q zM9+|i#|ULsnv1#|(1o-1#lkiB=|Hy#kn@U<2v8;!WaNVWwIFT~peP`&6WAp{nO%p6 zrdgzOdQm+qcvZP5xUuoyfsh9P^!{1FZvkyx|KOSUt(Xloynp7veQ7$cY3?gXDJbG~2-g+1pk)Mw1Mw>Y&-SFhbR|BioO601`UV2TYyOgd zz7`0gU`3}J%0pGADl6;ZNeET&;>PL6qNvT>DC_02c*d4@CTx28x2>rBtHr*5O5tO? LEWP)rE!qDCf2eVW diff --git a/cacti-main/cacti_python/__pycache__/tsv.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/tsv.cpython-311.pyc deleted file mode 100644 index 35d5b3648921f367a3507be77745aa6b354b0e07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10773 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 VjERLc?VQIwKaifEcIhWG{U1?y!E68k diff --git a/cacti-main/cacti_python/__pycache__/uca.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/uca.cpython-310.pyc deleted file mode 100644 index 03c46c92e36596ef9a7b9479b95db04f425170d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18737 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 diff --git a/cacti-main/cacti_python/__pycache__/uca.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/uca.cpython-311.pyc deleted file mode 100644 index 8b66dd121a8a9f434c0fe84b23bcae3d794f1f35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53848 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 diff --git a/cacti-main/cacti_python/__pycache__/wire.cpython-310.pyc b/cacti-main/cacti_python/__pycache__/wire.cpython-310.pyc deleted file mode 100644 index df41372ec634b6a223f8279fb083c51e7ed5f382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13615 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 diff --git a/cacti-main/cacti_python/__pycache__/wire.cpython-311.pyc b/cacti-main/cacti_python/__pycache__/wire.cpython-311.pyc deleted file mode 100644 index f6405271780c4780e301becfa2affa8d5a57b777..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36323 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 Date: Thu, 22 Aug 2024 18:47:47 -0700 Subject: [PATCH 3/5] remove uneeded wiring logic --- .DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index d670f388c3a641d9eb08f44605c6b4a86cd06d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM&u`O66n<06;!wJEOUo7klC`-YQA+wVR3KqO5bCZ_tGa?#Eu^;N1cNgZY`0w~ zm2!tWe*h;=9QL$FF5KY8UiYy7z+O0a-~0$PBo#=NPz5v9%=bL=KEIjI9@{Sk08&^l zj{yt=fPs~x*@I1o!pC`SD_yFm7m*+zAcXT!0T(7_LjYt6yyRlmov@s759800Cupv=U@tiVy zAc{&Q^6F8Tq`BPRr0Y=k;h&Be zM~oihj&qM~I;oqkCj~cN;YW*%MPAc(y<1_hSuzK&F`Bv|4PrqE%K^Hq-VSM*Z5G%% zEhmEO$N?i`WJ>1At*!H8lex(eE5AKrZH-OLOpjR8Gt=AK8Dl7W;nG6sK~$scsaP@) z^(+H^5q6hnc+gRh(BDvtBX66F`^Pk!%gY??IoA7gpV>cfynnENXz0W*!$T(rPMt29 z$3547P>uPtud#^5g=jq}nSBW^e%5DnJ`Of;(MxIYN9u%+acJN(!a`8K`>AX3Q5}5- zKXr(c-iU*Mu2kc&JXfhCLAtcdUgpvKm_^Y%OTsi{ba_=oPlMVltuTzpXE0aiL&>cm zP7vETOUrH?yR;e<9^HvtFNo%7fu$*{ErqxWK64S$sk?qitJy36NmVmh`>eD~$To$} z+SP`zjlpJ@Lb6C14UjZ1JF@ogYQ%tZa1|U_g@@39=kNmW)Lwd;x@+&z< zM#vP&6PwJE-^dDCBQCiw`CZKmeny>70ZGv4c)_FUnB%ireV2bnzZxqR)m?A=`96Nx zclpiLz0O%<<*)Xw-}}1w8%|6kMynW;uQAiIn;FDVZQaYLV(b3z!1!Kva)+h0$+ZC2 zQIaCuL>z@0lw0K@{D#^6xWq$Uv;zB6;E<#b^Zft%-oO9vFNkJq1+)SOS^?5sbczL> zV)OIl^V#xT+rqkrl^5>UkSHkFh;$rLq~nMm|6z!>g|3`qD{M%_9xUJdhXD1#{_Vcx O_4{93Xx$tr1^x$JcbsMb From 6a26439cd75f63ae283893a82d549a13cda1cd67 Mon Sep 17 00:00:00 2001 From: dwoen <123340822+dwoen@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:42:39 -0700 Subject: [PATCH 4/5] Create causality_trace.md --- cacti-main/causality_trace.md | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 cacti-main/causality_trace.md diff --git a/cacti-main/causality_trace.md b/cacti-main/causality_trace.md new file mode 100644 index 0000000..aaae6dd --- /dev/null +++ b/cacti-main/causality_trace.md @@ -0,0 +1,46 @@ +Causality Generated: +Flags: -verbal, -simple +[To obtain more detailed output, use the `-detailed` flag] + +Directory: cacti + +### Causality Trace for Cache Simulator + +#### **component.py:** +- Changing `total_diff_w` from relational to set value impacted **4** files downstream. +- **Changed files:** `mat.py`, `bank.py`, `uca.py`, `uca_org.py` +- **Details:** + - `mat.py` now produces a different result for energy, **3** vars are no longer used. + - `bank.py` calls from `mat.py`, **0** vars are no longer used. + - `uca.py` now produces a different result for energy, **2** vars are no longer used. + - `uca_org.py` now produces a different result for `cycle_time`, **2** vars are no longer used. + +#### **cache.py:** +- Modified `cache_size` calculation to account for new cache hierarchy structure. +- Change affected **5** files downstream. +- **Changed files:** memory.py, controller.py, lru.py, write_buffer.py, replacement_policy.py +- **Details:** + - `memory.py` now produces a different result for latency, **4** vars are no longer used. + - `controller.py` calls `cache_size` from `cache.py`, **1** var is no longer used. + - `lru.py` now calculates a different hit rate, **2** vars are no longer used. + - `write_buffer.py` depends on `cache_size`, **3** vars are no longer used. + - `replacement_policy.py` now adjusts eviction strategies, **1** var is no longer used. + +#### **latency.py:** +- Revised the `latency_model` to use a more accurate timing function. +- Change affected **3** files downstream. +- **Changed files:** read_path.py, write_path.py, hit_rate.py +- **Details:** + - `read_path.py` now produces a different read time, **1** var is no longer used. + - `write_path.py` now produces a different write time, **0** vars are no longer used. + - `hit_rate.py` now computes a different average hit rate, **2** vars are no longer used. + +#### **config.py:** +- Updated configuration parsing to include new cache policies. +- Change affected **2** files downstream. +- **Changed files:** cache.py, controller.py +- **Details:** + - `cache.py` now utilizes new configuration parameters, **3** vars are no longer used. + - `controller.py` now reads updated policies, **0** vars are no longer used. + +[To obtain more detailed output, use the `-detailed` flag] From f3aba6cc2e196a40dd2bfc416490438c11b69949 Mon Sep 17 00:00:00 2001 From: dwoen <123340822+dwoen@users.noreply.github.com> Date: Sun, 25 Aug 2024 13:46:22 -0700 Subject: [PATCH 5/5] Update causality_trace.md --- cacti-main/causality_trace.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cacti-main/causality_trace.md b/cacti-main/causality_trace.md index aaae6dd..d25a786 100644 --- a/cacti-main/causality_trace.md +++ b/cacti-main/causality_trace.md @@ -6,6 +6,9 @@ Directory: cacti ### Causality Trace for Cache Simulator +#### **OVERVIEW:** +Changes energy calculations for cache simulation. + #### **component.py:** - Changing `total_diff_w` from relational to set value impacted **4** files downstream. - **Changed files:** `mat.py`, `bank.py`, `uca.py`, `uca_org.py`