From 58fbc5351a7d1a5e95a26e2929aa9569d6bd16fc Mon Sep 17 00:00:00 2001 From: mrg Date: Wed, 8 Apr 2020 17:05:16 -0700 Subject: [PATCH] Change rows to outputs in hierarchical decoder --- compiler/modules/hierarchical_decoder.py | 26 ++++++++++--------- compiler/modules/port_address.py | 12 +++------ .../06_hierarchical_decoder_pbitcell_test.py | 16 ++++++------ .../tests/06_hierarchical_decoder_test.py | 20 +++++++------- 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/compiler/modules/hierarchical_decoder.py b/compiler/modules/hierarchical_decoder.py index 8776810a..36097269 100644 --- a/compiler/modules/hierarchical_decoder.py +++ b/compiler/modules/hierarchical_decoder.py @@ -18,7 +18,7 @@ class hierarchical_decoder(design.design): """ Dynamically generated hierarchical decoder. """ - def __init__(self, name, rows): + def __init__(self, name, num_outputs): design.design.__init__(self, name) self.AND_FORMAT = "DEC_AND_{0}" @@ -27,8 +27,10 @@ class hierarchical_decoder(design.design): self.pre3x8_inst = [] (self.cell_height, self.cell_multiple) = self.find_decoder_height() - self.rows = rows - self.num_inputs = math.ceil(math.log(self.rows, 2)) + self.num_outputs = num_outputs + # We may have more than one bitcell per decoder row + self.rows = math.ceil(num_outputs / self.cell_multiple) + self.num_inputs = math.ceil(math.log(self.num_outputs, 2)) (self.no_of_pre2x4, self.no_of_pre3x8)=self.determine_predecodes(self.num_inputs) self.create_netlist() @@ -176,7 +178,7 @@ class hierarchical_decoder(design.design): self.internal_routing_width = self.m2_pitch * self.total_number_of_predecoder_outputs self.row_decoder_height = self.inv.height * self.rows - self.input_routing_width = (self.num_inputs + 1) * self.m2_pitch + self.input_routing_width = (self.num_inputs + 1) * self.m2_pitch # Calculates height and width of hierarchical decoder self.height = self.row_decoder_height self.width = self.input_routing_width + self.predecoder_width \ @@ -253,7 +255,7 @@ class hierarchical_decoder(design.design): for i in range(self.num_inputs): self.add_pin("addr_{0}".format(i), "INPUT") - for j in range(self.rows): + for j in range(self.num_outputs): self.add_pin("decode_{0}".format(j), "OUTPUT") self.add_pin("vdd", "POWER") self.add_pin("gnd", "GROUND") @@ -351,7 +353,7 @@ class hierarchical_decoder(design.design): for i in range(len(self.predec_groups[0])): for j in range(len(self.predec_groups[1])): row = len(self.predec_groups[0]) * j + i - if (row < self.rows): + if (row < self.num_outputs): name = self.AND_FORMAT.format(row) self.and_inst.append(self.add_inst(name=name, mod=self.and2)) @@ -369,7 +371,7 @@ class hierarchical_decoder(design.design): row = (len(self.predec_groups[0]) * len(self.predec_groups[1])) * k \ + len(self.predec_groups[0]) * j + i - if (row < self.rows): + if (row < self.num_outputs): name = self.AND_FORMAT.format(row) self.and_inst.append(self.add_inst(name=name, mod=self.and3)) @@ -405,7 +407,7 @@ class hierarchical_decoder(design.design): def place_and_array(self, and_mod): """ Add a column of AND gates for the decoder above the predecoders.""" - for row in range(self.rows): + for row in range(self.num_outputs): if ((row % 2) == 0): y_off = and_mod.height * row mirror = "R0" @@ -419,7 +421,7 @@ class hierarchical_decoder(design.design): def route_decoder(self): """ Add the pins. """ - for row in range(self.rows): + for row in range(self.num_outputs): z_pin = self.and_inst[row].get_pin("Z") self.add_layout_pin(text="decode_{0}".format(row), layer="m1", @@ -475,7 +477,7 @@ class hierarchical_decoder(design.design): for index_B in self.predec_groups[1]: for index_A in self.predec_groups[0]: # FIXME: convert to connect_bus? - if (row_index < self.rows): + if (row_index < self.num_outputs): predecode_name = "predecode_{}".format(index_A) self.route_predecode_rail(predecode_name, self.and_inst[row_index].get_pin("A")) predecode_name = "predecode_{}".format(index_B) @@ -487,7 +489,7 @@ class hierarchical_decoder(design.design): for index_B in self.predec_groups[1]: for index_A in self.predec_groups[0]: # FIXME: convert to connect_bus? - if (row_index < self.rows): + if (row_index < self.num_outputs): predecode_name = "predecode_{}".format(index_A) self.route_predecode_rail(predecode_name, self.and_inst[row_index].get_pin("A")) predecode_name = "predecode_{}".format(index_B) @@ -501,7 +503,7 @@ class hierarchical_decoder(design.design): # The vias will be placed in the center and right of the cells, respectively. xoffset = self.and_inst[0].rx() - for num in range(0, self.rows): + for num in range(0, self.num_outputs): for pin_name in ["vdd", "gnd"]: # The nand and inv are the same height rows... supply_pin = self.and_inst[num].get_pin(pin_name) diff --git a/compiler/modules/port_address.py b/compiler/modules/port_address.py index 44b0d5a5..6938219a 100644 --- a/compiler/modules/port_address.py +++ b/compiler/modules/port_address.py @@ -90,17 +90,14 @@ class port_address(design.design): # The pre/post is to access the pin from "outside" the cell to avoid DRCs decoder_out_pos = self.row_decoder_inst.get_pin("decode_{}".format(row)).rc() driver_in_pos = self.wordline_driver_inst.get_pin("in_{}".format(row)).lc() - mid1 = decoder_out_pos.scale(0.5,1)+driver_in_pos.scale(0.5,0) - mid2 = decoder_out_pos.scale(0.5,0)+driver_in_pos.scale(0.5,1) + mid1 = decoder_out_pos.scale(0.5, 1) + driver_in_pos.scale(0.5, 0) + mid2 = decoder_out_pos.scale(0.5, 0) + driver_in_pos.scale(0.5, 1) self.add_path("m1", [decoder_out_pos, mid1, mid2, driver_in_pos]) - - - def add_modules(self): self.row_decoder = factory.create(module_type="decoder", - rows=self.num_rows) + num_outputs=self.num_rows) self.add_mod(self.row_decoder) self.wordline_driver = factory.create(module_type="wordline_driver", @@ -108,11 +105,10 @@ class port_address(design.design): cols=self.num_cols) self.add_mod(self.wordline_driver) - def create_row_decoder(self): """ Create the hierarchical row decoder """ - self.row_decoder_inst = self.add_inst(name="row_decoder", + self.row_decoder_inst = self.add_inst(name="row_decoder", mod=self.row_decoder) temp = [] diff --git a/compiler/tests/06_hierarchical_decoder_pbitcell_test.py b/compiler/tests/06_hierarchical_decoder_pbitcell_test.py index 1fb3a3f6..ec8f4efe 100755 --- a/compiler/tests/06_hierarchical_decoder_pbitcell_test.py +++ b/compiler/tests/06_hierarchical_decoder_pbitcell_test.py @@ -28,39 +28,39 @@ class hierarchical_decoder_test(openram_test): factory.reset() debug.info(1, "Testing 16 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=16) + a = factory.create(module_type="hierarchical_decoder", num_outputs=16) self.local_check(a) factory.reset() debug.info(1, "Testing 17 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=17) + a = factory.create(module_type="hierarchical_decoder", num_outputs=17) self.local_check(a) factory.reset() debug.info(1, "Testing 23 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=23) + a = factory.create(module_type="hierarchical_decoder", num_outputs=23) self.local_check(a) debug.info(1, "Testing 32 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=32) + a = factory.create(module_type="hierarchical_decoder", num_outputs=32) self.local_check(a) factory.reset() debug.info(1, "Testing 65 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=65) + a = factory.create(module_type="hierarchical_decoder", num_outputs=65) self.local_check(a) debug.info(1, "Testing 128 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=128) + a = factory.create(module_type="hierarchical_decoder", num_outputs=128) self.local_check(a) factory.reset() debug.info(1, "Testing 341 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=341) + a = factory.create(module_type="hierarchical_decoder", num_outputs=341) self.local_check(a) debug.info(1, "Testing 512 row sample for hierarchical_decoder (multi-port case)") - a = factory.create(module_type="hierarchical_decoder", rows=512) + a = factory.create(module_type="hierarchical_decoder", num_outputs=512) self.local_check(a) globals.end_openram() diff --git a/compiler/tests/06_hierarchical_decoder_test.py b/compiler/tests/06_hierarchical_decoder_test.py index ab7e844f..df979657 100755 --- a/compiler/tests/06_hierarchical_decoder_test.py +++ b/compiler/tests/06_hierarchical_decoder_test.py @@ -22,45 +22,45 @@ class hierarchical_decoder_test(openram_test): globals.init_openram(config_file) # Doesn't require hierarchical decoder # debug.info(1, "Testing 4 row sample for hierarchical_decoder") - # a = hierarchical_decoder.hierarchical_decoder(name="hd1, rows=4) + # a = hierarchical_decoder.hierarchical_decoder(name="hd1, num_outputs=4) # self.local_check(a) # Doesn't require hierarchical decoder # debug.info(1, "Testing 8 row sample for hierarchical_decoder") - # a = hierarchical_decoder.hierarchical_decoder(name="hd2", rows=8) + # a = hierarchical_decoder.hierarchical_decoder(name="hd2", num_outputs=8) # self.local_check(a) # check hierarchical decoder for single port debug.info(1, "Testing 16 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=16) + a = factory.create(module_type="hierarchical_decoder", num_outputs=16) self.local_check(a) debug.info(1, "Testing 17 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=17) + a = factory.create(module_type="hierarchical_decoder", num_outputs=17) self.local_check(a) debug.info(1, "Testing 23 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=23) + a = factory.create(module_type="hierarchical_decoder", num_outputs=23) self.local_check(a) debug.info(1, "Testing 32 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=32) + a = factory.create(module_type="hierarchical_decoder", num_outputs=32) self.local_check(a) debug.info(1, "Testing 65 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=65) + a = factory.create(module_type="hierarchical_decoder", num_outputs=65) self.local_check(a) debug.info(1, "Testing 128 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=128) + a = factory.create(module_type="hierarchical_decoder", num_outputs=128) self.local_check(a) debug.info(1, "Testing 341 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=341) + a = factory.create(module_type="hierarchical_decoder", num_outputs=341) self.local_check(a) debug.info(1, "Testing 512 row sample for hierarchical_decoder") - a = factory.create(module_type="hierarchical_decoder", rows=512) + a = factory.create(module_type="hierarchical_decoder", num_outputs=512) self.local_check(a) globals.end_openram()