# See LICENSE for licensing information. # # Copyright (c) 2016-2023 Regents of the University of California, Santa Cruz # All rights reserved. # import math from openram import debug from openram.base import design from openram.base import vector from openram.sram_factory import factory from openram.tech import drc from openram.tech import cell_properties from openram.tech import layer_properties as layer_props from openram import OPTS class column_decoder(design): """ Create the column mux decoder. """ def __init__(self, name, col_addr_size): super().__init__(name) self.col_addr_size = col_addr_size self.num_inputs = col_addr_size self.num_outputs = pow(2, col_addr_size) debug.info(2, "create column decoder of {0} inputs and {1} outputs".format(self.num_inputs, self.num_outputs)) self.create_netlist() if not OPTS.netlist_only: self.create_layout() self.DRC_LVS() def create_netlist(self): self.add_pins() self.add_modules() self.create_instances() def create_instances(self): self.column_decoder_inst = self.add_inst(name="column_decoder", mod=self.column_decoder) self.connect_inst(self.pins) def create_layout(self): self.column_decoder_inst.place(vector(0,0)) self.width = self.column_decoder_inst.width self.height = self.column_decoder_inst.height self.route_layout() def add_pins(self): """ Add the module pins """ for i in range(self.num_inputs): self.add_pin("in_{0}".format(i), "INPUT") for j in range(self.num_outputs): self.add_pin("out_{0}".format(j), "OUTPUT") self.add_pin("vdd", "POWER") self.add_pin("gnd", "GROUND") def route_layout_pins(self): """ Add the pins. """ if self.col_addr_size == 1: self.copy_layout_pin(self.column_decoder_inst, "A", "in_0") self.copy_layout_pin(self.column_decoder_inst, "Zb", "out_0") self.copy_layout_pin(self.column_decoder_inst, "Z", "out_1") elif self.col_addr_size > 1: for i in range(self.num_inputs): self.copy_layout_pin(self.column_decoder_inst, "in_{0}".format(i)) for i in range(self.num_outputs): self.copy_layout_pin(self.column_decoder_inst, "out_{0}".format(i)) def route_layout(self): """ Create routing among the modules """ self.route_layout_pins() self.route_supplies() def route_supplies(self): """ Propagate all vdd/gnd pins up to this level for all modules """ if self.col_addr_size == 1: self.copy_layout_pin(self.column_decoder_inst, "vdd") self.copy_layout_pin(self.column_decoder_inst, "gnd") else: self.route_vertical_pins("vdd", self.insts, xside="rx",) self.route_vertical_pins("gnd", self.insts, xside="lx",) def add_modules(self): self.dff =factory.create(module_type="dff") if self.col_addr_size == 1: self.column_decoder = factory.create(module_type="pinvbuf", height=self.dff.height) elif self.col_addr_size == 2: self.column_decoder = factory.create(module_type="hierarchical_predecode2x4", column_decoder=True, height=self.dff.height) elif self.col_addr_size == 3: self.column_decoder = factory.create(module_type="hierarchical_predecode3x8", column_decoder=True, height=self.dff.height) elif self.col_addr_size == 4: self.column_decoder = factory.create(module_type="hierarchical_predecode4x16", column_decoder=True, height=self.dff.height) else: # No error checking before? debug.error("Invalid column decoder?", -1)