add top level pins for sim

This commit is contained in:
Jacob Walker 2023-02-01 14:49:59 -08:00
parent 81bf2d7ae7
commit 736bd51fe1
11 changed files with 161 additions and 124 deletions

View File

@ -266,7 +266,7 @@ class rom_base_array(bitcell_base_array):
self.cell_pos[row, col] = vector(cell_x, cell_y) self.cell_pos[row, col] = vector(cell_x, cell_y)
self.cell_inst[row, col].place(self.cell_pos[row, col]) self.cell_inst[row, col].place(self.cell_pos[row, col])
cell_x += self.zero_cell.width cell_x += self.zero_cell.width
self.add_label("debug", "li", self.cell_pos[row, col]) # self.add_label("debug", "li", self.cell_pos[row, col])
self.strap_pos[row, self.column_size] = vector(cell_x, cell_y) self.strap_pos[row, self.column_size] = vector(cell_x, cell_y)
@ -326,7 +326,7 @@ class rom_base_array(bitcell_base_array):
def place_precharge(self): def place_precharge(self):
self.precharge_offset = vector(0, - self.precharge_inst.height - self.zero_cell.nmos.end_to_contact - 2 * drc["nwell_enclose_active"]) self.precharge_offset = vector(0, - self.precharge_inst.height - self.zero_cell.nmos.end_to_contact - 2 * drc["nwell_enclose_active"] - 3 * self.m1_pitch)
self.precharge_inst.place(offset=self.precharge_offset) self.precharge_inst.place(offset=self.precharge_offset)

View File

