OpenRAM/compiler/modules/rom_address_control_array.py

134 lines
4.5 KiB
Python
Raw Normal View History

2023-01-17 01:15:03 +01:00
# See LICENSE for licensing information.
#
2024-01-03 23:32:44 +01:00
# Copyright (c) 2016-2024 Regents of the University of California and The Board
2023-01-17 01:15:03 +01:00
# of Regents for the Oklahoma Agricultural and Mechanical College
# (acting for and on behalf of Oklahoma State University)
# All rights reserved.
#
from openram.base import design
from openram.sram_factory import factory
from openram.base import vector
from openram.tech import layer, drc
class rom_address_control_array(design):
"""
Takes the input address lines and creates the address and address bar lines for the decoder.
Adds control logic for the precharge cycle so that all address lines are high before the read cycle
"""
def __init__(self, cols, inv_height=None, inv_size=1, name="", route_layer="m1"):
self.size=inv_size
self.cols = cols
self.route_layer = route_layer
if name=="":
name = "rom_inv_array_{0}".format(cols)
if inv_height == None:
self.inv_height = drc("minwidth_{}".format(route_layer)) * 14
2023-03-01 06:10:52 +01:00
else:
2023-01-17 01:15:03 +01:00
self.inv_height = inv_height
if "li" in layer:
self.inv_layer = "li"
else:
self.inv_layer = "m1"
self.route_layer = "m2"
2023-01-17 01:15:03 +01:00
super().__init__(name)
self.create_netlist()
self.create_layout()
def create_netlist(self):
self.create_modules()
self.add_pins()
self.create_instances()
def create_layout(self):
self.width = self.cols * self.addr_control.width
2023-03-01 06:10:52 +01:00
self.height = self.addr_control.height
2023-01-17 01:15:03 +01:00
self.setup_layout_constants()
self.place_instances()
self.route_clk()
self.route_sources()
self.copy_pins()
self.add_boundary()
def create_modules(self):
self.addr_control = factory.create(module_type="rom_address_control_buf", size=self.inv_height)
2023-03-02 00:49:43 +01:00
2023-01-17 01:15:03 +01:00
def add_pins(self):
for col in range(self.cols):
self.add_pin("A{0}_in".format(col), "INPUT")
2023-01-27 00:48:38 +01:00
for col in range(self.cols):
2023-01-17 01:15:03 +01:00
self.add_pin("A{0}_out".format(col), "OUTPUT")
2023-01-27 00:48:38 +01:00
for col in range(self.cols):
2023-01-17 01:15:03 +01:00
self.add_pin("Abar{0}_out".format(col), "OUTPUT")
self.add_pin("clk", "INPUT")
self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND")
def create_instances(self):
2023-02-28 00:56:24 +01:00
2023-01-17 01:15:03 +01:00
self.buf_insts = []
for col in range(self.cols):
2023-02-28 00:56:24 +01:00
2023-01-17 01:15:03 +01:00
name = "Xaddr_buf_{0}".format(col)
addr_buf = self.add_inst(name=name, mod=self.addr_control)
A_in = "A{0}_in".format(col)
Aout = "A{0}_out".format(col)
Abar_out = "Abar{0}_out".format(col)
self.connect_inst([A_in, Aout, Abar_out, "clk", "vdd", "gnd"])
self.buf_insts.append(addr_buf)
def setup_layout_constants(self):
self.route_width = drc["minwidth_{}".format(self.route_layer)]
def place_instances(self):
for col in range(self.cols):
base = vector((col+1)*(self.addr_control.width), 0)
self.buf_insts[col].place(offset=base, mirror="MY")
def copy_pins(self):
for i in range(self.cols):
self.copy_layout_pin(self.buf_insts[i], "A_out", "A{0}_out".format(i))
self.copy_layout_pin(self.buf_insts[i], "Abar_out", "Abar{0}_out".format(i))
self.copy_layout_pin(self.buf_insts[i], "A_in", "A{0}_in".format(i))
def route_clk(self):
self.route_horizontal_pins("clk", insts=self.buf_insts, layer=self.route_layer)
def route_sources(self):
self.route_horizontal_pins("vdd", insts=self.buf_insts, layer=self.route_layer)
self.route_horizontal_pins("gnd", insts=self.buf_insts, layer=self.route_layer)
tmp_pins = []
for pin in self.get_pins("vdd"):
edge = vector(pin.lx() + 0.5 * self.route_width, pin.cy())
tmp_pins.append(self.add_layout_pin_rect_center("vdd_edge", layer=self.route_layer, offset=edge))
self.copy_layout_pin_shapes("vdd")
self.remove_layout_pin("vdd")
for pin in tmp_pins:
self.copy_layout_pin(self, "vdd_edge", "vdd")
self.remove_layout_pin("vdd_edge")
tmp_pins = []
for pin in self.get_pins("gnd"):
edge = vector(pin.rx() + 0.5 * self.route_width, pin.cy())
tmp_pins.append(self.add_layout_pin_rect_center("gnd_edge", layer=self.route_layer, offset=edge))
self.copy_layout_pin_shapes("gnd")
self.remove_layout_pin("gnd")
for pin in tmp_pins:
self.copy_layout_pin(self, "gnd_edge", "gnd")
2024-01-03 23:32:44 +01:00
self.remove_layout_pin("gnd_edge")