diff --git a/compiler/modules/write_mask_and_array.py b/compiler/modules/write_mask_and_array.py index 68276fab..bb10b5b9 100644 --- a/compiler/modules/write_mask_and_array.py +++ b/compiler/modules/write_mask_and_array.py @@ -63,8 +63,9 @@ class write_mask_and_array(design.design): def add_modules(self): # Size the AND gate for the number of write drivers it drives, which is equal to the write size. + # Assume stage effort of 3 to compute the size self.and2 = factory.create(module_type="pand2", - size=self.write_size) + size=self.write_size/4.0) self.add_mod(self.and2) @@ -92,18 +93,12 @@ class write_mask_and_array(design.design): else: self.driver_spacing = self.driver.width - if (self.words_per_row == 1): - wmask_en_len = (self.write_size * self.driver_spacing) - if self.driver_spacing * self.write_size < self.and2.width: - debug.error("Cannot layout write mask AND array. One pand2 is longer than the corresponding write drivers.") - else: - wmask_en_len = self.words_per_row * (self.write_size * self.driver_spacing) - if wmask_en_len < self.and2.width: - debug.error("Cannot layout write mask AND array. One pand2 is longer than the corresponding write drivers.") - self.wmask_en_len = wmask_en_len + self.wmask_en_len = self.words_per_row * (self.write_size * self.driver_spacing) + debug.check(self.wmask_en_len >= self.and2.width, + "Write mask AND is wider than the corresponding write drivers {0} vs {1}.".format(self.and2.width,self.wmask_en_len)) for i in range(self.num_wmasks): - base = vector(i * wmask_en_len, 0) + base = vector(i * self.wmask_en_len, 0) self.and2_insts[i].place(base) @@ -140,19 +135,8 @@ class write_mask_and_array(design.design): width=wmask_out_pin.width(), height=wmask_out_pin.height()) - for n in ["vdd", "gnd"]: - pin_list = self.and2_insts[i].get_pins(n) - for pin in pin_list: - pin_pos = vector(pin.lx()-0.75*drc('minwidth_metal1'), pin.cy()) - # Add the M1->M2 stack - self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=pin_pos) - # Add the M2->M3 stack - self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=pin_pos) - self.add_layout_pin_rect_center(text=n, - layer="metal3", - offset=pin_pos) + self.add_power_pin("gnd", vector(supply_pin.width()+i*self.wmask_en_len,0)) + self.add_power_pin("vdd", vector(supply_pin.width()+i*self.wmask_en_len,self.height)) def en_width(self, pin): diff --git a/compiler/pgates/pand2.py b/compiler/pgates/pand2.py index 48f111c7..d71b1e92 100644 --- a/compiler/pgates/pand2.py +++ b/compiler/pgates/pand2.py @@ -35,8 +35,8 @@ class pand2(pgate.pgate): # Shield the cap, but have at least a stage effort of 4 self.nand = factory.create(module_type="pnand2",height=self.height) self.add_mod(self.nand) - - self.inv = factory.create(module_type="pinv", size=self.size, height=self.height) + + self.inv = factory.create(module_type="pdriver", neg_polarity=True, fanout=3*self.size, height=self.height) self.add_mod(self.inv) def create_layout(self): diff --git a/compiler/pgates/pand3.py b/compiler/pgates/pand3.py index b221ad84..fcca6672 100644 --- a/compiler/pgates/pand3.py +++ b/compiler/pgates/pand3.py @@ -35,8 +35,9 @@ class pand3(pgate.pgate): # Shield the cap, but have at least a stage effort of 4 self.nand = factory.create(module_type="pnand3",height=self.height) self.add_mod(self.nand) - - self.inv = factory.create(module_type="pinv", size=self.size, height=self.height) + + # Assume stage effort of 3 + self.inv = factory.create(module_type="pdriver", neg_polarity=True, fanout=3*self.size, height=self.height) self.add_mod(self.inv) def create_layout(self): diff --git a/compiler/pgates/pdriver.py b/compiler/pgates/pdriver.py index 36811a5e..ec55f0c7 100644 --- a/compiler/pgates/pdriver.py +++ b/compiler/pgates/pdriver.py @@ -45,7 +45,7 @@ class pdriver(pgate.pgate): self.num_stages = len(self.size_list) else: # Find the optimal number of stages for the given effort - self.num_stages = max(1,int(round(log(self.fanout)/log(self.stage_effort)))) + self.num_stages = max(1,int(round(self.fanout**(1/self.stage_effort)))) # Increase the number of stages if we need to fix polarity if self.neg_polarity and (self.num_stages%2==0): diff --git a/compiler/sram/sram_1bank.py b/compiler/sram/sram_1bank.py index 245ec9e9..634f569c 100644 --- a/compiler/sram/sram_1bank.py +++ b/compiler/sram/sram_1bank.py @@ -226,6 +226,7 @@ class sram_1bank(sram_base): self.route_col_addr_dff() self.route_data_dff() + if self.write_size is not None: self.route_wmask_dff() @@ -361,20 +362,24 @@ class sram_1bank(sram_base): dff_names = ["dout_{}".format(x) for x in range(self.word_size)] dff_pins = [self.data_dff_insts[port].get_pin(x) for x in dff_names] for x in dff_names: + offset = self.data_dff_insts[port].get_pin(x).center() self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=self.data_dff_insts[port].get_pin(x).center()) + offset=offset) self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=self.data_dff_insts[port].get_pin(x).center()) + offset=offset) + self.add_via_center(layers=("metal3", "via3", "metal4"), + offset=offset) bank_names = ["din{0}_{1}".format(port,x) for x in range(self.word_size)] bank_pins = [self.bank_inst.get_pin(x) for x in bank_names] for x in bank_names: - pin_offset = vector(self.bank_inst.get_pin(x).cx(), - self.bank_inst.get_pin(x).by() - 0.75*drc('minwidth_metal1')) + offset = self.bank_inst.get_pin(x).center() self.add_via_center(layers=("metal1", "via1", "metal2"), - offset=pin_offset) + offset=offset) self.add_via_center(layers=("metal2", "via2", "metal3"), - offset=pin_offset) + offset=offset) + self.add_via_center(layers=("metal3", "via3", "metal4"), + offset=offset) . route_map = list(zip(bank_pins, dff_pins)) self.create_horizontal_channel_route(netlist=route_map, @@ -392,9 +397,18 @@ class sram_1bank(sram_base): dff_names = ["dout_{}".format(x) for x in range(self.num_wmasks)] dff_pins = [self.wmask_dff_insts[port].get_pin(x) for x in dff_names] + for x in dff_names: + offset = self.wmask_dff_insts[port].get_pin(x).center() + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=offset) bank_names = ["bank_wmask{0}_{1}".format(port, x) for x in range(self.num_wmasks)] bank_pins = [self.bank_inst.get_pin(x) for x in bank_names] + for x in bank_names: + offset = self.bank_inst.get_pin(x).center() + self.add_via_center(layers=("metal1", "via1", "metal2"), + offset=offset) + route_map = list(zip(bank_pins, dff_pins)) self.create_horizontal_channel_route(route_map,offset)