@ -2,7 +2,7 @@
from math import ceil, log, sqrt from math import ceil, log, sqrt
from openram.base import vector from openram.base import vector
from openram.base import design from openram.base import design
from openram import OPTS from openram import OPTS, debug
from openram.sram_factory import factory from openram.sram_factory import factory
from openram.tech import drc, layer from openram.tech import drc, layer
@ -14,8 +14,8 @@ class rom_base_bank(design):
word size is in bytes word size is in bytes
""" """
def __init__(self, strap_spacing=0, data_file=None, name="", word_size=2) -> None: def __init__(self, strap_spacing=0, data_file=None, name="", word_size=2):
super().__init__(name=name)
self.word_size = word_size * 8 self.word_size = word_size * 8
self.read_binary(word_size=word_size, data_file=data_file) self.read_binary(word_size=word_size, data_file=data_file)
@ -31,7 +31,7 @@ class rom_base_bank(design):
self.bitline_layer = "m1" self.bitline_layer = "m1"
self.wordline_layer = "m2" self.wordline_layer = "m2"
super().__init__(name=name)
if "li" in layer: if "li" in layer:
self.route_stack = self.m1_stack self.route_stack = self.m1_stack
else: else:
@ -39,7 +39,8 @@ class rom_base_bank(design):
self.route_layer = self.route_stack[0] self.route_layer = self.route_stack[0]
self.setup_layout_constants() self.setup_layout_constants()
self.create_netlist() self.create_netlist()
self.create_layout() if not OPTS.netlist_only:
self.create_layout()
""" """
Reads a hexadecimal file from a given directory to be used as the data written to the ROM Reads a hexadecimal file from a given directory to be used as the data written to the ROM
endian is either "big" or "little" endian is either "big" or "little"
@ -48,10 +49,17 @@ class rom_base_bank(design):
""" """
def read_binary(self, data_file, word_size=2, endian="big"): def read_binary(self, data_file, word_size=2, endian="big"):
# Read data as hexidecimal text file
hex_file = open(data_file, 'r') hex_file = open(data_file, 'r')
hex_data = hex_file.read() hex_data = hex_file.read()
bin_data = list("{0:08b}".format(int(hex_data, 16)))
# Convert from hex into an int
data_int = int(hex_data, 16)
# Then from int into a right aligned, zero padded string
bin_string = bin(data_int)[2:].zfill(len(hex_data) * 4)
# Then turn the string into a list of ints
bin_data = list(bin_string)
bin_data = [int(x) for x in bin_data] bin_data = [int(x) for x in bin_data]
# data size in bytes # data size in bytes
@ -78,17 +86,20 @@ class rom_base_bank(design):
self.data = chunked_data self.data = chunked_data
self.cols = bits_per_row self.cols = bits_per_row
self.rows = int(num_words / (self.words_per_row)) self.rows = int(num_words / (self.words_per_row))
debug.info(1, "Read rom binary: length {0} bytes, {1} words, set number of cols to {2}, rows to {3}, with {4} words per row".format(data_size, num_words, self.cols, self.rows, self.words_per_row))
# print("hex: {0}, binary: {1}, chunked: {2}".format(hex_data, bin_data, chunked_data)) # print("hex: {0}, binary: {1}, chunked: {2}".format(hex_data, bin_data, chunked_data))
def create_netlist(self): def create_netlist(self):
self.add_modules() self.add_modules()
# self.add_pins() self.add_pins()
print("Creating ROM bank instances")
self.create_instances()
def create_layout(self): def create_layout(self):
print("Creating ROM bank instances")
self.create_instances()
print("Placing ROM bank instances") print("Placing ROM bank instances")
self.place_instances() self.place_instances()
@ -101,13 +112,12 @@ class rom_base_bank(design):
print("Routing clock signal") print("Routing clock signal")
self.route_clock() self.route_clock()
self.route_array_outputs() self.route_array_outputs()
# self.route_supplies() self.place_top_level_pins()
self.route_supplies()
self.height = self.array_inst.height self.height = self.array_inst.height
self.width = self.array_inst.width self.width = self.array_inst.width
self.add_boundary() self.add_boundary()
print("Rom bank placement complete")
def setup_layout_constants(self): def setup_layout_constants(self):
self.route_layer_width = drc["minwidth_{}".format(self.route_stack[0])] self.route_layer_width = drc["minwidth_{}".format(self.route_stack[0])]
@ -121,11 +131,11 @@ class rom_base_bank(design):
self.add_pin("clk", "INPUT") self.add_pin("clk", "INPUT")
self.add_pin("CS", "INPUT") self.add_pin("CS", "INPUT")
for i in range(self.num_inputs): for i in range(self.row_bits + self.col_bits):
self.add_pin("addr_{}".format(i), "INPUT") self.add_pin("addr_{}".format(i), "INPUT")
out_pins = [] out_pins = []
for j in range(self.rows): for j in range(self.word_size):
out_pins.append("rom_out_{}".format(j)) out_pins.append("rom_out_{}".format(j))
self.add_pin_list(out_pins, "OUTPUT") self.add_pin_list(out_pins, "OUTPUT")
@ -153,14 +163,14 @@ class rom_base_bank(design):
strap_spacing=self.strap_spacing, strap_spacing=self.strap_spacing,
route_layer=self.route_layer, route_layer=self.route_layer,
cols=self.cols) cols=self.cols)
self.column_mux = factory.create(module_type="rom_column_mux_array", self.column_mux = factory.create(module_type="rom_column_mux_array",
columns=self.cols, columns=self.cols,
word_size=self.word_size, word_size=self.word_size,
bitline_layer=self.interconnect_layer) tap_spacing=self.strap_spacing,
bitline_layer=self.interconnect_layer,
input_layer=self.bitline_layer)
self.column_decode = factory.create(module_name="rom_column_decode", self.column_decode = factory.create(module_name="rom_column_decode",
module_type="rom_decoder", module_type="rom_decoder",
@ -173,55 +183,37 @@ class rom_base_bank(design):
self.control_logic = factory.create(module_type="rom_control_logic", self.control_logic = factory.create(module_type="rom_control_logic",
num_outputs=(self.rows + self.cols + self.words_per_row) * 0.5, num_outputs=(self.rows + self.cols + self.words_per_row) * 0.5,
clk_fanout=(self.col_bits + self.row_bits) * 2, clk_fanout=(self.col_bits + self.row_bits) * 2,
height=self.column_decode.height) height=self.column_decode.height )
print("Col decode height of {}".format(self.column_decode.height))
def create_instances(self): def create_instances(self):
gnd = ["gnd"] gnd = ["gnd"]
vdd = ["vdd"] vdd = ["vdd"]
prechrg = ["precharge"] prechrg = ["precharge"]
clk = ["clk_int"] clk = ["clk_int"]
array_pins = []
decode_pins = []
for bl in range(self.cols):
name = "bl_{}".format(bl)
array_pins.append(name)
for wl in range(self.rows):
name = "wl_{}".format(wl)
array_pins.append(wl)
array_pins.append("precharge")
array_pins.append("vdd")
array_pins.append("gnd")
for addr in range(self.row_bits):
name = "row_addr_{}".format(addr)
decode_pins.append(name)
for wl in range(self.rows):
name = "wl_{}".format(wl)
decode_pins.append(name)
decode_pins.append("precharge")
decode_pins.append("clk_int")
decode_pins.append("vdd")
decode_pins.append("gnd")
bitlines = ["bl_{}".format(bl) for bl in range(self.cols)] bitlines = ["bl_{}".format(bl) for bl in range(self.cols)]
select_lines = ["word_sel_{}".format(word) for word in range(self.words_per_row)] wordlines = ["wl_{}".format(wl) for wl in range(self.rows)]
bitline_out = ["rom_out_{}".format(bl) for bl in range(self.word_size)]
addr_lsb = ["col_addr_{}".format(addr) for addr in range(self.col_bits)]
col_mux_pins = bitlines + select_lines + bitline_out + gnd
addr_msb = ["addr_{}".format(addr + self.col_bits) for addr in range(self.row_bits)]
addr_lsb = ["addr_{}".format(addr) for addr in range(self.col_bits)]
select_lines = ["word_sel_{}".format(word) for word in range(self.words_per_row)]
outputs = ["rom_out_{}".format(bl) for bl in range(self.word_size)]
array_pins = bitlines + wordlines + prechrg + vdd + gnd
row_decode_pins = addr_msb + wordlines + prechrg + clk + vdd + gnd
col_decode_pins = addr_lsb + select_lines + prechrg + clk + vdd + gnd col_decode_pins = addr_lsb + select_lines + prechrg + clk + vdd + gnd
col_mux_pins = bitlines + select_lines + outputs + gnd
self.array_inst = self.add_inst(name="rom_bit_array", mod=self.array) self.array_inst = self.add_inst(name="rom_bit_array", mod=self.array)
self.connect_inst(array_pins) self.connect_inst(array_pins)
self.decode_inst = self.add_inst(name="rom_row_decoder", mod=self.decode_array) self.decode_inst = self.add_inst(name="rom_row_decoder", mod=self.decode_array)
self.connect_inst(decode_pins) self.connect_inst(row_decode_pins)
self.control_inst = self.add_inst(name="rom_control", mod=self.control_logic) self.control_inst = self.add_inst(name="rom_control", mod=self.control_logic)
self.connect_inst(["clk", "CS", "precharge", "clk_int", "vdd", "gnd"]) self.connect_inst(["clk", "CS", "precharge", "clk_int", "vdd", "gnd"])
@ -269,7 +261,7 @@ class rom_base_bank(design):
self.col_decode_inst.place(offset=self.col_decode_offset) self.col_decode_inst.place(offset=self.col_decode_offset)
def place_col_mux(self): def place_col_mux(self):
mux_y_offset = self.array_inst.by() - self.mux_inst.height - self.route_layer_pitch mux_y_offset = self.array_inst.by() - self.mux_inst.height - 5 * self.route_layer_pitch
mux_x_offset = self.array_inst.get_pin("bl_0_0").cx() - self.mux_inst.get_pin("bl_0").cx() mux_x_offset = self.array_inst.get_pin("bl_0_0").cx() - self.mux_inst.get_pin("bl_0").cx()
self.mux_offset = vector(mux_x_offset, mux_y_offset) self.mux_offset = vector(mux_x_offset, mux_y_offset)
@ -298,7 +290,7 @@ class rom_base_bank(design):
col_decode_pins = [self.col_decode_inst.get_pin("wl_{}".format(wl)) for wl in range(self.words_per_row)] col_decode_pins = [self.col_decode_inst.get_pin("wl_{}".format(wl)) for wl in range(self.words_per_row)]
sel_pins = [self.mux_inst.get_pin("sel_{}".format(wl)) for wl in range(self.words_per_row)] sel_pins = [self.mux_inst.get_pin("sel_{}".format(wl)) for wl in range(self.words_per_row)]
sel_pins.extend(col_decode_pins) sel_pins.extend(col_decode_pins)
self.connect_row_pins(self.array.bitline_layer, sel_pins, round=True) self.connect_row_pins(self.wordline_layer, sel_pins, round=True)
@ -391,34 +383,49 @@ class rom_base_bank(design):
self.add_path(self.array.bitline_layer, [bl_out, bl_mux]) self.add_path(self.array.bitline_layer, [bl_out, bl_mux])
def place_top_level_pins(self):
self.copy_layout_pin(self.control_inst, "CS", "CS")
for i in range(self.word_size):
self.copy_layout_pin(self.mux_inst, "bl_out_{}".format(i), "rom_out_{}".format(i))
for lsb in range(self.col_bits):
name = "addr_{}".format(lsb)
self.copy_layout_pin(self.col_decode_inst, "A{}".format(lsb), name)
for msb in range(self.col_bits, self.row_bits + self.col_bits):
name = "addr_{}".format(msb)
pin_num = msb - self.col_bits
self.copy_layout_pin(self.decode_inst, "A{}".format(pin_num), name)
def route_supplies(self): def route_supplies(self):
for inst in self.insts: for inst in self.insts:
self.copy_layout_pin(inst, "vdd") if not inst.mod.name.__contains__("contact"):
self.copy_layout_pin(inst, "gnd") self.copy_layout_pin(inst, "vdd")
gnd_start = vector(self.array_inst.get_pins("gnd")[0].cx(),0) self.copy_layout_pin(inst, "gnd")
# gnd_start = vector(self.array_inst.get_pins("gnd")[0].cx(),0)
decode_gnd = self.decode_inst.get_pin("gnd") # decode_gnd = self.decode_inst.get_pin("gnd")
decode_vdd = self.decode_inst.get_pin("vdd") # decode_vdd = self.decode_inst.get_pin("vdd")
array_vdd = self.array_inst.get_pin("vdd") # array_vdd = self.array_inst.get_pin("vdd")
# self.add_segment_center("m1", gnd_start, decode_gnd.center()) # # self.add_segment_center("m1", gnd_start, decode_gnd.center())
self.add_power_pin("gnd", decode_vdd.center()) # self.add_power_pin("gnd", decode_vdd.center())
self.add_power_pin("vdd", decode_gnd.center()) # self.add_power_pin("vdd", decode_gnd.center())
vdd_start = vector(array_vdd.lx() + 0.5 * self.via1_space, array_vdd.cy()) # vdd_start = vector(array_vdd.lx() + 0.5 * self.via1_space, array_vdd.cy())
end = vector(decode_vdd.lx(), vdd_start.y) # end = vector(decode_vdd.lx(), vdd_start.y)
self.add_segment_center(self.interconnect_layer, vdd_start, end) # self.add_segment_center(self.interconnect_layer, vdd_start, end)
self.add_via_stack_center(vdd_start, "m1", self.interconnect_layer) # self.add_via_stack_center(vdd_start, "m1", self.interconnect_layer)
vdd_start = vector(decode_vdd.cx(), vdd_start.y) # vdd_start = vector(decode_vdd.cx(), vdd_start.y)
self.add_segment_center(self.interconnect_layer, vdd_start, decode_vdd.center()) # self.add_segment_center(self.interconnect_layer, vdd_start, decode_vdd.center())

View File

@ -80,7 +80,7 @@ class rom_base_cell(design):
# height = self.base_width - min(self.cell_diffusion_offset, 0) - min(self.poly_active_offset, 0) - min(self.poly_tap_offset, 0) # height = self.base_width - min(self.cell_diffusion_offset, 0) - min(self.poly_active_offset, 0) - min(self.poly_tap_offset, 0)
# make the cells square so the pitch of wordlines will match bitlines # make the cells square so the pitch of wordlines will match bitlines
print("height: {0} width: {1}".format(height, width)) # print("height: {0} width: {1}".format(height, width))
if width > height: if width > height:
self.width = width self.width = width
self.height = width self.height = width

View File

@ -57,19 +57,13 @@ class rom_column_mux(pgate):
self.place_ptx() self.place_ptx()
# cell = factory.create(module_type=OPTS.bitcell)
# if(cell_props.use_strap == True and OPTS.num_ports == 1):
# strap = factory.create(module_type=cell_props.strap_module, version=cell_props.strap_version)
# precharge_width = cell.width + strap.width
# else:
# precharge_width = cell.width
self.width = self.bitcell.width self.width = self.bitcell.width
self.height = self.nmos_lower.uy() + self.pin_height self.height = self.nmos_lower.uy() + self.pin_height
self.connect_poly() self.connect_poly()
self.add_bitline_pins() self.add_bitline_pins()
self.connect_bitlines() self.connect_bitlines()
# self.add_pn_wells() self.add_pn_wells()
def add_ptx(self): def add_ptx(self):
self.bitcell = factory.create(module_type="rom_base_cell") self.bitcell = factory.create(module_type="rom_base_cell")
@ -107,7 +101,7 @@ class rom_column_mux(pgate):
def place_ptx(self): def place_ptx(self):
""" Create the two pass gate NMOS transistors to switch the bitlines""" """ Create the pass gate NMOS transistor to switch the bitline """
# Space it in the center # Space it in the center
nmos_lower_position = self.nmos.active_offset.scale(0, 1) \ nmos_lower_position = self.nmos.active_offset.scale(0, 1) \
@ -148,7 +142,9 @@ class rom_column_mux(pgate):
nmos_lower_s_pin = self.nmos_lower.get_pin("S") nmos_lower_s_pin = self.nmos_lower.get_pin("S")
nmos_lower_d_pin = self.nmos_lower.get_pin("D") nmos_lower_d_pin = self.nmos_lower.get_pin("D")
self.add_via_stack_center(from_layer=nmos_lower_s_pin.layer,
to_layer=self.input_layer,
offset=nmos_lower_s_pin.center())
self.add_via_stack_center(from_layer=nmos_lower_d_pin.layer, self.add_via_stack_center(from_layer=nmos_lower_d_pin.layer,
to_layer=self.output_layer, to_layer=self.output_layer,
@ -160,14 +156,14 @@ class rom_column_mux(pgate):
+ nmos_lower_s_pin.uc().scale(0, 0.5) + nmos_lower_s_pin.uc().scale(0, 0.5)
mid2 = bl_pin.bc().scale(0, 0.4) \ mid2 = bl_pin.bc().scale(0, 0.4) \
+ nmos_lower_s_pin.uc().scale(1, 0.5) + nmos_lower_s_pin.uc().scale(1, 0.5)
self.add_path(self.col_mux_stack[2], self.add_path(self.input_layer,
[bl_pin.bc(), mid1, mid2, nmos_lower_s_pin.center()]) [bl_pin.bc(), mid1, mid2, nmos_lower_s_pin.center()])
# halfway up, move over # halfway up, move over
mid1 = bl_out_pin.uc().scale(1, 0.4) \ mid1 = bl_out_pin.uc().scale(1, 0.4) \
+ nmos_lower_d_pin.bc().scale(0, 0.4) + nmos_lower_d_pin.bc().scale(0, 0.4)
mid2 = bl_out_pin.uc().scale(0, 0.4) \ mid2 = bl_out_pin.uc().scale(0, 0.4) \
+ nmos_lower_d_pin.bc().scale(1, 0.4) + nmos_lower_d_pin.bc().scale(1, 0.4)
self.add_path(self.col_mux_stack[0], self.add_path(self.output_layer,
[bl_out_pin.uc(), mid1, mid2, nmos_lower_d_pin.center()]) [bl_out_pin.uc(), mid1, mid2, nmos_lower_d_pin.center()])
@ -197,7 +193,7 @@ class rom_column_mux(pgate):
# rbc_width = self.bitcell.width # rbc_width = self.bitcell.width
# Add it to the right, aligned in between the two tx # Add it to the right, aligned in between the two tx
active_pos = vector(self.bitcell.width, active_pos = vector(self.bitcell.width,
self.nmos_upper.by() - 0.5 * self.poly_space) self.nmos_lower.uy() + self.active_contact.height + self.active_space)
self.add_via_center(layers=self.active_stack, self.add_via_center(layers=self.active_stack,
offset=active_pos, offset=active_pos,
@ -205,16 +201,17 @@ class rom_column_mux(pgate):
well_type="p") well_type="p")
# If there is a li layer, include it in the power stack # If there is a li layer, include it in the power stack
self.add_via_center(layers=self.col_mux_stack, self.add_via_stack_center(from_layer=self.active_stack[2],
offset=active_pos) to_layer=self.supply_stack[0],
offset=active_pos)
self.add_layout_pin_rect_center(text="gnd", self.add_layout_pin_rect_center(text="gnd",
layer="m1", layer=self.supply_stack[0],
offset=active_pos) offset=active_pos)
# Add well enclosure over all the tx and contact # Add well enclosure over all the tx and contact
if "pwell" in layer: # if "pwell" in layer:
self.add_rect(layer="pwell", # self.add_rect(layer="pwell",
offset=vector(0, 0), # offset=vector(0, 0),
width=rbc_width, # width=rbc_width,
height=self.height) # height=self.height)

View File

@ -20,7 +20,7 @@ class rom_column_mux_array(design):
Array of column mux to read the bitlines from ROM, based on the RAM column mux Array of column mux to read the bitlines from ROM, based on the RAM column mux
""" """
def __init__(self, name, columns, word_size, input_layer="m2", bitline_layer="m1", sel_layer="m2"): def __init__(self, name, columns, word_size, tap_spacing=4, input_layer="m2", bitline_layer="m1", sel_layer="m2"):
super().__init__(name) super().__init__(name)
debug.info(1, "Creating {0}".format(self.name)) debug.info(1, "Creating {0}".format(self.name))
self.add_comment("cols: {0} word_size: {1} ".format(columns, word_size)) self.add_comment("cols: {0} word_size: {1} ".format(columns, word_size))
@ -29,6 +29,7 @@ class rom_column_mux_array(design):
self.word_size = word_size self.word_size = word_size
self.words_per_row = int(self.columns / self.word_size) self.words_per_row = int(self.columns / self.word_size)
self.input_layer = input_layer self.input_layer = input_layer
self.tap_spacing = tap_spacing
# self.sel_layer = layer_props.column_mux_array.select_layer # self.sel_layer = layer_props.column_mux_array.select_layer
self.sel_layer = sel_layer self.sel_layer = sel_layer
@ -44,14 +45,6 @@ class rom_column_mux_array(design):
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.create_layout() self.create_layout()
def get_bl_name(self):
bl_name = self.mux.get_bl_names()
return bl_name
def get_br_name(self, port=0):
br_name = self.mux.get_br_names()
return br_name
def create_netlist(self): def create_netlist(self):
self.add_modules() self.add_modules()
self.add_pins() self.add_pins()
@ -61,12 +54,14 @@ class rom_column_mux_array(design):
self.setup_layout_constants() self.setup_layout_constants()
self.place_array() self.place_array()
self.add_routing() self.add_routing()
# Find the highest shapes to determine height before adding well # Find the highest shapes to determine height before adding well
highest = self.find_highest_coords() highest = self.find_highest_coords()
self.height = highest.y self.height = highest.y
self.add_layout_pins() self.add_layout_pins()
if "pwell" in layer: if "pwell" in layer:
self.add_enclosure(self.mux_inst, "pwell") self.add_enclosure(self.mux_inst, "pwell")
self.add_boundary() self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
@ -80,8 +75,8 @@ class rom_column_mux_array(design):
self.add_pin("gnd") self.add_pin("gnd")
def add_modules(self): def add_modules(self):
self.mux = factory.create(module_type="rom_column_mux") self.mux = factory.create(module_type="rom_column_mux", input_layer=self.input_layer, output_layer=self.bitline_layer)
self.tap = factory.create(module_type="rom_poly_tap", add_tap=True)
self.cell = factory.create(module_type="rom_base_cell") self.cell = factory.create(module_type="rom_base_cell")
def setup_layout_constants(self): def setup_layout_constants(self):
@ -145,8 +140,12 @@ class rom_column_mux_array(design):
def add_horizontal_input_rail(self): def add_horizontal_input_rail(self):
""" Create address input rails below the mux transistors """ """ Create address input rails below the mux transistors """
tap_offset = 0
for j in range(self.words_per_row): for j in range(self.words_per_row):
offset = vector(0, self.route_height + (j - self.words_per_row) * self.cell.width) if j % self.tap_spacing == 0 and j != 0:
tap_offset += self.tap.pitch_offset
offset = vector(0, self.route_height + tap_offset + (j - self.words_per_row) * self.cell.width)
self.add_layout_pin(text="sel_{}".format(j), self.add_layout_pin(text="sel_{}".format(j),
layer=self.sel_layer, layer=self.sel_layer,
offset=offset, offset=offset,
@ -208,7 +207,10 @@ class rom_column_mux_array(design):
directions=self.via_directions) directions=self.via_directions)
def add_taps(self):
pass
def graph_exclude_columns(self, column_include_num): def graph_exclude_columns(self, column_include_num):
""" """
Excludes all columns muxes unrelated to the target bit being simulated. Excludes all columns muxes unrelated to the target bit being simulated.

View File

@ -19,11 +19,9 @@ class rom_control_logic(design):
self.height = height self.height = height
if self.height is not None: if self.height is not None:
print("got height of {}".format(self.height)) self.driver_height = 0.5 * self.height
self.driver_height = 0.6 * self.height self.gate_height = 0.25 * self.height
self.gate_height = 0.2 * self.height
else: else:
print("got none height")
self.gate_height = 20 * self.m1_pitch self.gate_height = 20 * self.m1_pitch
self.driver_height = self.gate_height self.driver_height = self.gate_height
@ -98,12 +96,11 @@ class rom_control_logic(design):
def route_insts(self): def route_insts(self):
route_width = drc["minwidth_{}".format(self.route_stack[2])] route_width = drc["minwidth_{}".format(self.route_stack[2])]
self.copy_layout_pin(self.buf_inst, "A", "clk_in") self.copy_layout_pin(self.buf_inst, "A", "clk_in")
self.copy_layout_pin(self.buf_inst, "Zb", "clkb_out") self.copy_layout_pin(self.buf_inst, "Zb", "clkb_out")
self.copy_layout_pin(self.buf_inst, "Z", "clk_out") self.copy_layout_pin(self.buf_inst, "Z", "clk_out")
self.copy_layout_pin(self.driver_inst, "Z", "prechrg") self.copy_layout_pin(self.driver_inst, "Z", "prechrg")
self.copy_layout_pin(self.nand_inst, "B", "CS") self.copy_layout_pin(self.nand_inst, "A", "CS")
self.copy_layout_pin(self.buf_inst, "gnd") self.copy_layout_pin(self.buf_inst, "gnd")
self.copy_layout_pin(self.driver_inst, "vdd") self.copy_layout_pin(self.driver_inst, "vdd")
self.copy_layout_pin(self.buf_inst, "vdd") self.copy_layout_pin(self.buf_inst, "vdd")

View File

@ -112,17 +112,17 @@ class rom_decoder(design):
cols=self.num_inputs) cols=self.num_inputs)
self.wordline_buf = factory.create(module_type="rom_wordline_driver_array", module_name="{}_wordline_buffer".format(self.name), \ self.wordline_buf = factory.create(module_type="rom_wordline_driver_array", module_name="{}_wordline_buffer".format(self.name),
rows=self.num_outputs, \ rows=self.num_outputs,
cols=self.cols, cols=ceil(self.cols * 0.5),
invert_outputs=self.invert_outputs, invert_outputs=self.invert_outputs,
tap_spacing=self.strap_spacing) tap_spacing=self.strap_spacing)
self.array_mod = factory.create(module_type="rom_base_array", \ self.array_mod = factory.create(module_type="rom_base_array",
module_name="{}_array".format(self.name), \ module_name="{}_array".format(self.name),
cols=self.num_outputs, \ cols=self.num_outputs,
rows=2 * self.num_inputs, \ rows=2 * self.num_inputs,
bitmap=self.decode_map, bitmap=self.decode_map,
strap_spacing = self.strap_spacing, strap_spacing = self.strap_spacing,
bitline_layer=self.output_layer, bitline_layer=self.output_layer,

View File

@ -109,7 +109,7 @@ class rom_precharge_array(design):
def create_precharge_tx(self, col): def create_precharge_tx(self, col):
name = "Xpmos_c{0}".format(col) name = "pmos_c{0}".format(col)
pmos = self.add_inst(name=name, mod=self.pmos) pmos = self.add_inst(name=name, mod=self.pmos)
self.array_insts.append(pmos) self.array_insts.append(pmos)
self.pmos_insts.append(pmos) self.pmos_insts.append(pmos)

View File

@ -88,7 +88,6 @@ class rom_wordline_driver_array(design):
""" """
if layer_props.wordline_driver.vertical_supply: if layer_props.wordline_driver.vertical_supply:
print("copied")
# self.route_vertical_pins("vdd", self.wld_inst) # self.route_vertical_pins("vdd", self.wld_inst)
# self.route_vertical_pins("gnd", self.wld_inst) # self.route_vertical_pins("gnd", self.wld_inst)
self.route_vertical_pins("vdd", [self], layer=self.supply_layer) self.route_vertical_pins("vdd", [self], layer=self.supply_layer)

View File

@ -13,7 +13,7 @@ import sys, os
import openram import openram
from openram import OPTS from openram import OPTS
from openram.sram_factory import factory from openram.sram_factory import factory
import debug from openram import debug
class rom_bank_test(openram_test): class rom_bank_test(openram_test):
@ -21,8 +21,7 @@ class rom_bank_test(openram_test):
def runTest(self): def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME")) config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True) openram.init_openram(config_file, is_unit_test=True)
debug.info(1, "Testing 1kB rom cell")
debug.info(2, "Testing 4x4 array for rom cell")
a = factory.create(module_type="rom_base_bank", strap_spacing = 8, data_file="/openram/technology/rom_data_1kB", word_size=1) a = factory.create(module_type="rom_base_bank", strap_spacing = 8, data_file="/openram/technology/rom_data_1kB", word_size=1)

View File

@ -0,0 +1,36 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2021 Regents of the University of California and The Board
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
import unittest
from testutils import *
import sys, os
import openram
from openram import OPTS
from openram.sram_factory import factory
from openram import debug
class rom_bank_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
openram.init_openram(config_file, is_unit_test=True)
debug.info(1, "Testing 32 byte rom cell")
a = factory.create(module_type="rom_base_bank", strap_spacing = 8, data_file="/openram/technology/rom_data_64B", word_size=1)
self.local_check(a)
openram.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = openram.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())