class row_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): """ A single bit cell which is forced to store a 0. This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = [ props.bitcell.cell_1rw1r.pin.wl0, props.bitcell.cell_1rw1r.pin.wl1, props.bitcell.cell_1rw1r.pin.gnd ] type_list = ["INPUT", "INPUT", "GROUND"] (width, height) = utils.get_libcell_size("row_cap_cell_1rw_1r", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "row_cap_cell_1rw_1r", GDS["unit"]) def __init__(self, name=""): # Ignore the name argument bitcell_base.bitcell_base.__init__(self, "row_cap_cell_1rw_1r") debug.info(2, "Create row_cap bitcell 1rw+1r object") self.width = row_cap_bitcell_1rw_1r.width self.height = row_cap_bitcell_1rw_1r.height self.pin_map = row_cap_bitcell_1rw_1r.pin_map self.add_pin_types(self.type_list) self.no_instances = True
class dummy_bitcell(bitcell_base.bitcell_base): """ A single bit cell (6T, 8T, etc.) This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = [ props.bitcell.cell_6t.pin.bl, props.bitcell.cell_6t.pin.br, props.bitcell.cell_6t.pin.wl, props.bitcell.cell_6t.pin.vdd, props.bitcell.cell_6t.pin.gnd ] (width, height) = utils.get_libcell_size("dummy_cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "dummy_cell_6t", GDS["unit"]) def __init__(self, name=""): # Ignore the name argument bitcell_base.bitcell_base.__init__(self, "dummy_cell_6t") debug.info(2, "Create dummy bitcell") self.width = dummy_bitcell.width self.height = dummy_bitcell.height self.pin_map = dummy_bitcell.pin_map
class replica_bitcell_1w_1r(design.design): """ A single bit cell which is forced to store a 0. This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = [ props.bitcell.cell_1w1r.pin.bl0, props.bitcell.cell_1w1r.pin.br0, props.bitcell.cell_1w1r.pin.bl1, props.bitcell.cell_1w1r.pin.br1, props.bitcell.cell_1w1r.pin.wl0, props.bitcell.cell_1w1r.pin.wl1, props.bitcell.cell_1w1r.pin.vdd, props.bitcell.cell_1w1r.pin.gnd ] type_list = [ "OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND" ] (width, height) = utils.get_libcell_size("replica_cell_1w_1r", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "replica_cell_1w_1r", GDS["unit"]) def __init__(self, name=""): # Ignore the name argument design.design.__init__(self, "replica_cell_1w_1r") debug.info(2, "Create replica bitcell 1w+1r object") self.width = replica_bitcell_1w_1r.width self.height = replica_bitcell_1w_1r.height self.pin_map = replica_bitcell_1w_1r.pin_map self.add_pin_types(self.type_list) def get_stage_effort(self, load): parasitic_delay = 1 size = 0.5 #This accounts for bitline being drained thought the access TX and internal node cin = 3 #Assumes always a minimum sizes inverter. Could be specified in the tech.py file. read_port_load = 0.5 #min size NMOS gate load return logical_effort.logical_effort('bitline', size, cin, load + read_port_load, parasitic_delay, False) def input_load(self): """Return the relative capacitance of the access transistor gates""" # FIXME: This applies to bitline capacitances as well. # FIXME: sizing is not accurate with the handmade cell. Change once cell widths are fixed. access_tx_cin = parameter["6T_access_size"] / drc["minwidth_tx"] return 2 * access_tx_cin def build_graph(self, graph, inst_name, port_nets): """Adds edges to graph. Multiport bitcell timing graph is too complex to use the add_graph_edges function.""" debug.info(1, 'Adding edges for {}'.format(inst_name)) pin_dict = {pin: port for pin, port in zip(self.pins, port_nets)} pins = props.bitcell.cell_1w1r.pin #Edges hardcoded here. Essentially wl->bl/br for the read port. # Port 1 edges graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.bl1], self) graph.add_edge(pin_dict[pins.wl1], pin_dict[pins.br1], self)
class replica_bitcell(design.design): """ A single bit cell (6T, 8T, etc.) This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["bl", "br", "wl", "vdd", "gnd"] (width, height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "replica_cell_6t", GDS["unit"]) def __init__(self, name=""): # Ignore the name argument design.design.__init__(self, "replica_cell_6t") debug.info(2, "Create replica bitcell object") self.width = replica_bitcell.width self.height = replica_bitcell.height self.pin_map = replica_bitcell.pin_map def get_wl_cin(self): """Return the relative capacitance of the access transistor gates""" #This is a handmade cell so the value must be entered in the tech.py file or estimated. #Calculated in the tech file by summing the widths of all the related gates and dividing by the minimum width. access_tx_cin = parameter["6T_access_size"] / drc["minwidth_tx"] return 2 * access_tx_cin
class write_driver(design.design): """ Tristate write driver to be active during write operations only. This module implements the write driver cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["din", "bl", "br", "en", "gnd", "vdd"] (width, height) = utils.get_libcell_size("write_driver", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "write_driver", GDS["unit"]) def __init__(self, name): design.design.__init__(self, name) debug.info(2, "Create write_driver") self.width = write_driver.width self.height = write_driver.height self.pin_map = write_driver.pin_map def get_w_en_cin(self): """Get the relative capacitance of a single input""" # This is approximated from SCMOS. It has roughly 5 3x transistor gates. return 5 * 3
class write_driver(design.design): """ Tristate write driver to be active during write operations only. This module implements the write driver cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["din", "bl", "br", "en", "vdd", "gnd"] type_list = ["INPUT", "OUTPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] (width,height) = utils.get_libcell_size("write_driver", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "write_driver", GDS["unit"]) def __init__(self, name): design.design.__init__(self, name) debug.info(2, "Create write_driver") self.width = write_driver.width self.height = write_driver.height self.pin_map = write_driver.pin_map self.add_pin_types(self.type_list) def get_w_en_cin(self): """Get the relative capacitance of a single input""" # This is approximated from SCMOS. It has roughly 5 3x transistor gates. return 5*3 def build_graph(self, graph, inst_name, port_nets): """Adds edges based on inputs/outputs. Overrides base class function.""" self.add_graph_edges(graph, port_nets)
class dummy_bitcell_1w_1r(bitcell_base.bitcell_base): """ A single bit cell which is forced to store a 0. This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["bl0", "br0", "bl1", "br1", "wl0", "wl1", "vdd", "gnd"] type_list = [ "OUTPUT", "OUTPUT", "INPUT", "INPUT", "INPUT", "INPUT", "POWER", "GROUND" ] (width, height) = utils.get_libcell_size("dummy_cell_1w_1r", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "dummy_cell_1w_1r", GDS["unit"]) def __init__(self, name=""): # Ignore the name argument bitcell_base.bitcell_base.__init__(self, "dummy_cell_1w_1r") debug.info(2, "Create dummy bitcell 1w+1r object") self.width = dummy_bitcell_1w_1r.width self.height = dummy_bitcell_1w_1r.height self.pin_map = dummy_bitcell_1w_1r.pin_map self.add_pin_types(self.type_list)
class bitcell(design.design): """ A single bit cell (6T, 8T, etc.) This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["BL", "BR", "WL", "vdd", "gnd"] (width,height) = utils.get_libcell_size("cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "cell_6t", GDS["unit"], layer["boundary"]) def __init__(self): design.design.__init__(self, "cell_6t") debug.info(2, "Create bitcell object") self.width = bitcell.width self.height = bitcell.height self.pin_map = bitcell.pin_map def analytical_delay(self, slew, load=0, swing = 0.5): # delay of bit cell is not like a driver(from WL) # so the slew used should be 0 # it should not be slew dependent? # because the value is there # the delay is only over half transsmission gate from tech import spice r = spice["min_tx_r"]*3 c_para = spice["min_tx_drain_c"] result = self.cal_delay_with_rc(r = r, c = c_para+load, slew = slew, swing = swing) return result
class tri_gate(design.design): """ This module implements the tri gate cell used in the design for bit-line isolation. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["in", "en", "en_bar", "out", "gnd", "vdd"] (width, height) = utils.get_libcell_size("tri_gate", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "tri_gate", GDS["unit"], layer["boundary"]) unique_id = 1 def __init__(self, name=""): if name == "": name = "tri{0}".format(tri_gate.unique_id) tri_gate.unique_id += 1 design.design.__init__(self, name) debug.info(2, "Create tri_gate") self.width = tri_gate.width self.height = tri_gate.height self.pin_map = tri_gate.pin_map def analytical_delay(self, slew, load=0.0): from tech import spice r = spice["min_tx_r"] c_para = spice["min_tx_drain_c"] return self.cal_delay_with_rc(r=r, c=c_para + load, slew=slew) def input_load(self): return 9 * spice["min_tx_gate_c"]
class col_cap_bitcell_1rw_1r(bitcell_base.bitcell_base): """ todo""" pin_names = [props.bitcell.cell_1rw1r.pin.bl0, props.bitcell.cell_1rw1r.pin.br0, props.bitcell.cell_1rw1r.pin.bl1, props.bitcell.cell_1rw1r.pin.br1, props.bitcell.cell_1rw1r.pin.vdd] type_list = ["OUTPUT", "OUTPUT", "OUTPUT", "OUTPUT", "POWER", "GROUND"] (width, height) = utils.get_libcell_size("col_cap_cell_1rw_1r", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "col_cap_cell_1rw_1r", GDS["unit"]) def __init__(self, name=""): # Ignore the name argument bitcell_base.bitcell_base.__init__(self, "col_cap_cell_1rw_1r") debug.info(2, "Create col_cap bitcell 1rw+1r object") self.width = col_cap_bitcell_1rw_1r.width self.height = col_cap_bitcell_1rw_1r.height self.pin_map = col_cap_bitcell_1rw_1r.pin_map self.add_pin_types(self.type_list) self.no_instances = True
class sense_amp(design.design): """ This module implements the single sense amp cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. Sense amplifier to read a pair of bit-lines. """ pin_names = ["bl", "br", "dout", "en", "vdd", "gnd"] (width, height) = utils.get_libcell_size("sense_amp", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "sense_amp", GDS["unit"], layer["boundary"]) def __init__(self, name): design.design.__init__(self, name) debug.info(2, "Create sense_amp") self.width = sense_amp.width self.height = sense_amp.height self.pin_map = sense_amp.pin_map def analytical_delay(self, slew, load=0.0): from tech import spice r = spice["min_tx_r"] / (10) c_para = spice["min_tx_drain_c"] result = self.cal_delay_with_rc(r=r, c=c_para + load, slew=slew) return self.return_delay(result.delay, result.slew) def analytical_power(self, proc, vdd, temp, load): """Returns dynamic and leakage power. Results in nW""" #Power in this module currently not defined. Returns 0 nW (leakage and dynamic). total_power = self.return_power() return total_power
class dff(design.design): """ Memory address flip-flop """ if not props.dff.use_custom_ports: pin_names = ["D", "Q", "clk", "vdd", "gnd"] type_list = ["INPUT", "OUTPUT", "INPUT", "POWER", "GROUND"] clk_pin = "clk" else: pin_names = props.dff.custom_port_list type_list = props.dff.custom_type_list clk_pin = props.dff.clk_pin (width, height) = utils.get_libcell_size("dff", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "dff", GDS["unit"]) def __init__(self, name="dff"): design.design.__init__(self, name) self.width = dff.width self.height = dff.height self.pin_map = dff.pin_map self.add_pin_types(self.type_list) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" c_eff = self.calculate_effective_capacitance(load) freq = spice["default_event_frequency"] power_dyn = self.calc_dynamic_power(corner, c_eff, freq) power_leak = spice["dff_leakage"] total_power = self.return_power(power_dyn, power_leak) return total_power def calculate_effective_capacitance(self, load): """Computes effective capacitance. Results in fF""" from tech import parameter c_load = load c_para = spice["dff_out_cap"]#ff transition_prob = 0.5 return transition_prob*(c_load + c_para) def get_clk_cin(self): """Return the total capacitance (in relative units) that the clock is loaded by in the dff""" #This is a handmade cell so the value must be entered in the tech.py file or estimated. #Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width. return parameter["dff_clk_cin"] def build_graph(self, graph, inst_name, port_nets): """Adds edges based on inputs/outputs. Overrides base class function.""" self.add_graph_edges(graph, port_nets)
class sense_amp(design.design): """ This module implements the single sense amp cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. Sense amplifier to read a pair of bit-lines. """ pin_names = ["bl", "br", "dout", "en", "vdd", "gnd"] (width, height) = utils.get_libcell_size("sense_amp", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "sense_amp", GDS["unit"]) def __init__(self, name): design.design.__init__(self, name) debug.info(2, "Create sense_amp") self.width = sense_amp.width self.height = sense_amp.height self.pin_map = sense_amp.pin_map def input_load(self): #Input load for the bitlines which are connected to the source/drain of a TX. Not the selects. from tech import spice, parameter # Default is 8x. Per Samira and Hodges-Jackson book: # "Column-mux transistors driven by the decoder must be sized for optimal speed" bitline_pmos_size = 8 #FIXME: This should be set somewhere and referenced. Probably in tech file. return spice["min_tx_drain_c"] * ( bitline_pmos_size / parameter["min_tx_size"]) #ff def analytical_delay(self, corner, slew, load=0.0): from tech import spice r = spice["min_tx_r"] / (10) c_para = spice["min_tx_drain_c"] result = self.cal_delay_with_rc(corner, r=r, c=c_para + load, slew=slew) return self.return_delay(result.delay, result.slew) def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" #Power in this module currently not defined. Returns 0 nW (leakage and dynamic). total_power = self.return_power() return total_power def get_en_cin(self): """Get the relative capacitance of sense amp enable gate cin""" pmos_cin = parameter["sa_en_pmos_size"] / drc("minwidth_tx") nmos_cin = parameter["sa_en_nmos_size"] / drc("minwidth_tx") #sen is connected to 2 pmos isolation TX and 1 nmos per sense amp. return 2 * pmos_cin + nmos_cin
def __init__(self, version, name=""): # Ignore the name argument if version == "opt1": self.name = "s8sram_cell_opt1" self.border_structure = "s8sram_cell" elif version == "opt1a": self.name = "s8sram_cell_opt1a" self.border_structure = "s8sram_cell" self.pin_map = utils.get_libcell_pins(self.pin_names, self.name, GDS["unit"]) design.design.__init__(self, "replica_cell_6t") debug.info(2, "Create replica bitcell object") self.pin_map = utils.get_libcell_pins(self.pin_names, self.name, GDS["unit"]) self.add_pin_types(self.type_list) (self.width, self.height) = utils.get_libcell_size(self.name, GDS["unit"], layer["mem"])
def __init__(self, version, name=""): # Ignore the name argument if version == "opt1": self.name = "s8sram_cell_opt1" self.border_structure = "s8sram_cell" elif version == "opt1a": self.name = "s8sram_cell_opt1a" self.border_structure = "s8sram_cell" bitcell_base.bitcell_base.__init__(self, self.name) debug.info(2, "Create dummy bitcell") (self.width, self.height) = utils.get_libcell_size(self.name, GDS["unit"], layer["mem"], "s8sram_cell\x00") self.pin_map = utils.get_libcell_pins(self.pin_names, self.name, GDS["unit"])
class dff(design.design): """ Memory address flip-flop """ pin_names = ["D", "Q", "clk", "vdd", "gnd"] (width, height) = utils.get_libcell_size("dff", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "dff", GDS["unit"]) def __init__(self, name="dff"): design.design.__init__(self, name) self.width = dff.width self.height = dff.height self.pin_map = dff.pin_map def analytical_power(self, corner, load): """Returns dynamic and leakage power. Results in nW""" c_eff = self.calculate_effective_capacitance(load) freq = spice["default_event_rate"] power_dyn = self.calc_dynamic_power(corner, c_eff, freq) power_leak = spice["msflop_leakage"] total_power = self.return_power(power_dyn, power_leak) return total_power def calculate_effective_capacitance(self, load): """Computes effective capacitance. Results in fF""" from tech import parameter c_load = load c_para = spice["flop_para_cap"] #ff transition_prob = spice["flop_transition_prob"] return transition_prob * (c_load + c_para) def analytical_delay(self, corner, slew, load=0.0): # dont know how to calculate this now, use constant in tech file result = self.return_delay(spice["dff_delay"], spice["dff_slew"]) return result def get_clk_cin(self): """Return the total capacitance (in relative units) that the clock is loaded by in the dff""" #This is a handmade cell so the value must be entered in the tech.py file or estimated. #Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width. return parameter["dff_clk_cin"]
class flipflop(design.design): """ This module implements the single flipflop cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library.""" pin_names = ["in", "out", "out_bar", "clk", "vdd", "gnd"] (width, height) = utils.get_libcell_size("flipflop", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "flipflop", GDS["unit"]) def __init__(self): design.design.__init__(self, "flipflop") debug.info(2, "Create flipflop") self.width = flipflop.width self.height = flipflop.height self.pin_map = flipflop.pin_map
class xor2(design.design): """ This module implements the single 2 input xor cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library.""" pin_names = ["A", "B", "Z", "vdd", "gnd"] (width, height) = utils.get_libcell_size("xor2", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "xor2", GDS["unit"]) def __init__(self): design.design.__init__(self, "xor2") debug.info(2, "Create xor2") self.width = xor2.width self.height = xor2.height self.pin_map = xor2.pin_map
class bitcell(design.design): """ A single bit 6T cell. This module implements the single memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["bl", "br", "wl", "vdd", "gnd"] (width, height) = utils.get_libcell_size("cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "cell_6t", GDS["unit"]) def __init__(self): design.design.__init__(self, "cell_6t") debug.info(2, "Create bitcell") self.width = bitcell.width self.height = bitcell.height self.pin_map = bitcell.pin_map
class single_driver(design.design): """ A single single_driver cell. This module implements the single single_driver cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["in0", "in1", "out", "vdd", "gnd"] (width,height) = utils.get_libcell_size("single_driver", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "single_driver", GDS["unit"]) def __init__(self): design.design.__init__(self, "single_driver") debug.info(2, "Create single_driver") self.width = single_driver.width self.height = single_driver.height self.pin_map = single_driver.pin_map
class sense_amp(design.design): """ This module implements the single sense amp cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. Sense amplifier to amplify the voltage swing on a pair of bit-lines. """ pin_names = ["bl", "br", "dout", "dout_bar", "en", "vdd", "gnd"] (width,height) = utils.get_libcell_size("sense_amp", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "sense_amp", GDS["unit"]) def __init__(self): design.design.__init__(self, "sense_amp") debug.info(2, "Create sense_amp") self.width = sense_amp.width self.height = sense_amp.height self.pin_map = sense_amp.pin_map
class write_complete(design.design): """ This module implements the single write complete cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. """ pin_names = ["bl", "br", "en", "write_complete", "vdd", "gnd"] (width, height) = utils.get_libcell_size("write_complete", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "write_complete", GDS["unit"]) def __init__(self): design.design.__init__(self, "write_complete") debug.info(2, "Create write_complete") self.width = write_complete.width self.height = write_complete.height self.pin_map = write_complete.pin_map
class ms_flop(design.design): """ Memory address flip-flop """ pin_names = ["din", "dout", "dout_bar", "clk", "vdd", "gnd"] (width,height) = utils.get_libcell_size("ms_flop", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "ms_flop", GDS["unit"], layer["boundary"]) def __init__(self, name="ms_flop"): design.design.__init__(self, name) self.width = ms_flop.width self.height = ms_flop.height self.pin_map = ms_flop.pin_map def analytical_delay(self, slew, load = 0.0): # dont know how to calculate this now, use constant in tech file from tech import spice result = self.return_delay(spice["msflop_delay"], spice["msflop_slew"]) return result def analytical_power(self, proc, vdd, temp, load): """Returns dynamic and leakage power. Results in nW""" from tech import spice c_eff = self.calculate_effective_capacitance(load) f = spice["default_event_rate"] power_dyn = c_eff*vdd*vdd*f power_leak = spice["msflop_leakage"] total_power = self.return_power(power_dyn, power_leak) return total_power def calculate_effective_capacitance(self, load): """Computes effective capacitance. Results in fF""" from tech import spice, parameter c_load = load c_para = spice["flop_para_cap"]#ff transistion_prob = spice["flop_transisition_prob"] return transistion_prob*(c_load + c_para)
def __init__(self, version, name=""): # Ignore the name argument if version == "opt1": self.name = "s8sram_cell_opt1" elif version == "opt1a": self.name = "s8sram_cell_opt1a" bitcell_base.bitcell_base.__init__(self, self.name) debug.info(2, "Create bitcell") self.pin_map = utils.get_libcell_pins(self.pin_names, self.name, GDS["unit"]) self.add_pin_types(self.type_list) self.nets_match = self.do_nets_exist(self.storage_nets) (self.width, self.height) = utils.get_libcell_size(self.name, GDS["unit"], layer["mem"])
class merge(design.design): """ This module implements the single merge cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. merge for output data signals and some control signals when num of banks is greater than one """ pin_names = ["D", "Q", "en1_M", "en2_M", "reset", "M", "vdd", "gnd"] (width, height) = utils.get_libcell_size("merge", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "merge", GDS["unit"]) def __init__(self): design.design.__init__(self, "merge") debug.info(2, "Create merge") self.width = merge.width self.height = merge.height self.pin_map = merge.pin_map
class write_driver(design.design): """ Tristate write driver to be active during write operations only. This module implements the write driver cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. write driver drives input data to complementry bitlines. """ pin_names = ["din", "bl", "br", "en", "gnd", "vdd"] (width,height) = utils.get_libcell_size("write_driver", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "write_driver", GDS["unit"]) def __init__(self): design.design.__init__(self, "write_driver") debug.info(2, "Create write_driver") self.width = write_driver.width self.height = write_driver.height self.pin_map = write_driver.pin_map
class replica_bitcell(design.design): """ A single replica bit 6T cell. This module implements the single replica memory cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. A replica memory cell is a hard-wired memory cell that always stores "0" """ pin_names = ["bl", "br", "wl", "vdd", "gnd"] (width,height) = utils.get_libcell_size("replica_cell_6t", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "replica_cell_6t", GDS["unit"]) def __init__(self): design.design.__init__(self, "replica_cell_6t") debug.info(2, "Create replica bitcell object") self.width = replica_bitcell.width self.height = replica_bitcell.height self.pin_map = replica_bitcell.pin_map
class split(design.design): """ This module implements the single split cell used in the design. It is a hand-made cell, so the layout and netlist should be available in the technology library. split for input address, input data, and some control signals when num of banks is greater than one """ pin_names = ["D", "Q", "en1_S", "en2_S", "reset", "S", "vdd", "gnd"] (width, height) = utils.get_libcell_size("split", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "split", GDS["unit"]) def __init__(self): design.design.__init__(self, "split") debug.info(2, "Create split") self.width = split.width self.height = split.height self.pin_map = split.pin_map
class ms_flop(design.design): """ Memory address flip-flop """ pin_names = ["din", "dout", "dout_bar", "clk", "vdd", "gnd"] (width,height) = utils.get_libcell_size("ms_flop", GDS["unit"], layer["boundary"]) pin_map = utils.get_libcell_pins(pin_names, "ms_flop", GDS["unit"], layer["boundary"]) def __init__(self, name="ms_flop"): design.design.__init__(self, name) self.width = ms_flop.width self.height = ms_flop.height self.pin_map = ms_flop.pin_map def analytical_delay(self, slew, load = 0.0): # dont know how to calculate this now, use constant in tech file from tech import spice result = self.return_delay(spice["msflop_delay"], spice["msflop_slew"]) return result
def __init__(self, version, name=""): super().__init__(name) pin_names = ["wl", "vpwr"] type_list = ["OUTPUT", "POWER"] if version == "rowend": self.name = "s8sram16x16_rowend" elif version == "rowenda": self.name = "s8sram16x16_rowenda" else: debug.error("Invalid type for row_end", -1) design.design.__init__(self, name=self.name) (self.width, self.height) = utils.get_libcell_size(self.name, GDS["unit"], layer["mem"], "s8sram16x16_rowend_ce\x00") self.pin_map = utils.get_libcell_pins(pin_names, self.name, GDS["unit"]) self.add_pin("wl", "OUTPUT") self.add_pin("vpwr", "POWER")