mirror of https://github.com/VLSIDA/OpenRAM.git
Remove carriage returns form python files
This commit is contained in:
parent
abacf6a2d0
commit
34736b7b3f
|
|
@ -1,115 +1,115 @@
|
||||||
import gdsMill
|
import gdsMill
|
||||||
import tech
|
import tech
|
||||||
import globals
|
import globals
|
||||||
import math
|
import math
|
||||||
import debug
|
import debug
|
||||||
import datetime
|
import datetime
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
class lef:
|
class lef:
|
||||||
"""
|
"""
|
||||||
SRAM LEF Class open GDS file, read pins information, obstruction
|
SRAM LEF Class open GDS file, read pins information, obstruction
|
||||||
and write them to LEF file
|
and write them to LEF file
|
||||||
"""
|
"""
|
||||||
def __init__(self,layers):
|
def __init__(self,layers):
|
||||||
# LEF db units per micron
|
# LEF db units per micron
|
||||||
self.lef_units = 1000
|
self.lef_units = 1000
|
||||||
# These are the layers of the obstructions
|
# These are the layers of the obstructions
|
||||||
self.lef_layers = layers
|
self.lef_layers = layers
|
||||||
|
|
||||||
def lef_write(self, lef_name):
|
def lef_write(self, lef_name):
|
||||||
"""Write the entire lef of the object to the file."""
|
"""Write the entire lef of the object to the file."""
|
||||||
debug.info(3, "Writing to {0}".format(lef_name))
|
debug.info(3, "Writing to {0}".format(lef_name))
|
||||||
|
|
||||||
self.indent = "" # To maintain the indent level easily
|
self.indent = "" # To maintain the indent level easily
|
||||||
|
|
||||||
self.lef = open(lef_name,"w")
|
self.lef = open(lef_name,"w")
|
||||||
self.lef_write_header()
|
self.lef_write_header()
|
||||||
for pin in self.pins:
|
for pin in self.pins:
|
||||||
self.lef_write_pin(pin)
|
self.lef_write_pin(pin)
|
||||||
self.lef_write_obstructions()
|
self.lef_write_obstructions()
|
||||||
self.lef_write_footer()
|
self.lef_write_footer()
|
||||||
self.lef.close()
|
self.lef.close()
|
||||||
|
|
||||||
def lef_write_header(self):
|
def lef_write_header(self):
|
||||||
""" Header of LEF file """
|
""" Header of LEF file """
|
||||||
self.lef.write("VERSION 5.4 ;\n")
|
self.lef.write("VERSION 5.4 ;\n")
|
||||||
self.lef.write("NAMESCASESENSITIVE ON ;\n")
|
self.lef.write("NAMESCASESENSITIVE ON ;\n")
|
||||||
self.lef.write("BUSBITCHARS \"[]\" ;\n")
|
self.lef.write("BUSBITCHARS \"[]\" ;\n")
|
||||||
self.lef.write("DIVIDERCHAR \"/\" ;\n")
|
self.lef.write("DIVIDERCHAR \"/\" ;\n")
|
||||||
self.lef.write("UNITS\n")
|
self.lef.write("UNITS\n")
|
||||||
self.lef.write(" DATABASE MICRONS {0} ;\n".format(self.lef_units))
|
self.lef.write(" DATABASE MICRONS {0} ;\n".format(self.lef_units))
|
||||||
self.lef.write("END UNITS\n")
|
self.lef.write("END UNITS\n")
|
||||||
|
|
||||||
self.lef.write("SITE MacroSite\n")
|
self.lef.write("SITE MacroSite\n")
|
||||||
self.indent += " "
|
self.indent += " "
|
||||||
self.lef.write("{0}CLASS Core ;\n".format(self.indent))
|
self.lef.write("{0}CLASS Core ;\n".format(self.indent))
|
||||||
self.lef.write("{0}SIZE {1} by {2} ;\n".format(self.indent,
|
self.lef.write("{0}SIZE {1} by {2} ;\n".format(self.indent,
|
||||||
self.lef_units*self.width,
|
self.lef_units*self.width,
|
||||||
self.lef_units*self.height))
|
self.lef_units*self.height))
|
||||||
self.indent = self.indent[:-3]
|
self.indent = self.indent[:-3]
|
||||||
self.lef.write("END MacroSite\n")
|
self.lef.write("END MacroSite\n")
|
||||||
|
|
||||||
self.lef.write("{0}MACRO {1}\n".format(self.indent,self.name))
|
self.lef.write("{0}MACRO {1}\n".format(self.indent,self.name))
|
||||||
self.indent += " "
|
self.indent += " "
|
||||||
self.lef.write("{0}CLASS BLOCK ;\n".format(self.indent))
|
self.lef.write("{0}CLASS BLOCK ;\n".format(self.indent))
|
||||||
self.lef.write("{0}SIZE {1} BY {2} ;\n" .format(self.indent,
|
self.lef.write("{0}SIZE {1} BY {2} ;\n" .format(self.indent,
|
||||||
self.lef_units*self.width,
|
self.lef_units*self.width,
|
||||||
self.lef_units*self.height))
|
self.lef_units*self.height))
|
||||||
self.lef.write("{0}SYMMETRY X Y R90 ;\n".format(self.indent))
|
self.lef.write("{0}SYMMETRY X Y R90 ;\n".format(self.indent))
|
||||||
self.lef.write("{0}SITE MacroSite ;\n".format(self.indent))
|
self.lef.write("{0}SITE MacroSite ;\n".format(self.indent))
|
||||||
|
|
||||||
|
|
||||||
def lef_write_footer(self):
|
def lef_write_footer(self):
|
||||||
self.lef.write("{0}END {1}\n".format(self.indent,self.name))
|
self.lef.write("{0}END {1}\n".format(self.indent,self.name))
|
||||||
self.indent = self.indent[:-3]
|
self.indent = self.indent[:-3]
|
||||||
self.lef.write("END LIBRARY\n")
|
self.lef.write("END LIBRARY\n")
|
||||||
|
|
||||||
|
|
||||||
def lef_write_pin(self, name):
|
def lef_write_pin(self, name):
|
||||||
pin_dir = self.get_pin_dir(name)
|
pin_dir = self.get_pin_dir(name)
|
||||||
pin_type = self.get_pin_type(name)
|
pin_type = self.get_pin_type(name)
|
||||||
self.lef.write("{0}PIN {1}\n".format(self.indent,name))
|
self.lef.write("{0}PIN {1}\n".format(self.indent,name))
|
||||||
self.indent += " "
|
self.indent += " "
|
||||||
|
|
||||||
self.lef.write("{0}DIRECTION {1} ;\n".format(self.indent,pin_dir))
|
self.lef.write("{0}DIRECTION {1} ;\n".format(self.indent,pin_dir))
|
||||||
|
|
||||||
if pin_type in ["POWER","GROUND"]:
|
if pin_type in ["POWER","GROUND"]:
|
||||||
self.lef.write("{0}USE {1} ; \n".format(self.indent,pin_type))
|
self.lef.write("{0}USE {1} ; \n".format(self.indent,pin_type))
|
||||||
self.lef.write("{0}SHAPE ABUTMENT ; \n".format(self.indent))
|
self.lef.write("{0}SHAPE ABUTMENT ; \n".format(self.indent))
|
||||||
|
|
||||||
self.lef.write("{0}PORT\n".format(self.indent))
|
self.lef.write("{0}PORT\n".format(self.indent))
|
||||||
self.indent += " "
|
self.indent += " "
|
||||||
|
|
||||||
# We could sort these together to minimize different layer sections, but meh.
|
# We could sort these together to minimize different layer sections, but meh.
|
||||||
pin_list = self.get_pins(name)
|
pin_list = self.get_pins(name)
|
||||||
for pin in pin_list:
|
for pin in pin_list:
|
||||||
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,pin.layer))
|
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,pin.layer))
|
||||||
self.lef_write_rect(pin.rect)
|
self.lef_write_rect(pin.rect)
|
||||||
|
|
||||||
# End the PORT
|
# End the PORT
|
||||||
self.indent = self.indent[:-3]
|
self.indent = self.indent[:-3]
|
||||||
self.lef.write("{0}END\n".format(self.indent))
|
self.lef.write("{0}END\n".format(self.indent))
|
||||||
|
|
||||||
# End the PIN
|
# End the PIN
|
||||||
self.indent = self.indent[:-3]
|
self.indent = self.indent[:-3]
|
||||||
self.lef.write("{0}END {1}\n".format(self.indent,name))
|
self.lef.write("{0}END {1}\n".format(self.indent,name))
|
||||||
|
|
||||||
def lef_write_obstructions(self):
|
def lef_write_obstructions(self):
|
||||||
""" Write all the obstructions on each layer """
|
""" Write all the obstructions on each layer """
|
||||||
self.lef.write("{0}OBS\n".format(self.indent))
|
self.lef.write("{0}OBS\n".format(self.indent))
|
||||||
for layer in self.lef_layers:
|
for layer in self.lef_layers:
|
||||||
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,layer))
|
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,layer))
|
||||||
self.indent += " "
|
self.indent += " "
|
||||||
blockages = self.get_blockages(layer,True)
|
blockages = self.get_blockages(layer,True)
|
||||||
for b in blockages:
|
for b in blockages:
|
||||||
self.lef_write_rect(b)
|
self.lef_write_rect(b)
|
||||||
self.indent = self.indent[:-3]
|
self.indent = self.indent[:-3]
|
||||||
self.lef.write("{0}END\n".format(self.indent))
|
self.lef.write("{0}END\n".format(self.indent))
|
||||||
|
|
||||||
def lef_write_rect(self, rect):
|
def lef_write_rect(self, rect):
|
||||||
""" Write a LEF rectangle """
|
""" Write a LEF rectangle """
|
||||||
self.lef.write("{0}RECT ".format(self.indent))
|
self.lef.write("{0}RECT ".format(self.indent))
|
||||||
for item in rect:
|
for item in rect:
|
||||||
self.lef.write(" {0} {1}".format(self.lef_units*item[0], self.lef_units*item[1]))
|
self.lef.write(" {0} {1}".format(self.lef_units*item[0], self.lef_units*item[1]))
|
||||||
self.lef.write(" ;\n")
|
self.lef.write(" ;\n")
|
||||||
|
|
|
||||||
|
|
@ -1,202 +1,202 @@
|
||||||
import debug
|
import debug
|
||||||
import design
|
import design
|
||||||
from tech import drc, spice
|
from tech import drc, spice
|
||||||
from vector import vector
|
from vector import vector
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class bitcell_array(design.design):
|
class bitcell_array(design.design):
|
||||||
"""
|
"""
|
||||||
Creates a rows x cols array of memory cells. Assumes bit-lines
|
Creates a rows x cols array of memory cells. Assumes bit-lines
|
||||||
and word line is connected by abutment.
|
and word line is connected by abutment.
|
||||||
Connects the word lines and bit lines.
|
Connects the word lines and bit lines.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, cols, rows, name="bitcell_array"):
|
def __init__(self, cols, rows, name="bitcell_array"):
|
||||||
design.design.__init__(self, name)
|
design.design.__init__(self, name)
|
||||||
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
|
debug.info(1, "Creating {0} {1} x {2}".format(self.name, rows, cols))
|
||||||
|
|
||||||
|
|
||||||
self.column_size = cols
|
self.column_size = cols
|
||||||
self.row_size = rows
|
self.row_size = rows
|
||||||
|
|
||||||
from importlib import reload
|
from importlib import reload
|
||||||
c = reload(__import__(OPTS.bitcell))
|
c = reload(__import__(OPTS.bitcell))
|
||||||
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
self.mod_bitcell = getattr(c, OPTS.bitcell)
|
||||||
self.cell = self.mod_bitcell()
|
self.cell = self.mod_bitcell()
|
||||||
self.add_mod(self.cell)
|
self.add_mod(self.cell)
|
||||||
|
|
||||||
# We increase it by a well enclosure so the precharges don't overlap our wells
|
# We increase it by a well enclosure so the precharges don't overlap our wells
|
||||||
self.height = self.row_size*self.cell.height + drc["well_enclosure_active"] + self.m1_width
|
self.height = self.row_size*self.cell.height + drc["well_enclosure_active"] + self.m1_width
|
||||||
self.width = self.column_size*self.cell.width + self.m1_width
|
self.width = self.column_size*self.cell.width + self.m1_width
|
||||||
|
|
||||||
self.add_pins()
|
self.add_pins()
|
||||||
self.create_layout()
|
self.create_layout()
|
||||||
self.add_layout_pins()
|
self.add_layout_pins()
|
||||||
|
|
||||||
# We don't offset this because we need to align
|
# We don't offset this because we need to align
|
||||||
# the replica bitcell in the control logic
|
# the replica bitcell in the control logic
|
||||||
#self.offset_all_coordinates()
|
#self.offset_all_coordinates()
|
||||||
|
|
||||||
self.DRC_LVS()
|
self.DRC_LVS()
|
||||||
|
|
||||||
def add_pins(self):
|
def add_pins(self):
|
||||||
row_list = self.cell.list_row_pins()
|
row_list = self.cell.list_row_pins()
|
||||||
column_list = self.cell.list_all_column_pins()
|
column_list = self.cell.list_all_column_pins()
|
||||||
for col in range(self.column_size):
|
for col in range(self.column_size):
|
||||||
for cell_column in column_list:
|
for cell_column in column_list:
|
||||||
self.add_pin(cell_column+"[{0}]".format(col))
|
self.add_pin(cell_column+"[{0}]".format(col))
|
||||||
for row in range(self.row_size):
|
for row in range(self.row_size):
|
||||||
for cell_row in row_list:
|
for cell_row in row_list:
|
||||||
self.add_pin(cell_row+"[{0}]".format(row))
|
self.add_pin(cell_row+"[{0}]".format(row))
|
||||||
self.add_pin("vdd")
|
self.add_pin("vdd")
|
||||||
self.add_pin("gnd")
|
self.add_pin("gnd")
|
||||||
|
|
||||||
def create_layout(self):
|
def create_layout(self):
|
||||||
xoffset = 0.0
|
xoffset = 0.0
|
||||||
self.cell_inst = {}
|
self.cell_inst = {}
|
||||||
for col in range(self.column_size):
|
for col in range(self.column_size):
|
||||||
yoffset = 0.0
|
yoffset = 0.0
|
||||||
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)
|
||||||
|
|
||||||
if row % 2:
|
if row % 2:
|
||||||
tempy = yoffset + self.cell.height
|
tempy = yoffset + self.cell.height
|
||||||
dir_key = "MX"
|
dir_key = "MX"
|
||||||
else:
|
else:
|
||||||
tempy = yoffset
|
tempy = yoffset
|
||||||
dir_key = ""
|
dir_key = ""
|
||||||
|
|
||||||
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,
|
||||||
offset=[xoffset, tempy],
|
offset=[xoffset, tempy],
|
||||||
mirror=dir_key)
|
mirror=dir_key)
|
||||||
self.connect_inst(self.cell.list_bitcell_pins(col, row))
|
self.connect_inst(self.cell.list_bitcell_pins(col, row))
|
||||||
|
|
||||||
yoffset += self.cell.height
|
yoffset += self.cell.height
|
||||||
xoffset += self.cell.width
|
xoffset += self.cell.width
|
||||||
|
|
||||||
|
|
||||||
def add_layout_pins(self):
|
def add_layout_pins(self):
|
||||||
""" Add the layout pins """
|
""" Add the layout pins """
|
||||||
|
|
||||||
row_list = self.cell.list_row_pins()
|
row_list = self.cell.list_row_pins()
|
||||||
column_list = self.cell.list_all_column_pins()
|
column_list = self.cell.list_all_column_pins()
|
||||||
|
|
||||||
offset = vector(0.0, 0.0)
|
offset = vector(0.0, 0.0)
|
||||||
for col in range(self.column_size):
|
for col in range(self.column_size):
|
||||||
for cell_column in column_list:
|
for cell_column in column_list:
|
||||||
bl_pin = self.cell_inst[0,col].get_pin(cell_column)
|
bl_pin = self.cell_inst[0,col].get_pin(cell_column)
|
||||||
self.add_layout_pin(text=cell_column+"[{0}]".format(col),
|
self.add_layout_pin(text=cell_column+"[{0}]".format(col),
|
||||||
layer="metal2",
|
layer="metal2",
|
||||||
offset=bl_pin.ll(),
|
offset=bl_pin.ll(),
|
||||||
width=bl_pin.width(),
|
width=bl_pin.width(),
|
||||||
height=self.height)
|
height=self.height)
|
||||||
|
|
||||||
# increments to the next column width
|
# increments to the next column width
|
||||||
offset.x += self.cell.width
|
offset.x += self.cell.width
|
||||||
|
|
||||||
offset.x = 0.0
|
offset.x = 0.0
|
||||||
for row in range(self.row_size):
|
for row in range(self.row_size):
|
||||||
for cell_row in row_list:
|
for cell_row in row_list:
|
||||||
wl_pin = self.cell_inst[row,0].get_pin(cell_row)
|
wl_pin = self.cell_inst[row,0].get_pin(cell_row)
|
||||||
self.add_layout_pin(text=cell_row+"[{0}]".format(row),
|
self.add_layout_pin(text=cell_row+"[{0}]".format(row),
|
||||||
layer="metal1",
|
layer="metal1",
|
||||||
offset=wl_pin.ll(),
|
offset=wl_pin.ll(),
|
||||||
width=self.width,
|
width=self.width,
|
||||||
height=wl_pin.height())
|
height=wl_pin.height())
|
||||||
|
|
||||||
# increments to the next row height
|
# increments to the next row height
|
||||||
offset.y += self.cell.height
|
offset.y += self.cell.height
|
||||||
|
|
||||||
# For every second row and column, add a via for vdd
|
# For every second row and column, add a via for vdd
|
||||||
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):
|
||||||
inst = self.cell_inst[row,col]
|
inst = self.cell_inst[row,col]
|
||||||
for vdd_pin in inst.get_pins("vdd"):
|
for vdd_pin in inst.get_pins("vdd"):
|
||||||
# Drop to M1 if needed
|
# Drop to M1 if needed
|
||||||
if vdd_pin.layer == "metal1":
|
if vdd_pin.layer == "metal1":
|
||||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||||
offset=vdd_pin.center(),
|
offset=vdd_pin.center(),
|
||||||
rotate=90)
|
rotate=90)
|
||||||
# Always drop to M2
|
# Always drop to M2
|
||||||
self.add_via_center(layers=("metal2", "via2", "metal3"),
|
self.add_via_center(layers=("metal2", "via2", "metal3"),
|
||||||
offset=vdd_pin.center())
|
offset=vdd_pin.center())
|
||||||
self.add_layout_pin_rect_center(text="vdd",
|
self.add_layout_pin_rect_center(text="vdd",
|
||||||
layer="metal3",
|
layer="metal3",
|
||||||
offset=vdd_pin.center())
|
offset=vdd_pin.center())
|
||||||
|
|
||||||
|
|
||||||
# For every second row and column (+1), add a via for gnd
|
# For every second row and column (+1), add a via for gnd
|
||||||
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):
|
||||||
inst = self.cell_inst[row,col]
|
inst = self.cell_inst[row,col]
|
||||||
for gnd_pin in inst.get_pins("gnd"):
|
for gnd_pin in inst.get_pins("gnd"):
|
||||||
# Drop to M1 if needed
|
# Drop to M1 if needed
|
||||||
if gnd_pin.layer == "metal1":
|
if gnd_pin.layer == "metal1":
|
||||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||||
offset=gnd_pin.center(),
|
offset=gnd_pin.center(),
|
||||||
rotate=90)
|
rotate=90)
|
||||||
# Always drop to M2
|
# Always drop to M2
|
||||||
self.add_via_center(layers=("metal2", "via2", "metal3"),
|
self.add_via_center(layers=("metal2", "via2", "metal3"),
|
||||||
offset=gnd_pin.center())
|
offset=gnd_pin.center())
|
||||||
self.add_layout_pin_rect_center(text="gnd",
|
self.add_layout_pin_rect_center(text="gnd",
|
||||||
layer="metal3",
|
layer="metal3",
|
||||||
offset=gnd_pin.center())
|
offset=gnd_pin.center())
|
||||||
|
|
||||||
def analytical_delay(self, slew, load=0):
|
def analytical_delay(self, slew, load=0):
|
||||||
from tech import drc
|
from tech import drc
|
||||||
wl_wire = self.gen_wl_wire()
|
wl_wire = self.gen_wl_wire()
|
||||||
wl_wire.return_delay_over_wire(slew)
|
wl_wire.return_delay_over_wire(slew)
|
||||||
|
|
||||||
wl_to_cell_delay = wl_wire.return_delay_over_wire(slew)
|
wl_to_cell_delay = wl_wire.return_delay_over_wire(slew)
|
||||||
# hypothetical delay from cell to bl end without sense amp
|
# hypothetical delay from cell to bl end without sense amp
|
||||||
bl_wire = self.gen_bl_wire()
|
bl_wire = self.gen_bl_wire()
|
||||||
cell_load = 2 * bl_wire.return_input_cap() # we ingore the wire r
|
cell_load = 2 * bl_wire.return_input_cap() # we ingore the wire r
|
||||||
# hence just use the whole c
|
# hence just use the whole c
|
||||||
bl_swing = 0.1
|
bl_swing = 0.1
|
||||||
cell_delay = self.cell.analytical_delay(wl_to_cell_delay.slew, cell_load, swing = bl_swing)
|
cell_delay = self.cell.analytical_delay(wl_to_cell_delay.slew, cell_load, swing = bl_swing)
|
||||||
|
|
||||||
#we do not consider the delay over the wire for now
|
#we do not consider the delay over the wire for now
|
||||||
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
|
return self.return_delay(cell_delay.delay+wl_to_cell_delay.delay,
|
||||||
wl_to_cell_delay.slew)
|
wl_to_cell_delay.slew)
|
||||||
|
|
||||||
def analytical_power(self, proc, vdd, temp, load):
|
def analytical_power(self, proc, vdd, temp, load):
|
||||||
"""Power of Bitcell array and bitline in nW."""
|
"""Power of Bitcell array and bitline in nW."""
|
||||||
from tech import drc
|
from tech import drc
|
||||||
|
|
||||||
# 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 = 0.1 #This should probably be defined in the tech file or input
|
bl_swing = 0.1 #This should probably be defined in the tech file or input
|
||||||
freq = spice["default_event_rate"]
|
freq = spice["default_event_rate"]
|
||||||
bitline_dynamic = bl_swing*cell_load*vdd*vdd*freq #not sure if calculation is correct
|
bitline_dynamic = bl_swing*cell_load*vdd*vdd*freq #not sure if calculation is correct
|
||||||
|
|
||||||
#Calculate the bitcell power which currently only includes leakage
|
#Calculate the bitcell power which currently only includes leakage
|
||||||
cell_power = self.cell.analytical_power(proc, vdd, temp, load)
|
cell_power = self.cell.analytical_power(proc, vdd, temp, load)
|
||||||
|
|
||||||
#Leakage power grows with entire array and bitlines.
|
#Leakage power grows with entire array and bitlines.
|
||||||
total_power = self.return_power(cell_power.dynamic + bitline_dynamic * self.column_size,
|
total_power = self.return_power(cell_power.dynamic + bitline_dynamic * self.column_size,
|
||||||
cell_power.leakage * self.column_size * self.row_size)
|
cell_power.leakage * self.column_size * self.row_size)
|
||||||
return total_power
|
return total_power
|
||||||
|
|
||||||
def gen_wl_wire(self):
|
def gen_wl_wire(self):
|
||||||
wl_wire = self.generate_rc_net(int(self.column_size), self.width, drc["minwidth_metal1"])
|
wl_wire = self.generate_rc_net(int(self.column_size), self.width, drc["minwidth_metal1"])
|
||||||
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):
|
||||||
bl_pos = 0
|
bl_pos = 0
|
||||||
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), self.height, drc["minwidth_metal1"])
|
bl_wire = self.generate_rc_net(int(self.row_size-bl_pos), self.height, drc["minwidth_metal1"])
|
||||||
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 output_load(self, bl_pos=0):
|
def output_load(self, bl_pos=0):
|
||||||
bl_wire = self.gen_bl_wire()
|
bl_wire = self.gen_bl_wire()
|
||||||
return bl_wire.wire_c # sense amp only need to charge small portion of the bl
|
return bl_wire.wire_c # sense amp only need to charge small portion of the bl
|
||||||
# set as one segment for now
|
# set as one segment for now
|
||||||
|
|
||||||
def input_load(self):
|
def input_load(self):
|
||||||
wl_wire = self.gen_wl_wire()
|
wl_wire = self.gen_wl_wire()
|
||||||
return wl_wire.return_input_cap()
|
return wl_wire.return_input_cap()
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,78 +1,78 @@
|
||||||
#!/usr/bin/env python2.7
|
#!/usr/bin/env python2.7
|
||||||
"""
|
"""
|
||||||
Run regresion tests on a parameterized bitcell
|
Run regresion tests on a parameterized bitcell
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from testutils import header,openram_test
|
from testutils import header,openram_test
|
||||||
import sys,os
|
import sys,os
|
||||||
sys.path.append(os.path.join(sys.path[0],".."))
|
sys.path.append(os.path.join(sys.path[0],".."))
|
||||||
import globals
|
import globals
|
||||||
from globals import OPTS
|
from globals import OPTS
|
||||||
import debug
|
import debug
|
||||||
|
|
||||||
OPTS = globals.OPTS
|
OPTS = globals.OPTS
|
||||||
|
|
||||||
#@unittest.skip("SKIPPING 04_pbitcell_test")
|
#@unittest.skip("SKIPPING 04_pbitcell_test")
|
||||||
|
|
||||||
|
|
||||||
class pbitcell_test(openram_test):
|
class pbitcell_test(openram_test):
|
||||||
|
|
||||||
def runTest(self):
|
def runTest(self):
|
||||||
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
globals.init_openram("config_20_{0}".format(OPTS.tech_name))
|
||||||
global verify
|
global verify
|
||||||
import verify
|
import verify
|
||||||
|
|
||||||
import pbitcell
|
import pbitcell
|
||||||
import tech
|
import tech
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 1 of each port: read/write, write, and read")
|
debug.info(2, "Bitcell with 1 of each port: read/write, write, and read")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=1)
|
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=1)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 read/write ports")
|
debug.info(2, "Bitcell with 0 read/write ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=0,num_write=1,num_read=1)
|
tx = pbitcell.pbitcell(num_readwrite=0,num_write=1,num_read=1)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 write ports")
|
debug.info(2, "Bitcell with 0 write ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=1)
|
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=1)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 read ports")
|
debug.info(2, "Bitcell with 0 read ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=0)
|
tx = pbitcell.pbitcell(num_readwrite=1,num_write=1,num_read=0)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 read ports and 0 write ports")
|
debug.info(2, "Bitcell with 0 read ports and 0 write ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=0)
|
tx = pbitcell.pbitcell(num_readwrite=1,num_write=0,num_read=0)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 2 of each port: read/write, write, and read")
|
debug.info(2, "Bitcell with 2 of each port: read/write, write, and read")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=2,num_write=2,num_read=2)
|
tx = pbitcell.pbitcell(num_readwrite=2,num_write=2,num_read=2)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 read/write ports")
|
debug.info(2, "Bitcell with 0 read/write ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=0,num_write=2,num_read=2)
|
tx = pbitcell.pbitcell(num_readwrite=0,num_write=2,num_read=2)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 write ports")
|
debug.info(2, "Bitcell with 0 write ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=2,num_write=0,num_read=2)
|
tx = pbitcell.pbitcell(num_readwrite=2,num_write=0,num_read=2)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 read ports")
|
debug.info(2, "Bitcell with 0 read ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=2,num_write=2,num_read=0)
|
tx = pbitcell.pbitcell(num_readwrite=2,num_write=2,num_read=0)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
debug.info(2, "Bitcell with 0 read ports and 0 write ports")
|
debug.info(2, "Bitcell with 0 read ports and 0 write ports")
|
||||||
tx = pbitcell.pbitcell(num_readwrite=2,num_write=0,num_read=0)
|
tx = pbitcell.pbitcell(num_readwrite=2,num_write=0,num_read=0)
|
||||||
self.local_check(tx)
|
self.local_check(tx)
|
||||||
|
|
||||||
globals.end_openram()
|
globals.end_openram()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# instantiate a copy of the class to actually run the test
|
# instantiate a copy of the class to actually run the test
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
(OPTS, args) = globals.parse_args()
|
(OPTS, args) = globals.parse_args()
|
||||||
del sys.argv[1:]
|
del sys.argv[1:]
|
||||||
header(__file__, OPTS.tech_name)
|
header(__file__, OPTS.tech_name)
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue