From 2ed8fc1506902106095d16624cf8f63044ca1370 Mon Sep 17 00:00:00 2001 From: Matt Guthaus Date: Wed, 28 Nov 2018 12:42:29 -0800 Subject: [PATCH] pgate inputs and outputs are all on M1 for flexible via placement when using gates. --- compiler/modules/control_logic.py | 84 +++++++++---------------------- compiler/pgates/pand2.py | 20 ++++---- compiler/pgates/pbuf.py | 16 +++--- 3 files changed, 41 insertions(+), 79 deletions(-) diff --git a/compiler/modules/control_logic.py b/compiler/modules/control_logic.py index 77c0d8f1..13ee776a 100644 --- a/compiler/modules/control_logic.py +++ b/compiler/modules/control_logic.py @@ -287,16 +287,20 @@ class control_logic(design.design): clkbuf_map = zip(["Z"], ["clk_buf"]) self.connect_vertical_bus(clkbuf_map, self.clkbuf_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + # The pin is on M1, so we need another via as well + self.add_via_center(layers=("metal1","via1","metal2"), + offset=self.clkbuf_inst.get_pin("Z").center(), + rotate=90) self.connect_output(self.clkbuf_inst, "Z", "clk_buf") def create_gated_clk_bar_row(self): - self.clk_bar_inst = self.add_inst(name="clk_bar", + self.clk_bar_inst = self.add_inst(name="inv_clk_bar", mod=self.inv) self.connect_inst(["clk_buf","clk_bar","vdd","gnd"]) - self.gated_clk_bar_inst = self.add_inst(name="gated_clkbuf", - mod=self.and2) + self.gated_clk_bar_inst = self.add_inst(name="and2_gated_clk_bar", + mod=self.and2) self.connect_inst(["cs","clk_bar","gated_clk_bar","vdd","gnd"]) def place_gated_clk_bar_row(self,row): @@ -321,17 +325,27 @@ class control_logic(design.design): out_pos = self.clk_bar_inst.get_pin("Z").center() in_pos = self.gated_clk_bar_inst.get_pin("B").center() mid1 = vector(in_pos.x,out_pos.y) - self.add_wire(("metal1","via1","metal2"),[out_pos, mid1, in_pos]) + self.add_path("metal1",[out_pos, mid1, in_pos]) + # This is the second gate over, so it needs to be on M3 clkbuf_map = zip(["A"], ["cs"]) self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + # The pin is on M1, so we need another via as well + self.add_via_center(layers=("metal1","via1","metal2"), + offset=self.gated_clk_bar_inst.get_pin("A").center(), + rotate=90) + # This is the second gate over, so it needs to be on M3 clkbuf_map = zip(["Z"], ["gated_clk_bar"]) self.connect_vertical_bus(clkbuf_map, self.gated_clk_bar_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + # The pin is on M1, so we need another via as well + self.add_via_center(layers=("metal1","via1","metal2"), + offset=self.gated_clk_bar_inst.get_pin("Z").center(), + rotate=90) def create_gated_clk_buf_row(self): - self.gated_clk_buf_inst = self.add_inst(name="gated_clkinv", - mod=self.and2) + self.gated_clk_buf_inst = self.add_inst(name="and2_gated_clk_buf", + mod=self.and2) self.connect_inst(["clk_buf", "cs","gated_clk_buf","vdd","gnd"]) def place_gated_clk_buf_row(self,row): @@ -351,6 +365,10 @@ class control_logic(design.design): clkbuf_map = zip(["Z"], ["gated_clk_buf"]) self.connect_vertical_bus(clkbuf_map, self.gated_clk_buf_inst, self.rail_offsets, ("metal3", "via2", "metal2")) + # The pin is on M1, so we need another via as well + self.add_via_center(layers=("metal1","via1","metal2"), + offset=self.gated_clk_buf_inst.get_pin("Z").center(), + rotate=90) def create_wlen_row(self): # input pre_p_en, output: wl_en @@ -565,8 +583,6 @@ class control_logic(design.design): if (self.port_type == "rw"): self.copy_layout_pin(self.ctrl_dff_inst, "din_1", "web") - - def get_offset(self,row): """ Compute the y-offset and mirroring """ y_off = row*self.and2.height @@ -578,59 +594,7 @@ class control_logic(design.design): return (y_off,mirror) - - - - def connect_rail_from_right(self,inst, pin, rail): - """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ - in_pos = inst.get_pin(pin).center() - rail_pos = vector(self.rail_offsets[rail].x, in_pos.y) - self.add_wire(("metal1","via1","metal2"),[in_pos, rail_pos]) - self.add_via_center(layers=("metal1","via1","metal2"), - offset=rail_pos, - rotate=90) - - def connect_rail_from_right_m2m3(self,inst, pin, rail): - """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ - in_pos = inst.get_pin(pin).center() - rail_pos = vector(self.rail_offsets[rail].x, in_pos.y) - self.add_wire(("metal3","via2","metal2"),[in_pos, rail_pos]) - # Bring it up to M2 for M2/M3 routing - self.add_via_center(layers=("metal1","via1","metal2"), - offset=in_pos, - rotate=90) - self.add_via_center(layers=("metal2","via2","metal3"), - offset=in_pos, - rotate=90) - self.add_via_center(layers=("metal2","via2","metal3"), - offset=rail_pos, - rotate=90) - - - def connect_rail_from_left(self,inst, pin, rail): - """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ - in_pos = inst.get_pin(pin).lc() - rail_pos = vector(self.rail_offsets[rail].x, in_pos.y) - self.add_wire(("metal1","via1","metal2"),[in_pos, rail_pos]) - self.add_via_center(layers=("metal1","via1","metal2"), - offset=rail_pos, - rotate=90) - - def connect_rail_from_left_m2m3(self,inst, pin, rail): - """ Helper routine to connect an unrotated/mirrored oriented instance to the rails """ - in_pos = inst.get_pin(pin).lc() - rail_pos = vector(self.rail_offsets[rail].x, in_pos.y) - self.add_wire(("metal3","via2","metal2"),[in_pos, rail_pos]) - self.add_via_center(layers=("metal2","via2","metal3"), - offset=in_pos, - rotate=90) - self.add_via_center(layers=("metal2","via2","metal3"), - offset=rail_pos, - rotate=90) - - - def connect_output(self, inst, pin_name, out_name): """ Create an output pin on the right side from the pin of a given instance. """ diff --git a/compiler/pgates/pand2.py b/compiler/pgates/pand2.py index 4ab3be0b..00b6731c 100644 --- a/compiler/pgates/pand2.py +++ b/compiler/pgates/pand2.py @@ -102,22 +102,20 @@ class pand2(pgate.pgate): width=self.width, height=vdd_pin.height()) - z_pin = self.inv_inst.get_pin("Z") - self.add_via_center(layers=("metal1","via1","metal2"), - offset=z_pin.center(), - rotate=90) + pin = self.inv_inst.get_pin("Z") self.add_layout_pin_rect_center(text="Z", - layer="metal2", - offset=z_pin.center()) + layer=pin.layer, + offset=pin.center(), + width=pin.width(), + height=pin.height()) for pin_name in ["A","B"]: pin = self.nand_inst.get_pin(pin_name) self.add_layout_pin_rect_center(text=pin_name, - layer="metal2", - offset=pin.center()) - self.add_via_center(layers=("metal1","via1","metal2"), - offset=pin.center(), - rotate=90) + layer=pin.layer, + offset=pin.center(), + width=pin.width(), + height=pin.height()) diff --git a/compiler/pgates/pbuf.py b/compiler/pgates/pbuf.py index 246d4c52..d0c112fc 100644 --- a/compiler/pgates/pbuf.py +++ b/compiler/pgates/pbuf.py @@ -105,17 +105,17 @@ class pbuf(pgate.pgate): z_pin = self.inv2_inst.get_pin("Z") self.add_layout_pin_rect_center(text="Z", - layer="metal2", - offset=z_pin.center()) - self.add_via_center(layers=("metal1","via1","metal2"), - offset=z_pin.center()) + layer=z_pin.layer, + offset=z_pin.center(), + width=z_pin.width(), + height=z_pin.height()) a_pin = self.inv1_inst.get_pin("A") self.add_layout_pin_rect_center(text="A", - layer="metal2", - offset=a_pin.center()) - self.add_via_center(layers=("metal1","via1","metal2"), - offset=a_pin.center()) + layer=a_pin.layer, + offset=a_pin.center(), + width=a_pin.width(), + height=a_pin.height())