diff --git a/compiler/base/design.py b/compiler/base/design.py index 7d146fe0..1beb6337 100644 --- a/compiler/base/design.py +++ b/compiler/base/design.py @@ -125,6 +125,6 @@ class design(hierarchy_spice.spice, hierarchy_layout.layout): """ Get total power of a module """ #print "Getting power for ",self.name," module" total_module_power = self.return_power() - # for inst in self.insts: - # total_module_power += self.return_power()#inst.mod.analytical_power(vdd, temp, load) + for inst in self.insts: + total_module_power += inst.mod.analytical_power(vdd, temp, load) return total_module_power diff --git a/compiler/base/hierarchy_spice.py b/compiler/base/hierarchy_spice.py index 52218884..1dd9cc65 100644 --- a/compiler/base/hierarchy_spice.py +++ b/compiler/base/hierarchy_spice.py @@ -270,7 +270,7 @@ class power_data: Override - function (left), for power_data: a+b != b+a """ assert isinstance(other,power_data) - return delay_data(other.dynamic + self.dynamic, + return power_data(other.dynamic + self.dynamic, other.leakage + self.leakage) def __radd__(self, other): @@ -278,7 +278,7 @@ class power_data: Override - function (left), for power_data: a+b != b+a """ assert isinstance(other,power_data) - return delay_data(other.dynamic + self.dynamic, + return power_data(other.dynamic + self.dynamic, other.leakage + self.leakage) diff --git a/compiler/modules/bitcell.py b/compiler/modules/bitcell.py index 1127387a..d36b0c07 100644 --- a/compiler/modules/bitcell.py +++ b/compiler/modules/bitcell.py @@ -35,10 +35,11 @@ class bitcell(design.design): result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing) return result - def analytical_power(self, slew, load=0, swing = 0.5): + def analytical_power(self, vdd, temp, load): #Power of the bitcell. Mostly known for leakage, but dynamic can also be factored in. #Only consider leakage power for now. Value defined in tech file rather than calculated. from tech import spice leakage = spice["bitcell_leakage"] - total_power = leakage + dynamic = 0 #temporary + total_power = self.return_power(dynamic, leakage) return total_power diff --git a/compiler/modules/bitcell_array.py b/compiler/modules/bitcell_array.py index 27805c40..f58097dc 100644 --- a/compiler/modules/bitcell_array.py +++ b/compiler/modules/bitcell_array.py @@ -178,7 +178,7 @@ class bitcell_array(design.design): return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay, wl_to_cell_delay.slew) - def analytical_power(self, slew, load=0): + def analytical_power(self, vdd, temp, load): #This will be pretty bare bones as the power needs to be determined from the dynamic power #of the word line, leakage power from the cell, and dynamic power of the bitlines as a few #sources for power. These features are tbd. @@ -194,10 +194,12 @@ class bitcell_array(design.design): # hence just use the whole c bl_swing = 0.1 #Calculate the bitcell power which can include leakage as well as bitline dynamic - cell_power = self.cell.analytical_power(slew, cell_load, swing = bl_swing) - + cell_power = self.cell.analytical_power(vdd, temp, load) + + #Leakage power grows with entire array. Dynamic currently not accounted for. + total_power = self.return_power(cell_power.dynamic, cell_power.leakage * self.column_size * self.row_size) #calculate power for entire array based off a single cell - return cell_power * self.column_size * self.row_size + return total_power def gen_wl_wire(self): wl_wire = self.generate_rc_net(int(self.column_size), self.width, drc["minwidth_metal1"]) diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 0f87ae0e..07c95aff 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -494,21 +494,21 @@ class hierarchical_decoder(design.design): result = result + z_t_decodeout_delay return result - def analytical_power(self, slew, load = 0.0): - # A -> out - if self.determine_predecodes(self.num_inputs)[1]==0: - pre = self.pre2_4 - nand = self.nand2 - else: - pre = self.pre3_8 - nand = self.nand3 - a_t_out_power = pre.analytical_power(slew=slew,load = nand.input_load()) + # def analytical_power(self, slew, load = 0.0): + # # A -> out + # if self.determine_predecodes(self.num_inputs)[1]==0: + # pre = self.pre2_4 + # nand = self.nand2 + # else: + # pre = self.pre3_8 + # nand = self.nand3 + # a_t_out_power = pre.analytical_power(slew=slew,load = nand.input_load()) - out_t_z_power = nand.analytical_power(slew, - load = self.inv.input_load()) + # out_t_z_power = nand.analytical_power(slew, + # load = self.inv.input_load()) - z_t_decodeout_power = self.inv.analytical_power(slew, load = load) - return a_t_out_power + out_t_z_power + z_t_decodeout_power + # z_t_decodeout_power = self.inv.analytical_power(slew, load = load) + # return a_t_out_power + out_t_z_power + z_t_decodeout_power def input_load(self): if self.determine_predecodes(self.num_inputs)[1]==0: diff --git a/compiler/modules/hierarchical_predecode2x4.py b/compiler/modules/hierarchical_predecode2x4.py index bedc568d..a9752855 100644 --- a/compiler/modules/hierarchical_predecode2x4.py +++ b/compiler/modules/hierarchical_predecode2x4.py @@ -55,17 +55,17 @@ class hierarchical_predecode2x4(hierarchical_predecode): return a_t_b_delay + b_t_z_delay + a_t_out_delay - def analytical_power(self, slew, load = 0.0 ): - # in -> inbar - a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load()) + # def analytical_power(self, slew, load = 0.0 ): + # # in -> inbar + # a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load()) - # inbar -> z - b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load()) + # # inbar -> z + # b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load()) - # Z -> out - a_t_out_power = self.inv.analytical_power(slew, load=load) + # # Z -> out + # a_t_out_power = self.inv.analytical_power(slew, load=load) - return a_t_b_power + b_t_z_power + a_t_out_power + # return a_t_b_power + b_t_z_power + a_t_out_power def input_load(self): return self.nand.input_load() diff --git a/compiler/modules/hierarchical_predecode3x8.py b/compiler/modules/hierarchical_predecode3x8.py index df173548..5ecb5e16 100644 --- a/compiler/modules/hierarchical_predecode3x8.py +++ b/compiler/modules/hierarchical_predecode3x8.py @@ -63,17 +63,17 @@ class hierarchical_predecode3x8(hierarchical_predecode): return a_t_b_delay + b_t_z_delay + a_t_out_delay - def analytical_power(self, slew, load = 0.0 ): - # in -> inbar - a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load()) + # def analytical_power(self, slew, load = 0.0 ): + # # in -> inbar + # a_t_b_power = self.inv.analytical_power(slew=slew, load=self.nand.input_load()) - # inbar -> z - b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load()) + # # inbar -> z + # b_t_z_power = self.nand.analytical_power(slew, load=self.inv.input_load()) - # Z -> out - a_t_out_power = self.inv.analytical_power(slew, load=load) + # # Z -> out + # a_t_out_power = self.inv.analytical_power(slew, load=load) - return a_t_b_power + b_t_z_power + a_t_out_power + # return a_t_b_power + b_t_z_power + a_t_out_power def input_load(self): return self.nand.input_load() diff --git a/compiler/modules/replica_bitline.py b/compiler/modules/replica_bitline.py index db1477a7..d6c289c1 100644 --- a/compiler/modules/replica_bitline.py +++ b/compiler/modules/replica_bitline.py @@ -347,11 +347,12 @@ class replica_bitline(design.design): # def analytical_power(self, vdd, temp, load): # #This has yet to be fully determined. - # print "Instances:" - # total_power = 0 + # print self.name," Instances:" + # total_power = self.return_power() # for inst in self.insts: # print inst.name," Instance" - # #total_power += inst.mod.analytical_power(vdd, temp, load) - + # total_power += inst.mod.analytical_power(vdd, temp, load) + + # print self.name," Instances End" # #currently, only return flop array power # return total_power \ No newline at end of file diff --git a/compiler/modules/sense_amp.py b/compiler/modules/sense_amp.py index 319ed7e3..6ad8a595 100644 --- a/compiler/modules/sense_amp.py +++ b/compiler/modules/sense_amp.py @@ -30,7 +30,7 @@ class sense_amp(design.design): result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew) return self.return_delay(result.delay, result.slew) - def analytical_power(self, slew, load=0.0): - #This is just skeleton code which returns a magic number. The sense amp consumes static - #power during its operation and some dynamic power due to the switching. - return 2 + def analytical_power(self, vdd, temp, load): + #Not sure how to determine this yet. Sense amps return zero power for now + total_power = self.return_power() + return total_power diff --git a/compiler/modules/sense_amp_array.py b/compiler/modules/sense_amp_array.py index 4ec0a365..1c312d94 100644 --- a/compiler/modules/sense_amp_array.py +++ b/compiler/modules/sense_amp_array.py @@ -118,5 +118,5 @@ class sense_amp_array(design.design): def analytical_delay(self, slew, load=0.0): return self.amp.analytical_delay(slew=slew, load=load) - def analytical_power(self, slew, load=0.0): - return self.amp.analytical_power(slew=slew, load=load) + # def analytical_power(self, slew, load=0.0): + # return self.amp.analytical_power(slew=slew, load=load) diff --git a/compiler/modules/tri_gate.py b/compiler/modules/tri_gate.py index 2cac63a2..9b56160f 100644 --- a/compiler/modules/tri_gate.py +++ b/compiler/modules/tri_gate.py @@ -33,9 +33,10 @@ class tri_gate(design.design): c_para = spice["min_tx_drain_c"] return self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew) - def analytical_power(self, slew, load=0.0): - #Skeleton code for the power of a trigate. Returns magic number for now. - return 2 + def analytical_power(self, vdd, temp, load): + #Not sure how to determine this yet. Tri-gates return zero power for now + total_power = self.return_power() + return total_power def input_load(self): diff --git a/compiler/modules/tri_gate_array.py b/compiler/modules/tri_gate_array.py index 4b9132dc..933cf35f 100644 --- a/compiler/modules/tri_gate_array.py +++ b/compiler/modules/tri_gate_array.py @@ -112,5 +112,5 @@ class tri_gate_array(design.design): def analytical_delay(self, slew, load=0.0): return self.tri.analytical_delay(slew = slew, load = load) - def analytical_power(self, slew, load=0.0): - return self.tri.analytical_power(slew = slew, load = load) + # def analytical_power(self, slew, load=0.0): + # return self.tri.analytical_power(slew = slew, load = load) diff --git a/compiler/modules/wordline_driver.py b/compiler/modules/wordline_driver.py index c1e07bf5..2248b21a 100644 --- a/compiler/modules/wordline_driver.py +++ b/compiler/modules/wordline_driver.py @@ -206,14 +206,14 @@ class wordline_driver(design.design): return decode_t_net + net_t_wl - def analytical_power(self, slew, load=0): - # decode -> net - decode_p_net = self.nand2.analytical_power(slew, self.inv.input_load()) + # def analytical_power(self, slew, load=0): + # # decode -> net + # decode_p_net = self.nand2.analytical_power(slew, self.inv.input_load()) - # net -> wl - net_p_wl = self.inv.analytical_power(slew, load) + # # net -> wl + # net_p_wl = self.inv.analytical_power(slew, load) - return decode_p_net + net_p_wl + # return decode_p_net + net_p_wl def input_load(self): return self.nand2.input_load() diff --git a/compiler/sram.py b/compiler/sram.py index 91df3704..9b785763 100644 --- a/compiler/sram.py +++ b/compiler/sram.py @@ -1015,29 +1015,29 @@ class sram(design.design): """ LH and HL are the same in analytical model. """ return self.bank.analytical_delay(slew,load) - def analytical_power(self, vdd, temp, load): - """ Just a test function for the power.""" + # def analytical_power(self, vdd, temp, load): + # """ Just a test function for the power.""" - power_sum = 0; - print "Module Powers" - # for mod in self.mods: - # print mod.name," Power: ", mod.analytical_power(slew, load) - # power_sum += mod.analytical_power(slew, load) + # power_sum = 0; + # print "Module Powers" + # # for mod in self.mods: + # # print mod.name," Power: ", mod.analytical_power(slew, load) + # # power_sum += mod.analytical_power(slew, load) - # print "Instances:" - # for inst in self.insts: - # print inst.name," Instance" + # # print "Instances:" + # # for inst in self.insts: + # # print inst.name," Instance" - # print "Instances from Modules of Instances:" - # for inst in self.insts: - # print inst.mod.name," Module" - # for mod_inst in inst.mod.insts: - # print mod_inst.name," Instance" + # # print "Instances from Modules of Instances:" + # # for inst in self.insts: + # # print inst.mod.name," Module" + # # for mod_inst in inst.mod.insts: + # # print mod_inst.name," Instance" - power_sum = self.control_logic.analytical_power(vdd, temp, load) - return power_sum + # power_sum = self.control_logic.analytical_power(vdd, temp, load) + # return power_sum def save_output(self): """ Save all the output files while reporting time to do it as well. """ diff --git a/compiler/temp/sram_2_16_1_freepdk45.gds b/compiler/temp/sram_2_16_1_freepdk45.gds index 3d0a6910..44aaa87b 100644 Binary files a/compiler/temp/sram_2_16_1_freepdk45.gds and b/compiler/temp/sram_2_16_1_freepdk45.gds differ diff --git a/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib b/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib index 57acdc7c..71bddade 100644 --- a/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib +++ b/compiler/temp/sram_2_16_1_freepdk45_TT_10V_25C.lib @@ -76,3 +76,254 @@ cell (sram_2_16_1_freepdk45){ dont_touch : true; area : 1756.7563625; + bus(DATA){ + bus_type : DATA; + direction : inout; + max_capacitance : 1.6728; + three_state : "!OEb & !clk"; + memory_write(){ + address : ADDR; + clocked_on : clk; + } + memory_read(){ + address : ADDR; + } + pin(DATA[1:0]){ + internal_power(){ + when : "OEb & !clk"; + rise_power(scalar){ + values("Power Data: Dynamic 174266.64, Leakage 423.0 in nW"); + } + fall_power(scalar){ + values("Power Data: Dynamic 174266.64, Leakage 423.0 in nW"); + } + } + timing(){ + timing_type : setup_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + } + timing(){ + timing_type : hold_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + } + internal_power(){ + when : "!OEb & !clk"; + rise_power(scalar){ + values("Power Data: Dynamic 174266.64, Leakage 423.0 in nW"); + } + fall_power(scalar){ + values("Power Data: Dynamic 174266.64, Leakage 423.0 in nW"); + } + } + timing(){ + timing_sense : non_unate; + related_pin : "clk"; + timing_type : falling_edge; + cell_rise(CELL_TABLE) { + values("0.167, 0.168, 0.177",\ + "0.167, 0.168, 0.177",\ + "0.167, 0.168, 0.177"); + } + cell_fall(CELL_TABLE) { + values("0.167, 0.168, 0.177",\ + "0.167, 0.168, 0.177",\ + "0.167, 0.168, 0.177"); + } + rise_transition(CELL_TABLE) { + values("0.006, 0.007, 0.018",\ + "0.006, 0.007, 0.018",\ + "0.006, 0.007, 0.018"); + } + fall_transition(CELL_TABLE) { + values("0.006, 0.007, 0.018",\ + "0.006, 0.007, 0.018",\ + "0.006, 0.007, 0.018"); + } + } + } + } + + bus(ADDR){ + bus_type : ADDR; + direction : input; + capacitance : 0.2091; + max_transition : 0.04; + fanout_load : 1.000000; + pin(ADDR[6:0]){ + timing(){ + timing_type : setup_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + } + timing(){ + timing_type : hold_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + } + } + } + + pin(CSb){ + direction : input; + capacitance : 0.2091; + timing(){ + timing_type : setup_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + } + timing(){ + timing_type : hold_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + } + } + + pin(OEb){ + direction : input; + capacitance : 0.2091; + timing(){ + timing_type : setup_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + } + timing(){ + timing_type : hold_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + } + } + + pin(WEb){ + direction : input; + capacitance : 0.2091; + timing(){ + timing_type : setup_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009",\ + "0.009, 0.009, 0.009"); + } + } + timing(){ + timing_type : hold_rising; + related_pin : "clk"; + rise_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + fall_constraint(CONSTRAINT_TABLE) { + values("0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001",\ + "0.001, 0.001, 0.001"); + } + } + } + + pin(clk){ + clock : true; + direction : input; + capacitance : 0.2091; + timing(){ + timing_type :"min_pulse_width"; + related_pin : clk; + rise_constraint(scalar) { + values("0.0"); + } + fall_constraint(scalar) { + values("0.0"); + } + } + timing(){ + timing_type :"minimum_period"; + related_pin : clk; + rise_constraint(scalar) { + values("0.0"); + } + fall_constraint(scalar) { + values("0.0"); + } + } + } + } +}