diff --git a/compiler/modules/dff_array.py b/compiler/modules/dff_array.py index 6257c814..6673a130 100644 --- a/compiler/modules/dff_array.py +++ b/compiler/modules/dff_array.py @@ -4,6 +4,7 @@ from tech import drc from math import log from vector import vector from globals import OPTS +import dff_buf class dff_array(design.design): """ @@ -11,7 +12,7 @@ class dff_array(design.design): Unlike the data flops, these are never spaced out. """ - def __init__(self, rows, columns, name=""): + def __init__(self, rows, columns, inv1_size=2, inv2_size=4, name=""): self.rows = rows self.columns = columns @@ -20,13 +21,11 @@ class dff_array(design.design): design.design.__init__(self, name) debug.info(1, "Creating {}".format(self.name)) - c = reload(__import__(OPTS.dff)) - self.mod_dff = getattr(c, OPTS.dff) - self.ms = self.mod_dff("dff") - self.add_mod(self.ms) + self.dff = dff_buf.dff_buf(inv1_size, inv2_size) + self.add_mod(self.dff) - self.width = self.columns * self.ms.width - self.height = self.rows * self.ms.height + self.width = self.columns * self.dff.width + self.height = self.rows * self.dff.height self.create_layout() @@ -37,13 +36,13 @@ class dff_array(design.design): self.DRC_LVS() def add_pins(self): - for row in range(self.rows): - for col in range(self.columns): - self.add_pin("din[{0}][{1}]".format(row,col)) - for row in range(self.rows): - for col in range(self.columns): - self.add_pin("dout[{0}][{1}]".format(row,col)) - #self.add_pin("dout_bar[{0}]".format(i)) + for y in range(self.rows): + for x in range(self.columns): + self.add_pin(self.get_din_name(y,x)) + for y in range(self.rows): + for x in range(self.columns): + self.add_pin(self.get_dout_name(y,x)) + self.add_pin(self.get_dout_bar_name(y,x)) self.add_pin("clk") self.add_pin("vdd") self.add_pin("gnd") @@ -54,21 +53,52 @@ class dff_array(design.design): for x in range(self.columns): name = "Xdff_r{0}_c{1}".format(y,x) if (y % 2 == 0): - base = vector(x*self.ms.width,y*self.ms.height) + base = vector(x*self.dff.width,y*self.dff.height) mirror = "R0" else: - base = vector(x*self.ms.width,(y+1)*self.ms.height) + base = vector(x*self.dff.width,(y+1)*self.dff.height) mirror = "MX" self.dff_insts[x,y]=self.add_inst(name=name, - mod=self.ms, + mod=self.dff, offset=base, mirror=mirror) self.connect_inst(["din[{0}][{1}]".format(x,y), "dout[{0}][{1}]".format(x,y), + "dout_bar[{0}][{1}]".format(x,y), "clk", "vdd", "gnd"]) + def get_din_name(self, row, col): + if self.columns == 1: + din_name = "din[{0}]".format(row) + elif self.rows == 1: + din_name = "din[{0}]".format(col) + else: + din_name = "din[{0}][{1}]".format(row,col) + + return din_name + + def get_dout_name(self, row, col): + if self.columns == 1: + dout_name = "dout[{0}]".format(row) + elif self.rows == 1: + dout_name = "dout[{0}]".format(col) + else: + dout_name = "dout[{0}][{1}]".format(row,col) + + return dout_name + + def get_dout_bar_name(self, row, col): + if self.columns == 1: + dout_bar_name = "dout_bar[{0}]".format(row) + elif self.rows == 1: + dout_bar_name = "dout_bar[{0}]".format(col) + else: + dout_bar_name = "dout_bar[{0}][{1}]".format(row,col) + + return dout_bar_name + def add_layout_pins(self): for y in range(self.rows): @@ -92,22 +122,31 @@ class dff_array(design.design): for y in range(self.rows): for x in range(self.columns): din_pin = self.dff_insts[x,y].get_pin("D") - debug.check(din_pin.layer=="metal2","DFF d pin not on metal2") - self.add_layout_pin(text="din[{0}][{1}]".format(x,y), + debug.check(din_pin.layer=="metal2","DFF D pin not on metal2") + self.add_layout_pin(text=self.get_din_name(y,x), layer=din_pin.layer, offset=din_pin.ll(), width=din_pin.width(), height=din_pin.height()) dout_pin = self.dff_insts[x,y].get_pin("Q") - debug.check(dout_pin.layer=="metal2","DFF q pin not on metal2") - self.add_layout_pin(text="dout[{0}][{1}]".format(x,y), + debug.check(dout_pin.layer=="metal2","DFF Q pin not on metal2") + self.add_layout_pin(text=self.get_dout_name(y,x), layer=dout_pin.layer, offset=dout_pin.ll(), width=dout_pin.width(), height=dout_pin.height()) + dout_bar_pin = self.dff_insts[x,y].get_pin("Qb") + debug.check(dout_bar_pin.layer=="metal2","DFF Qb pin not on metal2") + self.add_layout_pin(text=self.get_dout_bar_name(y,x), + layer=dout_bar_pin.layer, + offset=dout_bar_pin.ll(), + width=dout_bar_pin.width(), + height=dout_bar_pin.height()) + + # Create vertical spines to a single horizontal rail clk_pin = self.dff_insts[0,0].get_pin("clk") debug.check(clk_pin.layer=="metal2","DFF clk pin not on metal2") @@ -138,4 +177,4 @@ class dff_array(design.design): def analytical_delay(self, slew, load=0.0): - return self.ms.analytical_delay(slew=slew, load=load) + return self.dff.analytical_delay(slew=slew, load=load) diff --git a/compiler/modules/dff_buf.py b/compiler/modules/dff_buf.py index bcd03f16..6d214e6e 100644 --- a/compiler/modules/dff_buf.py +++ b/compiler/modules/dff_buf.py @@ -13,7 +13,7 @@ class dff_buf(design.design): and qbar. This is to enable driving large fanout loads. """ - def __init__(self, inv1_size, inv2_size, name=""): + def __init__(self, inv1_size=2, inv2_size=4, name=""): if name=="": name = "dff_buf_{0}_{1}".format(inv1_size, inv2_size) @@ -122,18 +122,18 @@ class dff_buf(design.design): height=din_pin.height()) dout_pin = self.inv2_inst.get_pin("Z") - self.add_layout_pin(text="Q", - layer=dout_pin.layer, - offset=dout_pin.ll(), - width=dout_pin.width(), - height=dout_pin.height()) + self.add_layout_pin_center_rect(text="Q", + layer="metal2", + offset=dout_pin.center()) + self.add_via_center(layers=("metal1","via1","metal2"), + offset=dout_pin.center()) - dout_pin = self.inv1_inst.get_pin("Z") - self.add_layout_pin(text="Qb", - layer=dout_pin.layer, - offset=dout_pin.ll(), - width=dout_pin.width(), - height=dout_pin.height()) + dout_pin = self.inv2_inst.get_pin("A") + self.add_layout_pin_center_rect(text="Qb", + layer="metal2", + offset=dout_pin.center()) + self.add_via_center(layers=("metal1","via1","metal2"), + offset=dout_pin.center())