mirror of https://github.com/VLSIDA/OpenRAM.git
Change rows to outputs in hierarchical decoder
This commit is contained in:
parent
745450fadc
commit
58fbc5351a
|
|
@ -18,7 +18,7 @@ class hierarchical_decoder(design.design):
|
||||||
"""
|
"""
|
||||||
Dynamically generated hierarchical decoder.
|
Dynamically generated hierarchical decoder.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, rows):
|
def __init__(self, name, num_outputs):
|
||||||
design.design.__init__(self, name)
|
design.design.__init__(self, name)
|
||||||
|
|
||||||
self.AND_FORMAT = "DEC_AND_{0}"
|
self.AND_FORMAT = "DEC_AND_{0}"
|
||||||
|
|
@ -27,8 +27,10 @@ class hierarchical_decoder(design.design):
|
||||||
self.pre3x8_inst = []
|
self.pre3x8_inst = []
|
||||||
|
|
||||||
(self.cell_height, self.cell_multiple) = self.find_decoder_height()
|
(self.cell_height, self.cell_multiple) = self.find_decoder_height()
|
||||||
self.rows = rows
|
self.num_outputs = num_outputs
|
||||||
self.num_inputs = math.ceil(math.log(self.rows, 2))
|
# 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.no_of_pre2x4, self.no_of_pre3x8)=self.determine_predecodes(self.num_inputs)
|
||||||
|
|
||||||
self.create_netlist()
|
self.create_netlist()
|
||||||
|
|
@ -253,7 +255,7 @@ class hierarchical_decoder(design.design):
|
||||||
for i in range(self.num_inputs):
|
for i in range(self.num_inputs):
|
||||||
self.add_pin("addr_{0}".format(i), "INPUT")
|
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("decode_{0}".format(j), "OUTPUT")
|
||||||
self.add_pin("vdd", "POWER")
|
self.add_pin("vdd", "POWER")
|
||||||
self.add_pin("gnd", "GROUND")
|
self.add_pin("gnd", "GROUND")
|
||||||
|
|
@ -351,7 +353,7 @@ class hierarchical_decoder(design.design):
|
||||||
for i in range(len(self.predec_groups[0])):
|
for i in range(len(self.predec_groups[0])):
|
||||||
for j in range(len(self.predec_groups[1])):
|
for j in range(len(self.predec_groups[1])):
|
||||||
row = len(self.predec_groups[0]) * j + i
|
row = len(self.predec_groups[0]) * j + i
|
||||||
if (row < self.rows):
|
if (row < self.num_outputs):
|
||||||
name = self.AND_FORMAT.format(row)
|
name = self.AND_FORMAT.format(row)
|
||||||
self.and_inst.append(self.add_inst(name=name,
|
self.and_inst.append(self.add_inst(name=name,
|
||||||
mod=self.and2))
|
mod=self.and2))
|
||||||
|
|
@ -369,7 +371,7 @@ class hierarchical_decoder(design.design):
|
||||||
row = (len(self.predec_groups[0]) * len(self.predec_groups[1])) * k \
|
row = (len(self.predec_groups[0]) * len(self.predec_groups[1])) * k \
|
||||||
+ len(self.predec_groups[0]) * j + i
|
+ len(self.predec_groups[0]) * j + i
|
||||||
|
|
||||||
if (row < self.rows):
|
if (row < self.num_outputs):
|
||||||
name = self.AND_FORMAT.format(row)
|
name = self.AND_FORMAT.format(row)
|
||||||
self.and_inst.append(self.add_inst(name=name,
|
self.and_inst.append(self.add_inst(name=name,
|
||||||
mod=self.and3))
|
mod=self.and3))
|
||||||
|
|
@ -405,7 +407,7 @@ class hierarchical_decoder(design.design):
|
||||||
def place_and_array(self, and_mod):
|
def place_and_array(self, and_mod):
|
||||||
""" Add a column of AND gates for the decoder above the predecoders."""
|
""" 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):
|
if ((row % 2) == 0):
|
||||||
y_off = and_mod.height * row
|
y_off = and_mod.height * row
|
||||||
mirror = "R0"
|
mirror = "R0"
|
||||||
|
|
@ -419,7 +421,7 @@ class hierarchical_decoder(design.design):
|
||||||
def route_decoder(self):
|
def route_decoder(self):
|
||||||
""" Add the pins. """
|
""" 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")
|
z_pin = self.and_inst[row].get_pin("Z")
|
||||||
self.add_layout_pin(text="decode_{0}".format(row),
|
self.add_layout_pin(text="decode_{0}".format(row),
|
||||||
layer="m1",
|
layer="m1",
|
||||||
|
|
@ -475,7 +477,7 @@ class hierarchical_decoder(design.design):
|
||||||
for index_B in self.predec_groups[1]:
|
for index_B in self.predec_groups[1]:
|
||||||
for index_A in self.predec_groups[0]:
|
for index_A in self.predec_groups[0]:
|
||||||
# FIXME: convert to connect_bus?
|
# FIXME: convert to connect_bus?
|
||||||
if (row_index < self.rows):
|
if (row_index < self.num_outputs):
|
||||||
predecode_name = "predecode_{}".format(index_A)
|
predecode_name = "predecode_{}".format(index_A)
|
||||||
self.route_predecode_rail(predecode_name, self.and_inst[row_index].get_pin("A"))
|
self.route_predecode_rail(predecode_name, self.and_inst[row_index].get_pin("A"))
|
||||||
predecode_name = "predecode_{}".format(index_B)
|
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_B in self.predec_groups[1]:
|
||||||
for index_A in self.predec_groups[0]:
|
for index_A in self.predec_groups[0]:
|
||||||
# FIXME: convert to connect_bus?
|
# FIXME: convert to connect_bus?
|
||||||
if (row_index < self.rows):
|
if (row_index < self.num_outputs):
|
||||||
predecode_name = "predecode_{}".format(index_A)
|
predecode_name = "predecode_{}".format(index_A)
|
||||||
self.route_predecode_rail(predecode_name, self.and_inst[row_index].get_pin("A"))
|
self.route_predecode_rail(predecode_name, self.and_inst[row_index].get_pin("A"))
|
||||||
predecode_name = "predecode_{}".format(index_B)
|
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.
|
# The vias will be placed in the center and right of the cells, respectively.
|
||||||
xoffset = self.and_inst[0].rx()
|
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"]:
|
for pin_name in ["vdd", "gnd"]:
|
||||||
# The nand and inv are the same height rows...
|
# The nand and inv are the same height rows...
|
||||||
supply_pin = self.and_inst[num].get_pin(pin_name)
|
supply_pin = self.and_inst[num].get_pin(pin_name)
|
||||||
|
|
|
||||||
|
|
@ -90,17 +90,14 @@ class port_address(design.design):
|
||||||
# The pre/post is to access the pin from "outside" the cell to avoid DRCs
|
# 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()
|
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()
|
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)
|
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)
|
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])
|
self.add_path("m1", [decoder_out_pos, mid1, mid2, driver_in_pos])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def add_modules(self):
|
def add_modules(self):
|
||||||
|
|
||||||
self.row_decoder = factory.create(module_type="decoder",
|
self.row_decoder = factory.create(module_type="decoder",
|
||||||
rows=self.num_rows)
|
num_outputs=self.num_rows)
|
||||||
self.add_mod(self.row_decoder)
|
self.add_mod(self.row_decoder)
|
||||||
|
|
||||||
self.wordline_driver = factory.create(module_type="wordline_driver",
|
self.wordline_driver = factory.create(module_type="wordline_driver",
|
||||||
|
|
@ -108,7 +105,6 @@ class port_address(design.design):
|
||||||
cols=self.num_cols)
|
cols=self.num_cols)
|
||||||
self.add_mod(self.wordline_driver)
|
self.add_mod(self.wordline_driver)
|
||||||
|
|
||||||
|
|
||||||
def create_row_decoder(self):
|
def create_row_decoder(self):
|
||||||
""" Create the hierarchical row decoder """
|
""" Create the hierarchical row decoder """
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,39 +28,39 @@ class hierarchical_decoder_test(openram_test):
|
||||||
|
|
||||||
factory.reset()
|
factory.reset()
|
||||||
debug.info(1, "Testing 16 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
factory.reset()
|
factory.reset()
|
||||||
debug.info(1, "Testing 17 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
factory.reset()
|
factory.reset()
|
||||||
debug.info(1, "Testing 23 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 32 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
factory.reset()
|
factory.reset()
|
||||||
debug.info(1, "Testing 65 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 128 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
factory.reset()
|
factory.reset()
|
||||||
debug.info(1, "Testing 341 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 512 row sample for hierarchical_decoder (multi-port case)")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
globals.end_openram()
|
globals.end_openram()
|
||||||
|
|
|
||||||
|
|
@ -22,45 +22,45 @@ class hierarchical_decoder_test(openram_test):
|
||||||
globals.init_openram(config_file)
|
globals.init_openram(config_file)
|
||||||
# Doesn't require hierarchical decoder
|
# Doesn't require hierarchical decoder
|
||||||
# debug.info(1, "Testing 4 row sample for 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)
|
# self.local_check(a)
|
||||||
|
|
||||||
# Doesn't require hierarchical decoder
|
# Doesn't require hierarchical decoder
|
||||||
# debug.info(1, "Testing 8 row sample for 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)
|
# self.local_check(a)
|
||||||
|
|
||||||
# check hierarchical decoder for single port
|
# check hierarchical decoder for single port
|
||||||
debug.info(1, "Testing 16 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 17 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 23 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 32 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 65 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 128 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 341 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
debug.info(1, "Testing 512 row sample for hierarchical_decoder")
|
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)
|
self.local_check(a)
|
||||||
|
|
||||||
globals.end_openram()
|
globals.end_openram()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue