mirror of https://github.com/VLSIDA/OpenRAM.git
Clean up GdsMill. Fix rotate bug I introduced in transFlags!
This commit is contained in:
parent
0ce2dd2791
commit
73289a6090
|
|
@ -845,7 +845,7 @@ class layout(lef.lef):
|
|||
|
||||
def add_power_pin(self, name, loc, rotate=90):
|
||||
"""
|
||||
Add a single power pin from M3 own to M1 at the given center location
|
||||
Add a single power pin from M3 down to M1 at the given center location
|
||||
"""
|
||||
self.add_via_center(layers=("metal1", "via1", "metal2"),
|
||||
offset=loc,
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class GdsSref:
|
|||
self.elementFlags=""
|
||||
self.plex=""
|
||||
self.sName=""
|
||||
self.transFlags=(False,False,False)
|
||||
self.transFlags=[0,0,0]
|
||||
self.magFactor=""
|
||||
self.rotateAngle=""
|
||||
self.coordinates=""
|
||||
|
|
@ -129,7 +129,7 @@ class GdsAref:
|
|||
self.elementFlags=""
|
||||
self.plex=""
|
||||
self.aName=""
|
||||
self.transFlags=(False,False,False)
|
||||
self.transFlags=[0,0,0]
|
||||
self.magFactor=""
|
||||
self.rotateAngle=""
|
||||
self.coordinates=""
|
||||
|
|
@ -141,7 +141,7 @@ class GdsText:
|
|||
self.plex=""
|
||||
self.drawingLayer=""
|
||||
self.purposeLayer = None
|
||||
self.transFlags=(False,False,False)
|
||||
self.transFlags=[0,00]
|
||||
self.magFactor=""
|
||||
self.rotateAngle=""
|
||||
self.pathType=""
|
||||
|
|
@ -167,4 +167,4 @@ class GdsBox:
|
|||
self.drawingLayer=""
|
||||
self.purposeLayer = None
|
||||
self.boxValue=""
|
||||
self.coordinates=""
|
||||
self.coordinates=""
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class VlsiLayout:
|
|||
for coordinate in coordinatesToRotate:
|
||||
newX = coordinate[0]*math.cos(angle) - coordinate[1]*math.sin(angle)
|
||||
newY = coordinate[0]*math.sin(angle) + coordinate[1]*math.cos(angle)
|
||||
coordinatesRotate += [(newX,newY)]
|
||||
coordinatesRotate.extend((newX,newY))
|
||||
return coordinatesRotate
|
||||
|
||||
def rename(self,newName):
|
||||
|
|
@ -141,7 +141,7 @@ class VlsiLayout:
|
|||
contained by any other structure. this is the root."""
|
||||
structureNames=[]
|
||||
for name in self.structures:
|
||||
structureNames+=[name]
|
||||
structureNames.append(name)
|
||||
|
||||
for name in self.structures:
|
||||
if(len(self.structures[name].srefs)>0): #does this structure reference any others?
|
||||
|
|
@ -162,7 +162,8 @@ class VlsiLayout:
|
|||
if(rotateAngle == None or rotateAngle == ""):
|
||||
angle = 0
|
||||
else:
|
||||
angle = math.radians(float(rotateAngle))
|
||||
# MRG: Added negative to make CCW rotate 8/29/18
|
||||
angle = math.radians(-1.0*float(rotateAngle))
|
||||
mRotate = matrix([[math.cos(angle),-math.sin(angle),0.0],
|
||||
[math.sin(angle),math.cos(angle),0.0],
|
||||
[0.0,0.0,1.0]])
|
||||
|
|
@ -180,7 +181,7 @@ class VlsiLayout:
|
|||
|
||||
#we need to keep track of all transforms in the hierarchy
|
||||
#when we add an element to the xy tree, we apply all transforms from the bottom up
|
||||
transformPath += [(mRotate,mScale,mTranslate)]
|
||||
transformPath.append((mRotate,mScale,mTranslate))
|
||||
if delegateFunction != None:
|
||||
delegateFunction(startingStructureName, transformPath)
|
||||
#starting with a particular structure, we will recursively traverse the tree
|
||||
|
|
@ -226,8 +227,10 @@ class VlsiLayout:
|
|||
vVector = transform[1] * vVector #scale
|
||||
origin = transform[2] * origin #translate
|
||||
#we don't need to do a translation on the basis vectors
|
||||
self.xyTree+=[(startingStructureName,origin,uVector,vVector)] #populate the xyTree with each
|
||||
#structureName and coordinate space
|
||||
#uVector = transform[2] * uVector #translate
|
||||
#vVector = transform[2] * vVector #translate
|
||||
#populate the xyTree with each structureName and coordinate space
|
||||
self.xyTree.append((startingStructureName,origin,uVector,vVector))
|
||||
self.traverseTheHierarchy(delegateFunction = addToXyTree)
|
||||
|
||||
def microns(self,userUnits):
|
||||
|
|
@ -303,7 +306,7 @@ class VlsiLayout:
|
|||
#also combine the "layers in use" list
|
||||
for layerNumber in layoutToAdd.layerNumbersInUse:
|
||||
if layerNumber not in self.layerNumbersInUse:
|
||||
self.layerNumbersInUse += [layerNumber]
|
||||
self.layerNumbersInUse.append(layerNumber)
|
||||
|
||||
# if debug: print("DEBUG: vlsilayout: Using %d layers")
|
||||
|
||||
|
|
@ -314,7 +317,9 @@ class VlsiLayout:
|
|||
layoutToAddSref.coordinates = offsetInLayoutUnits
|
||||
|
||||
if mirror or rotate:
|
||||
# transFlags = (mirror around x-axis, magnification, rotation)
|
||||
# This is NOT the same as the order in the GDS spec!
|
||||
# It gets written out in gds2writer in the right order though.
|
||||
# transFlags = (mirror around x-axis, rotation, magnification)
|
||||
# If magnification or rotation is true, it is the flags are then
|
||||
# followed by an amount in the record
|
||||
if mirror=="R90":
|
||||
|
|
@ -326,19 +331,20 @@ class VlsiLayout:
|
|||
|
||||
layoutToAddSref.transFlags = [0,0,0]
|
||||
if rotate:
|
||||
layoutToAddSref.transFlags = [0,0,1]
|
||||
layoutToAddSref.transFlags = [0,1,0]
|
||||
layoutToAddSref.rotateAngle = rotate
|
||||
if mirror == "x" or mirror == "MX":
|
||||
layoutToAddSref.transFlags = [1,0,0]
|
||||
if mirror == "y" or mirror == "MY": #NOTE: "MY" option will override specified rotate angle
|
||||
layoutToAddSref.transFlags = [1,0,1]
|
||||
layoutToAddSref.transFlags = [1,1,0]
|
||||
#layoutToAddSref.transFlags = [1,0,0]
|
||||
layoutToAddSref.rotateAngle = 180.0
|
||||
if mirror == "xy" or mirror == "XY": #NOTE: "XY" option will override specified rotate angle
|
||||
layoutToAddSref.transFlags = [0,0,1]
|
||||
layoutToAddSref.transFlags = [0,1,0]
|
||||
layoutToAddSref.rotateAngle = 180.0
|
||||
|
||||
#add the sref to the root structure
|
||||
self.structures[self.rootStructureName].srefs+=[layoutToAddSref]
|
||||
self.structures[self.rootStructureName].srefs.append(layoutToAddSref)
|
||||
|
||||
def addBox(self,layerNumber=0, purposeNumber=None, offsetInMicrons=(0,0), width=1.0, height=1.0,center=False):
|
||||
"""
|
||||
|
|
@ -356,11 +362,7 @@ class VlsiLayout:
|
|||
(offsetInLayoutUnits[0],offsetInLayoutUnits[1]+heightInLayoutUnits),
|
||||
offsetInLayoutUnits]
|
||||
else:
|
||||
|
||||
#is there where gdsmill is halving the coordinates???
|
||||
#if you printGDS of temp.gds, the header says 1 user unit = .0005 database units. By default user units = .001.
|
||||
#something to do with the ieeedouble in gdswriter.py????
|
||||
startPoint = (offsetInLayoutUnits[0]-widthInLayoutUnits/2, offsetInLayoutUnits[1]-heightInLayoutUnits/2) #width/2 height/2
|
||||
startPoint = (offsetInLayoutUnits[0]-widthInLayoutUnits/2.0, offsetInLayoutUnits[1]-heightInLayoutUnits/2.0)
|
||||
coordinates=[startPoint,
|
||||
(startPoint[0]+widthInLayoutUnits,startPoint[1]),
|
||||
(startPoint[0]+widthInLayoutUnits,startPoint[1]+heightInLayoutUnits),
|
||||
|
|
@ -373,7 +375,7 @@ class VlsiLayout:
|
|||
boundaryToAdd.coordinates = coordinates
|
||||
boundaryToAdd.purposeLayer = purposeNumber
|
||||
#add the sref to the root structure
|
||||
self.structures[self.rootStructureName].boundaries+=[boundaryToAdd]
|
||||
self.structures[self.rootStructureName].boundaries.append(boundaryToAdd)
|
||||
|
||||
def addPath(self, layerNumber=0, purposeNumber = None, coordinates=[(0,0)], width=1.0):
|
||||
"""
|
||||
|
|
@ -385,14 +387,14 @@ class VlsiLayout:
|
|||
for coordinate in coordinates:
|
||||
cX = self.userUnits(coordinate[0])
|
||||
cY = self.userUnits(coordinate[1])
|
||||
layoutUnitCoordinates += [(cX,cY)]
|
||||
layoutUnitCoordinates.append((cX,cY))
|
||||
pathToAdd = GdsPath()
|
||||
pathToAdd.drawingLayer=layerNumber
|
||||
pathToAdd.purposeLayer = purposeNumber
|
||||
pathToAdd.pathWidth=widthInLayoutUnits
|
||||
pathToAdd.coordinates=layoutUnitCoordinates
|
||||
#add the sref to the root structure
|
||||
self.structures[self.rootStructureName].paths+=[pathToAdd]
|
||||
self.structures[self.rootStructureName].paths.append(pathToAdd)
|
||||
|
||||
def addText(self, text, layerNumber=0, purposeNumber = None, offsetInMicrons=(0,0), magnification=0.1, rotate = None):
|
||||
offsetInLayoutUnits = (self.userUnits(offsetInMicrons[0]),self.userUnits(offsetInMicrons[1]))
|
||||
|
|
@ -411,7 +413,7 @@ class VlsiLayout:
|
|||
textToAdd.transFlags[2] = 1
|
||||
textToAdd.rotateAngle = rotate
|
||||
#add the sref to the root structure
|
||||
self.structures[self.rootStructureName].texts+=[textToAdd]
|
||||
self.structures[self.rootStructureName].texts.append(textToAdd)
|
||||
|
||||
def isBounded(self,testPoint,startPoint,endPoint):
|
||||
#these arguments are touples of (x,y) coordinates
|
||||
|
|
@ -523,7 +525,7 @@ class VlsiLayout:
|
|||
#remap coordinates
|
||||
shiftedBoundaryCoordinates = []
|
||||
for shapeCoordinate in boundary.rotatedCoordinates(rotateAngle):
|
||||
shiftedBoundaryCoordinates+=[(shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1])]
|
||||
shiftedBoundaryCoordinates.append((shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1]))
|
||||
joint = self.doShapesIntersect(self.tempCoordinates, shiftedBoundaryCoordinates)
|
||||
if joint:
|
||||
self.tempPassFail = False
|
||||
|
|
@ -536,7 +538,7 @@ class VlsiLayout:
|
|||
#remap coordinates
|
||||
shiftedBoundaryCoordinates = []
|
||||
for shapeCoordinate in path.equivalentBoundaryCoordinates(rotateAngle):
|
||||
shiftedBoundaryCoordinates+=[(shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1])]
|
||||
shiftedBoundaryCoordinates.append((shapeCoordinate[0]+coordinates[0],shapeCoordinate[1]+coordinates[1]))
|
||||
joint = self.doShapesIntersect(self.tempCoordinates, shiftedBoundaryCoordinates)
|
||||
if joint:
|
||||
self.tempPassFail = False
|
||||
|
|
@ -559,7 +561,7 @@ class VlsiLayout:
|
|||
self.traverseTheHierarchy(delegateFunction = isThisBlockOk)
|
||||
#if its bad, this global tempPassFail will be false
|
||||
#if true, we can add the block
|
||||
passFailRecord+=[self.tempPassFail]
|
||||
passFailRecord.append(self.tempPassFail)
|
||||
print("Percent Complete:"+str(percentDone))
|
||||
|
||||
|
||||
|
|
@ -570,7 +572,7 @@ class VlsiLayout:
|
|||
blockY = (yIndex*effectiveBlock)+offsetInMicrons[1]
|
||||
if passFailRecord[passFailIndex]:
|
||||
self.addBox(layerToFill, (blockX,blockY), width=blockSize, height=blockSize)
|
||||
passFailIndex+=1
|
||||
passFailIndex += 1
|
||||
print("Done\n\n")
|
||||
|
||||
def getLayoutBorder(self,borderlayer):
|
||||
|
|
@ -606,19 +608,15 @@ class VlsiLayout:
|
|||
return [[self.units[0]*cellBoundary[0],self.units[0]*cellBoundary[1]],
|
||||
[self.units[0]*cellBoundary[2],self.units[0]*cellBoundary[3]]]
|
||||
|
||||
def measureSizeInStructure(self,Structure,cellBoundary):
|
||||
StructureName=Structure[0]
|
||||
StructureOrigin=[Structure[1][0],Structure[1][1]]
|
||||
StructureuVector=[Structure[2][0],Structure[2][1],Structure[2][2]]
|
||||
StructurevVector=[Structure[3][0],Structure[3][1],Structure[3][2]]
|
||||
|
||||
for boundary in self.structures[str(StructureName)].boundaries:
|
||||
def measureSizeInStructure(self,structure,cellBoundary):
|
||||
(structureName,structureOrigin,structureuVector,structurevVector)=structure
|
||||
for boundary in self.structures[str(structureName)].boundaries:
|
||||
left_bottom=boundary.coordinates[0]
|
||||
right_top=boundary.coordinates[2]
|
||||
thisBoundary=[left_bottom[0],left_bottom[1],right_top[0],right_top[1]]
|
||||
thisBoundary=self.transformRectangle(thisBoundary,StructureuVector,StructurevVector)
|
||||
thisBoundary=[thisBoundary[0]+StructureOrigin[0],thisBoundary[1]+StructureOrigin[1],
|
||||
thisBoundary[2]+StructureOrigin[0],thisBoundary[3]+StructureOrigin[1]]
|
||||
thisBoundary=self.transformRectangle(thisBoundary,structureuVector,structurevVector)
|
||||
thisBoundary=[thisBoundary[0]+structureOrigin[0],thisBoundary[1]+structureOrigin[1],
|
||||
thisBoundary[2]+structureOrigin[0],thisBoundary[3]+structureOrigin[1]]
|
||||
cellBoundary=self.updateBoundary(thisBoundary,cellBoundary)
|
||||
return cellBoundary
|
||||
|
||||
|
|
@ -755,9 +753,8 @@ class VlsiLayout:
|
|||
Return all pin shapes.
|
||||
"""
|
||||
boundaries = []
|
||||
|
||||
for TreeUnit in self.xyTree:
|
||||
boundaries += self.getPinInStructure(coordinates,layer,TreeUnit)
|
||||
boundaries.extend(self.getPinInStructure(coordinates,layer,TreeUnit))
|
||||
|
||||
return boundaries
|
||||
|
||||
|
|
@ -768,14 +765,8 @@ class VlsiLayout:
|
|||
that the label coordinates are inside.
|
||||
"""
|
||||
|
||||
# check if this is a rectangle
|
||||
structureName=structure[0]
|
||||
structureOrigin=[structure[1][0],structure[1][1]]
|
||||
structureuVector=[structure[2][0],structure[2][1],structure[2][2]]
|
||||
structurevVector=[structure[3][0],structure[3][1],structure[3][2]]
|
||||
|
||||
(structureName,structureOrigin,structureuVector,structurevVector)=structure
|
||||
boundaries = []
|
||||
|
||||
for boundary in self.structures[str(structureName)].boundaries:
|
||||
# Pin enclosures only work on rectangular pins so ignore any non rectangle
|
||||
# This may report not finding pins, but the user should fix this by adding a rectangle.
|
||||
|
|
@ -789,7 +780,7 @@ class VlsiLayout:
|
|||
boundaryRect=self.transformRectangle(boundaryRect,structureuVector,structurevVector)
|
||||
boundaryRect=[boundaryRect[0]+structureOrigin[0].item(),boundaryRect[1]+structureOrigin[1].item(),
|
||||
boundaryRect[2]+structureOrigin[0].item(),boundaryRect[3]+structureOrigin[1].item()]
|
||||
|
||||
|
||||
if self.labelInRectangle(coordinates,boundaryRect):
|
||||
boundaries.append(boundaryRect)
|
||||
|
||||
|
|
@ -803,7 +794,7 @@ class VlsiLayout:
|
|||
boundaries = []
|
||||
for TreeUnit in self.xyTree:
|
||||
#print(TreeUnit[0])
|
||||
boundaries += self.getShapesInStructure(layer,TreeUnit)
|
||||
boundaries.extend(self.getShapesInStructure(layer,TreeUnit))
|
||||
|
||||
# Remove duplicates without defining a hash
|
||||
# (could be sped up by creating hash and using list(set())
|
||||
|
|
@ -826,14 +817,8 @@ class VlsiLayout:
|
|||
Go through all the shapes in a structure and return the list of shapes.
|
||||
"""
|
||||
|
||||
# check if this is a rectangle
|
||||
structureName=structure[0]
|
||||
structureOrigin=[structure[1][0],structure[1][1]]
|
||||
structureuVector=[structure[2][0],structure[2][1],structure[2][2]]
|
||||
structurevVector=[structure[3][0],structure[3][1],structure[3][2]]
|
||||
|
||||
(structureName,structureOrigin,structureuVector,structurevVector)=structure
|
||||
boundaries = []
|
||||
|
||||
for boundary in self.structures[str(structureName)].boundaries:
|
||||
# Pin enclosures only work on rectangular pins so ignore any non rectangle
|
||||
# This may report not finding pins, but the user should fix this by adding a rectangle.
|
||||
|
|
|
|||
|
|
@ -15,12 +15,21 @@ class router:
|
|||
It populates blockages on a grid class.
|
||||
"""
|
||||
|
||||
def __init__(self, gds_name):
|
||||
"""Use the gds file for the blockages with the top module topName and
|
||||
def __init__(self, gds_name=None, module=None):
|
||||
"""Use the gds file or the cell for the blockages with the top module topName and
|
||||
layers for the layers to route on
|
||||
"""
|
||||
# Load the gds file and read in all the shapes
|
||||
self.gds_name = gds_name
|
||||
self.module = module
|
||||
debug.check(not (gds_name and module), "Specify only a GDS file or module")
|
||||
|
||||
# If we specified a module instead, write it out to read the gds
|
||||
# This isn't efficient, but easy for now
|
||||
if module:
|
||||
gds_name = OPTS.openram_temp+"temp.gds"
|
||||
module.gds_write(gds_name)
|
||||
|
||||
# Load the gds file and read in all the shapes
|
||||
self.layout = gdsMill.VlsiLayout(units=tech.GDS["unit"])
|
||||
self.reader = gdsMill.Gds2reader(self.layout)
|
||||
self.reader.loadFromFile(gds_name)
|
||||
|
|
@ -212,12 +221,14 @@ class router:
|
|||
"""
|
||||
|
||||
shapes = self.layout.getAllShapesInStructureList(layer_num)
|
||||
|
||||
|
||||
for boundary in shapes:
|
||||
rect = [vector(boundary[0],boundary[1]),vector(boundary[2],boundary[3])]
|
||||
new_pin = pin_layout("blockage",rect,layer_num)
|
||||
ll = vector(boundary[0],boundary[1])
|
||||
ur = vector(boundary[2],boundary[3])
|
||||
rect = [ll,ur]
|
||||
new_pin = pin_layout("blockage{}".format(len(self.blockages)),rect,layer_num)
|
||||
self.blockages.append(new_pin)
|
||||
|
||||
|
||||
|
||||
# for boundary in self.layout.structures[sref].boundaries:
|
||||
# coord_trans = self.translate_coordinates(boundary.coordinates, mirr, angle, xyShift)
|
||||
|
|
@ -470,7 +481,6 @@ class router:
|
|||
layer="text",
|
||||
offset=shape[0],
|
||||
zoom=0.05)
|
||||
|
||||
for blockage in self.blockages:
|
||||
self.cell.add_rect(layer="boundary",
|
||||
offset=blockage.ll(),
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ class signal_router(router):
|
|||
route on a given layer. This is limited to two layer routes.
|
||||
"""
|
||||
|
||||
def __init__(self, gds_name):
|
||||
def __init__(self, gds_name=None, module=None):
|
||||
"""Use the gds file for the blockages with the top module topName and
|
||||
layers for the layers to route on
|
||||
"""
|
||||
router.__init__(self, gds_name)
|
||||
router.__init__(self, gds_name, module)
|
||||
|
||||
# all the paths we've routed so far (to supplement the blockages)
|
||||
self.paths = []
|
||||
|
|
@ -43,6 +43,7 @@ class signal_router(router):
|
|||
the simplified rectilinear path. Cost factor is how sub-optimal to explore for a feasible route.
|
||||
This is used to speed up the routing when there is not much detouring needed.
|
||||
"""
|
||||
debug.info(1,"Running signal router from {0} to {1}...".format(src,dest))
|
||||
self.cell = cell
|
||||
self.source_pin_name = src
|
||||
self.target_pin_name = dest
|
||||
|
|
|
|||
|
|
@ -16,12 +16,11 @@ class supply_router(router):
|
|||
routes a grid to connect the supply on the two layers.
|
||||
"""
|
||||
|
||||
def __init__(self, gds_name):
|
||||
def __init__(self, gds_name=None, module=None):
|
||||
"""Use the gds file for the blockages with the top module topName and
|
||||
layers for the layers to route on
|
||||
"""
|
||||
|
||||
router.__init__(self, gds_name)
|
||||
router.__init__(self, gds_name, module)
|
||||
|
||||
self.pins = {}
|
||||
|
||||
|
|
@ -40,6 +39,7 @@ class supply_router(router):
|
|||
Route a single source-destination net and return
|
||||
the simplified rectilinear path.
|
||||
"""
|
||||
debug.info(1,"Running supply router on {0} and {1}...".format(vdd_name, gnd_name))
|
||||
self.cell = cell
|
||||
self.pins[vdd_name] = []
|
||||
self.pins[gnd_name] = []
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
import unittest
|
||||
from testutils import header,openram_test
|
||||
import sys,os
|
||||
sys.path.append(os.path.join(sys.path[0],"../.."))
|
||||
sys.path.append(os.path.join(sys.path[0],".."))
|
||||
import globals
|
||||
import debug
|
||||
|
|
@ -30,14 +29,17 @@ class no_blockages_test(openram_test):
|
|||
design.__init__(self, "top")
|
||||
|
||||
# Instantiate a GDS cell with the design
|
||||
gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),name)
|
||||
cell = gds_cell(name, gds_file)
|
||||
globals.setup_paths()
|
||||
from control_logic import control_logic
|
||||
cell = control_logic(16)
|
||||
#gds_file = "{0}/{1}.gds".format(os.path.dirname(os.path.realpath(__file__)),"control_logic")
|
||||
#cell = gds_cell(name, gds_file)
|
||||
self.add_inst(name=name,
|
||||
mod=cell,
|
||||
offset=[0,0])
|
||||
self.connect_inst([])
|
||||
self.connect_inst(["csb","web","clk","s_en","w_en","clk_buf_bar","clk_buf","vdd","gnd"])
|
||||
|
||||
r=router(gds_file)
|
||||
r=router(module=cell)
|
||||
layer_stack =("metal3","via2","metal2")
|
||||
self.assertTrue(r.route(self,layer_stack))
|
||||
|
||||
|
|
|
|||
|
|
@ -3,21 +3,8 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "freepdk45"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [1.0]
|
||||
temperatures = [25]
|
||||
|
||||
|
||||
decoder = "hierarchical_decoder"
|
||||
ms_flop = "ms_flop"
|
||||
ms_flop_array = "ms_flop_array"
|
||||
control_logic = "control_logic"
|
||||
bitcell_array = "bitcell_array"
|
||||
sense_amp = "sense_amp"
|
||||
sense_amp_array = "sense_amp_array"
|
||||
precharge_array = "precharge_array"
|
||||
column_mux_array = "single_level_column_mux_array"
|
||||
write_driver = "write_driver"
|
||||
write_driver_array = "write_driver_array"
|
||||
tri_gate = "tri_gate"
|
||||
tri_gate_array = "tri_gate_array"
|
||||
wordline_driver = "wordline_driver"
|
||||
replica_bitcell = "replica_bitcell"
|
||||
bitcell = "bitcell"
|
||||
delay_chain = "logic_effort_dc"
|
||||
|
|
|
|||
|
|
@ -3,21 +3,7 @@ num_words = 16
|
|||
num_banks = 1
|
||||
|
||||
tech_name = "scn3me_subm"
|
||||
process_corners = ["TT"]
|
||||
supply_voltages = [5.0]
|
||||
temperatures = [25]
|
||||
|
||||
decoder = "hierarchical_decoder"
|
||||
ms_flop = "ms_flop"
|
||||
ms_flop_array = "ms_flop_array"
|
||||
control_logic = "control_logic"
|
||||
bitcell_array = "bitcell_array"
|
||||
sense_amp = "sense_amp"
|
||||
sense_amp_array = "sense_amp_array"
|
||||
precharge_array = "precharge_array"
|
||||
column_mux_array = "single_level_column_mux_array"
|
||||
write_driver = "write_driver"
|
||||
write_driver_array = "write_driver_array"
|
||||
tri_gate = "tri_gate"
|
||||
tri_gate_array = "tri_gate_array"
|
||||
wordline_driver = "wordline_driver"
|
||||
replica_bitcell = "replica_bitcell"
|
||||
bitcell = "bitcell"
|
||||
delay_chain = "logic_effort_dc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue