fix merge conflicts

This commit is contained in:
Joey Kunzler 2020-04-23 11:51:46 -07:00
commit 0bae652be9
41 changed files with 1017 additions and 714 deletions

2
.gitignore vendored
View File

@ -8,3 +8,5 @@
*.toc *.toc
*.synctex.gz *.synctex.gz
**/model_data **/model_data
outputs
technology/freepdk45/ncsu_basekit

View File

@ -296,11 +296,11 @@ class path(geometry):
def __str__(self): def __str__(self):
""" override print function output """ """ override print function output """
return "path: layer=" + self.layerNumber + " w=" + self.width return "path: layer=" + self.layerNumber + " purpose=" + str(self.layerPurpose) + " w=" + self.width
def __repr__(self): def __repr__(self):
""" override print function output """ """ override print function output """
return "( path: layer=" + self.layerNumber + " w=" + self.width + " coords=" + str(self.coordinates) + " )" return "( path: layer=" + self.layerNumber + " purpose=" + str(self.layerPurpose) + " w=" + self.width + " coords=" + str(self.coordinates) + " )"
class label(geometry): class label(geometry):
@ -340,11 +340,11 @@ class label(geometry):
def __str__(self): def __str__(self):
""" override print function output """ """ override print function output """
return "label: " + self.text + " layer=" + str(self.layerNumber) return "label: " + self.text + " layer=" + str(self.layerNumber) + " purpose=" + str(self.layerPurpose)
def __repr__(self): def __repr__(self):
""" override print function output """ """ override print function output """
return "( label: " + self.text + " @" + str(self.offset) + " layer=" + str(self.layerNumber) + " )" return "( label: " + self.text + " @" + str(self.offset) + " layer=" + str(self.layerNumber) + " purpose=" + str(self.layerPurpose) + " )"
class rectangle(geometry): class rectangle(geometry):
@ -391,4 +391,4 @@ class rectangle(geometry):
def __repr__(self): def __repr__(self):
""" override print function output """ """ override print function output """
return "( rect: @" + str(self.offset) + " WxH=" + str(self.width) + "x" + str(self.height) + " layer=" + str(self.layerNumber) + " )" return "( rect: @" + str(self.offset) + " WxH=" + str(self.width) + "x" + str(self.height) + " layer=" + str(self.layerNumber) + " purpose=" + str(self.layerPurpose) + " )"

View File

@ -975,6 +975,7 @@ class layout():
def create_channel_route(self, netlist, def create_channel_route(self, netlist,
offset, offset,
layer_stack, layer_stack,
layer_dirs=None,
vertical=False): vertical=False):
""" """
The net list is a list of the nets. Each net is a list of pins The net list is a list of the nets. Each net is a list of pins
@ -1013,25 +1014,38 @@ class layout():
def vcg_pin_overlap(pin1, pin2, vertical, pitch): def vcg_pin_overlap(pin1, pin2, vertical, pitch):
""" Check for vertical or horizontal overlap of the two pins """ """ Check for vertical or horizontal overlap of the two pins """
# FIXME: If the pins are not in a row, this may break. # FIXME: If the pins are not in a row, this may break.
# However, a top pin shouldn't overlap another top pin, # However, a top pin shouldn't overlap another top pin,
# for example, so the # for example, so the
# extra comparison *shouldn't* matter. # extra comparison *shouldn't* matter.
# Pin 1 must be in the "BOTTOM" set # Pin 1 must be in the "BOTTOM" set
x_overlap = pin1.by() < pin2.by() and abs(pin1.center().x-pin2.center().x)<pitch x_overlap = pin1.by() < pin2.by() and abs(pin1.center().x - pin2.center().x) < pitch
# Pin 1 must be in the "LEFT" set # Pin 1 must be in the "LEFT" set
y_overlap = pin1.lx() < pin2.lx() and abs(pin1.center().y-pin2.center().y)<pitch y_overlap = pin1.lx() < pin2.lx() and abs(pin1.center().y - pin2.center().y) < pitch
overlaps = (not vertical and x_overlap) or (vertical and y_overlap) overlaps = (not vertical and x_overlap) or (vertical and y_overlap)
return overlaps return overlaps
if self.get_preferred_direction(layer_stack[0]) == "V": if not layer_dirs:
self.vertical_layer = layer_stack[0] # Use the preferred layer directions
self.horizontal_layer = layer_stack[2] if self.get_preferred_direction(layer_stack[0]) == "V":
self.vertical_layer = layer_stack[0]
self.horizontal_layer = layer_stack[2]
else:
self.vertical_layer = layer_stack[2]
self.horizontal_layer = layer_stack[0]
else: else:
self.vertical_layer = layer_stack[2] # Use the layer directions specified to the router rather than
self.horizontal_layer = layer_stack[0] # the preferred directions
debug.check(layer_dirs[0] != layer_dirs[1], "Must have unique layer directions.")
if layer_dirs[0] == "V":
self.vertical_layer = layer_stack[0]
self.horizontal_layer = layer_stack[2]
else:
self.horizontal_layer = layer_stack[0]
self.vertical_layer = layer_stack[2]
layer_stuff = self.get_layer_pitch(self.vertical_layer) layer_stuff = self.get_layer_pitch(self.vertical_layer)
(self.vertical_pitch, self.vertical_width, self.vertical_space) = layer_stuff (self.vertical_pitch, self.vertical_width, self.vertical_space) = layer_stuff
@ -1114,17 +1128,17 @@ class layout():
self.horizontal_pitch) self.horizontal_pitch)
offset += vector(0, self.horizontal_pitch) offset += vector(0, self.horizontal_pitch)
def create_vertical_channel_route(self, netlist, offset, layer_stack): def create_vertical_channel_route(self, netlist, offset, layer_stack, layer_dirs=None):
""" """
Wrapper to create a vertical channel route Wrapper to create a vertical channel route
""" """
self.create_channel_route(netlist, offset, layer_stack, vertical=True) self.create_channel_route(netlist, offset, layer_stack, layer_dirs, vertical=True)
def create_horizontal_channel_route(self, netlist, offset, layer_stack): def create_horizontal_channel_route(self, netlist, offset, layer_stack, layer_dirs=None):
""" """
Wrapper to create a horizontal channel route Wrapper to create a horizontal channel route
""" """
self.create_channel_route(netlist, offset, layer_stack, vertical=False) self.create_channel_route(netlist, offset, layer_stack, layer_dirs, vertical=False)
def add_boundary(self, ll=vector(0, 0), ur=None): def add_boundary(self, ll=vector(0, 0), ur=None):
""" Add boundary for debugging dimensions """ """ Add boundary for debugging dimensions """

View File

@ -59,7 +59,8 @@ class delay(simulation):
""" Create measurement names. The names themselves currently define the type of measurement """ """ Create measurement names. The names themselves currently define the type of measurement """
self.delay_meas_names = ["delay_lh", "delay_hl", "slew_lh", "slew_hl"] self.delay_meas_names = ["delay_lh", "delay_hl", "slew_lh", "slew_hl"]
self.power_meas_names = ["read0_power", "read1_power", "write0_power", "write1_power"] self.power_meas_names = ["read0_power", "read1_power", "write0_power", "write1_power",
"disabled_read0_power", "disabled_read1_power", "disabled_write0_power", "disabled_write1_power"]
# self.voltage_when_names = ["volt_bl", "volt_br"] # self.voltage_when_names = ["volt_bl", "volt_br"]
# self.bitline_delay_names = ["delay_bl", "delay_br"] # self.bitline_delay_names = ["delay_bl", "delay_br"]
@ -108,6 +109,11 @@ class delay(simulation):
self.read_lib_meas.append(power_measure("read0_power", "FALL", measure_scale=1e3)) self.read_lib_meas.append(power_measure("read0_power", "FALL", measure_scale=1e3))
self.read_lib_meas[-1].meta_str = sram_op.READ_ZERO self.read_lib_meas[-1].meta_str = sram_op.READ_ZERO
self.read_lib_meas.append(power_measure("disabled_read1_power", "RISE", measure_scale=1e3))
self.read_lib_meas[-1].meta_str = "disabled_read1"
self.read_lib_meas.append(power_measure("disabled_read0_power", "FALL", measure_scale=1e3))
self.read_lib_meas[-1].meta_str = "disabled_read0"
# This will later add a half-period to the spice time delay. Only for reading 0. # This will later add a half-period to the spice time delay. Only for reading 0.
for obj in self.read_lib_meas: for obj in self.read_lib_meas:
if obj.meta_str is sram_op.READ_ZERO: if obj.meta_str is sram_op.READ_ZERO:
@ -156,6 +162,11 @@ class delay(simulation):
self.write_lib_meas.append(power_measure("write0_power", "FALL", measure_scale=1e3)) self.write_lib_meas.append(power_measure("write0_power", "FALL", measure_scale=1e3))
self.write_lib_meas[-1].meta_str = sram_op.WRITE_ZERO self.write_lib_meas[-1].meta_str = sram_op.WRITE_ZERO
self.write_lib_meas.append(power_measure("disabled_write1_power", "RISE", measure_scale=1e3))
self.write_lib_meas[-1].meta_str = "disabled_write1"
self.write_lib_meas.append(power_measure("disabled_write0_power", "FALL", measure_scale=1e3))
self.write_lib_meas[-1].meta_str = "disabled_write0"
write_measures = [] write_measures = []
write_measures.append(self.write_lib_meas) write_measures.append(self.write_lib_meas)
write_measures.append(self.create_write_bit_measures()) write_measures.append(self.create_write_bit_measures())
@ -665,7 +676,7 @@ class delay(simulation):
if not success: if not success:
feasible_period = 2 * feasible_period feasible_period = 2 * feasible_period
continue continue
# Positions of measurements currently hardcoded. First 2 are delays, next 2 are slews # Positions of measurements currently hardcoded. First 2 are delays, next 2 are slews
feasible_delays = [results[port][mname] for mname in self.delay_meas_names if "delay" in mname] feasible_delays = [results[port][mname] for mname in self.delay_meas_names if "delay" in mname]
feasible_slews = [results[port][mname] for mname in self.delay_meas_names if "slew" in mname] feasible_slews = [results[port][mname] for mname in self.delay_meas_names if "slew" in mname]
@ -1198,6 +1209,9 @@ class delay(simulation):
write_port) write_port)
self.measure_cycles[write_port][sram_op.WRITE_ZERO] = len(self.cycle_times)-1 self.measure_cycles[write_port][sram_op.WRITE_ZERO] = len(self.cycle_times)-1
self.add_noop_clock_one_port(write_port)
self.measure_cycles[write_port]["disabled_write0"] = len(self.cycle_times)-1
# This also ensures we will have a H->L transition on the next read # This also ensures we will have a H->L transition on the next read
self.add_read("R data 1 address {} to set dout caps".format(inverse_address), self.add_read("R data 1 address {} to set dout caps".format(inverse_address),
inverse_address, inverse_address,
@ -1208,6 +1222,10 @@ class delay(simulation):
read_port) read_port)
self.measure_cycles[read_port][sram_op.READ_ZERO] = len(self.cycle_times)-1 self.measure_cycles[read_port][sram_op.READ_ZERO] = len(self.cycle_times)-1
self.add_noop_clock_one_port(read_port)
self.measure_cycles[read_port]["disabled_read0"] = len(self.cycle_times) - 1
self.add_noop_all_ports("Idle cycle (if read takes >1 cycle)") self.add_noop_all_ports("Idle cycle (if read takes >1 cycle)")
self.add_write("W data 1 address {} to write value".format(self.probe_address), self.add_write("W data 1 address {} to write value".format(self.probe_address),
@ -1217,12 +1235,19 @@ class delay(simulation):
write_port) write_port)
self.measure_cycles[write_port][sram_op.WRITE_ONE] = len(self.cycle_times)-1 self.measure_cycles[write_port][sram_op.WRITE_ONE] = len(self.cycle_times)-1
self.add_noop_clock_one_port(write_port)
self.measure_cycles[write_port]["disabled_write1"] = len(self.cycle_times)-1
self.add_write("W data 0 address {} to clear din caps".format(inverse_address), self.add_write("W data 0 address {} to clear din caps".format(inverse_address),
inverse_address, inverse_address,
data_zeros, data_zeros,
wmask_ones, wmask_ones,
write_port) write_port)
self.add_noop_clock_one_port(read_port)
self.measure_cycles[read_port]["disabled_read1"] = len(self.cycle_times) - 1
# This also ensures we will have a L->H transition on the next read # This also ensures we will have a L->H transition on the next read
self.add_read("R data 0 address {} to clear dout caps".format(inverse_address), self.add_read("R data 0 address {} to clear dout caps".format(inverse_address),
inverse_address, inverse_address,

View File

@ -181,17 +181,20 @@ class lib:
self.lib.write(" dont_touch : true;\n") self.lib.write(" dont_touch : true;\n")
self.lib.write(" area : {};\n\n".format(self.sram.width * self.sram.height)) self.lib.write(" area : {};\n\n".format(self.sram.width * self.sram.height))
#Build string of all control signals. self.write_pg_pin()
#Build string of all control signals.
control_str = 'csb0' #assume at least 1 port control_str = 'csb0' #assume at least 1 port
for i in range(1, self.total_port_num): for i in range(1, self.total_port_num):
control_str += ' & csb{0}'.format(i) control_str += ' & csb{0}'.format(i)
# Leakage is included in dynamic when macro is enabled # Leakage is included in dynamic when macro is enabled
self.lib.write(" leakage_power () {\n") self.lib.write(" leakage_power () {\n")
self.lib.write(" when : \"{0}\";\n".format(control_str)) # 'when' condition unnecessary when cs pin does not turn power to devices
# self.lib.write(" when : \"{0}\";\n".format(control_str))
self.lib.write(" value : {};\n".format(self.char_sram_results["leakage_power"])) self.lib.write(" value : {};\n".format(self.char_sram_results["leakage_power"]))
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" cell_leakage_power : {};\n".format(0)) self.lib.write(" cell_leakage_power : {};\n".format(self.char_sram_results["leakage_power"]))
def write_units(self): def write_units(self):
@ -240,6 +243,9 @@ class lib:
self.lib.write(" default_max_fanout : 4.0 ;\n") self.lib.write(" default_max_fanout : 4.0 ;\n")
self.lib.write(" default_connection_class : universal ;\n\n") self.lib.write(" default_connection_class : universal ;\n\n")
self.lib.write(" voltage_map ( VDD, {} );\n".format(tech.spice["nom_supply_voltage"]))
self.lib.write(" voltage_map ( GND, 0 );\n\n")
def create_list(self,values): def create_list(self,values):
""" Helper function to create quoted, line wrapped list """ """ Helper function to create quoted, line wrapped list """
list_values = ", ".join(str(v) for v in values) list_values = ", ".join(str(v) for v in values)
@ -516,42 +522,69 @@ class lib:
if port in self.write_ports: if port in self.write_ports:
if port in self.read_ports: if port in self.read_ports:
web_name = " & !web{0}".format(port) web_name = " & !web{0}".format(port)
avg_write_power = np.mean(self.char_port_results[port]["write1_power"] + self.char_port_results[port]["write0_power"]) write1_power = np.mean(self.char_port_results[port]["write1_power"])
write0_power = np.mean(self.char_port_results[port]["write0_power"])
self.lib.write(" internal_power(){\n") self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!csb{0} & clk{0}{1}\"; \n".format(port, web_name)) self.lib.write(" when : \"!csb{0}{1}\"; \n".format(port, web_name))
self.lib.write(" rise_power(scalar){\n") self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0)) self.lib.write(" values(\"{0:.6e}\");\n".format(write1_power))
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n") self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_write_power/2.0)) self.lib.write(" values(\"{0:.6e}\");\n".format(write0_power))
self.lib.write(" }\n")
self.lib.write(" }\n")
# Disabled power.
disabled_write1_power = np.mean(self.char_port_results[port]["disabled_write1_power"])
disabled_write0_power = np.mean(self.char_port_results[port]["disabled_write0_power"])
self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"csb{0}{1}\"; \n".format(port, web_name))
self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0:.6e}\");\n".format(disabled_write1_power))
self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0:.6e}\");\n".format(disabled_write0_power))
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" }\n") self.lib.write(" }\n")
if port in self.read_ports: if port in self.read_ports:
if port in self.write_ports: if port in self.write_ports:
web_name = " & web{0}".format(port) web_name = " & web{0}".format(port)
avg_read_power = np.mean(self.char_port_results[port]["read1_power"] + self.char_port_results[port]["read0_power"]) read1_power = np.mean(self.char_port_results[port]["read1_power"])
read0_power = np.mean(self.char_port_results[port]["read0_power"])
self.lib.write(" internal_power(){\n") self.lib.write(" internal_power(){\n")
self.lib.write(" when : \"!csb{0} & !clk{0}{1}\"; \n".format(port, web_name)) self.lib.write(" when : \"!csb{0}{1}\"; \n".format(port, web_name))
self.lib.write(" rise_power(scalar){\n") self.lib.write(" rise_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0)) self.lib.write(" values(\"{0:.6e}\");\n".format(read1_power))
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" fall_power(scalar){\n") self.lib.write(" fall_power(scalar){\n")
self.lib.write(" values(\"{0}\");\n".format(avg_read_power/2.0)) self.lib.write(" values(\"{0:.6e}\");\n".format(read0_power))
self.lib.write(" }\n") self.lib.write(" }\n")
self.lib.write(" }\n") self.lib.write(" }\n")
# Have 0 internal power when disabled, this will be represented as leakage power. # Disabled power.
self.lib.write(" internal_power(){\n") disabled_read1_power = np.mean(self.char_port_results[port]["disabled_read1_power"])
self.lib.write(" when : \"csb{0}\"; \n".format(port)) disabled_read0_power = np.mean(self.char_port_results[port]["disabled_read0_power"])
self.lib.write(" rise_power(scalar){\n") self.lib.write(" internal_power(){\n")
self.lib.write(" values(\"0\");\n") self.lib.write(" when : \"csb{0}{1}\"; \n".format(port, web_name))
self.lib.write(" }\n") self.lib.write(" rise_power(scalar){\n")
self.lib.write(" fall_power(scalar){\n") self.lib.write(" values(\"{0:.6e}\");\n".format(disabled_read1_power))
self.lib.write(" values(\"0\");\n") self.lib.write(" }\n")
self.lib.write(" }\n") self.lib.write(" fall_power(scalar){\n")
self.lib.write(" }\n") self.lib.write(" values(\"{0:.6e}\");\n".format(disabled_read0_power))
self.lib.write(" }\n")
self.lib.write(" }\n")
def write_pg_pin(self):
self.lib.write(" pg_pin(vdd) {\n")
self.lib.write(" voltage_name : VDD;\n")
self.lib.write(" pg_type : primary_power;\n")
self.lib.write(" }\n\n")
self.lib.write(" pg_pin(gnd) {\n")
self.lib.write(" voltage_name : GND;\n")
self.lib.write(" pg_type : primary_ground;\n")
self.lib.write(" }\n\n")
def compute_delay(self): def compute_delay(self):
"""Compute SRAM delays for current corner""" """Compute SRAM delays for current corner"""
self.d = delay(self.sram, self.sp_file, self.corner) self.d = delay(self.sram, self.sp_file, self.corner)

View File

@ -279,6 +279,23 @@ class simulation():
except: except:
self.add_wmask("0"*self.num_wmasks, port) self.add_wmask("0"*self.num_wmasks, port)
def add_noop_clock_one_port(self, port):
""" Add the control values for a noop to a single port. Increments the period. """
debug.info(2, 'Clock only on port {}'.format(port))
self.fn_cycle_comments.append('Clock only on port {}'.format(port))
self.append_cycle_comment(port, 'Clock only on port {}'.format(port))
self.cycle_times.append(self.t_current)
self.t_current += self.period
self.add_noop_one_port(port)
#Add noops to all other ports.
for unselected_port in self.all_ports:
if unselected_port != port:
self.add_noop_one_port(unselected_port)
def append_cycle_comment(self, port, comment): def append_cycle_comment(self, port, comment):
"""Add comment to list to be printed in stimulus file""" """Add comment to list to be printed in stimulus file"""
#Clean up time before appending. Make spacing dynamic as well. #Clean up time before appending. Make spacing dynamic as well.

View File

@ -19,7 +19,7 @@ import re
import copy import copy
import importlib import importlib
VERSION = "1.1.4" VERSION = "1.1.5"
NAME = "OpenRAM v{}".format(VERSION) NAME = "OpenRAM v{}".format(VERSION)
USAGE = "openram.py [options] <config file>\nUse -h for help.\n" USAGE = "openram.py [options] <config file>\nUse -h for help.\n"

View File

@ -28,7 +28,6 @@ class bitcell_array(bitcell_base_array):
# the replica bitcell in the control logic # the replica bitcell in the control logic
# self.offset_all_coordinates() # self.offset_all_coordinates()
def create_netlist(self): def create_netlist(self):
""" Create and connect the netlist """ """ Create and connect the netlist """
self.add_modules() self.add_modules()
@ -56,22 +55,21 @@ class bitcell_array(bitcell_base_array):
for col in range(self.column_size): for col in range(self.column_size):
for row in range(self.row_size): for row in range(self.row_size):
name = "bit_r{0}_c{1}".format(row, col) name = "bit_r{0}_c{1}".format(row, col)
self.cell_inst[row,col]=self.add_inst(name=name, self.cell_inst[row, col]=self.add_inst(name=name,
mod=self.cell) mod=self.cell)
self.connect_inst(self.get_bitcell_pins(col, row)) self.connect_inst(self.get_bitcell_pins(col, row))
def analytical_power(self, corner, load): def analytical_power(self, corner, load):
"""Power of Bitcell array and bitline in nW.""" """Power of Bitcell array and bitline in nW."""
from tech import drc, parameter
# Dynamic Power from Bitline # Dynamic Power from Bitline
bl_wire = self.gen_bl_wire() bl_wire = self.gen_bl_wire()
cell_load = 2 * bl_wire.return_input_cap() cell_load = 2 * bl_wire.return_input_cap()
bl_swing = OPTS.rbl_delay_percentage bl_swing = OPTS.rbl_delay_percentage
freq = spice["default_event_frequency"] freq = spice["default_event_frequency"]
bitline_dynamic = self.calc_dynamic_power(corner, cell_load, freq, swing=bl_swing) bitline_dynamic = self.calc_dynamic_power(corner, cell_load, freq, swing=bl_swing)
# Calculate the bitcell power which currently only includes leakage # Calculate the bitcell power which currently only includes leakage
cell_power = self.cell.analytical_power(corner, load) cell_power = self.cell.analytical_power(corner, load)
# Leakage power grows with entire array and bitlines. # Leakage power grows with entire array and bitlines.
@ -85,7 +83,7 @@ class bitcell_array(bitcell_base_array):
else: else:
width = self.width width = self.width
wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_m1")) wl_wire = self.generate_rc_net(int(self.column_size), width, drc("minwidth_m1"))
wl_wire.wire_c = 2*spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell wl_wire.wire_c = 2 * spice["min_tx_gate_c"] + wl_wire.wire_c # 2 access tx gate per cell
return wl_wire return wl_wire
def gen_bl_wire(self): def gen_bl_wire(self):
@ -94,26 +92,26 @@ class bitcell_array(bitcell_base_array):
else: else:
height = self.height height = self.height
bl_pos = 0 bl_pos = 0
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), height, drc("minwidth_m1")) bl_wire = self.generate_rc_net(int(self.row_size - bl_pos), height, drc("minwidth_m1"))
bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell bl_wire.wire_c =spice["min_tx_drain_c"] + bl_wire.wire_c # 1 access tx d/s per cell
return bl_wire return bl_wire
def get_wordline_cin(self): def get_wordline_cin(self):
"""Get the relative input capacitance from the wordline connections in all the bitcell""" """Get the relative input capacitance from the wordline connections in all the bitcell"""
#A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns # A single wordline is connected to all the bitcells in a single row meaning the capacitance depends on the # of columns
bitcell_wl_cin = self.cell.get_wl_cin() bitcell_wl_cin = self.cell.get_wl_cin()
total_cin = bitcell_wl_cin * self.column_size total_cin = bitcell_wl_cin * self.column_size
return total_cin return total_cin
def graph_exclude_bits(self, targ_row, targ_col): def graph_exclude_bits(self, targ_row, targ_col):
"""Excludes bits in column from being added to graph except target""" """Excludes bits in column from being added to graph except target"""
#Function is not robust with column mux configurations # Function is not robust with column mux configurations
for row in range(self.row_size): for row in range(self.row_size):
for col in range(self.column_size): for col in range(self.column_size):
if row == targ_row and col == targ_col: if row == targ_row and col == targ_col:
continue continue
self.graph_inst_exclude.add(self.cell_inst[row,col]) self.graph_inst_exclude.add(self.cell_inst[row, col])
def get_cell_name(self, inst_name, row, col): def get_cell_name(self, inst_name, row, col):
"""Gets the spice name of the target bitcell.""" """Gets the spice name of the target bitcell."""
return inst_name+'.x'+self.cell_inst[row,col].name, self.cell_inst[row,col] return inst_name + '.x' + self.cell_inst[row, col].name, self.cell_inst[row, col]

View File

@ -90,7 +90,7 @@ class control_logic(design.design):
self.add_mod(self.ctrl_dff_array) self.add_mod(self.ctrl_dff_array)
self.and2 = factory.create(module_type="pand2", self.and2 = factory.create(module_type="pand2",
size=4, size=12,
height=dff_height) height=dff_height)
self.add_mod(self.and2) self.add_mod(self.and2)

View File

@ -7,12 +7,11 @@
# #
import debug import debug
import design import design
from tech import drc
from contact import contact
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
class delay_chain(design.design): class delay_chain(design.design):
""" """
Generate a delay chain with the given number of stages and fanout. Generate a delay chain with the given number of stages and fanout.
@ -28,7 +27,7 @@ class delay_chain(design.design):
# Two fanouts are needed so that we can route the vdd/gnd connections # Two fanouts are needed so that we can route the vdd/gnd connections
for f in fanout_list: for f in fanout_list:
debug.check(f>=2,"Must have >=2 fanouts for each stage.") debug.check(f>=2, "Must have >=2 fanouts for each stage.")
# number of inverters including any fanout loads. # number of inverters including any fanout loads.
self.fanout_list = fanout_list self.fanout_list = fanout_list
@ -36,7 +35,6 @@ class delay_chain(design.design):
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
self.create_layout() self.create_layout()
def create_netlist(self): def create_netlist(self):
self.add_modules() self.add_modules()
@ -45,12 +43,13 @@ class delay_chain(design.design):
def create_layout(self): def create_layout(self):
# Each stage is a a row # Each stage is a a row
self.height = len(self.fanout_list)*self.inv.height self.height = len(self.fanout_list) * self.inv.height
# The width is determined by the largest fanout plus the driver # The width is determined by the largest fanout plus the driver
self.width = (max(self.fanout_list)+1) * self.inv.width self.width = (max(self.fanout_list) + 1) * self.inv.width
self.place_inverters() self.place_inverters()
self.route_inverters() self.route_inverters()
self.route_supplies()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary() self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
@ -69,9 +68,8 @@ class delay_chain(design.design):
def create_inverters(self): def create_inverters(self):
""" Create the inverters and connect them based on the stage list """ """ Create the inverters and connect them based on the stage list """
self.driver_inst_list = [] self.driver_inst_list = []
self.rightest_load_inst = {}
self.load_inst_map = {} self.load_inst_map = {}
for stage_num,fanout_size in zip(range(len(self.fanout_list)),self.fanout_list): for stage_num, fanout_size in zip(range(len(self.fanout_list)), self.fanout_list):
# Add the inverter # Add the inverter
cur_driver=self.add_inst(name="dinv{}".format(stage_num), cur_driver=self.add_inst(name="dinv{}".format(stage_num),
mod=self.inv) mod=self.inv)
@ -79,40 +77,37 @@ class delay_chain(design.design):
self.driver_inst_list.append(cur_driver) self.driver_inst_list.append(cur_driver)
# Hook up the driver # Hook up the driver
if stage_num+1==len(self.fanout_list): if stage_num + 1 == len(self.fanout_list):
stageout_name = "out" stageout_name = "out"
else: else:
stageout_name = "dout_{}".format(stage_num+1) stageout_name = "dout_{}".format(stage_num + 1)
if stage_num == 0: if stage_num == 0:
stagein_name = "in" stagein_name = "in"
else: else:
stagein_name = "dout_{}".format(stage_num) stagein_name = "dout_{}".format(stage_num)
self.connect_inst([stagein_name, stageout_name, "vdd", "gnd"]) self.connect_inst([stagein_name, stageout_name, "vdd", "gnd"])
# Now add the dummy loads to the right # Now add the dummy loads to the right
self.load_inst_map[cur_driver]=[] self.load_inst_map[cur_driver]=[]
for i in range(fanout_size): for i in range(fanout_size):
cur_load=self.add_inst(name="dload_{0}_{1}".format(stage_num,i), cur_load=self.add_inst(name="dload_{0}_{1}".format(stage_num, i),
mod=self.inv) mod=self.inv)
# Fanout stage is always driven by driver and output is disconnected # Fanout stage is always driven by driver and output is disconnected
disconnect_name = "n_{0}_{1}".format(stage_num,i) disconnect_name = "n_{0}_{1}".format(stage_num, i)
self.connect_inst([stageout_name, disconnect_name, "vdd", "gnd"]) self.connect_inst([stageout_name, disconnect_name, "vdd", "gnd"])
# Keep track of all the loads to connect their inputs as a load # Keep track of all the loads to connect their inputs as a load
self.load_inst_map[cur_driver].append(cur_load) self.load_inst_map[cur_driver].append(cur_load)
else:
# Keep track of the last one so we can add the the wire later
self.rightest_load_inst[cur_driver]=cur_load
def place_inverters(self): def place_inverters(self):
""" Place the inverters and connect them based on the stage list """ """ Place the inverters and connect them based on the stage list """
for stage_num,fanout_size in zip(range(len(self.fanout_list)),self.fanout_list): for stage_num, fanout_size in zip(range(len(self.fanout_list)), self.fanout_list):
if stage_num % 2: if stage_num % 2:
inv_mirror = "MX" inv_mirror = "MX"
inv_offset = vector(0, (stage_num+1)* self.inv.height) inv_offset = vector(0, (stage_num + 1) * self.inv.height)
else: else:
inv_mirror = "R0" inv_mirror = "R0"
inv_offset = vector(0, stage_num * self.inv.height) inv_offset = vector(0, stage_num * self.inv.height)
# Add the inverter # Add the inverter
cur_driver=self.driver_inst_list[stage_num] cur_driver=self.driver_inst_list[stage_num]
@ -122,10 +117,9 @@ class delay_chain(design.design):
# Now add the dummy loads to the right # Now add the dummy loads to the right
load_list = self.load_inst_map[cur_driver] load_list = self.load_inst_map[cur_driver]
for i in range(fanout_size): for i in range(fanout_size):
inv_offset += vector(self.inv.width,0) inv_offset += vector(self.inv.width, 0)
load_list[i].place(offset=inv_offset, load_list[i].place(offset=inv_offset,
mirror=inv_mirror) mirror=inv_mirror)
def add_route(self, pin1, pin2): def add_route(self, pin1, pin2):
""" This guarantees that we route from the top to bottom row correctly. """ """ This guarantees that we route from the top to bottom row correctly. """
@ -134,9 +128,9 @@ class delay_chain(design.design):
if pin1_pos.y == pin2_pos.y: if pin1_pos.y == pin2_pos.y:
self.add_path("m2", [pin1_pos, pin2_pos]) self.add_path("m2", [pin1_pos, pin2_pos])
else: else:
mid_point = vector(pin2_pos.x, 0.5*(pin1_pos.y+pin2_pos.y)) mid_point = vector(pin2_pos.x, 0.5 * (pin1_pos.y + pin2_pos.y))
# Written this way to guarantee it goes right first if we are switching rows # Written this way to guarantee it goes right first if we are switching rows
self.add_path("m2", [pin1_pos, vector(pin1_pos.x,mid_point.y), mid_point, vector(mid_point.x,pin2_pos.y), pin2_pos]) self.add_path("m2", [pin1_pos, vector(pin1_pos.x, mid_point.y), mid_point, vector(mid_point.x, pin2_pos.y), pin2_pos])
def route_inverters(self): def route_inverters(self):
""" Add metal routing for each of the fanout stages """ """ Add metal routing for each of the fanout stages """
@ -145,7 +139,7 @@ class delay_chain(design.design):
inv = self.driver_inst_list[i] inv = self.driver_inst_list[i]
for load in self.load_inst_map[inv]: for load in self.load_inst_map[inv]:
# Drop a via on each A pin # Drop a via on each A pin
a_pin = load.get_pin("A") a_pin = load.get_pin("A")
self.add_via_center(layers=self.m1_stack, self.add_via_center(layers=self.m1_stack,
offset=a_pin.center()) offset=a_pin.center())
self.add_via_center(layers=self.m2_stack, self.add_via_center(layers=self.m2_stack,
@ -154,54 +148,42 @@ class delay_chain(design.design):
# Route an M3 horizontal wire to the furthest # Route an M3 horizontal wire to the furthest
z_pin = inv.get_pin("Z") z_pin = inv.get_pin("Z")
a_pin = inv.get_pin("A") a_pin = inv.get_pin("A")
a_max = self.rightest_load_inst[inv].get_pin("A") a_max = self.load_inst_map[inv][-1].get_pin("A")
self.add_via_center(layers=self.m1_stack, self.add_via_center(layers=self.m1_stack,
offset=a_pin.center()) offset=a_pin.center())
self.add_via_center(layers=self.m1_stack, self.add_via_center(layers=self.m1_stack,
offset=z_pin.center()) offset=z_pin.center())
self.add_via_center(layers=self.m2_stack, self.add_via_center(layers=self.m2_stack,
offset=z_pin.center()) offset=z_pin.center())
self.add_path("m3",[z_pin.center(), a_max.center()]) self.add_path("m3", [z_pin.center(), a_max.center()])
# Route Z to the A of the next stage # Route Z to the A of the next stage
if i+1 < len(self.driver_inst_list): if i + 1 < len(self.driver_inst_list):
z_pin = inv.get_pin("Z") z_pin = inv.get_pin("Z")
next_inv = self.driver_inst_list[i+1] next_inv = self.driver_inst_list[i + 1]
next_a_pin = next_inv.get_pin("A") next_a_pin = next_inv.get_pin("A")
y_mid = (z_pin.cy() + next_a_pin.cy())/2 y_mid = (z_pin.cy() + next_a_pin.cy()) / 2
mid1_point = vector(z_pin.cx(), y_mid) mid1_point = vector(z_pin.cx(), y_mid)
mid2_point = vector(next_a_pin.cx(), y_mid) mid2_point = vector(next_a_pin.cx(), y_mid)
self.add_path("m2",[z_pin.center(), mid1_point, mid2_point, next_a_pin.center()]) self.add_path("m2", [z_pin.center(), mid1_point, mid2_point, next_a_pin.center()])
def add_layout_pins(self):
""" Add vdd and gnd rails and the input/output. Connect the gnd rails internally on
the top end with no input/output to obstruct. """
def route_supplies(self):
# Add power and ground to all the cells except: # Add power and ground to all the cells except:
# the fanout driver, the right-most load # the fanout driver, the right-most load
# The routing to connect the loads is over the first and last cells # The routing to connect the loads is over the first and last cells
# We have an even number of drivers and must only do every other # We have an even number of drivers and must only do every other
# supply rail # supply rail
for i in range(0,len(self.driver_inst_list),2):
inv = self.driver_inst_list[i]
for load in self.load_inst_map[inv]:
if load==self.rightest_load_inst[inv]:
continue
for pin_name in ["vdd", "gnd"]:
pin = load.get_pin(pin_name)
self.add_power_pin(pin_name, pin.rc())
else:
# We have an even number of rows, so need to get the last gnd rail
inv = self.driver_inst_list[-1]
for load in self.load_inst_map[inv]:
if load==self.rightest_load_inst[inv]:
continue
pin_name = "gnd"
pin = load.get_pin(pin_name)
self.add_power_pin(pin_name, pin.rc())
for inst in self.driver_inst_list:
load_list = self.load_inst_map[inst]
for pin_name in ["vdd", "gnd"]:
pin = load_list[0].get_pin(pin_name)
self.add_power_pin(pin_name, pin.rc() - vector(self.m1_pitch, 0))
pin = load_list[-1].get_pin(pin_name)
self.add_power_pin(pin_name, pin.rc() - vector(0.5 * self.m1_pitch, 0))
def add_layout_pins(self):
# input is A pin of first inverter # input is A pin of first inverter
a_pin = self.driver_inst_list[0].get_pin("A") a_pin = self.driver_inst_list[0].get_pin("A")
@ -209,36 +191,36 @@ class delay_chain(design.design):
offset=a_pin.center()) offset=a_pin.center())
self.add_layout_pin(text="in", self.add_layout_pin(text="in",
layer="m2", layer="m2",
offset=a_pin.ll().scale(1,0), offset=a_pin.ll().scale(1, 0),
height=a_pin.cy()) height=a_pin.cy())
# output is A pin of last load inverter # output is A pin of last load inverter
last_driver_inst = self.driver_inst_list[-1] last_driver_inst = self.driver_inst_list[-1]
a_pin = self.rightest_load_inst[last_driver_inst].get_pin("A") a_pin = self.load_inst_map[last_driver_inst][-1].get_pin("A")
self.add_via_center(layers=self.m1_stack, self.add_via_center(layers=self.m1_stack,
offset=a_pin.center()) offset=a_pin.center())
mid_point = vector(a_pin.cx()+3*self.m2_width,a_pin.cy()) mid_point = vector(a_pin.cx() + 3 * self.m2_width, a_pin.cy())
self.add_path("m2",[a_pin.center(), mid_point, mid_point.scale(1,0)]) self.add_path("m2", [a_pin.center(), mid_point, mid_point.scale(1, 0)])
self.add_layout_pin_segment_center(text="out", self.add_layout_pin_segment_center(text="out",
layer="m2", layer="m2",
start=mid_point, start=mid_point,
end=mid_point.scale(1,0)) end=mid_point.scale(1, 0))
def get_cin(self): def get_cin(self):
"""Get the enable input ralative capacitance""" """Get the enable input ralative capacitance"""
#Only 1 input to the delay chain which is connected to an inverter. # Only 1 input to the delay chain which is connected to an inverter.
dc_cin = self.inv.get_cin() dc_cin = self.inv.get_cin()
return dc_cin return dc_cin
def determine_delayed_en_stage_efforts(self, ext_delayed_en_cout, inp_is_rise=True): def determine_delayed_en_stage_efforts(self, ext_delayed_en_cout, inp_is_rise=True):
"""Get the stage efforts from the en to s_en. Does not compute the delay for the bitline load.""" """Get the stage efforts from the en to s_en. Does not compute the delay for the bitline load."""
stage_effort_list = [] stage_effort_list = []
#Add a stage to the list for every stage in delay chain. Stages only differ in fanout except the last which has an external cout. # Add a stage to the list for every stage in delay chain.
# Stages only differ in fanout except the last which has an external cout.
last_stage_is_rise = inp_is_rise last_stage_is_rise = inp_is_rise
for stage_fanout in self.fanout_list: for stage_fanout in self.fanout_list:
stage_cout = self.inv.get_cin()*(stage_fanout+1) stage_cout = self.inv.get_cin() * (stage_fanout + 1)
if len(stage_effort_list) == len(self.fanout_list)-1: #last stage if len(stage_effort_list) == len(self.fanout_list) - 1:
stage_cout+=ext_delayed_en_cout stage_cout+=ext_delayed_en_cout
stage = self.inv.get_stage_effort(stage_cout, last_stage_is_rise) stage = self.inv.get_stage_effort(stage_cout, last_stage_is_rise)
stage_effort_list.append(stage) stage_effort_list.append(stage)

View File

@ -35,7 +35,7 @@ class dff_buf(design.design):
# This causes a DRC in the pinv which assumes min width rails. This ensures the output # This causes a DRC in the pinv which assumes min width rails. This ensures the output
# contact does not violate spacing to the rail in the NMOS. # contact does not violate spacing to the rail in the NMOS.
debug.check(inv1_size>=2, "Inverter must be greater than two for rail spacing DRC rules.") debug.check(inv1_size>=2, "Inverter must be greater than two for rail spacing DRC rules.")
debug.check(inv2_size>=2, "Inverter must be greater than two for rail spacing DRC rules.") debug.check(inv2_size>=2, "Inverter must be greater than two for rail spacing DRC rules.")
self.inv1_size=inv1_size self.inv1_size=inv1_size
self.inv2_size=inv2_size self.inv2_size=inv2_size
@ -52,14 +52,13 @@ class dff_buf(design.design):
def create_layout(self): def create_layout(self):
self.place_instances() self.place_instances()
self.width = self.inv2_inst.rx() self.width = self.inv2_inst.rx()
self.height = self.dff.height self.height = self.dff.height
self.route_wires() self.route_wires()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary() self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_modules(self): def add_modules(self):
self.dff = factory.create(module_type="dff") self.dff = factory.create(module_type="dff")
self.add_mod(self.dff) self.add_mod(self.dff)
@ -73,8 +72,6 @@ class dff_buf(design.design):
size=self.inv2_size, size=self.inv2_size,
height=self.dff.height) height=self.dff.height)
self.add_mod(self.inv2) self.add_mod(self.inv2)
def add_pins(self): def add_pins(self):
self.add_pin("D", "INPUT") self.add_pin("D", "INPUT")
@ -96,17 +93,19 @@ class dff_buf(design.design):
self.inv1_inst=self.add_inst(name="dff_buf_inv1", self.inv1_inst=self.add_inst(name="dff_buf_inv1",
mod=self.inv1) mod=self.inv1)
self.connect_inst(["qint", "Qb", "vdd", "gnd"]) self.connect_inst(["qint", "Qb", "vdd", "gnd"])
self.inv2_inst=self.add_inst(name="dff_buf_inv2", self.inv2_inst=self.add_inst(name="dff_buf_inv2",
mod=self.inv2) mod=self.inv2)
self.connect_inst(["Qb", "Q", "vdd", "gnd"]) self.connect_inst(["Qb", "Q", "vdd", "gnd"])
def place_instances(self): def place_instances(self):
# Add the DFF # Add the DFF
self.dff_inst.place(vector(0,0)) self.dff_inst.place(vector(0, 0))
# Add INV1 to the right # Add INV1 to the right
# The INV needs well spacing because the DFF is likely from a library
# with different well construction rules
well_spacing = 0 well_spacing = 0
try: try:
well_spacing = max(well_spacing, self.nwell_space) well_spacing = max(well_spacing, self.nwell_space)
@ -129,7 +128,7 @@ class dff_buf(design.design):
# Route dff q to inv1 a # Route dff q to inv1 a
q_pin = self.dff_inst.get_pin("Q") q_pin = self.dff_inst.get_pin("Q")
a1_pin = self.inv1_inst.get_pin("A") a1_pin = self.inv1_inst.get_pin("A")
mid_x_offset = 0.5*(a1_pin.cx() + q_pin.cx()) mid_x_offset = 0.5 * (a1_pin.cx() + q_pin.cx())
mid1 = vector(mid_x_offset, q_pin.cy()) mid1 = vector(mid_x_offset, q_pin.cy())
mid2 = vector(mid_x_offset, a1_pin.cy()) mid2 = vector(mid_x_offset, a1_pin.cy())
self.add_path("m3", [q_pin.center(), mid1, mid2, a1_pin.center()]) self.add_path("m3", [q_pin.center(), mid1, mid2, a1_pin.center()])
@ -143,7 +142,7 @@ class dff_buf(design.design):
# Route inv1 z to inv2 a # Route inv1 z to inv2 a
z1_pin = self.inv1_inst.get_pin("Z") z1_pin = self.inv1_inst.get_pin("Z")
a2_pin = self.inv2_inst.get_pin("A") a2_pin = self.inv2_inst.get_pin("A")
mid_x_offset = 0.5*(z1_pin.cx() + a2_pin.cx()) mid_x_offset = 0.5 * (z1_pin.cx() + a2_pin.cx())
self.mid_qb_pos = vector(mid_x_offset, z1_pin.cy()) self.mid_qb_pos = vector(mid_x_offset, z1_pin.cy())
mid2 = vector(mid_x_offset, a2_pin.cy()) mid2 = vector(mid_x_offset, a2_pin.cy())
self.add_path("m1", [z1_pin.center(), self.mid_qb_pos, mid2, a2_pin.center()]) self.add_path("m1", [z1_pin.center(), self.mid_qb_pos, mid2, a2_pin.center()])
@ -181,8 +180,8 @@ class dff_buf(design.design):
height=din_pin.height()) height=din_pin.height())
dout_pin = self.inv2_inst.get_pin("Z") dout_pin = self.inv2_inst.get_pin("Z")
mid_pos = dout_pin.center() + vector(self.m1_pitch,0) mid_pos = dout_pin.center() + vector(self.m1_pitch, 0)
q_pos = mid_pos - vector(0,self.m2_pitch) q_pos = mid_pos - vector(0, self.m2_pitch)
self.add_layout_pin_rect_center(text="Q", self.add_layout_pin_rect_center(text="Q",
layer="m2", layer="m2",
offset=q_pos) offset=q_pos)
@ -190,7 +189,7 @@ class dff_buf(design.design):
self.add_via_center(layers=self.m1_stack, self.add_via_center(layers=self.m1_stack,
offset=q_pos) offset=q_pos)
qb_pos = self.mid_qb_pos + vector(0,self.m2_pitch) qb_pos = self.mid_qb_pos + vector(0, self.m2_pitch)
self.add_layout_pin_rect_center(text="Qb", self.add_layout_pin_rect_center(text="Qb",
layer="m2", layer="m2",
offset=qb_pos) offset=qb_pos)
@ -200,7 +199,7 @@ class dff_buf(design.design):
def get_clk_cin(self): def get_clk_cin(self):
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff""" """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. # 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. # Calculated in the tech file by summing the widths of all the gates and dividing by the minimum width.
#FIXME: Dff changed in a past commit. The parameter need to be updated. # FIXME: Dff changed in a past commit. The parameter need to be updated.
return parameter["dff_clk_cin"] return parameter["dff_clk_cin"]

View File

@ -7,13 +7,12 @@
# #
import debug import debug
import design import design
from tech import drc
from tech import cell_properties as props from tech import cell_properties as props
from math import log
from vector import vector from vector import vector
from globals import OPTS from globals import OPTS
from sram_factory import factory from sram_factory import factory
class dff_buf_array(design.design): class dff_buf_array(design.design):
""" """
This is a simple row (or multiple rows) of flops. This is a simple row (or multiple rows) of flops.
@ -49,18 +48,19 @@ class dff_buf_array(design.design):
self.width = self.columns * self.dff.width self.width = self.columns * self.dff.width
self.height = self.rows * self.dff.height self.height = self.rows * self.dff.height
self.place_dff_array() self.place_dff_array()
self.route_supplies()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary() self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):
for row in range(self.rows): for row in range(self.rows):
for col in range(self.columns): for col in range(self.columns):
self.add_pin(self.get_din_name(row,col), "INPUT") self.add_pin(self.get_din_name(row, col), "INPUT")
for row in range(self.rows): for row in range(self.rows):
for col in range(self.columns): for col in range(self.columns):
self.add_pin(self.get_dout_name(row,col), "OUTPUT") self.add_pin(self.get_dout_name(row, col), "OUTPUT")
self.add_pin(self.get_dout_bar_name(row,col), "OUTPUT") self.add_pin(self.get_dout_bar_name(row, col), "OUTPUT")
self.add_pin("clk", "INPUT") self.add_pin("clk", "INPUT")
self.add_pin("vdd", "POWER") self.add_pin("vdd", "POWER")
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
@ -75,17 +75,16 @@ class dff_buf_array(design.design):
inv2_size=self.inv2_size) inv2_size=self.inv2_size)
self.add_mod(self.dff) self.add_mod(self.dff)
def create_dff_array(self): def create_dff_array(self):
self.dff_insts={} self.dff_insts={}
for row in range(self.rows): for row in range(self.rows):
for col in range(self.columns): for col in range(self.columns):
name = "dff_r{0}_c{1}".format(row,col) name = "dff_r{0}_c{1}".format(row, col)
self.dff_insts[row,col]=self.add_inst(name=name, self.dff_insts[row, col]=self.add_inst(name=name,
mod=self.dff) mod=self.dff)
inst_ports = [self.get_din_name(row,col), inst_ports = [self.get_din_name(row, col),
self.get_dout_name(row,col), self.get_dout_name(row, col),
self.get_dout_bar_name(row,col), self.get_dout_bar_name(row, col),
"clk", "clk",
"vdd", "vdd",
"gnd"] "gnd"]
@ -96,23 +95,33 @@ class dff_buf_array(design.design):
def place_dff_array(self): def place_dff_array(self):
well_spacing = max(self.nwell_space, well_spacing = 0
self.pwell_space, try:
self.pwell_to_nwell) well_spacing = max(self.nwell_space, well_spacing)
except AttributeError:
pass
try:
well_spacing = max(self.pwell_space, well_spacing)
except AttributeError:
pass
try:
well_spacing = max(self.pwell_to_nwell, well_spacing)
except AttributeError:
pass
dff_pitch = self.dff.width + well_spacing + self.well_extend_active dff_pitch = self.dff.width + well_spacing + self.well_extend_active
for row in range(self.rows): for row in range(self.rows):
for col in range(self.columns): for col in range(self.columns):
name = "Xdff_r{0}_c{1}".format(row,col) # name = "Xdff_r{0}_c{1}".format(row, col)
if (row % 2 == 0): if (row % 2 == 0):
base = vector(col*dff_pitch,row*self.dff.height) base = vector(col * dff_pitch, row * self.dff.height)
mirror = "R0" mirror = "R0"
else: else:
base = vector(col*dff_pitch,(row+1)*self.dff.height) base = vector(col * dff_pitch, (row + 1) * self.dff.height)
mirror = "MX" mirror = "MX"
self.dff_insts[row,col].place(offset=base, self.dff_insts[row, col].place(offset=base,
mirror=mirror) mirror=mirror)
def get_din_name(self, row, col): def get_din_name(self, row, col):
if self.columns == 1: if self.columns == 1:
@ -120,7 +129,7 @@ class dff_buf_array(design.design):
elif self.rows == 1: elif self.rows == 1:
din_name = "din_{0}".format(col) din_name = "din_{0}".format(col)
else: else:
din_name = "din_{0}_{1}".format(row,col) din_name = "din_{0}_{1}".format(row, col)
return din_name return din_name
@ -130,7 +139,7 @@ class dff_buf_array(design.design):
elif self.rows == 1: elif self.rows == 1:
dout_name = "dout_{0}".format(col) dout_name = "dout_{0}".format(col)
else: else:
dout_name = "dout_{0}_{1}".format(row,col) dout_name = "dout_{0}_{1}".format(row, col)
return dout_name return dout_name
@ -140,75 +149,84 @@ class dff_buf_array(design.design):
elif self.rows == 1: elif self.rows == 1:
dout_bar_name = "dout_bar_{0}".format(col) dout_bar_name = "dout_bar_{0}".format(col)
else: else:
dout_bar_name = "dout_bar_{0}_{1}".format(row,col) dout_bar_name = "dout_bar_{0}_{1}".format(row, col)
return dout_bar_name return dout_bar_name
def add_layout_pins(self): def route_supplies(self):
for row in range(self.rows): for row in range(self.rows):
for col in range(self.columns): vdd0_pin=self.dff_insts[row, 0].get_pin("vdd")
vddn_pin=self.dff_insts[row, self.columns - 1].get_pin("vdd")
self.add_path(vdd0_pin.layer, [vdd0_pin.lc(), vddn_pin.rc()], width=vdd0_pin.height())
gnd0_pin=self.dff_insts[row, 0].get_pin("gnd")
gndn_pin=self.dff_insts[row, self.columns - 1].get_pin("gnd")
self.add_path(gnd0_pin.layer, [gnd0_pin.lc(), gndn_pin.rc()], width=gnd0_pin.height())
for row in range(self.rows):
for col in range(self.columns):
# Continous vdd rail along with label. # Continous vdd rail along with label.
vdd_pin=self.dff_insts[row,col].get_pin("vdd") vdd_pin=self.dff_insts[row, col].get_pin("vdd")
self.add_power_pin("vdd", vdd_pin.lc()) self.add_power_pin("vdd", vdd_pin.lc())
# Continous gnd rail along with label. # Continous gnd rail along with label.
gnd_pin=self.dff_insts[row,col].get_pin("gnd") gnd_pin=self.dff_insts[row, col].get_pin("gnd")
self.add_power_pin("gnd", gnd_pin.lc()) self.add_power_pin("gnd", gnd_pin.lc())
def add_layout_pins(self):
for row in range(self.rows):
for row in range(self.rows): for col in range(self.columns):
for col in range(self.columns): din_pin = self.dff_insts[row, col].get_pin("D")
din_pin = self.dff_insts[row,col].get_pin("D") debug.check(din_pin.layer=="m2", "DFF D pin not on metal2")
debug.check(din_pin.layer=="m2","DFF D pin not on metal2") self.add_layout_pin(text=self.get_din_name(row, col),
self.add_layout_pin(text=self.get_din_name(row,col),
layer=din_pin.layer, layer=din_pin.layer,
offset=din_pin.ll(), offset=din_pin.ll(),
width=din_pin.width(), width=din_pin.width(),
height=din_pin.height()) height=din_pin.height())
dout_pin = self.dff_insts[row,col].get_pin("Q") dout_pin = self.dff_insts[row, col].get_pin("Q")
debug.check(dout_pin.layer=="m2","DFF Q pin not on metal2") debug.check(dout_pin.layer=="m2", "DFF Q pin not on metal2")
self.add_layout_pin(text=self.get_dout_name(row,col), self.add_layout_pin(text=self.get_dout_name(row, col),
layer=dout_pin.layer, layer=dout_pin.layer,
offset=dout_pin.ll(), offset=dout_pin.ll(),
width=dout_pin.width(), width=dout_pin.width(),
height=dout_pin.height()) height=dout_pin.height())
dout_bar_pin = self.dff_insts[row,col].get_pin("Qb") dout_bar_pin = self.dff_insts[row, col].get_pin("Qb")
debug.check(dout_bar_pin.layer=="m2","DFF Qb pin not on metal2") debug.check(dout_bar_pin.layer=="m2", "DFF Qb pin not on metal2")
self.add_layout_pin(text=self.get_dout_bar_name(row,col), self.add_layout_pin(text=self.get_dout_bar_name(row, col),
layer=dout_bar_pin.layer, layer=dout_bar_pin.layer,
offset=dout_bar_pin.ll(), offset=dout_bar_pin.ll(),
width=dout_bar_pin.width(), width=dout_bar_pin.width(),
height=dout_bar_pin.height()) height=dout_bar_pin.height())
# Create vertical spines to a single horizontal rail # Create vertical spines to a single horizontal rail
clk_pin = self.dff_insts[0,0].get_pin("clk") clk_pin = self.dff_insts[0, 0].get_pin("clk")
clk_ypos = 2*self.m3_pitch+self.m3_width clk_ypos = 2 * self.m3_pitch + self.m3_width
debug.check(clk_pin.layer=="m2","DFF clk pin not on metal2") debug.check(clk_pin.layer=="m2", "DFF clk pin not on metal2")
if self.columns==1: if self.columns==1:
self.add_layout_pin(text="clk", self.add_layout_pin(text="clk",
layer="m2", layer="m2",
offset=clk_pin.ll().scale(1,0), offset=clk_pin.ll().scale(1, 0),
width=self.m2_width, width=self.m2_width,
height=self.height) height=self.height)
else: else:
self.add_layout_pin_segment_center(text="clk", self.add_layout_pin_segment_center(text="clk",
layer="m3", layer="m3",
start=vector(0,clk_ypos), start=vector(0, clk_ypos),
end=vector(self.width,clk_ypos)) end=vector(self.width, clk_ypos))
for col in range(self.columns): for col in range(self.columns):
clk_pin = self.dff_insts[0,col].get_pin("clk") clk_pin = self.dff_insts[0, col].get_pin("clk")
# Make a vertical strip for each column # Make a vertical strip for each column
self.add_rect(layer="m2", self.add_rect(layer="m2",
offset=clk_pin.ll().scale(1,0), offset=clk_pin.ll().scale(1, 0),
width=self.m2_width, width=self.m2_width,
height=self.height) height=self.height)
# Drop a via to the M3 pin # Drop a via to the M3 pin
self.add_via_center(layers=self.m2_stack, self.add_via_center(layers=self.m2_stack,
offset=vector(clk_pin.cx(),clk_ypos)) offset=vector(clk_pin.cx(), clk_ypos))
def get_clk_cin(self): def get_clk_cin(self):
"""Return the total capacitance (in relative units) that the clock is loaded by in the dff array""" """Return the total capacitance (in relative units) that the clock is loaded by in the dff array"""

View File

@ -32,7 +32,6 @@ class hierarchical_decoder(design.design):
self.cell_multiple = cell_properties.bitcell.decoder_bitcell_multiple self.cell_multiple = cell_properties.bitcell.decoder_bitcell_multiple
except AttributeError: except AttributeError:
self.cell_multiple = 1 self.cell_multiple = 1
# For debugging
self.cell_height = self.cell_multiple * b.height self.cell_height = self.cell_multiple * b.height
self.num_outputs = num_outputs self.num_outputs = num_outputs

View File

@ -699,8 +699,13 @@ class port_data(design.design):
bottom_names = self._get_bitline_pins(bot_inst_group, bit) bottom_names = self._get_bitline_pins(bot_inst_group, bit)
top_names = self._get_bitline_pins(top_inst_group, bit) top_names = self._get_bitline_pins(top_inst_group, bit)
if bottom_names[0].layer == "m2":
bitline_dirs = ("H", "V")
elif bottom_names[0].layer == "m1":
bitline_dirs = ("V", "H")
route_map = list(zip(bottom_names, top_names)) route_map = list(zip(bottom_names, top_names))
self.create_horizontal_channel_route(route_map, offset, self.m1_stack) self.create_horizontal_channel_route(route_map, offset, self.m1_stack, bitline_dirs)
def connect_bitlines(self, inst1, inst2, num_bits, def connect_bitlines(self, inst1, inst2, num_bits,
inst1_bls_template="{inst}_{bit}", inst1_bls_template="{inst}_{bit}",

View File

@ -151,7 +151,7 @@ class single_level_column_mux_array(design.design):
def add_horizontal_input_rail(self): def add_horizontal_input_rail(self):
""" Create address input rails on M1 below the mux transistors """ """ Create address input rails on M1 below the mux transistors """
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.col_mux_stack_pitch) #edit offset = vector(0, self.route_height + (j - self.words_per_row) * self.col_mux_stack_pitch)
self.add_layout_pin(text="sel_{}".format(j), self.add_layout_pin(text="sel_{}".format(j),
layer=self.col_mux_stack[0], layer=self.col_mux_stack[0],
offset=offset, offset=offset,

View File

@ -7,10 +7,12 @@
# #
import debug import debug
import design import design
import math
import contact import contact
from vector import vector from vector import vector
from sram_factory import factory from sram_factory import factory
from globals import OPTS from globals import OPTS
from tech import cell_properties
class wordline_driver(design.design): class wordline_driver(design.design):
@ -26,6 +28,13 @@ class wordline_driver(design.design):
self.rows = rows self.rows = rows
self.cols = cols self.cols = cols
b = factory.create(module_type="bitcell")
try:
self.cell_multiple = cell_properties.bitcell.decoder_bitcell_multiple
except AttributeError:
self.cell_multiple = 1
self.cell_height = self.cell_multiple * b.height
self.create_netlist() self.create_netlist()
if not OPTS.netlist_only: if not OPTS.netlist_only:
@ -37,6 +46,7 @@ class wordline_driver(design.design):
self.create_drivers() self.create_drivers()
def create_layout(self): def create_layout(self):
self.setup_layout_constants()
self.place_drivers() self.place_drivers()
self.route_layout() self.route_layout()
self.route_vdd_gnd() self.route_vdd_gnd()
@ -56,17 +66,10 @@ class wordline_driver(design.design):
self.add_pin("gnd", "GROUND") self.add_pin("gnd", "GROUND")
def add_modules(self): def add_modules(self):
b = factory.create(module_type="bitcell") self.and2 = factory.create(module_type="pand2",
height=self.cell_height,
self.inv = factory.create(module_type="pdriver", size=self.cols)
fanout=self.cols, self.add_mod(self.and2)
neg_polarity=True,
height=b.height)
self.add_mod(self.inv)
self.nand2 = factory.create(module_type="pnand2",
height=b.height)
self.add_mod(self.nand2)
def route_vdd_gnd(self): def route_vdd_gnd(self):
""" """
@ -75,68 +78,64 @@ class wordline_driver(design.design):
""" """
# Find the x offsets for where the vias/pins should be placed # Find the x offsets for where the vias/pins should be placed
a_xoffset = self.nand_inst[0].lx() xoffset_list = [self.and_inst[0].lx()]
for num in range(self.rows): for num in range(self.rows):
# this will result in duplicate polygons for rails, but who cares # this will result in duplicate polygons for rails, but who cares
# use the inverter offset even though it will be the nand's too # use the inverter offset even though it will be the and's too
(gate_offset, y_dir) = self.get_gate_offset(0, (gate_offset, y_dir) = self.get_gate_offset(0,
self.inv.height, self.and2.height,
num) num)
# Route both supplies # Route both supplies
for name in ["vdd", "gnd"]: for name in ["vdd", "gnd"]:
supply_pin = self.inv2_inst[num].get_pin(name) supply_pin = self.and_inst[num].get_pin(name)
# Add pins in two locations # Add pins in two locations
for xoffset in [a_xoffset]: for xoffset in xoffset_list:
pin_pos = vector(xoffset, supply_pin.cy()) pin_pos = vector(xoffset, supply_pin.cy())
self.add_power_pin(name, pin_pos) self.add_power_pin(name, pin_pos)
def create_drivers(self): def create_drivers(self):
self.nand_inst = [] self.and_inst = []
self.inv2_inst = []
for row in range(self.rows): for row in range(self.rows):
name_nand = "wl_driver_nand{}".format(row) name_and = "wl_driver_and{}".format(row)
name_inv2 = "wl_driver_inv{}".format(row)
# add nand 2 # add and2
self.nand_inst.append(self.add_inst(name=name_nand, self.and_inst.append(self.add_inst(name=name_and,
mod=self.nand2)) mod=self.and2))
self.connect_inst(["en", self.connect_inst(["en",
"in_{0}".format(row), "in_{0}".format(row),
"wl_bar_{0}".format(row),
"vdd", "gnd"])
# add inv2
self.inv2_inst.append(self.add_inst(name=name_inv2,
mod=self.inv))
self.connect_inst(["wl_bar_{0}".format(row),
"wl_{0}".format(row), "wl_{0}".format(row),
"vdd", "gnd"]) "vdd", "gnd"])
def setup_layout_constants(self):
# We may have more than one bitcell per decoder row
self.num_rows = math.ceil(self.rows / self.cell_multiple)
# We will place this many final decoders per row
self.decoders_per_row = math.ceil(self.rows / self.num_rows)
def place_drivers(self): def place_drivers(self):
nand2_xoffset = 2 * self.m1_width + 5 * self.m1_space and2_xoffset = 2 * self.m1_width + 5 * self.m1_space
inv2_xoffset = nand2_xoffset + self.nand2.width
self.width = inv2_xoffset + self.inv.width self.width = and2_xoffset + self.and2.width
self.height = self.inv.height * self.rows self.height = self.and2.height * self.num_rows
for row in range(self.rows): for row in range(self.rows):
#row = math.floor(inst_index / self.decoders_per_row)
#dec = inst_index % self.decoders_per_row
if (row % 2): if (row % 2):
y_offset = self.inv.height * (row + 1) y_offset = self.and2.height * (row + 1)
inst_mirror = "MX" inst_mirror = "MX"
else: else:
y_offset = self.inv.height * row y_offset = self.and2.height * row
inst_mirror = "R0" inst_mirror = "R0"
nand2_offset = [nand2_xoffset, y_offset] # x_off = self.internal_routing_width + dec * and_mod.width
inv2_offset = [inv2_xoffset, y_offset] and2_offset = [and2_xoffset, y_offset]
# add nand 2 # add and2
self.nand_inst[row].place(offset=nand2_offset, self.and_inst[row].place(offset=and2_offset,
mirror=inst_mirror)
# add inv2
self.inv2_inst[row].place(offset=inv2_offset,
mirror=inst_mirror) mirror=inst_mirror)
def route_layout(self): def route_layout(self):
@ -151,11 +150,10 @@ class wordline_driver(design.design):
height=self.height) height=self.height)
for row in range(self.rows): for row in range(self.rows):
nand_inst = self.nand_inst[row] and_inst = self.and_inst[row]
inv2_inst = self.inv2_inst[row]
# en connection # en connection
a_pin = nand_inst.get_pin("A") a_pin = and_inst.get_pin("A")
a_pos = a_pin.lc() a_pos = a_pin.lc()
clk_offset = vector(en_pin.bc().x, a_pos.y) clk_offset = vector(en_pin.bc().x, a_pos.y)
self.add_segment_center(layer="m1", self.add_segment_center(layer="m1",
@ -164,18 +162,10 @@ class wordline_driver(design.design):
self.add_via_center(layers=self.m1_stack, self.add_via_center(layers=self.m1_stack,
offset=clk_offset) offset=clk_offset)
# Nand2 out to 2nd inv # connect the decoder input pin to and2 B
zr_pos = nand_inst.get_pin("Z").rc() b_pin = and_inst.get_pin("B")
al_pos = inv2_inst.get_pin("A").lc()
# ensure the bend is in the middle
mid1_pos = vector(0.5 * (zr_pos.x + al_pos.x), zr_pos.y)
mid2_pos = vector(0.5 * (zr_pos.x + al_pos.x), al_pos.y)
self.add_path("m1", [zr_pos, mid1_pos, mid2_pos, al_pos])
# connect the decoder input pin to nand2 B
b_pin = nand_inst.get_pin("B")
b_pos = b_pin.lc() b_pos = b_pin.lc()
# needs to move down since B nand input is # needs to move down since B and input is
# nearly aligned with A inv input # nearly aligned with A inv input
up_or_down = self.m2_space if row % 2 else -self.m2_space up_or_down = self.m2_space if row % 2 else -self.m2_space
input_offset = vector(0, b_pos.y + up_or_down) input_offset = vector(0, b_pos.y + up_or_down)
@ -192,7 +182,7 @@ class wordline_driver(design.design):
offset=mid_via_offset, offset=mid_via_offset,
directions=("V", "V")) directions=("V", "V"))
# now connect to the nand2 B # now connect to the and2 B
self.add_path("m2", [mid_via_offset, b_pos]) self.add_path("m2", [mid_via_offset, b_pos])
contact_offset = b_pos - vector(0.5 * contact.m1_via.height, 0) contact_offset = b_pos - vector(0.5 * contact.m1_via.height, 0)
self.add_via_center(layers=self.m1_stack, self.add_via_center(layers=self.m1_stack,
@ -200,7 +190,7 @@ class wordline_driver(design.design):
directions=("H", "H")) directions=("H", "H"))
# output each WL on the right # output each WL on the right
wl_offset = inv2_inst.get_pin("Z").rc() wl_offset = and_inst.get_pin("Z").rc()
self.add_layout_pin_segment_center(text="wl_{0}".format(row), self.add_layout_pin_segment_center(text="wl_{0}".format(row),
layer="m1", layer="m1",
start=wl_offset, start=wl_offset,
@ -213,13 +203,8 @@ class wordline_driver(design.design):
""" """
stage_effort_list = [] stage_effort_list = []
stage1_cout = self.inv.get_cin() stage1 = self.and2.get_stage_effort(external_cout, inp_is_rise)
stage1 = self.nand2.get_stage_effort(stage1_cout, inp_is_rise)
stage_effort_list.append(stage1) stage_effort_list.append(stage1)
last_stage_is_rise = stage1.is_rise
stage2 = self.inv.get_stage_efforts(external_cout, last_stage_is_rise)
stage_effort_list.extend(stage2)
return stage_effort_list return stage_effort_list
@ -228,6 +213,6 @@ class wordline_driver(design.design):
Get the relative capacitance of all Get the relative capacitance of all
the enable connections in the bank the enable connections in the bank
""" """
# The enable is connected to a nand2 for every row. # The enable is connected to a and2 for every row.
total_cin = self.nand2.get_cin() * self.rows total_cin = self.and2.get_cin() * self.rows
return total_cin return total_cin

View File

@ -30,13 +30,12 @@ class pand2(pgate.pgate):
self.create_insts() self.create_insts()
def create_modules(self): def create_modules(self):
# Shield the cap, but have at least a stage effort of 4
self.nand = factory.create(module_type="pnand2", height=self.height) self.nand = factory.create(module_type="pnand2", height=self.height)
self.add_mod(self.nand) self.add_mod(self.nand)
self.inv = factory.create(module_type="pdriver", self.inv = factory.create(module_type="pdriver",
neg_polarity=True, neg_polarity=True,
fanout=3*self.size, fanout=self.size,
height=self.height) height=self.height)
self.add_mod(self.inv) self.add_mod(self.inv)
@ -45,6 +44,7 @@ class pand2(pgate.pgate):
self.place_insts() self.place_insts()
self.add_wires() self.add_wires()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -44,6 +44,7 @@ class pand3(pgate.pgate):
self.place_insts() self.place_insts()
self.add_wires() self.add_wires()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.DRC_LVS() self.DRC_LVS()
def add_pins(self): def add_pins(self):

View File

@ -37,6 +37,7 @@ class pbuf(pgate.pgate):
self.place_insts() self.place_insts()
self.add_wires() self.add_wires()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
def add_pins(self): def add_pins(self):
self.add_pin("A", "INPUT") self.add_pin("A", "INPUT")

View File

@ -76,6 +76,7 @@ class pdriver(pgate.pgate):
self.width = self.inv_inst_list[-1].rx() self.width = self.inv_inst_list[-1].rx()
self.height = self.inv_inst_list[0].height self.height = self.inv_inst_list[0].height
self.add_boundary()
def add_pins(self): def add_pins(self):
self.add_pin("A", "INPUT") self.add_pin("A", "INPUT")

View File

@ -68,6 +68,7 @@ class pinv(pgate.pgate):
"A", "A",
position="farleft") position="farleft")
self.route_outputs() self.route_outputs()
self.add_boundary()
def add_pins(self): def add_pins(self):
""" Adds pins for spice netlist """ """ Adds pins for spice netlist """

View File

@ -47,6 +47,7 @@ class pinvbuf(pgate.pgate):
self.place_modules() self.place_modules()
self.route_wires() self.route_wires()
self.add_layout_pins() self.add_layout_pins()
self.add_boundary()
self.offset_all_coordinates() self.offset_all_coordinates()

View File

@ -62,7 +62,8 @@ class pnand2(pgate.pgate):
self.extend_wells() self.extend_wells()
self.route_inputs() self.route_inputs()
self.route_output() self.route_output()
self.add_boundary()
def add_pins(self): def add_pins(self):
""" Adds pins for spice netlist """ """ Adds pins for spice netlist """
pin_list = ["A", "B", "Z", "vdd", "gnd"] pin_list = ["A", "B", "Z", "vdd", "gnd"]

View File

@ -70,6 +70,7 @@ class pnand3(pgate.pgate):
self.extend_wells() self.extend_wells()
self.route_inputs() self.route_inputs()
self.route_output() self.route_output()
self.add_boundary()
def add_ptx(self): def add_ptx(self):
""" Create the PMOS and NMOS transistors. """ """ Create the PMOS and NMOS transistors. """

View File

@ -61,6 +61,7 @@ class pnor2(pgate.pgate):
self.extend_wells() self.extend_wells()
self.route_inputs() self.route_inputs()
self.route_output() self.route_output()
self.add_boundary()
def add_pins(self): def add_pins(self):
""" Adds pins for spice netlist """ """ Adds pins for spice netlist """

View File

@ -70,7 +70,8 @@ class precharge(design.design):
self.route_vdd_rail() self.route_vdd_rail()
self.route_bitlines() self.route_bitlines()
self.connect_to_bitlines() self.connect_to_bitlines()
self.add_boundary()
def add_pins(self): def add_pins(self):
self.add_pin_list(["bl", "br", "en_bar", "vdd"], self.add_pin_list(["bl", "br", "en_bar", "vdd"],
["OUTPUT", "OUTPUT", "INPUT", "POWER"]) ["OUTPUT", "OUTPUT", "INPUT", "POWER"])

View File

@ -56,6 +56,7 @@ class ptristate_inv(pgate.pgate):
self.connect_rails() self.connect_rails()
self.route_inputs() self.route_inputs()
self.route_outputs() self.route_outputs()
self.add_boundary()
def add_pins(self): def add_pins(self):
""" Adds pins for spice netlist """ """ Adds pins for spice netlist """

View File

@ -52,6 +52,7 @@ class pwrite_driver(design.design):
self.place_modules() self.place_modules()
self.route_wires() self.route_wires()
self.route_supplies() self.route_supplies()
self.add_boundary()
def add_pins(self): def add_pins(self):
self.add_pin("din", "INPUT") self.add_pin("din", "INPUT")

View File

@ -0,0 +1,78 @@
#!/usr/bin/env python3
# See LICENSE for licensing information.
#
# Copyright (c) 2016-2019 Regents of the University of California
# All rights reserved.
#
import unittest
from testutils import *
import sys,os
sys.path.append(os.getenv("OPENRAM_HOME"))
import globals
from globals import OPTS
from sram_factory import factory
import debug
class port_data_1rw_1r_test(openram_test):
def runTest(self):
config_file = "{}/tests/configs/config".format(os.getenv("OPENRAM_HOME"))
globals.init_openram(config_file)
from sram_config import sram_config
OPTS.bitcell = "bitcell_1w_1r"
OPTS.num_rw_ports = 0
OPTS.num_r_ports = 1
OPTS.num_w_ports = 1
c = sram_config(word_size=4,
num_words=16)
c.words_per_row=1
factory.reset()
c.recompute_sizes()
debug.info(1, "No column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
c.num_words=32
c.words_per_row=2
factory.reset()
c.recompute_sizes()
debug.info(1, "Two way column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
c.num_words=64
c.words_per_row=4
factory.reset()
c.recompute_sizes()
debug.info(1, "Four way column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
c.word_size=2
c.num_words=128
c.words_per_row=8
factory.reset()
c.recompute_sizes()
debug.info(1, "Eight way column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
globals.end_openram()
# run the test from the command line
if __name__ == "__main__":
(OPTS, args) = globals.parse_args()
del sys.argv[1:]
header(__file__, OPTS.tech_name)
unittest.main(testRunner=debugTestRunner())

View File

@ -55,52 +55,6 @@ class port_data_test(openram_test):
a = factory.create("port_data", sram_config=c, port=0) a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a) self.local_check(a)
OPTS.bitcell = "bitcell_1w_1r"
OPTS.num_rw_ports = 0
OPTS.num_r_ports = 1
OPTS.num_w_ports = 1
c.num_words=16
c.words_per_row=1
factory.reset()
c.recompute_sizes()
debug.info(1, "No column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
c.num_words=32
c.words_per_row=2
factory.reset()
c.recompute_sizes()
debug.info(1, "Two way column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
c.num_words=64
c.words_per_row=4
factory.reset()
c.recompute_sizes()
debug.info(1, "Four way column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
c.word_size=2
c.num_words=128
c.words_per_row=8
factory.reset()
c.recompute_sizes()
debug.info(1, "Eight way column mux")
a = factory.create("port_data", sram_config=c, port=0)
self.local_check(a)
a = factory.create("port_data", sram_config=c, port=1)
self.local_check(a)
globals.end_openram() globals.end_openram()
# run the test from the command line # run the test from the command line

View File

@ -60,29 +60,36 @@ class timing_sram_test(openram_test):
data, port_data = d.analyze(probe_address, probe_data, slews, loads) data, port_data = d.analyze(probe_address, probe_data, slews, loads)
#Combine info about port into all data #Combine info about port into all data
data.update(port_data[0]) data.update(port_data[0])
if OPTS.tech_name == "freepdk45": if OPTS.tech_name == "freepdk45":
golden_data = {'delay_hl': [0.2383338], golden_data = {'min_period': 0.898,
'delay_lh': [0.2383338], 'write1_power': [0.2659137999999999],
'leakage_power': 0.0014532999999999998, 'disabled_write0_power': [0.1782495],
'min_period': 0.898, 'disabled_read0_power': [0.14490679999999997],
'read0_power': [0.30059800000000003], 'write0_power': [0.3330119],
'read1_power': [0.30061810000000005], 'disabled_write1_power': [0.1865223],
'slew_hl': [0.25358420000000004], 'leakage_power': 0.0014532,
'slew_lh': [0.25358420000000004], 'disabled_read1_power': [0.1627516],
'write0_power': [0.34616749999999996], 'slew_lh': [0.25367799999999996],
'write1_power': [0.2792924]} 'slew_hl': [0.25367799999999996],
'delay_lh': [0.23820930000000004],
'delay_hl': [0.23820930000000004],
'read1_power': [0.3005756],
'read0_power': [0.3005888]}
elif OPTS.tech_name == "scn4m_subm": elif OPTS.tech_name == "scn4m_subm":
golden_data = {'delay_hl': [1.7448], golden_data = {'leakage_power': 0.0006356576000000001,
'delay_lh': [1.7448], 'write1_power': [11.292700000000002],
'leakage_power': 0.0006356744000000001, 'read0_power': [12.98],
'disabled_write1_power': [8.3707],
'write0_power': [14.4447], 'delay_hl': [1.7445000000000002],
'disabled_read0_power': [6.4325],
'slew_hl': [1.7437],
'disabled_write0_power': [8.1307],
'slew_lh': [1.7437],
'read1_power': [12.9869],
'disabled_read1_power': [7.706],
'min_period': 6.25, 'min_period': 6.25,
'read0_power': [12.9846], 'delay_lh': [1.7445000000000002]}
'read1_power': [12.9722],
'slew_hl': [1.7433],
'slew_lh': [1.7433],
'write0_power': [14.8772],
'write1_power': [11.7217]}
else: else:
self.assertTrue(False) # other techs fail self.assertTrue(False) # other techs fail
# Check if no too many or too few results # Check if no too many or too few results

View File

@ -55,27 +55,35 @@ class timing_sram_test(openram_test):
data.update(port_data[0]) data.update(port_data[0])
if OPTS.tech_name == "freepdk45": if OPTS.tech_name == "freepdk45":
golden_data = {'delay_hl': [0.2264205], golden_data = {'slew_lh': [0.2592187],
'delay_lh': [0.2264205], 'slew_hl': [0.2592187],
'leakage_power': 0.0021017429999999997, 'delay_lh': [0.2465583],
'min_period': 0.859, 'disabled_write0_power': [0.1924678],
'read0_power': [0.3339161], 'disabled_read0_power': [0.152483],
'read1_power': [0.31329440000000003], 'write0_power': [0.3409064],
'slew_hl': [0.2590786], 'disabled_read1_power': [0.1737818],
'slew_lh': [0.2590786], 'read0_power': [0.3096708],
'write0_power': [0.36360849999999995], 'read1_power': [0.3107916],
'write1_power': [0.3486931]} 'delay_hl': [0.2465583],
'write1_power': [0.26915849999999997],
'leakage_power': 0.002044307,
'min_period': 0.898,
'disabled_write1_power': [0.201411]}
elif OPTS.tech_name == "scn4m_subm": elif OPTS.tech_name == "scn4m_subm":
golden_data = {'delay_hl': [1.85985], golden_data = {'read1_power': [12.11658],
'delay_lh': [1.85985], 'write1_power': [10.52653],
'read0_power': [11.956710000000001],
'disabled_write0_power': [7.673665],
'disabled_write1_power': [7.981922000000001],
'slew_lh': [1.868836],
'slew_hl': [1.868836],
'delay_hl': [1.8598510000000001],
'delay_lh': [1.8598510000000001],
'leakage_power': 0.008613619, 'leakage_power': 0.008613619,
'disabled_read0_power': [5.904712],
'min_period': 6.875, 'min_period': 6.875,
'read0_power': [12.656310000000001], 'disabled_read1_power': [7.132159],
'read1_power': [12.11682], 'write0_power': [13.406400000000001]}
'slew_hl': [1.868942],
'slew_lh': [1.868942],
'write0_power': [13.978110000000001],
'write1_power': [11.437930000000001]}
else: else:
self.assertTrue(False) # other techs fail self.assertTrue(False) # other techs fail

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_freepdk45_FF_1p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 1.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.00125, 0.005, 0.04"); index_1("0.00125, 0.005, 0.04");
index_2("0.052275, 0.2091, 1.6728"); index_2("5.2275e-05, 0.0002091, 0.0008364");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_freepdk45){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 1124.88; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.000198;
value : 0.000167;
} }
cell_leakage_power : 0; cell_leakage_power : 0.000198;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -127,8 +139,8 @@ cell (sram_2_16_1_freepdk45){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 1.6728; max_capacitance : 0.0008364000000000001;
min_capacitance : 0.052275; min_capacitance : 5.2275000000000003e-05;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,14 +150,14 @@ cell (sram_2_16_1_freepdk45){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.088, 0.088, 0.088",\ values("0.193, 0.193, 0.194",\
"0.088, 0.088, 0.088",\ "0.193, 0.193, 0.194",\
"0.088, 0.088, 0.088"); "0.193, 0.193, 0.194");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.088, 0.088, 0.088",\ values("0.193, 0.193, 0.194",\
"0.088, 0.088, 0.088",\ "0.193, 0.193, 0.194",\
"0.088, 0.088, 0.088"); "0.193, 0.193, 0.194");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.001, 0.001, 0.001",\ values("0.001, 0.001, 0.001",\
@ -164,7 +176,7 @@ cell (sram_2_16_1_freepdk45){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
max_transition : 0.04; max_transition : 0.04;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
@ -200,7 +212,7 @@ cell (sram_2_16_1_freepdk45){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -233,7 +245,7 @@ cell (sram_2_16_1_freepdk45){
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -267,52 +279,61 @@ cell (sram_2_16_1_freepdk45){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.033101244168888884"); values("9.240667e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0.033101244168888884"); values("9.240667e-02");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.033101244168888884"); values("9.240667e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0.033101244168888884"); values("9.240667e-02");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("9.240667e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("9.240667e-02");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("9.240667e-02");
}
fall_power(scalar){
values("9.240667e-02");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.009"); values("0.0195");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.009"); values("0.0195");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.018"); values("0.039");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.018"); values("0.039");
} }
} }
} }

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_freepdk45_SS_1p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 1.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.00125, 0.005, 0.04"); index_1("0.00125, 0.005, 0.04");
index_2("0.052275, 0.2091, 1.6728"); index_2("5.2275e-05, 0.0002091, 0.0008364");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_freepdk45){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 1124.88; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.000198;
value : 0.000167;
} }
cell_leakage_power : 0; cell_leakage_power : 0.000198;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -127,8 +139,8 @@ cell (sram_2_16_1_freepdk45){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 1.6728; max_capacitance : 0.0008364000000000001;
min_capacitance : 0.052275; min_capacitance : 5.2275000000000003e-05;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,14 +150,14 @@ cell (sram_2_16_1_freepdk45){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.107, 0.107, 0.107",\ values("0.236, 0.236, 0.237",\
"0.107, 0.107, 0.107",\ "0.236, 0.236, 0.237",\
"0.107, 0.107, 0.107"); "0.236, 0.236, 0.237");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.107, 0.107, 0.107",\ values("0.236, 0.236, 0.237",\
"0.107, 0.107, 0.107",\ "0.236, 0.236, 0.237",\
"0.107, 0.107, 0.107"); "0.236, 0.236, 0.237");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.001, 0.001, 0.001",\ values("0.001, 0.001, 0.001",\
@ -164,7 +176,7 @@ cell (sram_2_16_1_freepdk45){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
max_transition : 0.04; max_transition : 0.04;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
@ -200,7 +212,7 @@ cell (sram_2_16_1_freepdk45){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -233,7 +245,7 @@ cell (sram_2_16_1_freepdk45){
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -267,52 +279,61 @@ cell (sram_2_16_1_freepdk45){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.033101244168888884"); values("7.560546e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0.033101244168888884"); values("7.560546e-02");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.033101244168888884"); values("7.560546e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0.033101244168888884"); values("7.560546e-02");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("7.560546e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("7.560546e-02");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("7.560546e-02");
}
fall_power(scalar){
values("7.560546e-02");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.0105"); values("0.0235");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.0105"); values("0.0235");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.021"); values("0.047");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.021"); values("0.047");
} }
} }
} }

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 1.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.00125, 0.005, 0.04"); index_1("0.00125, 0.005, 0.04");
index_2("0.052275, 0.2091, 1.6728"); index_2("5.2275e-05, 0.0002091, 0.0008364");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_freepdk45){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 977.4951374999999; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.00163;
value : 0.0011164579999999999;
} }
cell_leakage_power : 0; cell_leakage_power : 0.00163;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -98,9 +110,9 @@ cell (sram_2_16_1_freepdk45){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.033, 0.039",\ values("0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039",\ "0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039"); "0.033, 0.033, 0.033");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.027, 0.027, 0.033",\ values("0.027, 0.027, 0.033",\
@ -112,14 +124,14 @@ cell (sram_2_16_1_freepdk45){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.01, -0.016, -0.022",\ values("-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022",\ "-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022"); "-0.01, -0.01, 0.021");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.016, -0.016, -0.016",\ values("-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016",\ "-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016"); "-0.016, -0.01, -0.016");
} }
} }
} }
@ -127,8 +139,8 @@ cell (sram_2_16_1_freepdk45){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 1.6728; max_capacitance : 0.0008364000000000001;
min_capacitance : 0.052275; min_capacitance : 5.2275000000000003e-05;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,24 +150,24 @@ cell (sram_2_16_1_freepdk45){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.235, 0.235, 0.239",\ values("0.226, 0.227, 0.232",\
"0.235, 0.236, 0.24",\ "0.227, 0.228, 0.233",\
"0.241, 0.242, 0.246"); "0.232, 0.234, 0.238");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("2.583, 2.585, 2.612",\ values("0.226, 0.227, 0.232",\
"2.584, 2.585, 2.613",\ "0.227, 0.228, 0.233",\
"2.59, 2.592, 2.62"); "0.232, 0.234, 0.238");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.022, 0.022, 0.03",\ values("0.256, 0.256, 0.257",\
"0.022, 0.023, 0.03",\ "0.256, 0.256, 0.257",\
"0.022, 0.022, 0.03"); "0.256, 0.256, 0.257");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.078, 0.079, 0.083",\ values("0.256, 0.256, 0.257",\
"0.078, 0.079, 0.083",\ "0.256, 0.256, 0.257",\
"0.079, 0.079, 0.083"); "0.256, 0.256, 0.257");
} }
} }
} }
@ -164,16 +176,16 @@ cell (sram_2_16_1_freepdk45){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
max_transition : 0.04; max_transition : 0.04;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.033, 0.039",\ values("0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039",\ "0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039"); "0.033, 0.033, 0.033");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.027, 0.027, 0.033",\ values("0.027, 0.027, 0.033",\
@ -185,14 +197,14 @@ cell (sram_2_16_1_freepdk45){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.01, -0.016, -0.022",\ values("-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022",\ "-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022"); "-0.01, -0.01, 0.021");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.016, -0.016, -0.016",\ values("-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016",\ "-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016"); "-0.016, -0.01, -0.016");
} }
} }
} }
@ -200,14 +212,14 @@ cell (sram_2_16_1_freepdk45){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.033, 0.039",\ values("0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039",\ "0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039"); "0.033, 0.033, 0.033");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.027, 0.027, 0.033",\ values("0.027, 0.027, 0.033",\
@ -219,28 +231,28 @@ cell (sram_2_16_1_freepdk45){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.01, -0.016, -0.022",\ values("-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022",\ "-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022"); "-0.01, -0.01, 0.021");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.016, -0.016, -0.016",\ values("-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016",\ "-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016"); "-0.016, -0.01, -0.016");
} }
} }
} }
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.033, 0.033, 0.039",\ values("0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039",\ "0.033, 0.033, 0.033",\
"0.033, 0.033, 0.039"); "0.033, 0.033, 0.033");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.027, 0.027, 0.033",\ values("0.027, 0.027, 0.033",\
@ -252,14 +264,14 @@ cell (sram_2_16_1_freepdk45){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.01, -0.016, -0.022",\ values("-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022",\ "-0.01, -0.01, 0.021",\
"-0.01, -0.016, -0.022"); "-0.01, -0.01, 0.021");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.016, -0.016, -0.016",\ values("-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016",\ "-0.016, -0.01, -0.016",\
"-0.016, -0.016, -0.016"); "-0.016, -0.01, -0.016");
} }
} }
} }
@ -267,52 +279,61 @@ cell (sram_2_16_1_freepdk45){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.03599689694444445"); values("3.069977e-01");
} }
fall_power(scalar){ fall_power(scalar){
values("0.03599689694444445"); values("3.686680e-01");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.029906643888888886"); values("2.055845e-01");
} }
fall_power(scalar){ fall_power(scalar){
values("0.029906643888888886"); values("1.933561e-01");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("3.315565e-01");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("3.314553e-01");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("1.777355e-01");
}
fall_power(scalar){
values("1.615044e-01");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("2.422"); values("0.449");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("2.422"); values("0.449");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("4.844"); values("0.898");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("4.844"); values("0.898");
} }
} }
} }

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_freepdk45_TT_1p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 1.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.00125, 0.005, 0.04"); index_1("0.00125, 0.005, 0.04");
index_2("0.052275, 0.2091, 1.6728"); index_2("5.2275e-05, 0.0002091, 0.0008364");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_freepdk45){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 977.4951374999999; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.000198;
value : 0.000179;
} }
cell_leakage_power : 0; cell_leakage_power : 0.000198;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -127,8 +139,8 @@ cell (sram_2_16_1_freepdk45){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 1.6728; max_capacitance : 0.0008364000000000001;
min_capacitance : 0.052275; min_capacitance : 5.2275000000000003e-05;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,14 +150,14 @@ cell (sram_2_16_1_freepdk45){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.098, 0.098, 0.098",\ values("0.215, 0.215, 0.216",\
"0.098, 0.098, 0.098",\ "0.215, 0.215, 0.216",\
"0.098, 0.098, 0.098"); "0.215, 0.215, 0.216");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.098, 0.098, 0.098",\ values("0.215, 0.215, 0.216",\
"0.098, 0.098, 0.098",\ "0.215, 0.215, 0.216",\
"0.098, 0.098, 0.098"); "0.215, 0.215, 0.216");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.001, 0.001, 0.001",\ values("0.001, 0.001, 0.001",\
@ -164,7 +176,7 @@ cell (sram_2_16_1_freepdk45){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
max_transition : 0.04; max_transition : 0.04;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
@ -200,7 +212,7 @@ cell (sram_2_16_1_freepdk45){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -233,7 +245,7 @@ cell (sram_2_16_1_freepdk45){
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -267,52 +279,61 @@ cell (sram_2_16_1_freepdk45){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 0.2091; capacitance : 0.00020910000000000001;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.0747594982142222"); values("8.316600e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0.0747594982142222"); values("8.316600e-02");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("0.0747594982142222"); values("8.316600e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0.0747594982142222"); values("8.316600e-02");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("8.316600e-02");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("8.316600e-02");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("8.316600e-02");
}
fall_power(scalar){
values("8.316600e-02");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.0"); values("0.0215");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.0"); values("0.0215");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0"); values("0.043");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0"); values("0.043");
} }
} }
} }

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_scn4m_subm_FF_5p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 5.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.0125, 0.05, 0.4"); index_1("0.0125, 0.05, 0.4");
index_2("2.45605, 9.8242, 78.5936"); index_2("0.00245605, 0.0098242, 0.0392968");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_scn4m_subm){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 73068.14000000001; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.000198;
value : 0.000167;
} }
cell_leakage_power : 0; cell_leakage_power : 0.000198;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -127,8 +139,8 @@ cell (sram_2_16_1_scn4m_subm){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 78.5936; max_capacitance : 0.0392968;
min_capacitance : 2.45605; min_capacitance : 0.00245605;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,24 +150,24 @@ cell (sram_2_16_1_scn4m_subm){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.241, 0.241, 0.241",\ values("1.183, 1.199, 1.264",\
"0.241, 0.241, 0.241",\ "1.183, 1.199, 1.264",\
"0.241, 0.241, 0.241"); "1.183, 1.199, 1.264");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.241, 0.241, 0.241",\ values("1.183, 1.199, 1.264",\
"0.241, 0.241, 0.241",\ "1.183, 1.199, 1.264",\
"0.241, 0.241, 0.241"); "1.183, 1.199, 1.264");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.004, 0.004, 0.004",\ values("0.006, 0.007, 0.014",\
"0.004, 0.004, 0.004",\ "0.006, 0.007, 0.014",\
"0.004, 0.004, 0.004"); "0.006, 0.007, 0.014");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.004, 0.004, 0.004",\ values("0.006, 0.007, 0.014",\
"0.004, 0.004, 0.004",\ "0.006, 0.007, 0.014",\
"0.004, 0.004, 0.004"); "0.006, 0.007, 0.014");
} }
} }
} }
@ -164,7 +176,7 @@ cell (sram_2_16_1_scn4m_subm){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
max_transition : 0.4; max_transition : 0.4;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
@ -200,7 +212,7 @@ cell (sram_2_16_1_scn4m_subm){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -233,7 +245,7 @@ cell (sram_2_16_1_scn4m_subm){
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -267,52 +279,61 @@ cell (sram_2_16_1_scn4m_subm){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("4.99880645"); values("7.797263e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("4.99880645"); values("7.797263e+00");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("4.99880645"); values("7.797263e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("4.99880645"); values("7.797263e+00");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("7.797263e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("7.797263e+00");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("7.797263e+00");
}
fall_power(scalar){
values("7.797263e+00");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.024"); values("0.1265");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.024"); values("0.1265");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.048"); values("0.253");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.048"); values("0.253");
} }
} }
} }

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_scn4m_subm_SS_5p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 5.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.0125, 0.05, 0.4"); index_1("0.0125, 0.05, 0.4");
index_2("2.45605, 9.8242, 78.5936"); index_2("0.00245605, 0.0098242, 0.0392968");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_scn4m_subm){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 73068.14000000001; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.000198;
value : 0.000167;
} }
cell_leakage_power : 0; cell_leakage_power : 0.000198;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -127,8 +139,8 @@ cell (sram_2_16_1_scn4m_subm){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 78.5936; max_capacitance : 0.0392968;
min_capacitance : 2.45605; min_capacitance : 0.00245605;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,24 +150,24 @@ cell (sram_2_16_1_scn4m_subm){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.294, 0.294, 0.294",\ values("1.446, 1.466, 1.545",\
"0.294, 0.294, 0.294",\ "1.446, 1.466, 1.545",\
"0.294, 0.294, 0.294"); "1.446, 1.466, 1.545");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.294, 0.294, 0.294",\ values("1.446, 1.466, 1.545",\
"0.294, 0.294, 0.294",\ "1.446, 1.466, 1.545",\
"0.294, 0.294, 0.294"); "1.446, 1.466, 1.545");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.004, 0.004, 0.004",\ values("0.007, 0.009, 0.017",\
"0.004, 0.004, 0.004",\ "0.007, 0.009, 0.017",\
"0.004, 0.004, 0.004"); "0.007, 0.009, 0.017");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.004, 0.004, 0.004",\ values("0.007, 0.009, 0.017",\
"0.004, 0.004, 0.004",\ "0.007, 0.009, 0.017",\
"0.004, 0.004, 0.004"); "0.007, 0.009, 0.017");
} }
} }
} }
@ -164,7 +176,7 @@ cell (sram_2_16_1_scn4m_subm){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
max_transition : 0.4; max_transition : 0.4;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
@ -200,7 +212,7 @@ cell (sram_2_16_1_scn4m_subm){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -233,7 +245,7 @@ cell (sram_2_16_1_scn4m_subm){
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -267,52 +279,61 @@ cell (sram_2_16_1_scn4m_subm){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("4.99880645"); values("6.379579e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("4.99880645"); values("6.379579e+00");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("4.99880645"); values("6.379579e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("4.99880645"); values("6.379579e+00");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("6.379579e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("6.379579e+00");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("6.379579e+00");
}
fall_power(scalar){
values("6.379579e+00");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.0295"); values("0.1545");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.0295"); values("0.1545");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.059"); values("0.309");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.059"); values("0.309");
} }
} }
} }

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 5.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.0125, 0.05, 0.4"); index_1("0.0125, 0.05, 0.4");
index_2("2.45605, 9.8242, 78.5936"); index_2("0.00245605, 0.0098242, 0.0392968");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_scn4m_subm){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 60774.3; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.000198;
value : 0.0009813788999999999;
} }
cell_leakage_power : 0; cell_leakage_power : 0.000198;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -98,28 +110,28 @@ cell (sram_2_16_1_scn4m_subm){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.167, 0.167, 0.228",\ values("0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228",\ "0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228"); "0.009, 0.009, 0.009");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.131, 0.125, 0.137",\ values("0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137",\ "0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137"); "0.009, 0.009, 0.009");
} }
} }
timing(){ timing(){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.065, -0.071, -0.114",\ values("0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114",\ "0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114"); "0.001, 0.001, 0.001");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.089, -0.089, -0.089",\ values("0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089",\ "0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089"); "0.001, 0.001, 0.001");
} }
} }
} }
@ -127,8 +139,8 @@ cell (sram_2_16_1_scn4m_subm){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 78.5936; max_capacitance : 0.0392968;
min_capacitance : 2.45605; min_capacitance : 0.00245605;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,24 +150,24 @@ cell (sram_2_16_1_scn4m_subm){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("1.556, 1.576, 1.751",\ values("1.314, 1.332, 1.404",\
"1.559, 1.579, 1.754",\ "1.314, 1.332, 1.404",\
"1.624, 1.643, 1.819"); "1.314, 1.332, 1.404");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("3.445, 3.504, 3.926",\ values("1.314, 1.332, 1.404",\
"3.448, 3.507, 3.93",\ "1.314, 1.332, 1.404",\
"3.49, 3.549, 3.972"); "1.314, 1.332, 1.404");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.13, 0.169, 0.574",\ values("0.006, 0.008, 0.015",\
"0.13, 0.169, 0.574",\ "0.006, 0.008, 0.015",\
"0.13, 0.169, 0.574"); "0.006, 0.008, 0.015");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.467, 0.49, 0.959",\ values("0.006, 0.008, 0.015",\
"0.467, 0.49, 0.959",\ "0.006, 0.008, 0.015",\
"0.47, 0.493, 0.96"); "0.006, 0.008, 0.015");
} }
} }
} }
@ -164,35 +176,35 @@ cell (sram_2_16_1_scn4m_subm){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
max_transition : 0.4; max_transition : 0.4;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.167, 0.167, 0.228",\ values("0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228",\ "0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228"); "0.009, 0.009, 0.009");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.131, 0.125, 0.137",\ values("0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137",\ "0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137"); "0.009, 0.009, 0.009");
} }
} }
timing(){ timing(){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.065, -0.071, -0.114",\ values("0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114",\ "0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114"); "0.001, 0.001, 0.001");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.089, -0.089, -0.089",\ values("0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089",\ "0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089"); "0.001, 0.001, 0.001");
} }
} }
} }
@ -200,66 +212,66 @@ cell (sram_2_16_1_scn4m_subm){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.167, 0.167, 0.228",\ values("0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228",\ "0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228"); "0.009, 0.009, 0.009");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.131, 0.125, 0.137",\ values("0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137",\ "0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137"); "0.009, 0.009, 0.009");
} }
} }
timing(){ timing(){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.065, -0.071, -0.114",\ values("0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114",\ "0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114"); "0.001, 0.001, 0.001");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.089, -0.089, -0.089",\ values("0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089",\ "0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089"); "0.001, 0.001, 0.001");
} }
} }
} }
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("0.167, 0.167, 0.228",\ values("0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228",\ "0.009, 0.009, 0.009",\
"0.167, 0.167, 0.228"); "0.009, 0.009, 0.009");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("0.131, 0.125, 0.137",\ values("0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137",\ "0.009, 0.009, 0.009",\
"0.131, 0.125, 0.137"); "0.009, 0.009, 0.009");
} }
} }
timing(){ timing(){
timing_type : hold_rising; timing_type : hold_rising;
related_pin : "clk0"; related_pin : "clk0";
rise_constraint(CONSTRAINT_TABLE) { rise_constraint(CONSTRAINT_TABLE) {
values("-0.065, -0.071, -0.114",\ values("0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114",\ "0.001, 0.001, 0.001",\
"-0.065, -0.071, -0.114"); "0.001, 0.001, 0.001");
} }
fall_constraint(CONSTRAINT_TABLE) { fall_constraint(CONSTRAINT_TABLE) {
values("-0.089, -0.089, -0.089",\ values("0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089",\ "0.001, 0.001, 0.001",\
"-0.089, -0.089, -0.089"); "0.001, 0.001, 0.001");
} }
} }
} }
@ -267,52 +279,61 @@ cell (sram_2_16_1_scn4m_subm){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("9.972790277777777"); values("7.017537e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("9.972790277777777"); values("7.017537e+00");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("8.899322499999998"); values("7.017537e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("8.899322499999998"); values("7.017537e+00");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("7.017537e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("7.017537e+00");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("7.017537e+00");
}
fall_power(scalar){
values("7.017537e+00");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("2.344"); values("0.1405");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("2.344"); values("0.1405");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("4.688"); values("0.281");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("4.688"); values("0.281");
} }
} }
} }

View File

@ -35,11 +35,14 @@ library (sram_2_16_1_scn4m_subm_TT_5p0V_25C_lib){
default_max_fanout : 4.0 ; default_max_fanout : 4.0 ;
default_connection_class : universal ; default_connection_class : universal ;
voltage_map ( VDD, 5.0 );
voltage_map ( GND, 0 );
lu_table_template(CELL_TABLE){ lu_table_template(CELL_TABLE){
variable_1 : input_net_transition; variable_1 : input_net_transition;
variable_2 : total_output_net_capacitance; variable_2 : total_output_net_capacitance;
index_1("0.0125, 0.05, 0.4"); index_1("0.0125, 0.05, 0.4");
index_2("2.45605, 9.8242, 78.5936"); index_2("0.00245605, 0.0098242, 0.0392968");
} }
lu_table_template(CONSTRAINT_TABLE){ lu_table_template(CONSTRAINT_TABLE){
@ -78,17 +81,26 @@ cell (sram_2_16_1_scn4m_subm){
dont_use : true; dont_use : true;
map_only : true; map_only : true;
dont_touch : true; dont_touch : true;
area : 60774.3; area : 0;
pg_pin(vdd) {
voltage_name : VDD;
pg_type : primary_power;
}
pg_pin(gnd) {
voltage_name : GND;
pg_type : primary_ground;
}
leakage_power () { leakage_power () {
when : "csb0"; value : 0.000198;
value : 0.000179;
} }
cell_leakage_power : 0; cell_leakage_power : 0.000198;
bus(din0){ bus(din0){
bus_type : data; bus_type : data;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
memory_write(){ memory_write(){
address : addr0; address : addr0;
clocked_on : clk0; clocked_on : clk0;
@ -127,8 +139,8 @@ cell (sram_2_16_1_scn4m_subm){
bus(dout0){ bus(dout0){
bus_type : data; bus_type : data;
direction : output; direction : output;
max_capacitance : 78.5936; max_capacitance : 0.0392968;
min_capacitance : 2.45605; min_capacitance : 0.00245605;
memory_read(){ memory_read(){
address : addr0; address : addr0;
} }
@ -138,24 +150,24 @@ cell (sram_2_16_1_scn4m_subm){
related_pin : "clk0"; related_pin : "clk0";
timing_type : falling_edge; timing_type : falling_edge;
cell_rise(CELL_TABLE) { cell_rise(CELL_TABLE) {
values("0.268, 0.268, 0.268",\ values("1.314, 1.332, 1.404",\
"0.268, 0.268, 0.268",\ "1.314, 1.332, 1.404",\
"0.268, 0.268, 0.268"); "1.314, 1.332, 1.404");
} }
cell_fall(CELL_TABLE) { cell_fall(CELL_TABLE) {
values("0.268, 0.268, 0.268",\ values("1.314, 1.332, 1.404",\
"0.268, 0.268, 0.268",\ "1.314, 1.332, 1.404",\
"0.268, 0.268, 0.268"); "1.314, 1.332, 1.404");
} }
rise_transition(CELL_TABLE) { rise_transition(CELL_TABLE) {
values("0.004, 0.004, 0.004",\ values("0.006, 0.008, 0.015",\
"0.004, 0.004, 0.004",\ "0.006, 0.008, 0.015",\
"0.004, 0.004, 0.004"); "0.006, 0.008, 0.015");
} }
fall_transition(CELL_TABLE) { fall_transition(CELL_TABLE) {
values("0.004, 0.004, 0.004",\ values("0.006, 0.008, 0.015",\
"0.004, 0.004, 0.004",\ "0.006, 0.008, 0.015",\
"0.004, 0.004, 0.004"); "0.006, 0.008, 0.015");
} }
} }
} }
@ -164,7 +176,7 @@ cell (sram_2_16_1_scn4m_subm){
bus(addr0){ bus(addr0){
bus_type : addr; bus_type : addr;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
max_transition : 0.4; max_transition : 0.4;
pin(addr0[3:0]){ pin(addr0[3:0]){
timing(){ timing(){
@ -200,7 +212,7 @@ cell (sram_2_16_1_scn4m_subm){
pin(csb0){ pin(csb0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -233,7 +245,7 @@ cell (sram_2_16_1_scn4m_subm){
pin(web0){ pin(web0){
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
timing(){ timing(){
timing_type : setup_rising; timing_type : setup_rising;
related_pin : "clk0"; related_pin : "clk0";
@ -267,52 +279,61 @@ cell (sram_2_16_1_scn4m_subm){
pin(clk0){ pin(clk0){
clock : true; clock : true;
direction : input; direction : input;
capacitance : 9.8242; capacitance : 0.0098242;
internal_power(){ internal_power(){
when : "!csb0 & clk0 & !web0"; when : "!csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("11.3049604371"); values("7.017537e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("11.3049604371"); values("7.017537e+00");
} }
} }
internal_power(){ internal_power(){
when : "!csb0 & !clk0 & web0"; when : "csb0 & !web0";
rise_power(scalar){ rise_power(scalar){
values("11.3049604371"); values("7.017537e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("11.3049604371"); values("7.017537e+00");
} }
} }
internal_power(){ internal_power(){
when : "csb0"; when : "!csb0 & web0";
rise_power(scalar){ rise_power(scalar){
values("0"); values("7.017537e+00");
} }
fall_power(scalar){ fall_power(scalar){
values("0"); values("7.017537e+00");
}
}
internal_power(){
when : "csb0 & web0";
rise_power(scalar){
values("7.017537e+00");
}
fall_power(scalar){
values("7.017537e+00");
} }
} }
timing(){ timing(){
timing_type :"min_pulse_width"; timing_type :"min_pulse_width";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0.0"); values("0.1405");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0.0"); values("0.1405");
} }
} }
timing(){ timing(){
timing_type :"minimum_period"; timing_type :"minimum_period";
related_pin : clk0; related_pin : clk0;
rise_constraint(scalar) { rise_constraint(scalar) {
values("0"); values("0.281");
} }
fall_constraint(scalar) { fall_constraint(scalar) {
values("0"); values("0.281");
} }
} }
} }

View File

@ -89,7 +89,7 @@ power_grid = m3_stack
################################################### ###################################################
# create the GDS layer map # create the GDS layer map
layer={} layer={}
layer["pwell"] = (41, 0) layer["pwell"] = (41, 0)
layer["nwell"] = (42, 0) layer["nwell"] = (42, 0)
layer["active"] = (43, 0) layer["active"] = (43, 0)
@ -98,9 +98,9 @@ layer["nimplant"] = (45, 0)
layer["poly"] = (46, 0) layer["poly"] = (46, 0)
layer["poly_contact"] = (47, 0) layer["poly_contact"] = (47, 0)
layer["active_contact"] = (48, 0) layer["active_contact"] = (48, 0)
layer["m1"] = (49, 0) layer["m1"] = (49, 0)
layer["via1"] = (50, 0) layer["via1"] = (50, 0)
layer["m2"] = (51, 0) layer["m2"] = (51, 0)
layer["via2"] = (61, 0) layer["via2"] = (61, 0)
layer["m3"] = (62, 0) layer["m3"] = (62, 0)
layer["via3"] = (30, 0) layer["via3"] = (30, 0)