Cleanup after SVN importation, <ccb> builder script adaptation.
Project hierarchy reorganisation: * With svn, we were doing a tool by tool checkout, suppressing the whole repository hierarchy level. * The tools were also grouped, inside one repository, into multiple projects (<bootstrap>, <vlsisapd>, <coriolis>). * We do not want to split up each tool into a separate repository, given their tight integration (except for vlsisapd). * We choose to simplify, and consider all tools in a svn repository one project. Due to the way Git clone repositories, the directory containing the project is now to be seen under "src/". CMake modifications: * Now that the <vlsisapd> and <bootstrap> projects are merged into coriolis, modificate the top CMakeLists.txt of each tool to uses only Coriolis (and bootstrap hard wired). CCB compile script modifications: * Uses the new source tree hierarchy, with the project directory inserted. * Remove (comment) all parts relateds to svn managment. * Git is sufficiently simple so that we do not want to integrate command shortcut into the script. SVN cleanup: * Remove the obsolete <chamsin> tool, that has become the full fledged <chams> project long time ago.
|
@ -0,0 +1,11 @@
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
*.pyc
|
||||||
|
*.log
|
||||||
|
man/
|
||||||
|
rtf/
|
||||||
|
html/
|
||||||
|
latex/
|
||||||
|
|
||||||
|
crlcore/doc/UsersGuide/UsersGuide.tex
|
||||||
|
crlcore/doc/UsersGuide/UsersGuide.html
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- mode: CMAKE explicit-buffer-name: "CMakeLists.txt<bootstrap>" -*-
|
||||||
|
|
||||||
project(Bootstrap)
|
project(Bootstrap)
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,14 @@
|
||||||
|
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
# This file is *not* a Python module but will be executed
|
# This file is *not* a Python module but will be executed
|
||||||
# inside a Python function.
|
# inside a Python function.
|
||||||
|
|
||||||
|
|
||||||
svnconfig = { 'method':'svn+ssh://bip.soc.lip6.fr' }
|
|
||||||
|
|
||||||
projectdir = 'coriolis-2.x'
|
projectdir = 'coriolis-2.x'
|
||||||
|
|
||||||
projects = [ { 'name' : 'bootstrap'
|
projects = [ { 'name' : "coriolis"
|
||||||
, 'tools' : [ 'bootstrap' ]
|
, 'tools' : [ "bootstrap"
|
||||||
, 'repository': '/users/outil/coriolis/svn' }
|
, "vlsisapd"
|
||||||
|
, "hurricane"
|
||||||
, { 'name' : 'vlsisapd'
|
|
||||||
, 'tools' : [ 'vlsisapd' ]
|
|
||||||
, 'repository': '/users/outil/coriolis/svn' }
|
|
||||||
|
|
||||||
, { 'name' : "coriolis"
|
|
||||||
, 'tools' : [ "hurricane"
|
|
||||||
, "crlcore"
|
, "crlcore"
|
||||||
, "nimbus"
|
, "nimbus"
|
||||||
, "metis"
|
, "metis"
|
||||||
|
@ -33,27 +24,21 @@ projects = [ { 'name' : 'bootstrap'
|
||||||
, "cumulus"
|
, "cumulus"
|
||||||
, "stratus1"
|
, "stratus1"
|
||||||
]
|
]
|
||||||
, 'repository': "/users/outil/coriolis/svn" }
|
, 'repository': 'ssh://asim-t/users/largo2/git/coriolis.git' }
|
||||||
|
|
||||||
, { 'name' : "coriolis-redev"
|
#, { 'name' : "chams"
|
||||||
, 'tools' : [ "katabatic3"
|
# , 'tools' : [ "hurricaneAMS"
|
||||||
, "kite3"
|
# , "amsCore"
|
||||||
]
|
# , "opSim"
|
||||||
, 'repository': "/users/outil/coriolis/svn" }
|
# , "scribe"
|
||||||
|
# , "graph"
|
||||||
, { 'name' : "chams"
|
# , "pharos"
|
||||||
, 'tools' : [ "hurricaneAMS"
|
# , "isis"
|
||||||
, "amsCore"
|
# , "schematic"
|
||||||
, "opSim"
|
# , "solver"
|
||||||
, "scribe"
|
# , "autoDTR"
|
||||||
, "graph"
|
# ]
|
||||||
, "pharos"
|
# , 'repository':"/users/outil/chams/svn" }
|
||||||
, "isis"
|
|
||||||
, "schematic"
|
|
||||||
, "solver"
|
|
||||||
, "autoDTR"
|
|
||||||
]
|
|
||||||
, 'repository':"/users/outil/chams/svn" }
|
|
||||||
]
|
]
|
||||||
|
|
||||||
package = { 'name' : 'coriolis2'
|
package = { 'name' : 'coriolis2'
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -75,23 +75,24 @@ class Builder:
|
||||||
return self.__dict__[attribute]
|
return self.__dict__[attribute]
|
||||||
|
|
||||||
|
|
||||||
def _guessSvnTag ( self, project ):
|
#def _guessGitHash ( self, project ):
|
||||||
revisionPattern = re.compile ( r"^Revision:\s*(?P<revision>\d+)" )
|
# revisionPattern = re.compile ( r"^Revision:\s*(?P<revision>\d+)" )
|
||||||
projectSvnDir = os.path.join ( self.svnMethod+project.getRepository() )
|
# projectSvnDir = os.path.join ( self.svnMethod+project.getRepository() )
|
||||||
|
#
|
||||||
command = [ "svn", "info", projectSvnDir ]
|
# os.chdir( )
|
||||||
svnInfo = subprocess.Popen ( command, stdout=subprocess.PIPE )
|
# command = [ 'git', 'log', '--pretty="%h"', '-n', '1']
|
||||||
|
# svnInfo = subprocess.Popen ( command, stdout=subprocess.PIPE )
|
||||||
for line in svnInfo.stdout.readlines():
|
#
|
||||||
m = revisionPattern.match ( line )
|
# for line in svnInfo.stdout.readlines():
|
||||||
if m:
|
# m = revisionPattern.match ( line )
|
||||||
self.svnTag = m.group("revision")
|
# if m:
|
||||||
print "Latest revision of project %s is %s." % (project.getName(),self.svnTag)
|
# self.gitHash = m.group("revision")
|
||||||
return
|
# print "Latest revision of project %s is %s." % (project.getName(),self.gitHash)
|
||||||
|
# return
|
||||||
print "[WARNING] Cannot guess revision for project \"%s\"." % project.getName()
|
#
|
||||||
print " (using: \"x\")"
|
# print "[WARNING] Cannot guess revision for project \"%s\"." % project.getName()
|
||||||
return
|
# print " (using: \"x\")"
|
||||||
|
# return
|
||||||
|
|
||||||
|
|
||||||
def _configure ( self, fileIn, file ):
|
def _configure ( self, fileIn, file ):
|
||||||
|
@ -103,7 +104,7 @@ class Builder:
|
||||||
substituted0 = line
|
substituted0 = line
|
||||||
|
|
||||||
while not stable:
|
while not stable:
|
||||||
substituted1 = re.sub ( r"@svntag@" , self.svnTag, substituted0 )
|
substituted1 = re.sub ( r"@svntag@" , self.gitHash, substituted0 )
|
||||||
substituted1 = re.sub ( r"@coriolisTop@", "/opt/coriolis2" , substituted1 )
|
substituted1 = re.sub ( r"@coriolisTop@", "/opt/coriolis2" , substituted1 )
|
||||||
if substituted0 == substituted1: stable = True
|
if substituted0 == substituted1: stable = True
|
||||||
else: substituted0 = substituted1
|
else: substituted0 = substituted1
|
||||||
|
@ -141,8 +142,8 @@ class Builder:
|
||||||
|
|
||||||
|
|
||||||
def _build ( self, tool ):
|
def _build ( self, tool ):
|
||||||
toolSourceDir = os.path.join ( self.sourceDir, tool )
|
toolSourceDir = os.path.join ( self.sourceDir, tool.getToolDir() )
|
||||||
toolBuildDir = os.path.join ( self.buildDir , tool )
|
toolBuildDir = os.path.join ( self.buildDir , tool.name )
|
||||||
# Supplied directly in the CMakeLists.txt.
|
# Supplied directly in the CMakeLists.txt.
|
||||||
#cmakeModules = os.path.join ( self.installDir, "share", "cmake", "Modules" )
|
#cmakeModules = os.path.join ( self.installDir, "share", "cmake", "Modules" )
|
||||||
|
|
||||||
|
@ -188,8 +189,8 @@ class Builder:
|
||||||
command = [ "make" ]
|
command = [ "make" ]
|
||||||
#command += [ "DESTDIR=%s" % self.installDir ]
|
#command += [ "DESTDIR=%s" % self.installDir ]
|
||||||
if self._enableDoc == "ON":
|
if self._enableDoc == "ON":
|
||||||
#if tool == "crlcore" or tool == "stratus1":
|
#if tool.name == "crlcore" or tool.name == "stratus1":
|
||||||
if tool == "stratus1":
|
if tool.name == "stratus1":
|
||||||
command += [ "dvi", "safepdf", "html" ]
|
command += [ "dvi", "safepdf", "html" ]
|
||||||
command += self._makeArguments
|
command += self._makeArguments
|
||||||
print "Make command:", command
|
print "Make command:", command
|
||||||
|
@ -198,108 +199,108 @@ class Builder:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def _svnStatus ( self, tool ):
|
#def _svnStatus ( self, tool ):
|
||||||
toolSourceDir = os.path.join ( self.sourceDir , tool )
|
# toolSourceDir = os.path.join ( self.sourceDir , tool )
|
||||||
if not os.path.isdir(toolSourceDir):
|
# if not os.path.isdir(toolSourceDir):
|
||||||
if not self._quiet:
|
# if not self._quiet:
|
||||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
# print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||||
return
|
# return
|
||||||
os.chdir ( toolSourceDir )
|
# os.chdir ( toolSourceDir )
|
||||||
|
#
|
||||||
print "Checking SVN status of tool: ", tool
|
# print "Checking SVN status of tool: ", tool
|
||||||
command = [ "svn", "status", "-u", "-q" ]
|
# command = [ "svn", "status", "-u", "-q" ]
|
||||||
self._execute ( command, "svn status -u -q" )
|
# self._execute ( command, "svn status -u -q" )
|
||||||
print
|
# print
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def _svnDiff ( self, tool ):
|
#def _svnDiff ( self, tool ):
|
||||||
toolSourceDir = os.path.join ( self.sourceDir , tool )
|
# toolSourceDir = os.path.join ( self.sourceDir , tool )
|
||||||
if not os.path.isdir(toolSourceDir):
|
# if not os.path.isdir(toolSourceDir):
|
||||||
if not self._quiet:
|
# if not self._quiet:
|
||||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
# print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||||
return
|
# return
|
||||||
os.chdir ( toolSourceDir )
|
# os.chdir ( toolSourceDir )
|
||||||
|
#
|
||||||
print "Doing a SVN diff of tool: ", tool
|
# print "Doing a SVN diff of tool: ", tool
|
||||||
command = [ "svn", "diff" ]
|
# command = [ "svn", "diff" ]
|
||||||
if self.svnTag != "x":
|
# if self.gitHash != "x":
|
||||||
command += [ "--revision", self.svnTag ]
|
# command += [ "--revision", self.gitHash ]
|
||||||
self._execute ( command, "svn diff %s" % tool )
|
# self._execute ( command, "svn diff %s" % tool )
|
||||||
print
|
# print
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def _svnUpdate ( self, tool ):
|
#def _svnUpdate ( self, tool ):
|
||||||
toolSourceDir = os.path.join ( self.sourceDir , tool )
|
# toolSourceDir = os.path.join ( self.sourceDir , tool )
|
||||||
if not os.path.isdir(toolSourceDir):
|
# if not os.path.isdir(toolSourceDir):
|
||||||
if not self._quiet:
|
# if not self._quiet:
|
||||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir)
|
# print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir)
|
||||||
return
|
# return
|
||||||
os.chdir ( toolSourceDir )
|
# os.chdir ( toolSourceDir )
|
||||||
|
#
|
||||||
print "Doing a SVN update of tool: ", tool
|
# print "Doing a SVN update of tool: ", tool
|
||||||
command = [ "svn", "update" ]
|
# command = [ "svn", "update" ]
|
||||||
self._execute ( command, "svn update" )
|
# self._execute ( command, "svn update" )
|
||||||
print
|
# print
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def _svnCheckout ( self, tool ):
|
#def _svnCheckout ( self, tool ):
|
||||||
project = self._conf.getToolProject ( tool )
|
# project = self._conf.getToolProject ( tool )
|
||||||
if not project:
|
# if not project:
|
||||||
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
# print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
||||||
,"Cannot guess the SVN repository." )
|
# ,"Cannot guess the SVN repository." )
|
||||||
return
|
# return
|
||||||
if not project.getRepository ():
|
# if not project.getRepository ():
|
||||||
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
# print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
if not os.path.isdir(self.sourceDir):
|
# if not os.path.isdir(self.sourceDir):
|
||||||
print ErrorMessage( 0, "Source directory <%s> doesn't exists. Creating."%self.sourceDir )
|
# print ErrorMessage( 0, "Source directory <%s> doesn't exists. Creating."%self.sourceDir )
|
||||||
os.makedirs( self.sourceDir )
|
# os.makedirs( self.sourceDir )
|
||||||
|
#
|
||||||
toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
|
# toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
|
||||||
os.chdir ( self.sourceDir )
|
# os.chdir ( self.sourceDir )
|
||||||
|
#
|
||||||
print "Doing a SVN checkout of tool: ", tool
|
# print "Doing a SVN checkout of tool: ", tool
|
||||||
command = [ "svn", "co", toolSvnTrunkDir, tool ]
|
# command = [ "svn", "co", toolSvnTrunkDir, tool ]
|
||||||
if self.svnTag != "x":
|
# if self.gitHash != "x":
|
||||||
command += [ "--revision", self.svnTag ]
|
# command += [ "--revision", self.gitHash ]
|
||||||
self._execute ( command, "svn checkout %s" % tool )
|
# self._execute ( command, "svn checkout %s" % tool )
|
||||||
print
|
# print
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def _svnExport ( self, tool ):
|
#def _svnExport ( self, tool ):
|
||||||
project = self._conf.getToolProject ( tool )
|
# project = self._conf.getToolProject ( tool )
|
||||||
if not project:
|
# if not project:
|
||||||
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
# print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
|
||||||
, "Cannot guess the SVN repository.")
|
# , "Cannot guess the SVN repository.")
|
||||||
return
|
# return
|
||||||
if not project.getRepository ():
|
# if not project.getRepository ():
|
||||||
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
# print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
|
# toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
|
||||||
|
#
|
||||||
if not os.path.isdir ( self.archiveDir ):
|
# if not os.path.isdir ( self.archiveDir ):
|
||||||
os.mkdir ( self.archiveDir )
|
# os.mkdir ( self.archiveDir )
|
||||||
os.chdir ( self.archiveDir )
|
# os.chdir ( self.archiveDir )
|
||||||
|
#
|
||||||
toolExportDir = os.path.join ( self.archiveDir, tool )
|
# toolExportDir = os.path.join ( self.archiveDir, tool )
|
||||||
if os.path.isdir ( toolExportDir ):
|
# if os.path.isdir ( toolExportDir ):
|
||||||
print "Removing tool export (tarball) directory: \"%s\"." % toolExportDir
|
# print "Removing tool export (tarball) directory: \"%s\"." % toolExportDir
|
||||||
command = [ "/bin/rm", "-r", toolExportDir ]
|
# command = [ "/bin/rm", "-r", toolExportDir ]
|
||||||
self._execute ( command, "Removing tool export (tarball) directory" )
|
# self._execute ( command, "Removing tool export (tarball) directory" )
|
||||||
|
#
|
||||||
print "Doing a SVN export of tool: ", tool
|
# print "Doing a SVN export of tool: ", tool
|
||||||
command = [ "svn", "export", toolSvnTrunkDir, toolExportDir ]
|
# command = [ "svn", "export", toolSvnTrunkDir, toolExportDir ]
|
||||||
if self.svnTag != "x":
|
# if self.gitHash != "x":
|
||||||
command += [ "--revision", self.svnTag ]
|
# command += [ "--revision", self.gitHash ]
|
||||||
self._execute ( command, "svn export %s" % toolExportDir )
|
# self._execute ( command, "svn export %s" % toolExportDir )
|
||||||
print
|
# print
|
||||||
return
|
# return
|
||||||
|
|
||||||
|
|
||||||
def _setEnvironment ( self, systemVariable, userVariable ):
|
def _setEnvironment ( self, systemVariable, userVariable ):
|
||||||
|
@ -347,11 +348,7 @@ class Builder:
|
||||||
|
|
||||||
for project in self.projects:
|
for project in self.projects:
|
||||||
for tool in project.getActives():
|
for tool in project.getActives():
|
||||||
print "\nProcessing tool: \"%s\"." % tool
|
print "\nProcessing tool: \"%s\"." % tool.name
|
||||||
getattr(self,command) ( tool )
|
|
||||||
|
|
||||||
for tool in self.standalones:
|
|
||||||
print "\nProcessing tool: \"%s\"." % tool
|
|
||||||
getattr(self,command) ( tool )
|
getattr(self,command) ( tool )
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -373,81 +370,81 @@ class Builder:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def svnStatus ( self, tools, projects ):
|
#def svnStatus ( self, tools, projects ):
|
||||||
self._commandTemplate ( tools, projects, "_svnStatus" )
|
# self._commandTemplate ( tools, projects, "_svnStatus" )
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def svnUpdate ( self, tools, projects ):
|
#def svnUpdate ( self, tools, projects ):
|
||||||
self._commandTemplate ( tools, projects, "_svnUpdate" )
|
# self._commandTemplate ( tools, projects, "_svnUpdate" )
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def svnCheckout ( self, tools, projects ):
|
#def svnCheckout ( self, tools, projects ):
|
||||||
self._commandTemplate ( tools, projects, "_svnCheckout" )
|
# self._commandTemplate ( tools, projects, "_svnCheckout" )
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def svnDiff ( self, tools, projects ):
|
#def svnDiff ( self, tools, projects ):
|
||||||
self._commandTemplate ( tools, projects, "_svnDiff" )
|
# self._commandTemplate ( tools, projects, "_svnDiff" )
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def svnExport ( self, tools, projects ):
|
#def svnExport ( self, tools, projects ):
|
||||||
self._commandTemplate ( tools, projects, "_svnExport" )
|
# self._commandTemplate ( tools, projects, "_svnExport" )
|
||||||
return
|
# return
|
||||||
|
#
|
||||||
|
#
|
||||||
def svnTarball ( self, tools, projects ):
|
#def svnTarball ( self, tools, projects ):
|
||||||
if self.svnTag == "x":
|
# if self.gitHash == "x":
|
||||||
self._guessSvnTag ( self.getProject(projects[0]) )
|
# self._guessGitHash ( self.getProject(projects[0]) )
|
||||||
|
#
|
||||||
self._doSpec ()
|
# self._doSpec ()
|
||||||
self._doDebChangelog ()
|
# self._doDebChangelog ()
|
||||||
|
#
|
||||||
if os.path.isdir(self.tarballDir):
|
# if os.path.isdir(self.tarballDir):
|
||||||
print "Removing previous tarball directory: \"%s\"." % self.tarballDir
|
# print "Removing previous tarball directory: \"%s\"." % self.tarballDir
|
||||||
command = [ "/bin/rm", "-rf", self.tarballDir ]
|
# command = [ "/bin/rm", "-rf", self.tarballDir ]
|
||||||
self._execute ( command, "Removing top export (tarball) directory" )
|
# self._execute ( command, "Removing top export (tarball) directory" )
|
||||||
|
#
|
||||||
print "Creating tarball directory: \"%s\"." % self.tarballDir
|
# print "Creating tarball directory: \"%s\"." % self.tarballDir
|
||||||
os.makedirs ( self.tarballDir )
|
# os.makedirs ( self.tarballDir )
|
||||||
self.svnExport ( tools, projects )
|
# self.svnExport ( tools, projects )
|
||||||
|
#
|
||||||
# Remove unpublisheds (yet) tools/files.
|
# # Remove unpublisheds (yet) tools/files.
|
||||||
for item in self.packageExcludes:
|
# for item in self.packageExcludes:
|
||||||
command = [ "/bin/rm", "-rf", os.path.join(self.archiveDir,item) ]
|
# command = [ "/bin/rm", "-rf", os.path.join(self.archiveDir,item) ]
|
||||||
self._execute ( command, "rm of %s failed" % item)
|
# self._execute ( command, "rm of %s failed" % item)
|
||||||
|
#
|
||||||
# Adds files neededs only for packaging purpose.
|
# # Adds files neededs only for packaging purpose.
|
||||||
command = [ "/bin/cp", "-r", os.path.join(self.sourceDir ,"bootstrap","Makefile.package")
|
# command = [ "/bin/cp", "-r", os.path.join(self.sourceDir ,"bootstrap","Makefile.package")
|
||||||
, os.path.join(self.archiveDir,"Makefile") ]
|
# , os.path.join(self.archiveDir,"Makefile") ]
|
||||||
self._execute ( command, "copy of %s failed" % "boostrap/Makefile.package")
|
# self._execute ( command, "copy of %s failed" % "boostrap/Makefile.package")
|
||||||
|
#
|
||||||
command = [ "/bin/cp", self.specFile, self.archiveDir ]
|
# command = [ "/bin/cp", self.specFile, self.archiveDir ]
|
||||||
self._execute ( command, "Copying RPM spec file" )
|
# self._execute ( command, "Copying RPM spec file" )
|
||||||
|
#
|
||||||
command = [ "/bin/cp", "-r", self.debianDir, self.archiveDir ]
|
# command = [ "/bin/cp", "-r", self.debianDir, self.archiveDir ]
|
||||||
self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
# self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
||||||
|
#
|
||||||
os.chdir ( self.archiveDir )
|
# os.chdir ( self.archiveDir )
|
||||||
#command = [ "/usr/bin/patch", "--remove-empty-files"
|
# #command = [ "/usr/bin/patch", "--remove-empty-files"
|
||||||
# , "--no-backup-if-mismatch"
|
# # , "--no-backup-if-mismatch"
|
||||||
# , "-p0", "-i", self.distribPatch ]
|
# # , "-p0", "-i", self.distribPatch ]
|
||||||
#self._execute ( command, "patch for distribution command failed" )
|
# #self._execute ( command, "patch for distribution command failed" )
|
||||||
|
#
|
||||||
os.chdir ( self.tarballDir )
|
# os.chdir ( self.tarballDir )
|
||||||
command = [ "/bin/tar"
|
# command = [ "/bin/tar"
|
||||||
, "--exclude-backups"
|
# , "--exclude-backups"
|
||||||
, "--exclude-vcs"
|
# , "--exclude-vcs"
|
||||||
, "-jcvf", self.sourceTarBz2, os.path.basename(self.archiveDir) ]
|
# , "-jcvf", self.sourceTarBz2, os.path.basename(self.archiveDir) ]
|
||||||
self._execute ( command, "tar command failed" )
|
# self._execute ( command, "tar command failed" )
|
||||||
|
#
|
||||||
print "Cleanup SVN export tarball archive directory: \"%s\"." % self.archiveDir
|
# print "Cleanup SVN export tarball archive directory: \"%s\"." % self.archiveDir
|
||||||
command = [ "/bin/rm", "-rf", self.archiveDir ]
|
# command = [ "/bin/rm", "-rf", self.archiveDir ]
|
||||||
self._execute ( command, "Removing archive export (tarball) directory" )
|
# self._execute ( command, "Removing archive export (tarball) directory" )
|
||||||
|
#
|
||||||
return
|
# return
|
||||||
|
|
||||||
|
|
||||||
def userTarball ( self, tools, projects ):
|
def userTarball ( self, tools, projects ):
|
||||||
|
@ -516,7 +513,7 @@ class Builder:
|
||||||
|
|
||||||
os.chdir ( self.debbuildDir )
|
os.chdir ( self.debbuildDir )
|
||||||
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
|
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
|
||||||
debOrigFile = os.path.join ( self.debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self.svnTag )
|
debOrigFile = os.path.join ( self.debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self.gitHash )
|
||||||
if not os.path.islink(debOrigFile):
|
if not os.path.islink(debOrigFile):
|
||||||
os.link ( sourceFile, debOrigFile )
|
os.link ( sourceFile, debOrigFile )
|
||||||
|
|
||||||
|
@ -526,7 +523,7 @@ class Builder:
|
||||||
#command = [ "/bin/cp", "-r", self.debianDir, "." ]
|
#command = [ "/bin/cp", "-r", self.debianDir, "." ]
|
||||||
#self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
#self._execute ( command, "Copying Debian/Ubuntu package control files" )
|
||||||
|
|
||||||
packageDir = os.path.join ( self.debbuildDir, "coriolis2-1.0.%s" % self.svnTag )
|
packageDir = os.path.join ( self.debbuildDir, "coriolis2-1.0.%s" % self.gitHash )
|
||||||
os.chdir ( packageDir )
|
os.chdir ( packageDir )
|
||||||
|
|
||||||
self._environment["CFLAGS" ] = "-O2"
|
self._environment["CFLAGS" ] = "-O2"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -131,7 +131,7 @@ class CompileWidget ( QWidget ):
|
||||||
|
|
||||||
|
|
||||||
def shellCommand ( self ):
|
def shellCommand ( self ):
|
||||||
command = [ 'buildCoriolis.py' ]
|
command = [ self.conf.bootstrapDir+'/ccb.py' ]
|
||||||
for project in self.options.projects:
|
for project in self.options.projects:
|
||||||
for tool in project.actives:
|
for tool in project.actives:
|
||||||
command += [ '--tool='+tool ]
|
command += [ '--tool='+tool ]
|
||||||
|
@ -139,8 +139,8 @@ class CompileWidget ( QWidget ):
|
||||||
|
|
||||||
if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
|
if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
|
||||||
|
|
||||||
if self.options.svnUpdate: command += [ '--svn-update' ]
|
#if self.options.svnUpdate: command += [ '--svn-update' ]
|
||||||
if self.options.svnStatus: command += [ '--svn-update' ]
|
#if self.options.svnStatus: command += [ '--svn-update' ]
|
||||||
if self.options.enableDoc: command += [ '--doc' ]
|
if self.options.enableDoc: command += [ '--doc' ]
|
||||||
if self.options.noCache: command += [ '--no-cache' ]
|
if self.options.noCache: command += [ '--no-cache' ]
|
||||||
if self.options.rmBuild: command += [ '--rm-build' ]
|
if self.options.rmBuild: command += [ '--rm-build' ]
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -29,7 +29,7 @@ class Configuration ( object ):
|
||||||
|
|
||||||
PrimaryNames = \
|
PrimaryNames = \
|
||||||
[ 'confFile', 'projects', 'standalones'
|
[ 'confFile', 'projects', 'standalones'
|
||||||
, 'svnTag', 'svnMethod'
|
, 'gitHash', 'gitMethod'
|
||||||
, 'projectDir', 'rootDir'
|
, 'projectDir', 'rootDir'
|
||||||
, 'packageName', 'packageVersion', 'packageExcludes', 'packageProject'
|
, 'packageName', 'packageVersion', 'packageExcludes', 'packageProject'
|
||||||
, 'osType', 'libSuffix', 'buildMode', 'libMode', 'enableShared'
|
, 'osType', 'libSuffix', 'buildMode', 'libMode', 'enableShared'
|
||||||
|
@ -37,7 +37,7 @@ class Configuration ( object ):
|
||||||
SecondaryNames = \
|
SecondaryNames = \
|
||||||
[ 'rpmbuildDir' , 'debbuildDir' , 'tmppathDir' , 'tarballDir'
|
[ 'rpmbuildDir' , 'debbuildDir' , 'tmppathDir' , 'tarballDir'
|
||||||
, 'archiveDir' , 'sourceDir' , 'osDir' , 'buildDir'
|
, 'archiveDir' , 'sourceDir' , 'osDir' , 'buildDir'
|
||||||
, 'installDir' , 'specFileIn' , 'specFile'
|
, 'installDir' , 'bootstrapDir' , 'specFileIn' , 'specFile'
|
||||||
, 'debianDir' , 'debChangelogIn', 'debChangelog', 'sourceTarBz2'
|
, 'debianDir' , 'debChangelogIn', 'debChangelog', 'sourceTarBz2'
|
||||||
, 'binaryTarBz2', 'distribPatch'
|
, 'binaryTarBz2', 'distribPatch'
|
||||||
]
|
]
|
||||||
|
@ -46,8 +46,8 @@ class Configuration ( object ):
|
||||||
self._confFile = None
|
self._confFile = None
|
||||||
self._projects = []
|
self._projects = []
|
||||||
self._standalones = []
|
self._standalones = []
|
||||||
self._svnTag = "x"
|
self._gitHash = "x"
|
||||||
self._svnMethod = None
|
self._gitMethod = None
|
||||||
self._projectDir = 'coriolis-2.x'
|
self._projectDir = 'coriolis-2.x'
|
||||||
self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
|
self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
|
||||||
self._packageName = None
|
self._packageName = None
|
||||||
|
@ -99,21 +99,22 @@ class Configuration ( object ):
|
||||||
self._tarballDir = os.path.join ( self._rootDir , "tarball" )
|
self._tarballDir = os.path.join ( self._rootDir , "tarball" )
|
||||||
self._archiveDir = os.path.join ( self._tarballDir , "%s-%s.%s" % (self._packageName
|
self._archiveDir = os.path.join ( self._tarballDir , "%s-%s.%s" % (self._packageName
|
||||||
,self._packageVersion
|
,self._packageVersion
|
||||||
,self._svnTag) )
|
,self._gitHash) )
|
||||||
self._sourceDir = os.path.join ( self._rootDir , "src" )
|
self._sourceDir = os.path.join ( self._rootDir , "src" )
|
||||||
|
self._bootstrapDir = os.path.join ( self._sourceDir , "coriolis/bootstrap" )
|
||||||
self._osDir = os.path.join ( self._rootDir
|
self._osDir = os.path.join ( self._rootDir
|
||||||
, self._osType
|
, self._osType
|
||||||
, "%s.%s" % (self._buildMode,self._libMode) )
|
, "%s.%s" % (self._buildMode,self._libMode) )
|
||||||
self._buildDir = os.path.join ( self._osDir, "build" )
|
self._buildDir = os.path.join ( self._osDir, "build" )
|
||||||
self._installDir = os.path.join ( self._osDir, "install" )
|
self._installDir = os.path.join ( self._osDir, "install" )
|
||||||
|
|
||||||
self._specFileIn = os.path.join ( self._sourceDir, "bootstrap", "%s.spec.in"%self._packageName )
|
self._specFileIn = os.path.join ( self._bootstrapDir, "%s.spec.in"%self._packageName )
|
||||||
self._specFile = os.path.join ( self._sourceDir, "bootstrap", "%s.spec" %self._packageName )
|
self._specFile = os.path.join ( self._bootstrapDir, "%s.spec" %self._packageName )
|
||||||
self._debianDir = os.path.join ( self._sourceDir, "bootstrap", "debian" )
|
self._debianDir = os.path.join ( self._bootstrapDir, "debian" )
|
||||||
self._debChangelogIn = os.path.join ( self._debianDir , "changelog.in" )
|
self._debChangelogIn = os.path.join ( self._debianDir , "changelog.in" )
|
||||||
self._debChangelog = os.path.join ( self._debianDir , "changelog" )
|
self._debChangelog = os.path.join ( self._debianDir , "changelog" )
|
||||||
self._sourceTarBz2 = "%s-%s.%s.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
|
self._sourceTarBz2 = "%s-%s.%s.tar.bz2" % (self._packageName,self._packageVersion,self._gitHash)
|
||||||
self._binaryTarBz2 = "%s-binary-%s.%s-1.slsoc6.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
|
self._binaryTarBz2 = "%s-binary-%s.%s-1.slsoc6.tar.bz2" % (self._packageName,self._packageVersion,self._gitHash)
|
||||||
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
|
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -198,12 +199,12 @@ class Configuration ( object ):
|
||||||
if not confFile:
|
if not confFile:
|
||||||
print 'Making an educated guess to locate the configuration file:'
|
print 'Making an educated guess to locate the configuration file:'
|
||||||
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||||
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
|
, os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap'
|
||||||
, os.environ['HOME']+'/coriolis/src/bootstrap'
|
, os.environ['HOME']+'/coriolis/src/coriolis/bootstrap'
|
||||||
, os.environ['HOME']+'/chams-2.x/src/bootstrap'
|
, os.environ['HOME']+'/chams-2.x/src/coriolis/bootstrap'
|
||||||
, os.environ['HOME']+'/chams/src/bootstrap'
|
, os.environ['HOME']+'/chams/src/coriolis/bootstrap'
|
||||||
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
|
, '/users/outil/coriolis/coriolis-2.x/src/coriolis/bootstrap'
|
||||||
, self._rootDir+'/src/bootstrap'
|
, self._rootDir+'/src/coriolis/bootstrap'
|
||||||
]
|
]
|
||||||
|
|
||||||
for location in locations:
|
for location in locations:
|
||||||
|
@ -278,10 +279,10 @@ class Configuration ( object ):
|
||||||
|
|
||||||
def show ( self ):
|
def show ( self ):
|
||||||
print 'CCB Configuration:'
|
print 'CCB Configuration:'
|
||||||
if self._svnMethod:
|
if self._gitMethod:
|
||||||
print ' SVN Method: <%s>' % self._svnMethod
|
print ' Git Method: <%s>' % self._gitMethod
|
||||||
else:
|
else:
|
||||||
print ' SVN Method not defined, will not be able to checkout/commit.'
|
print ' Git Method not defined, will not be able to push/pull.'
|
||||||
|
|
||||||
for project in self._projects:
|
for project in self._projects:
|
||||||
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
|
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -165,11 +165,13 @@ class ConfigureWidget ( QWidget ):
|
||||||
gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
|
gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
|
||||||
|
|
||||||
|
|
||||||
def _getRootDir ( self ): return self._rootDir
|
|
||||||
def _getConf ( self ): return self._conf
|
def _getConf ( self ): return self._conf
|
||||||
|
def _getRootDir ( self ): return self._rootDir
|
||||||
|
def _getBootstrapDir ( self ): return self._getConf().bootstrapDir
|
||||||
|
|
||||||
rootDir = property( _getRootDir )
|
|
||||||
conf = property( _getConf )
|
conf = property( _getConf )
|
||||||
|
rootDir = property( _getRootDir )
|
||||||
|
bootstrapDir = property( _getBootstrapDir )
|
||||||
|
|
||||||
|
|
||||||
def rootDirChanged ( self, rootDir ):
|
def rootDirChanged ( self, rootDir ):
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -48,20 +48,21 @@ class OptionsWidget ( QWidget ):
|
||||||
self._projects += [ ProjectWidgets(project) ]
|
self._projects += [ ProjectWidgets(project) ]
|
||||||
|
|
||||||
gLayout = QGridLayout()
|
gLayout = QGridLayout()
|
||||||
for column in range(len(self._projects)):
|
column = 0
|
||||||
self._projects[column].addToLayout( column, gLayout )
|
for iproject in range(len(self._projects)):
|
||||||
|
column += self._projects[iproject].addToLayout( column, gLayout )
|
||||||
toolsGroup = QGroupBox( 'Projects && Tools' )
|
toolsGroup = QGroupBox( 'Projects && Tools' )
|
||||||
toolsGroup.setLayout( gLayout )
|
toolsGroup.setLayout( gLayout )
|
||||||
|
|
||||||
scrollToolsGroup = QScrollArea()
|
scrollToolsGroup = QScrollArea()
|
||||||
scrollToolsGroup.setMinimumHeight( 400 )
|
scrollToolsGroup.setMinimumHeight( 350 )
|
||||||
#scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
|
#scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
|
||||||
scrollToolsGroup.setWidget( toolsGroup )
|
scrollToolsGroup.setWidget( toolsGroup )
|
||||||
|
|
||||||
self._buildMode = QComboBox()
|
self._buildMode = QComboBox()
|
||||||
self._buildMode.addItems( ('Release', 'Debug') )
|
self._buildMode.addItems( ('Release', 'Debug') )
|
||||||
self._svnUpdate = QCheckBox( 'SVN Update' )
|
#self._svnUpdate = QCheckBox( 'SVN Update' )
|
||||||
self._svnStatus = QCheckBox( 'SVN Status' )
|
#self._svnStatus = QCheckBox( 'SVN Status' )
|
||||||
self._make = QCheckBox( 'Build' )
|
self._make = QCheckBox( 'Build' )
|
||||||
self._enableDoc = QCheckBox( 'Build Documentation' )
|
self._enableDoc = QCheckBox( 'Build Documentation' )
|
||||||
self._noCache = QCheckBox( 'Remove previous CMake cache' )
|
self._noCache = QCheckBox( 'Remove previous CMake cache' )
|
||||||
|
@ -73,13 +74,13 @@ class OptionsWidget ( QWidget ):
|
||||||
|
|
||||||
self._commandGroup = QButtonGroup()
|
self._commandGroup = QButtonGroup()
|
||||||
self._commandGroup.setExclusive( True )
|
self._commandGroup.setExclusive( True )
|
||||||
self._commandGroup.addButton( self._svnUpdate )
|
#self._commandGroup.addButton( self._svnUpdate )
|
||||||
self._commandGroup.addButton( self._svnStatus )
|
#self._commandGroup.addButton( self._svnStatus )
|
||||||
self._commandGroup.addButton( self._make )
|
self._commandGroup.addButton( self._make )
|
||||||
|
|
||||||
vLayout = QVBoxLayout()
|
vLayout = QVBoxLayout()
|
||||||
vLayout.addWidget( self._svnUpdate )
|
#vLayout.addWidget( self._svnUpdate )
|
||||||
vLayout.addWidget( self._svnStatus )
|
#vLayout.addWidget( self._svnStatus )
|
||||||
vLayout.addWidget( self._make )
|
vLayout.addWidget( self._make )
|
||||||
vLayout.addStretch()
|
vLayout.addStretch()
|
||||||
commandGroup = QGroupBox( 'Command' )
|
commandGroup = QGroupBox( 'Command' )
|
||||||
|
@ -121,8 +122,8 @@ class OptionsWidget ( QWidget ):
|
||||||
def _getProjects ( self ): return self._projects
|
def _getProjects ( self ): return self._projects
|
||||||
def _getBuildMode ( self ): return self._buildMode.currentText()
|
def _getBuildMode ( self ): return self._buildMode.currentText()
|
||||||
def _getThreads ( self ): return self._threads.currentText()
|
def _getThreads ( self ): return self._threads.currentText()
|
||||||
def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
|
#def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
|
||||||
def _getSvnStatus ( self ): return self._svnStatus.isChecked()
|
#def _getSvnStatus ( self ): return self._svnStatus.isChecked()
|
||||||
def _getMake ( self ): return self._make.isChecked()
|
def _getMake ( self ): return self._make.isChecked()
|
||||||
def _getEnableDoc ( self ): return self._enableDoc.isChecked()
|
def _getEnableDoc ( self ): return self._enableDoc.isChecked()
|
||||||
def _getNoCache ( self ): return self._noCache.isChecked()
|
def _getNoCache ( self ): return self._noCache.isChecked()
|
||||||
|
@ -132,8 +133,8 @@ class OptionsWidget ( QWidget ):
|
||||||
projects = property( _getProjects )
|
projects = property( _getProjects )
|
||||||
buildMode = property( _getBuildMode )
|
buildMode = property( _getBuildMode )
|
||||||
threads = property( _getThreads )
|
threads = property( _getThreads )
|
||||||
svnUpdate = property( _getSvnUpdate )
|
#svnUpdate = property( _getSvnUpdate )
|
||||||
svnStatus = property( _getSvnStatus )
|
#svnStatus = property( _getSvnStatus )
|
||||||
make = property( _getMake )
|
make = property( _getMake )
|
||||||
enableDoc = property( _getEnableDoc )
|
enableDoc = property( _getEnableDoc )
|
||||||
noCache = property( _getNoCache )
|
noCache = property( _getNoCache )
|
||||||
|
@ -143,8 +144,8 @@ class OptionsWidget ( QWidget ):
|
||||||
|
|
||||||
def readSettings ( self ):
|
def readSettings ( self ):
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
self._svnUpdate.setChecked( settings.value('builder/svnUpdate').toBool() )
|
#self._svnUpdate.setChecked( settings.value('builder/svnUpdate').toBool() )
|
||||||
self._svnStatus.setChecked( settings.value('builder/svnStatus').toBool() )
|
#self._svnStatus.setChecked( settings.value('builder/svnStatus').toBool() )
|
||||||
self._make .setChecked( settings.value('builder/make' ).toBool() )
|
self._make .setChecked( settings.value('builder/make' ).toBool() )
|
||||||
self._enableDoc.setChecked( settings.value('builder/enableDoc').toBool() )
|
self._enableDoc.setChecked( settings.value('builder/enableDoc').toBool() )
|
||||||
self._noCache .setChecked( settings.value('builder/noCache' ).toBool() )
|
self._noCache .setChecked( settings.value('builder/noCache' ).toBool() )
|
||||||
|
@ -165,8 +166,8 @@ class OptionsWidget ( QWidget ):
|
||||||
|
|
||||||
def saveSettings ( self ):
|
def saveSettings ( self ):
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
settings.setValue('builder/svnUpdate', self._svnUpdate.isChecked() )
|
#settings.setValue('builder/svnUpdate', self._svnUpdate.isChecked() )
|
||||||
settings.setValue('builder/svnStatus', self._svnStatus.isChecked() )
|
#settings.setValue('builder/svnStatus', self._svnStatus.isChecked() )
|
||||||
settings.setValue('builder/make' , self._make .isChecked() )
|
settings.setValue('builder/make' , self._make .isChecked() )
|
||||||
settings.setValue('builder/enableDoc', self._enableDoc.isChecked() )
|
settings.setValue('builder/enableDoc', self._enableDoc.isChecked() )
|
||||||
settings.setValue('builder/buildMode', self._buildMode.currentText() )
|
settings.setValue('builder/buildMode', self._buildMode.currentText() )
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -15,37 +15,58 @@
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
class Tool ( object ):
|
||||||
|
|
||||||
|
def __init__ ( self, project, name ):
|
||||||
|
self.project = project
|
||||||
|
self.name = name
|
||||||
|
self.active = False
|
||||||
|
return
|
||||||
|
|
||||||
|
def getToolDir ( self ): return self.project.getName()+'/'+self.name
|
||||||
|
|
||||||
|
|
||||||
class Project ( object ):
|
class Project ( object ):
|
||||||
|
|
||||||
def __init__ ( self, name, tools, repository ):
|
def __init__ ( self, name, toolNames, repository ):
|
||||||
self._name = name
|
self._name = name
|
||||||
self._tools = tools
|
self._tools = []
|
||||||
self._repository = repository
|
self._repository = repository
|
||||||
self._actives = []
|
|
||||||
|
for toolName in toolNames:
|
||||||
|
self._tools.append( Tool(self,toolName) )
|
||||||
return
|
return
|
||||||
|
|
||||||
def getName ( self ): return self._name
|
def getName ( self ): return self._name
|
||||||
def getTools ( self ): return self._tools
|
def getTools ( self ): return self._tools
|
||||||
def getRepository ( self ): return self._repository
|
def getRepository ( self ): return self._repository
|
||||||
def getActives ( self ): return self._actives
|
|
||||||
def hasTool ( self, tool ): return tool in self._tools
|
def hasTool ( self, toolName ):
|
||||||
|
for tool in self._tools:
|
||||||
|
if tool.name == toolName: return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getActives ( self ):
|
||||||
|
actives = []
|
||||||
|
for tool in self._tools:
|
||||||
|
if tool.active: actives.append( tool )
|
||||||
|
return actives
|
||||||
|
|
||||||
def desactivate ( self ):
|
def desactivate ( self ):
|
||||||
self._active = []
|
self._active = []
|
||||||
return
|
return
|
||||||
|
|
||||||
def activateAll ( self ):
|
def activateAll ( self ):
|
||||||
self._actives = self._tools
|
for tool in self._tools:
|
||||||
|
tool.active = True
|
||||||
return
|
return
|
||||||
|
|
||||||
def activate ( self, tools ):
|
def activate ( self, toolNames ):
|
||||||
# Build the ordered list.
|
|
||||||
for tool in self._tools:
|
|
||||||
if (tool in tools) and not (tool in self._actives):
|
|
||||||
self._actives += [ tool ]
|
|
||||||
# Find the tools not part of the project.
|
|
||||||
rejecteds = []
|
rejecteds = []
|
||||||
for tool in tools:
|
for tool in self._tools:
|
||||||
if not (tool in self._tools) and (not tool in rejecteds):
|
if tool.name in toolNames:
|
||||||
rejecteds += [ tool ]
|
tool.active = True
|
||||||
|
else:
|
||||||
|
if tool.name in toolNames:
|
||||||
|
rejecteds.append( tool.name )
|
||||||
return rejecteds
|
return rejecteds
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -15,23 +15,29 @@
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
import string
|
||||||
from PyQt4.QtCore import Qt
|
from PyQt4.QtCore import Qt
|
||||||
from PyQt4.QtCore import QObject
|
from PyQt4.QtCore import QObject
|
||||||
from PyQt4.QtCore import QSettings
|
from PyQt4.QtCore import QSettings
|
||||||
|
from PyQt4.QtGui import QSizePolicy
|
||||||
|
from PyQt4.QtGui import QFrame
|
||||||
from PyQt4.QtGui import QPushButton
|
from PyQt4.QtGui import QPushButton
|
||||||
from PyQt4.QtGui import QCheckBox
|
from PyQt4.QtGui import QCheckBox
|
||||||
|
from PyQt4.QtGui import QLabel
|
||||||
|
|
||||||
|
|
||||||
class ProjectWidgets ( QObject ):
|
class ProjectWidgets ( QObject ):
|
||||||
|
|
||||||
def __init__ ( self, project ):
|
def __init__ ( self, project ):
|
||||||
self._project = project
|
self._project = project
|
||||||
self._projectButton = QPushButton( self._project.getName() )
|
self._projectButton = QLabel( string.capwords(self._project.getName()) )
|
||||||
self._projectButton.setStyleSheet( 'font-weight: bold;' )
|
self._projectButton.setStyleSheet( 'font-weight: bold;' )
|
||||||
|
self._projectButton.setFrameShape( QFrame.Box )
|
||||||
|
self._projectButton.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred )
|
||||||
|
|
||||||
self._toolsCheckBoxes = []
|
self._toolsCheckBoxes = []
|
||||||
for tool in self._project.getTools():
|
for tool in self._project.getTools():
|
||||||
self._toolsCheckBoxes += [ QCheckBox( tool ) ]
|
self._toolsCheckBoxes += [ QCheckBox( tool.name ) ]
|
||||||
|
|
||||||
#self._projectButton.clicked.connect( self.toggleToolsVisibility )
|
#self._projectButton.clicked.connect( self.toggleToolsVisibility )
|
||||||
return
|
return
|
||||||
|
@ -50,10 +56,22 @@ class ProjectWidgets ( QObject ):
|
||||||
actives = property( _getActives )
|
actives = property( _getActives )
|
||||||
|
|
||||||
def addToLayout( self, column, layout ):
|
def addToLayout( self, column, layout ):
|
||||||
|
toolsNb = len(self._toolsCheckBoxes)
|
||||||
|
if toolsNb <= 10:
|
||||||
layout.addWidget( self._projectButton, 0, column, Qt.AlignLeft )
|
layout.addWidget( self._projectButton, 0, column, Qt.AlignLeft )
|
||||||
for row in range(len(self._toolsCheckBoxes)):
|
for row in range(toolsNb):
|
||||||
layout.addWidget( self._toolsCheckBoxes[row], row+1, column, Qt.AlignTop )
|
layout.addWidget( self._toolsCheckBoxes[row], row+1, column, Qt.AlignTop )
|
||||||
return
|
return 1
|
||||||
|
|
||||||
|
columnSpan = toolsNb / 10
|
||||||
|
if toolsNb % 10: columnSpan += 1
|
||||||
|
|
||||||
|
layout.addWidget( self._projectButton, 0, column, 1, columnSpan, Qt.AlignJustify )
|
||||||
|
for row in range(toolsNb):
|
||||||
|
if row and row % 10 == 0: column += 1
|
||||||
|
layout.addWidget( self._toolsCheckBoxes[row], row%10+1, column, Qt.AlignTop )
|
||||||
|
|
||||||
|
return columnSpan
|
||||||
|
|
||||||
#def toggleToolsVisibility ( self ):
|
#def toggleToolsVisibility ( self ):
|
||||||
# self._visibleTools = not self._visibleTools
|
# self._visibleTools = not self._visibleTools
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
|
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
|
#
|
||||||
|
# This file is part of the Coriolis Software.
|
||||||
|
# Copyright (c) UPMC/LIP6 2012-2014, All Rights Reserved
|
||||||
|
#
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
# | C O R I O L I S |
|
||||||
|
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||||
|
# | |
|
||||||
|
# | Author : Damien Dupuis |
|
||||||
|
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||||
|
# | =============================================================== |
|
||||||
|
# | Python : "./builder/__init__.py" |
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# -*- mode:Python -*-
|
# -*- mode:Python -*-
|
||||||
#
|
#
|
||||||
# This file is part of the Coriolis Software.
|
# This file is part of the Coriolis Software.
|
||||||
# Copyright (c) UPMC 2008-2013, All Rights Reserved
|
# Copyright (c) UPMC 2008-2014, All Rights Reserved
|
||||||
#
|
#
|
||||||
# +-----------------------------------------------------------------+
|
# +-----------------------------------------------------------------+
|
||||||
# | C O R I O L I S |
|
# | C O R I O L I S |
|
||||||
|
@ -116,11 +116,11 @@ def autoLocate ():
|
||||||
|
|
||||||
builderDir = None
|
builderDir = None
|
||||||
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||||
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
|
, os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap'
|
||||||
, os.environ['HOME']+'/coriolis/src/bootstrap'
|
, os.environ['HOME']+'/coriolis/src/coriolis/bootstrap'
|
||||||
, os.environ['HOME']+'/chams-1.x/src/bootstrap'
|
, os.environ['HOME']+'/chams-1.x/src/coriolis/bootstrap'
|
||||||
, os.environ['HOME']+'/chams/src/bootstrap'
|
, os.environ['HOME']+'/chams/src/coriolis/bootstrap'
|
||||||
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
|
, '/users/outil/coriolis/coriolis-2.x/src/coriolis/bootstrap'
|
||||||
, os.environ['HOME']+'/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
, os.environ['HOME']+'/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
||||||
, os.environ['HOME']+'/chams-1.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
, os.environ['HOME']+'/chams-1.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
||||||
, os.environ['HOME']+'/chams/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
, os.environ['HOME']+'/chams/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
|
||||||
|
@ -173,12 +173,13 @@ parser.add_option ( "--make" , action="store" , type="string",
|
||||||
parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
|
parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
|
||||||
parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
|
parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
|
||||||
# SVN repository relateds.
|
# SVN repository relateds.
|
||||||
parser.add_option ( "--svn-tag" , action="store" , type="string", dest="svnTag" , help="Explicitly select a SVN tag (for SVN related commands)." )
|
# Have to be ported to Git.
|
||||||
parser.add_option ( "--svn-method" , action="store" , type="string", dest="svnMethod" , help="Allows to sets the svn checkout method (svn+ssh://coriolis.soc.lip6.fr)." )
|
#parser.add_option ( "--svn-tag" , action="store" , type="string", dest="svnTag" , help="Explicitly select a SVN tag (for SVN related commands)." )
|
||||||
parser.add_option ( "--svn-status" , action="store_true" , dest="svnStatus" , help="Check status against the SVN repository." )
|
#parser.add_option ( "--svn-method" , action="store" , type="string", dest="svnMethod" , help="Allows to sets the svn checkout method (svn+ssh://coriolis.soc.lip6.fr)." )
|
||||||
parser.add_option ( "--svn-diff" , action="store_true" , dest="svnDiff" , help="Perform a diff against the SVN repository." )
|
#parser.add_option ( "--svn-status" , action="store_true" , dest="svnStatus" , help="Check status against the SVN repository." )
|
||||||
parser.add_option ( "--svn-update" , action="store_true" , dest="svnUpdate" , help="Update to the latest SVN version *or* the one given by svn-tag." )
|
#parser.add_option ( "--svn-diff" , action="store_true" , dest="svnDiff" , help="Perform a diff against the SVN repository." )
|
||||||
parser.add_option ( "--svn-checkout" , action="store_true" , dest="svnCheckout", help="Checkout the latest SVN version *or* the one given by svn-tag." )
|
#parser.add_option ( "--svn-update" , action="store_true" , dest="svnUpdate" , help="Update to the latest SVN version *or* the one given by svn-tag." )
|
||||||
|
#parser.add_option ( "--svn-checkout" , action="store_true" , dest="svnCheckout", help="Checkout the latest SVN version *or* the one given by svn-tag." )
|
||||||
# Miscellaneous.
|
# Miscellaneous.
|
||||||
parser.add_option ( "--user-tarball" , action="store_true" , dest="userTarball", help="Regenerate a tarball from checked out sources (in <root>/tarball/." )
|
parser.add_option ( "--user-tarball" , action="store_true" , dest="userTarball", help="Regenerate a tarball from checked out sources (in <root>/tarball/." )
|
||||||
parser.add_option ( "--tarball" , action="store_true" , dest="tarball" , help="Regenerate a tarball (in <root>/tarball/." )
|
parser.add_option ( "--tarball" , action="store_true" , dest="tarball" , help="Regenerate a tarball (in <root>/tarball/." )
|
||||||
|
@ -239,14 +240,14 @@ else:
|
||||||
if options.noCache: builder.noCache = True
|
if options.noCache: builder.noCache = True
|
||||||
if options.rmBuild: builder.rmBuild = True
|
if options.rmBuild: builder.rmBuild = True
|
||||||
if options.makeArguments: builder.makeArguments = options.makeArguments
|
if options.makeArguments: builder.makeArguments = options.makeArguments
|
||||||
if options.svnMethod: builder.svnMethod = options.svnMethod
|
#if options.svnMethod: builder.svnMethod = options.svnMethod
|
||||||
if options.svnTag: builder.svnTag = options.svnTag
|
#if options.svnTag: builder.svnTag = options.svnTag
|
||||||
|
|
||||||
if options.svnStatus: builder.svnStatus ( tools=options.tools, projects=options.projects )
|
#if options.svnStatus: builder.svnStatus ( tools=options.tools, projects=options.projects )
|
||||||
elif options.svnUpdate: builder.svnUpdate ( tools=options.tools, projects=options.projects )
|
#elif options.svnUpdate: builder.svnUpdate ( tools=options.tools, projects=options.projects )
|
||||||
elif options.svnDiff: builder.svnDiff ( tools=options.tools, projects=options.projects )
|
#elif options.svnDiff: builder.svnDiff ( tools=options.tools, projects=options.projects )
|
||||||
elif options.svnCheckout: builder.svnCheckout ( tools=options.tools, projects=options.projects )
|
#elif options.svnCheckout: builder.svnCheckout ( tools=options.tools, projects=options.projects )
|
||||||
elif options.userTarball: builder.userTarball ( tools=options.tools, projects=options.projects )
|
if options.userTarball: builder.userTarball ( tools=options.tools, projects=options.projects )
|
||||||
elif options.tarball: builder.svnTarball ( tools=options.tools, projects=options.projects )
|
elif options.tarball: builder.svnTarball ( tools=options.tools, projects=options.projects )
|
||||||
elif options.doRpm: builder.doRpm ()
|
elif options.doRpm: builder.doRpm ()
|
||||||
elif options.doDeb: builder.doDeb ()
|
elif options.doDeb: builder.doDeb ()
|
||||||
|
|
|
@ -220,21 +220,34 @@
|
||||||
# Setup the <PROJECT>_SEARCH_PATH.
|
# Setup the <PROJECT>_SEARCH_PATH.
|
||||||
# Where to find includes & libraries.
|
# Where to find includes & libraries.
|
||||||
#
|
#
|
||||||
MACRO(SETUP_SEARCH_DIR project)
|
macro(setup_search_dir project)
|
||||||
IF( NOT("$ENV{${project}_TOP}" STREQUAL "") )
|
if( NOT("$ENV{${project}_TOP}" STREQUAL "") )
|
||||||
MESSAGE("-- ${project}_TOP is set to $ENV{${project}_TOP}")
|
message("-- ${project}_TOP is set to $ENV{${project}_TOP}")
|
||||||
LIST(INSERT ${project}_DIR_SEARCH 0 "${DESTDIR}$ENV{${project}_TOP}")
|
list(INSERT ${project}_DIR_SEARCH 0 "${DESTDIR}$ENV{${project}_TOP}")
|
||||||
ENDIF( NOT("$ENV{${project}_TOP}" STREQUAL "") )
|
endif( NOT("$ENV{${project}_TOP}" STREQUAL "") )
|
||||||
|
|
||||||
IF( NOT("$ENV{${project}_USER_TOP}" STREQUAL "") )
|
if( NOT("$ENV{${project}_USER_TOP}" STREQUAL "") )
|
||||||
MESSAGE("-- ${project}_USER_TOP is set to $ENV{${project}_USER_TOP}")
|
message("-- ${project}_USER_TOP is set to $ENV{${project}_USER_TOP}")
|
||||||
LIST(INSERT ${project}_DIR_SEARCH 0 "${DESTDIR}$ENV{${project}_USER_TOP}")
|
list(INSERT ${project}_DIR_SEARCH 0 "${DESTDIR}$ENV{${project}_USER_TOP}")
|
||||||
ENDIF( NOT("$ENV{${project}_USER_TOP}" STREQUAL "") )
|
endif( NOT("$ENV{${project}_USER_TOP}" STREQUAL "") )
|
||||||
|
|
||||||
LIST(REMOVE_DUPLICATES ${project}_DIR_SEARCH)
|
LIST(REMOVE_DUPLICATES ${project}_DIR_SEARCH)
|
||||||
|
|
||||||
MESSAGE("-- Components of ${project}_DIR_SEARCH:")
|
message("-- Components of ${project}_DIR_SEARCH:")
|
||||||
FOREACH(PATH ${${project}_DIR_SEARCH})
|
foreach(PATH ${${project}_DIR_SEARCH})
|
||||||
MESSAGE("-- ${PATH}")
|
message("-- ${PATH}")
|
||||||
ENDFOREACH(PATH)
|
endforeach(PATH)
|
||||||
ENDMACRO(SETUP_SEARCH_DIR project)
|
endmacro(setup_search_dir project)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Setup the <PROJECT>_FOUND.
|
||||||
|
# Set to TRUE if both includes & libraries have been found.
|
||||||
|
#
|
||||||
|
macro(set_found project)
|
||||||
|
if(${project}_INCLUDE_DIR AND ${project}_LIBRARY)
|
||||||
|
set(${project}_FOUND TRUE)
|
||||||
|
else(${project}_INCLUDE_DIR AND ${project}_LIBRARY)
|
||||||
|
set(${project}_FOUND FALSE)
|
||||||
|
endif(${project}_INCLUDE_DIR AND ${project}_LIBRARY)
|
||||||
|
endmacro(set_found project)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
alain = Alain Greiner <alliance-users@asim.lip6.fr>
|
||||||
|
bodin = Bruno Bodin <alliance-users@asim.lip6.fr>
|
||||||
|
boris = Boris Boutillier <alliance-users@asim.lip6.fr>
|
||||||
|
caba = Jean-Manuel Caba <alliance-users@asim.lip6.fr>
|
||||||
|
chams = The Chams Project <alliance-users@asim.lip6.fr>
|
||||||
|
cobell = Sophie Belloeil <alliance-users@asim.lip6.fr>
|
||||||
|
coriolis = The Coriolis Project <alliance-users@asim.lip6.fr>
|
||||||
|
czo = Olivier Sirol <alliance-users@asim.lip6.fr>
|
||||||
|
d2 = Damien Dupuis <alliance-users@asim.lip6.fr>
|
||||||
|
dom = Dominique Ledu <alliance-users@asim.lip6.fr>
|
||||||
|
franck = Franck Wajsburt <alliance-users@asim.lip6.fr>
|
||||||
|
francois = Francois Donnet <alliance-users@asim.lip6.fr>
|
||||||
|
fred = Frederic Petrot <alliance-users@asim.lip6.fr>
|
||||||
|
gregoire = Gregoire Avot <alliance-users@asim.lip6.fr>
|
||||||
|
hcl = Hugo Clement <alliance-users@asim.lip6.fr>
|
||||||
|
javid = Farakh Javid <alliance-users@asim.lip6.fr>
|
||||||
|
karim = Karim Dioury <alliance-users@asim.lip6.fr>
|
||||||
|
labiadh = Forgotten Author (labiadh) <alliance-users@asim.lip6.fr>
|
||||||
|
ludo = Ludovic Jacomme <alliance-users@asim.lip6.fr>
|
||||||
|
masson = Christian Masson <alliance-users@asim.lip6.fr>
|
||||||
|
mitri = Forgotten Author (mitri) <alliance-users@asim.lip6.fr>
|
||||||
|
noury = Ludovic Noury <alliance-users@asim.lip6.fr>
|
||||||
|
pnt = Pierre Nguyen Tuong <alliance-users@asim.lip6.fr>
|
||||||
|
sirol = Olivier Sirol <alliance-users@asim.lip6.fr>
|
||||||
|
stephany = Stephanie Youssef <alliance-users@asim.lip6.fr>
|
||||||
|
xtof = Christophe Alexandre <alliance-users@asim.lip6.fr>
|
||||||
|
youssef = Stephanie Youssef <alliance-users@asim.lip6.fr>
|
||||||
|
jpc = Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
||||||
|
ramy = Ramy Iskander <Ramy.Iskander@lip6.fr>
|
||||||
|
roselyne = Roselyne Chotin <Roselyne.Chotin-Avot@lip6.fr>
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
create repository coriolis.git
|
||||||
|
end repository
|
||||||
|
|
||||||
|
match /io/trunk/
|
||||||
|
repository coriolis.git
|
||||||
|
branch master
|
||||||
|
prefix vlsisapd/
|
||||||
|
end match
|
||||||
|
|
||||||
|
match /goodies/trunk/
|
||||||
|
repository coriolis.git
|
||||||
|
branch master
|
||||||
|
prefix bootstrap/
|
||||||
|
end match
|
||||||
|
|
||||||
|
match /vlsisapd/trunk/
|
||||||
|
repository coriolis.git
|
||||||
|
branch master
|
||||||
|
prefix vlsisapd/
|
||||||
|
end match
|
||||||
|
|
||||||
|
match /([a-z0-9]+)/trunk/
|
||||||
|
repository coriolis.git
|
||||||
|
branch master
|
||||||
|
prefix \1/
|
||||||
|
end match
|
||||||
|
|
||||||
|
match .*/
|
||||||
|
end match
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
svn-all-fast-export --resume-from 0 \
|
||||||
|
--rules ./coriolis.rules \
|
||||||
|
--identity-map ./authors.txt \
|
||||||
|
/dsk/l1/jpc/svn2git/svn > svn-all-fast-export.log
|
|
@ -1,16 +0,0 @@
|
||||||
project(CHAMSIN)
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.4.0)
|
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "$ENV{HURRICANE_TOP}/share/cmake_modules/"
|
|
||||||
"$ENV{HURRICANE_TOP}/share/cmake_modules/")
|
|
||||||
|
|
||||||
find_package(BISON REQUIRED)
|
|
||||||
find_package(FLEX REQUIRED)
|
|
||||||
find_package(HURRICANE REQUIRED)
|
|
||||||
find_package(CORIOLIS REQUIRED)
|
|
||||||
find_package(Qt4 REQUIRED) # find and setup Qt4 for this project
|
|
||||||
find_package(LibXml2 REQUIRED)
|
|
||||||
|
|
||||||
add_subdirectory(src)
|
|
||||||
add_subdirectory(etc)
|
|
|
@ -1 +0,0 @@
|
||||||
install(FILES technology.hcmos9.dtr.xml DESTINATION /share/etc)
|
|
|
@ -1,57 +0,0 @@
|
||||||
<technology name="hcmos9">
|
|
||||||
<physical_rules>
|
|
||||||
<rule name="transistorMinL" value="0.13" ref="13-1.a"/>
|
|
||||||
<rule name="transistorMaxL" value="13.0" ref="13-1.a"/>
|
|
||||||
<rule name="transistorMinW" value="0.15" ref="2-1"/>
|
|
||||||
<rule name="transistorMaxW" value="1500.0" ref="2-1"/>
|
|
||||||
|
|
||||||
<rule name="minWidth" layer="cut0" value="0.16" ref="19-1"/>
|
|
||||||
<rule name="minSpacing" layer="cut0" value="0.18" ref="19-2.a"/>
|
|
||||||
<arule name="minExtension" layer1="poly" layer2="cut0" value="0.07" ref="19-3"/>
|
|
||||||
|
|
||||||
<arule name="minEnclosure" layer1="nWell" layer2="active" value="0.31" ref="1-4.a"/>
|
|
||||||
|
|
||||||
<arule name="minGateEnclosure" layer1="nImplant" layer2="poly" value="0.4" ref="16-6"/>
|
|
||||||
<arule name="minEnclosure" layer1="nImplant" layer2="poly" value="0.2" ref="16-17"/>
|
|
||||||
<arule name="minExtension" layer1="nImplant" layer2="active" value="0.18" ref="16-8"/>
|
|
||||||
|
|
||||||
<arule name="minGateEnclosure" layer1="pImplant" layer2="poly" value="0.4" ref="17-6"/>
|
|
||||||
<arule name="minEnclosure" layer1="pImplant" layer2="poly" value="0.2" ref="17-17"/>
|
|
||||||
<arule name="minExtension" layer1="pImplant" layer2="active" value="0.18" ref="17-8"/>
|
|
||||||
|
|
||||||
<arule name="minExtension" layer1="active" layer2="cut0" value="0.07" ref="19-4.a"/>
|
|
||||||
<arule name="minExtension" layer1="pImplant" layer2="cut0" value="0.09" ref="19-4.b"/>
|
|
||||||
<arule name="minExtension" layer1="nImplant" layer2="cut0" value="0.09" ref="19-4.c"/>
|
|
||||||
|
|
||||||
<rule name="minSpacing" layer1="active" layer2="cut0" value="0.14" ref="19-5"/>
|
|
||||||
<arule name="minGateSpacing" layer1="cut0" layer2="active" value="0.11" ref="19-6.a"/>
|
|
||||||
<rule name="minSpacing" layer1="active" layer2="poly" value="0.07" ref="13-5"/>
|
|
||||||
<arule name="minExtension" layer1="active" layer2="poly" value="0.23" ref="13-6"/>
|
|
||||||
|
|
||||||
<arule name="minExtension" layer1="poly" layer2="active" value="0.18" ref="13-7"/>
|
|
||||||
|
|
||||||
<!-- physical rules for PADOPEN-MIM -->
|
|
||||||
<rule name="padOpenMIMWidth" value="1.0" ref="M-40.1"/>
|
|
||||||
<rule name="padOpenMIMSpace" value="1.0" ref="M-40.2"/>
|
|
||||||
<rule name="padOpenMIMMETAL6Enclosure" value="0.7" ref="M-40.4"/>
|
|
||||||
<!-- physical rules for ALUCAP-MIM -->
|
|
||||||
<rule name="aluCapMIMWidth" value="1.0" ref="M-41.1"/>
|
|
||||||
<rule name="aluCapMIMSpace" value="1.0" ref="M-41.2"/>
|
|
||||||
<rule name="aluCapMIMVIA6Enclosure" value="0.7" ref="M-41.3"/>
|
|
||||||
<rule name="aluCapMIMTopMIM6Enclosure" value="0.3" ref="M-41.6"/>
|
|
||||||
<rule name="aluCapMIMBotMIM6Enclosure" value="0.3" ref="M-41.7"/>
|
|
||||||
<!-- physical rules for TOPMIM6 -->
|
|
||||||
<rule name="topPlateMIMminWidth" value="3.5" ref="M-97.1"/>
|
|
||||||
<rule name="topPlateMIMSpacing" value="3.5" ref="M-97.2"/>
|
|
||||||
<rule name="topPlateMIMBotEnclosure" value="0.5" ref="M-97.6"/>
|
|
||||||
<rule name="topPlateMIMBotmimContact" value="2.0" ref="M-97.8"/>
|
|
||||||
<!-- physical rules for BOTMIM6 -->
|
|
||||||
<rule name="botPlateMIMWidth" value="4.5" ref="M-96.1"/>
|
|
||||||
<rule name="botPlateMIMSpacing" value="2.5" ref="M-96.2"/>
|
|
||||||
<rule name="botPlateMIMViaEnclosure" value="0.3" ref="M-96.3"/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</physical_rules>
|
|
||||||
</technology>
|
|
|
@ -1,3 +0,0 @@
|
||||||
ADD_SUBDIRECTORY(technology)
|
|
||||||
ADD_SUBDIRECTORY(analogic)
|
|
||||||
ADD_SUBDIRECTORY(tests)
|
|
|
@ -1,34 +0,0 @@
|
||||||
#ifndef ANALOGCOMPONENT_H
|
|
||||||
#define ANALOGCOMPONENT_H
|
|
||||||
|
|
||||||
#include "hurricane/Cell.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
//#include "DeviceParameter.h"
|
|
||||||
|
|
||||||
class AnalogComponent : public Cell {
|
|
||||||
#if 0
|
|
||||||
public:
|
|
||||||
struct ParameterCompare:
|
|
||||||
public std::binary_function<const Parameter*, const Parameter*, bool> {
|
|
||||||
bool operator()(const Parameter<>* dp1, const Parameter<>* dp2) const {
|
|
||||||
return dp1->_id < dp2->_id;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef set<Parameter*>, ParameterCompare> ParameterSet;
|
|
||||||
Parameter* getParameter(const string& parameterId) const;
|
|
||||||
#endif
|
|
||||||
protected:
|
|
||||||
AnalogComponent(Library* library, const Name& name): Cell(library, name) {}
|
|
||||||
#if 0
|
|
||||||
void addParameter(const Parameter* parameter) {
|
|
||||||
_parameterSet.insert(parameter);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ParameterSet _parameterSet;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ANALOGCOMPONENT_H
|
|
|
@ -1,8 +0,0 @@
|
||||||
INCLUDE_DIRECTORIES(${CHAMSIN_SOURCE_DIR}/src/technology ${HURRICANE_INCLUDE_DIR})
|
|
||||||
|
|
||||||
ADD_LIBRARY(analogic SHARED Transistor.cpp Capacitor.cpp Resistor.cpp Device.cpp
|
|
||||||
MetaTransistor.cpp MetaCapacitor.cpp)
|
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(analogic atechnology ${HURRICANE_LIBRARIES})
|
|
||||||
|
|
||||||
INSTALL(TARGETS analogic DESTINATION /lib)
|
|
|
@ -1,298 +0,0 @@
|
||||||
#include "hurricane/Technology.h"
|
|
||||||
#include "hurricane/Pad.h"
|
|
||||||
#include "hurricane/UpdateSession.h"
|
|
||||||
#include "hurricane/DataBase.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "AEnv.h"
|
|
||||||
#include "ATechnology.h"
|
|
||||||
#include "Capacitor.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
Layer* getLayer(Technology* technology, const string& layerStr) {
|
|
||||||
Layer* layer = technology->getLayer(layerStr);
|
|
||||||
if (!layer) {
|
|
||||||
throw Error("Unknown Layer : " + layerStr);
|
|
||||||
}
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pad* createPad(Technology* technology, Net* net, const string& layerName) {
|
|
||||||
static Box emptyBox(0, 0, 0, 0);
|
|
||||||
Layer* layer = getLayer(technology, layerName);
|
|
||||||
Pad* pad = Pad::create(net, layer, emptyBox);
|
|
||||||
return pad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Déclaration des deux armatures:
|
|
||||||
//*******************************
|
|
||||||
const Name Capacitor::BottomPlateName("BOTTOMPLATE");
|
|
||||||
const Name Capacitor::TopPlateName("TOPPLATE");
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
const Name Capacitor::AnonymousName("ANONYMOUS");
|
|
||||||
|
|
||||||
|
|
||||||
//les 4 types des capas unitaire:
|
|
||||||
//1-capa unitaire
|
|
||||||
//2-le Rectangle
|
|
||||||
//3-le Stub
|
|
||||||
//4-le Trou
|
|
||||||
Capacitor::Type::Type(const Code& code):
|
|
||||||
_code(code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Capacitor::Type::Type(const Type& type):
|
|
||||||
_code(type._code)
|
|
||||||
{}SVN
|
|
||||||
|
|
||||||
Capasitor::Type& Capasitor::Type::operator=(const Type& type) {
|
|
||||||
_code = type._code;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//la mise des valeurs initials:
|
|
||||||
//c'est le Constructeur:
|
|
||||||
//*********************
|
|
||||||
Capacitor::Capacitor(Library* library, const Name& name):
|
|
||||||
AnalogComponent(library, name),
|
|
||||||
_bottomPlate(NULL),
|
|
||||||
_topPlate(NULL),
|
|
||||||
_anonymous(NULL),
|
|
||||||
_l(0), _w(0),
|
|
||||||
_topPlate10(NULL),
|
|
||||||
_topPlate20(NULL),_topPlate30(NULL),
|
|
||||||
_bottomPlate00(NULL)
|
|
||||||
#if 0
|
|
||||||
_anonymous01(NULL),
|
|
||||||
_anonymous11(NULL),
|
|
||||||
_anonymous12(NULL),
|
|
||||||
_anonymous13(NULL),
|
|
||||||
_anonymous21(NULL),
|
|
||||||
_anonymousT11(NULL),
|
|
||||||
_anonymousT12(NULL),
|
|
||||||
_anonymousT13(NULL),
|
|
||||||
_anonymousT14(NULL),
|
|
||||||
_anonymousT21(NULL)
|
|
||||||
#endif
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
//Déclaration de la library:
|
|
||||||
//*************************
|
|
||||||
Capacitor* Capacitor::create(Library* library, const Name& name) {
|
|
||||||
Capacitor* capacitor = new Capacitor(library, name);
|
|
||||||
capacitor->_postCreate();
|
|
||||||
return capacitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//création des signaux et des noeuds:
|
|
||||||
//***********************************
|
|
||||||
void Capacitor::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
Technology* technology = db->getTechnology();
|
|
||||||
|
|
||||||
_bottomPlate = Net::create(this, BottomPlateName);
|
|
||||||
_bottomPlate->setExternal(true);
|
|
||||||
_topPlate = Net::create(this, TopPlateName);
|
|
||||||
_topPlate->setExternal(true);
|
|
||||||
// _anonymous = Net::create(this, AnonymousName);
|
|
||||||
|
|
||||||
|
|
||||||
_topPlate10 = createPad(technology, _topPlate, "topmim6");
|
|
||||||
_topPlate20 = createPad(technology, _topPlate, "padopen");
|
|
||||||
_topPlate30 = createPad(technology, _topPlate, "alucap");
|
|
||||||
_bottomPlate00 = createPad(technology, _bottomPlate, "botmim6");
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
_anonymous01 = createPad(technology, _anonymous, "Implant");
|
|
||||||
_anonymous11 = createPad(technology, _anonymous, "topmim6");
|
|
||||||
_anonymous12 = createPad(technology, _anonymous, "topmim6");
|
|
||||||
_anonymous13 = createPad(technology, _anonymous, "topmim6");
|
|
||||||
_anonymous21 = createPad(technology, _anonymous, "padopen");
|
|
||||||
_anonymous14 = createPad(technology, _anonymous, "topmim6");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void Capacitor::setType(Type type) {
|
|
||||||
UpdateSession::open();
|
|
||||||
if (type != _type) {
|
|
||||||
_type = type;
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
Technology* technology = db->getTechnology();
|
|
||||||
|
|
||||||
if (_type == Type::unitaire) {
|
|
||||||
_anonymous01->setLayer(getLayer(technology, "Implant"));
|
|
||||||
} else if (_type == Type::Rectangle) {
|
|
||||||
_anonymous11->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous12->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous21->setLayer(getLayer(technology, "padopen"));
|
|
||||||
} else if (_type == Type::Stub) {
|
|
||||||
_anonymous11->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous12->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous13->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous21->setLayer(getLayer(technology, "padopen"));
|
|
||||||
} else if (_type == Type::Trou) {
|
|
||||||
_anonymous11->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous12->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous13->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous14->setLayer(getLayer(technology, "topmim6"));
|
|
||||||
_anonymous21->setLayer(getLayer(technology, "padopen"));
|
|
||||||
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//la fonction updateLayout
|
|
||||||
//qui met en oeuvre de nouvau les parametres du capa
|
|
||||||
//au cas ou il y a n' importe auel changement
|
|
||||||
//******************************************
|
|
||||||
void Capacitor::updateLayout() {
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
|
|
||||||
if (!db) {
|
|
||||||
throw Error("Error : no DataBase");
|
|
||||||
}
|
|
||||||
Technology* techno = db->getTechnology();
|
|
||||||
if (!techno) {
|
|
||||||
throw Error("Error : no Technology");
|
|
||||||
}
|
|
||||||
|
|
||||||
ATechnology* atechno = AEnv::getATechnology();
|
|
||||||
|
|
||||||
//**Pour topPlate20 -> PADOPEN-MIM
|
|
||||||
//********************************
|
|
||||||
DbU::Unit widthCut6 = atechno->getPhysicalRule("padOpenMIMWidth")->getValue();
|
|
||||||
DbU::Unit spacingCut6 = atechno->getPhysicalRule("padOpenMIMSpace")->getValue();
|
|
||||||
DbU::Unit enclosureCut6 = atechno->getPhysicalRule("padOpenMIMMETAL6Enclosure")->getValue();
|
|
||||||
|
|
||||||
//**Pour topPlate30 -> ALUCAP-MIM
|
|
||||||
//*******************************
|
|
||||||
DbU::Unit widthAluCap = atechno->getPhysicalRule("aluCapMIMWidth")->getValue();
|
|
||||||
DbU::Unit enclosureVia6 = atechno->getPhysicalRule("aluCapMIMVIA6Enclosure")->getValue();
|
|
||||||
//DbU::Unit distanceAlucapTopmin = atechno->getPhysicalRule("aluCapMIMDistance")->getValue();
|
|
||||||
DbU::Unit enclosureTopMim = atechno->getPhysicalRule("aluCapMIMTopMIM6Enclosure")->getValue();
|
|
||||||
DbU::Unit enclosureBotMim = atechno->getPhysicalRule("aluCapMIMBotMIM6Enclosure")->getValue();
|
|
||||||
//DbU::Unit distanceAluc = atechno->getPhysicalRule("minAlucapDistance")->getValue();
|
|
||||||
|
|
||||||
//**Pour topPlate10 -> TOPMIM6
|
|
||||||
//****************************
|
|
||||||
DbU::Unit widthTopmim = atechno->getPhysicalRule("topPlateMIMminWidth")->getValue();
|
|
||||||
DbU::Unit spacingTopmim = atechno->getPhysicalRule("topPlateMIMSpacing")->getValue();
|
|
||||||
DbU::Unit enclosureByBotmimTopmim = atechno->getPhysicalRule("topPlateMIMBotEnclosure")->getValue();
|
|
||||||
//DbU::Unit enclosureVia6Topmim = atechno->getPhysicalRule("minViaEnclosure")->getValue();
|
|
||||||
DbU::Unit enclosureBotmimContact = atechno->getPhysicalRule("topPlateMIMBotmimContact")->getValue();
|
|
||||||
|
|
||||||
//**Pour BottomPlate -> BOTMIM6
|
|
||||||
//*****************************
|
|
||||||
DbU::Unit widthBotmim = atechno->getPhysicalRule("botPlateMIMWidth")->getValue();
|
|
||||||
DbU::Unit spacingBotmim = atechno->getPhysicalRule("botPlateMIMSpacing")->getValue();
|
|
||||||
DbU::Unit enclosureVia6Botmim = atechno->getPhysicalRule("botPlateMIMViaEnclosure")->getValue();
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
DbU::setStringMode(1);
|
|
||||||
|
|
||||||
|
|
||||||
//*les Box*//
|
|
||||||
//*********//
|
|
||||||
|
|
||||||
//topPlate 10:
|
|
||||||
//l'armature haute est le reference
|
|
||||||
//car la valeur du capa corespond au W et L de l'armature haute
|
|
||||||
//*************************************************************
|
|
||||||
|
|
||||||
DbU::Unit x10 = 0;
|
|
||||||
DbU::Unit y10 = 0;
|
|
||||||
DbU::Unit dx10 = _l;
|
|
||||||
DbU::Unit dy10 = _w;
|
|
||||||
Box box10(x10, y10, x10 + dx10, y10 + dy10);
|
|
||||||
_topPlate10->setBoundingBox(box10);
|
|
||||||
|
|
||||||
|
|
||||||
//topPlate 30:
|
|
||||||
//***********
|
|
||||||
DbU::Unit x30 = enclosureTopMim;
|
|
||||||
DbU::Unit y30 = enclosureTopMim;
|
|
||||||
DbU::Unit dx30 = _l -(2 * enclosureTopMim);
|
|
||||||
DbU::Unit dy30 = _w -(2 * enclosureTopMim) ;
|
|
||||||
Box box30(x30, y30, x30 + dx30, y30 + dy30);
|
|
||||||
_topPlate30->setBoundingBox(box30);
|
|
||||||
|
|
||||||
|
|
||||||
//topPlate 20:
|
|
||||||
//***********
|
|
||||||
DbU::Unit x20 = enclosureTopMim + enclosureVia6 ;
|
|
||||||
DbU::Unit y20 = enclosureTopMim + enclosureVia6 ;
|
|
||||||
DbU::Unit dx20 = widthCut6 ;
|
|
||||||
DbU::Unit dy20 = widthCut6 ;
|
|
||||||
Box box20(x20, y20, x20 + dx20, y20 + dy20);
|
|
||||||
_topPlate20->setBoundingBox(box20);
|
|
||||||
|
|
||||||
|
|
||||||
//bottomPlate 00:
|
|
||||||
//**************
|
|
||||||
DbU::Unit x00 = 0 - enclosureByBotmimTopmim;
|
|
||||||
DbU::Unit y00 = 0 - enclosureByBotmimTopmim;
|
|
||||||
DbU::Unit dx00 = _l + (2 * enclosureByBotmimTopmim);
|
|
||||||
DbU::Unit dy00 = _w + (2 * enclosureByBotmimTopmim);
|
|
||||||
Box box00(x00, y00, x00 + dx00, y00 + dy00);
|
|
||||||
_bottomPlate00->setBoundingBox(box00);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
//emboitement->anonymous01:
|
|
||||||
//************************
|
|
||||||
DbU::Unit x01 = 0 - enclosureByBotmimTopmim - spacingTopmim ;
|
|
||||||
DbU::Unit y01 = 0 - enclosureByBotmimTopmim - spacingTopmim ;
|
|
||||||
DbU::Unit dx01 = _l + (2 * enclosureByBotmimTopmim) + (2 * spacingTopmim);
|
|
||||||
DbU::Unit dy01 = _w + (2 * enclosureByBotmimTopmim) + (2 * spacingTopmim);
|
|
||||||
Box box01(x01, y01, x01 + dx01, y01 + dy01);
|
|
||||||
_anonymous01->setBoundingBox(box01);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Record* Capacitor::_getRecord() const {
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
if (record) {
|
|
||||||
record->add(getSlot("BottomPlate", _bottomPlate));
|
|
||||||
record->add(getSlot("TopPlate", _topPlate));
|
|
||||||
|
|
||||||
record->add(getSlot("L", &_l));
|
|
||||||
record->add(getSlot("W", &_w));
|
|
||||||
|
|
||||||
record->add(getSlot("TopPlate20", _topPlate20));
|
|
||||||
record->add(getSlot("TopPlate30", _topPlate30));
|
|
||||||
record->add(getSlot("TopPlate10", _topPlate10));
|
|
||||||
record->add(getSlot("BottomPlate00", _bottomPlate00));
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
record->add(getSlot("Anonymous01", _anonymous01));
|
|
||||||
record->add(getSlot("Anonymous11", _anonymous11));
|
|
||||||
record->add(getSlot("Anonymous12", _anonymous12));
|
|
||||||
record->add(getSlot("Anonymous13", _anonymous13));
|
|
||||||
record->add(getSlot("Anonymous21", _anonymous21));
|
|
||||||
record->add(getSlot("AnonymousT11", _anonymousT11));
|
|
||||||
record->add(getSlot("AnonymousT12", _anonymousT12));
|
|
||||||
record->add(getSlot("AnonymousT13", _anonymousT13));
|
|
||||||
record->add(getSlot("AnonymousT14", _anonymousT14));
|
|
||||||
record->add(getSlot("AnonymousT21", _anonymousT21));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
#ifndef CAPACITOR_H
|
|
||||||
#define CAPACITOR_H
|
|
||||||
|
|
||||||
#include "AnalogComponent.h"
|
|
||||||
|
|
||||||
class Capacitor : public AnalogComponent {
|
|
||||||
public:
|
|
||||||
static const Name BottomPlateName;
|
|
||||||
static const Name TopPlateName;
|
|
||||||
|
|
||||||
static Capacitor* create(Library* library, const Name& name);
|
|
||||||
void updateLayout();
|
|
||||||
|
|
||||||
// void setType(Type type);
|
|
||||||
// void setType(Type type);
|
|
||||||
|
|
||||||
void setW(DbU::Unit value) { _w = value; updateLayout(); }
|
|
||||||
void setL(DbU::Unit value) { _l = value; updateLayout(); }
|
|
||||||
|
|
||||||
virtual Record* _getRecord() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _postCreate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Net* _bottomPlate;
|
|
||||||
Net* _topPlate;
|
|
||||||
Net* _anonymous;
|
|
||||||
DbU::Unit _l;
|
|
||||||
DbU::Unit _w;
|
|
||||||
Pad* _topPlate10;
|
|
||||||
Pad* _topPlate20;
|
|
||||||
Pad* _topPlate30;
|
|
||||||
Pad* _bottomPlate00;
|
|
||||||
Pad *_anonymous01;
|
|
||||||
Pad *_anonymous11;
|
|
||||||
Pad *_anonymous12;
|
|
||||||
Pad *_anonymous13;
|
|
||||||
Pad *_anonymous21;
|
|
||||||
Pad *_anonymous14;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Capacitor(Library* library, const Name& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // CAPACITOR_H
|
|
|
@ -1,23 +0,0 @@
|
||||||
#ifndef CHOICEPARAMETER_H
|
|
||||||
#define CHOICEPARAMETER_H
|
|
||||||
|
|
||||||
#include "DeviceParameter.h"
|
|
||||||
|
|
||||||
template <class Class>
|
|
||||||
class ChoiceParameter : public Parameter<Class> {
|
|
||||||
public:
|
|
||||||
typedef vector<string> Choices;
|
|
||||||
ChoiceParameter<Class>(string id, Choices& choices,
|
|
||||||
unsigned value, CallBack<Class>* callBack):
|
|
||||||
Parameter<Class>(id, callBack), _choices(), _value(value) {
|
|
||||||
if (_value > choices.size()) {
|
|
||||||
throw Error("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Choices _choices;
|
|
||||||
unsigned _value;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CHOICEPARAMETER_H
|
|
|
@ -1,24 +0,0 @@
|
||||||
#include "hurricane/UpdateSession.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "Device.h"
|
|
||||||
|
|
||||||
Device::Device(Library* library, const Name& name):
|
|
||||||
AnalogComponent(library, name)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Device* Device::create(Library* library, const Name& name) {
|
|
||||||
Device* device = new Device(library, name);
|
|
||||||
|
|
||||||
device->_postCreate();
|
|
||||||
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
/////
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
#ifndef DEVICE_H
|
|
||||||
#define DEVICE_H
|
|
||||||
|
|
||||||
#include "AnalogComponent.h"
|
|
||||||
|
|
||||||
class Device : public AnalogComponent {
|
|
||||||
public:
|
|
||||||
static Device* create(Library* library, const Name& name);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _postCreate();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Device(Library* library, const Name& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // DEVICE_H
|
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef PARAMETER_H
|
|
||||||
#define PARAMETER_H
|
|
||||||
|
|
||||||
#include "CallBack.h"
|
|
||||||
|
|
||||||
class Parameter {
|
|
||||||
public:
|
|
||||||
const string _id;
|
|
||||||
protected:
|
|
||||||
Parameter(string id, CallBack* callBack): _id(id), _callBack(callBack) {}
|
|
||||||
private:
|
|
||||||
CallBack* _callBack;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PARAMETER_H
|
|
|
@ -1,581 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: GenV1Trans.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 04/04/2007
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#include "Technology.h"
|
|
||||||
#include "UpdateSession.h"
|
|
||||||
#include "DataBase.h"
|
|
||||||
|
|
||||||
#include "RdsUnit.h"
|
|
||||||
#include "DtrAccess.h"
|
|
||||||
#include "AnalogicalCommons.h"
|
|
||||||
#include "GenTrans.h"
|
|
||||||
|
|
||||||
#define MAXLONG(a,b) (a>b?a:b)
|
|
||||||
#define MINLONG(a,b) (a>b?b:a)
|
|
||||||
|
|
||||||
#define SAVE_RECTANGLE(s, x, y, dx, dy) \
|
|
||||||
_mapString2Box[string(s)] = Box(getUnit(x), getUnit(y), getUnit(x+dx), getUnit(y+dy)); \
|
|
||||||
xmin = MINLONG(xmin, getUnit(x)); \
|
|
||||||
ymin = MINLONG(ymin, getUnit(y));
|
|
||||||
|
|
||||||
#define GET_RULE(s) \
|
|
||||||
dtraccess->getSingleRdsRuleByLabel(string(s))
|
|
||||||
|
|
||||||
#define BOX_IS_VALID(box) \
|
|
||||||
( (long)(getValue(box.getXMin()))%2==0 )&& \
|
|
||||||
( (long)(getValue(box.getXMax()))%2==0 )&& \
|
|
||||||
( (long)(getValue(box.getYMin()))%2==0 )&& \
|
|
||||||
( (long)(getValue(box.getYMax()))%2==0 )
|
|
||||||
|
|
||||||
#define CREATE_CONTACT_MATRIX_UNDER(underbox, nbcolumn, layer, net) \
|
|
||||||
\
|
|
||||||
if(underbox.getHeight()<rw_cont) \
|
|
||||||
nbcontact = 0; \
|
|
||||||
else \
|
|
||||||
nbcontact = (underbox.getHeight()-rw_cont)/(rw_cont + rd_cont) + 1 ;\
|
|
||||||
\
|
|
||||||
\
|
|
||||||
tmp_xcenter = underbox.getXMin() + (rw_cont/2); \
|
|
||||||
tmp_ycenter = underbox.getYMin() + (rw_cont/2); \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
for(unsigned i=0; i<nbcolumn; i++) { \
|
|
||||||
\
|
|
||||||
for(unsigned j=0; j<nbcontact; j++) { \
|
|
||||||
Contact::create(net, layer \
|
|
||||||
, tmp_xcenter \
|
|
||||||
, tmp_ycenter \
|
|
||||||
, rw_cont \
|
|
||||||
, rw_cont \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
tmp_ycenter += (rw_cont + rd_cont); \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
tmp_xcenter += (rw_cont + rd_cont); \
|
|
||||||
tmp_ycenter = underbox.getYMin() + (rw_cont/2); \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Hurricane {
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Globals Datas
|
|
||||||
// ****************************************************************************************************
|
|
||||||
string segsforsource[] = {string("20"), string("22")};
|
|
||||||
string segsfordrain[] = {string("40"), string("42")};
|
|
||||||
string segsforgrid[] = {string("00"), string("01"), string("30"), string("31")};
|
|
||||||
//string segsforgrid[] = {string("00"), string("30") };
|
|
||||||
string segsforanonym[] = {string("10"), string("11"), string("12"), string("50")};
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Class getV1Trans implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
GenV1Trans::GenV1Trans(Transistor::MaskV1Info* masqueinfo)
|
|
||||||
// *********************************************************
|
|
||||||
: _masqueV1Info(masqueinfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GenV1Trans::Calculate(Transistor* transistor)
|
|
||||||
// **********************************************
|
|
||||||
{
|
|
||||||
DtrAccess* dtraccess = DtrAccess::getDtrAccess();
|
|
||||||
|
|
||||||
// Check out mask param.
|
|
||||||
// *********************
|
|
||||||
if(_masqueV1Info->getL() < dtraccess->getSingleRealRuleByLabel("L_TRANS") ||
|
|
||||||
_masqueV1Info->getL() > dtraccess->getSingleRealRuleByLabel("L_TRANS_MAX") ||
|
|
||||||
_masqueV1Info->getW() < dtraccess->getSingleRealRuleByLabel("W_TRANS") ||
|
|
||||||
_masqueV1Info->getW() > dtraccess->getSingleRealRuleByLabel("W_TRANS_MAX") )
|
|
||||||
|
|
||||||
throw Error("Can't launch function GenV1Trans::Calculate for " + getString(transistor)
|
|
||||||
+ " the L " + getString(_masqueV1Info->getL())
|
|
||||||
+ " or the W " + getString(_masqueV1Info->getW())
|
|
||||||
+ " of this transistor is invalid."
|
|
||||||
);
|
|
||||||
|
|
||||||
if(_masqueV1Info->getNbSourceColumn() < 1 || _masqueV1Info->getNbSourceColumn() > GenV1Trans::maxNbContacts ||
|
|
||||||
_masqueV1Info->getNbDrainColumn() < 1 || _masqueV1Info->getNbDrainColumn() > GenV1Trans::maxNbContacts )
|
|
||||||
|
|
||||||
throw Error("Can't launch function GenV1Trans::Calculate for " + getString(transistor)
|
|
||||||
+ " the nbsourcecolumn " + getString(_masqueV1Info->getNbSourceColumn())
|
|
||||||
+ " or the nbdraincolumn " + getString(_masqueV1Info->getNbDrainColumn())
|
|
||||||
+ " of this transistor is invalid."
|
|
||||||
);
|
|
||||||
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << getString(transistor) + " 's masqueinfo is " + getString(_masqueV1Info)
|
|
||||||
<< endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
|
|
||||||
// Tempory Variable.
|
|
||||||
// **************************
|
|
||||||
long x00, y00, dx00, dy00;
|
|
||||||
long x10, y10, dx10, dy10;
|
|
||||||
long x11, y11, dx11, dy11;
|
|
||||||
long x12, y12, dx12, dy12;
|
|
||||||
long x20, y20, dx20, dy20;
|
|
||||||
long x23, y23, dx23, dy23;
|
|
||||||
long x30, y30, dx30, dy30;
|
|
||||||
long x31, y31, dx31, dy31;
|
|
||||||
long x01, y01, dx01, dy01;
|
|
||||||
long x40, y40, dx40, dy40;
|
|
||||||
long x43, y43, dx43, dy43;
|
|
||||||
long x50, y50, dx50, dy50;
|
|
||||||
|
|
||||||
long xmin = 999999L, ymin = 999999L;
|
|
||||||
long realw = 0;
|
|
||||||
|
|
||||||
// Tempory Variable.
|
|
||||||
// **************************
|
|
||||||
long extension1 = 0;
|
|
||||||
long extension2 = 0;
|
|
||||||
long extension3 = 0;
|
|
||||||
long extension4 = 0;
|
|
||||||
long ymax = 0;
|
|
||||||
string mostype; // get Mos Type (N/P).
|
|
||||||
|
|
||||||
if(transistor->isNmos())
|
|
||||||
mostype='N';
|
|
||||||
else
|
|
||||||
mostype='P';
|
|
||||||
|
|
||||||
//string mostype; // get Mos Type (N/P).
|
|
||||||
//mostype=transistor->getType();
|
|
||||||
|
|
||||||
// -------------------------------------------------------------
|
|
||||||
// Begin Calculate.
|
|
||||||
|
|
||||||
//long re_imp_acti = GET_RULE_BYNP("RE_", mostype, "IMP_ACTI");
|
|
||||||
long re_imp_acti = dtraccess->getSingleRdsRuleByLabel("RE_", mostype, "IMP_ACTI");
|
|
||||||
long re_imp_poly = dtraccess->getSingleRdsRuleByLabel("RE_", mostype, "IMP_POLY");
|
|
||||||
long re_imp_cont = dtraccess->getSingleRdsRuleByLabel("RE_", mostype, "IMP_CONT");
|
|
||||||
long re_imp_gate = dtraccess->getSingleRdsRuleByLabel("RE_", mostype, "IMP_GATE");
|
|
||||||
//long re_well_acti = GET_RULE_BYNP("RE_", mostype, "WELL_ACTI");
|
|
||||||
|
|
||||||
// Calculate Rectangle 00
|
|
||||||
// **********************
|
|
||||||
x00 = 0;
|
|
||||||
y00 = -dtraccess->getSingleRdsRuleByLabel("RE_GATE_ACTI");
|
|
||||||
|
|
||||||
dx00 = ConvertRealToRdsUnit(_masqueV1Info->getL());
|
|
||||||
realw = ConvertRealToRdsUnit(_masqueV1Info->getW());
|
|
||||||
|
|
||||||
dy00 = realw + 2*(-y00);
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("00", x00, y00, dx00, dy00);
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 30
|
|
||||||
// **********************
|
|
||||||
|
|
||||||
// cout << "RD_ACTI_CONT is " << dtraccess->getSingleRdsRuleByLabel("RD_ACTI_CONT")<<endl;
|
|
||||||
// cout << "RD_ACTI_POLY is " << dtraccess->getSingleRdsRuleByLabel("RD_ACTI_POLY")<<endl;
|
|
||||||
// cout << "RE_POLY_CONT is " << dtraccess->getSingleRdsRuleByLabel("RE_POLY_CONT")<<endl;
|
|
||||||
// cout << "MAX RD_ACTI_POLY is " << (MAXLONG(dtraccess->getSingleRdsRuleByLabel("RD_ACTI_CONT"), GET_RULE("RD_ACTI_POLY") + GET_RULE("RE_POLY_CONT"))) <<endl;
|
|
||||||
//
|
|
||||||
|
|
||||||
dx31 = dtraccess->getSingleRdsRuleByLabel("RW_CONT") + 2*GET_RULE("RE_POLY_CONT");
|
|
||||||
if (dx31 >= dx00) {
|
|
||||||
dx30 = dtraccess->getSingleRdsRuleByLabel("RW_CONT");
|
|
||||||
dy30 = dx30;
|
|
||||||
y30 = 0 + realw + MAXLONG(dtraccess->getSingleRdsRuleByLabel("RD_ACTI_CONT"), GET_RULE("RD_ACTI_POLY") + GET_RULE("RE_POLY_CONT"));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dx30 = dx00 - 2*dtraccess->getSingleRdsRuleByLabel("RE_POLY_CONT");
|
|
||||||
dy30 = dtraccess->getSingleRdsRuleByLabel("RW_CONT");
|
|
||||||
y30 = 0 + realw + dtraccess->getSingleRdsRuleByLabel("RD_ACTI_CONT");
|
|
||||||
}
|
|
||||||
|
|
||||||
x30 = x00 + dx00/2 - dx30/2;
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("30", x30, y30, dx30, dy30)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 31
|
|
||||||
// **********************
|
|
||||||
dx31 = dx30 + 2*dtraccess->getSingleRdsRuleByLabel("RE_POLY_CONT");
|
|
||||||
dy31 = dy30 + 2*dtraccess->getSingleRdsRuleByLabel("RE_POLY_CONT");
|
|
||||||
x31 = x30 - dtraccess->getSingleRdsRuleByLabel("RE_POLY_CONT");
|
|
||||||
y31 = y30 - dtraccess->getSingleRdsRuleByLabel("RE_POLY_CONT");
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("31", x31, y31, dx31, dy31)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 01
|
|
||||||
// **********************
|
|
||||||
if ( y31 <= (y00+dy00) ) {
|
|
||||||
x01 = 0; y01 = 0; dx01 = 0; dy01 = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
x01 = x00;
|
|
||||||
y01 = y00 + dy00;
|
|
||||||
dx01 = dx00;
|
|
||||||
dy01 = y31 - (y00 + dy00);
|
|
||||||
}
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("01", x01, y01, dx01, dy01)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 12
|
|
||||||
// **********************
|
|
||||||
x12 = MINLONG(x31, x00) - re_imp_poly;
|
|
||||||
y12 = MINLONG(0 - re_imp_acti, y00 - re_imp_poly);
|
|
||||||
dx12 = MAXLONG(dx31, dx00) + 2 * re_imp_poly;
|
|
||||||
|
|
||||||
ymax = MAXLONG( MAXLONG( y30 + dy30 + re_imp_cont
|
|
||||||
, MAXLONG(y31 + dy31, y00 + dy00) + re_imp_poly )
|
|
||||||
, realw + re_imp_acti );
|
|
||||||
|
|
||||||
dy12 = ymax - y12 ;
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("12", x12, y12, dx12, dy12)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 20
|
|
||||||
// **********************
|
|
||||||
y20 = 0 + dtraccess->getSingleRdsRuleByLabel("RE_ACTI_CONT");
|
|
||||||
dy20 = realw - 2 * dtraccess->getSingleRdsRuleByLabel("RE_ACTI_CONT");
|
|
||||||
dx20 = (_masqueV1Info->getNbSourceColumn()) * dtraccess->getSingleRdsRuleByLabel("RW_CONT") +
|
|
||||||
((_masqueV1Info->getNbSourceColumn()) - 1) * dtraccess->getSingleRdsRuleByLabel("RD_CONT");
|
|
||||||
x20 = 0 - ( dx20 + dtraccess->getSingleRdsRuleByLabel("RD_CONT_GATE") );
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("20", x20, y20, dx20, dy20)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 40
|
|
||||||
// **********************
|
|
||||||
y40 = y20;
|
|
||||||
x40 = x00 + dx00 + dtraccess->getSingleRdsRuleByLabel("RD_CONT_GATE");
|
|
||||||
dx40 = (_masqueV1Info->getNbDrainColumn()) * dtraccess->getSingleRdsRuleByLabel("RW_CONT") +
|
|
||||||
((_masqueV1Info->getNbDrainColumn()) - 1) * dtraccess->getSingleRdsRuleByLabel("RD_CONT");
|
|
||||||
dy40 = dy20;
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("40", x40, y40, dx40, dy40)
|
|
||||||
|
|
||||||
// Calculate Rectangle 10
|
|
||||||
// **********************
|
|
||||||
y10 = 0;
|
|
||||||
x10 = MINLONG(x20 - dtraccess->getSingleRdsRuleByLabel("RE_ACTI_CONT"), 0 - GET_RULE("RE_ACTI_GATE"));
|
|
||||||
dy10 = realw;
|
|
||||||
|
|
||||||
extension1 = MAXLONG(0 + x40 + dx40 + dtraccess->getSingleRdsRuleByLabel("RE_ACTI_CONT"), dx00 + GET_RULE("RE_ACTI_GATE"));
|
|
||||||
|
|
||||||
dx10 = 0 - x10 + extension1;
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("10", x10, y10, dx10, dy10)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 23
|
|
||||||
// ***********************
|
|
||||||
x23 = x10;
|
|
||||||
y23 = y10;
|
|
||||||
dx23 = 0 - x10;
|
|
||||||
dy23 = realw;
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("23", x23, y23, dx23, dy23)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 43
|
|
||||||
// **********************
|
|
||||||
x43 = x00 + dx00 ;
|
|
||||||
y43 = y10;
|
|
||||||
dx43 = x10 + dx10 - (x00 + dx00);
|
|
||||||
dy43 = realw;
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("43", x43, y43, dx43, dy43)
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 11
|
|
||||||
// **********************
|
|
||||||
extension1 = re_imp_gate;
|
|
||||||
extension2 = re_imp_cont + 0 - x20;
|
|
||||||
extension3 = re_imp_acti + 0 - x10;
|
|
||||||
|
|
||||||
extension4 = MAXLONG(MAXLONG(extension1, extension2), extension3);
|
|
||||||
|
|
||||||
x11 = 0 - extension4;
|
|
||||||
|
|
||||||
extension1 = re_imp_gate + x00 + dx00;
|
|
||||||
extension2 = re_imp_cont + x40 + dx40;
|
|
||||||
extension3 = re_imp_acti + x10 + dx10;
|
|
||||||
|
|
||||||
extension4 = MAXLONG(MAXLONG(extension1, extension2), extension3);
|
|
||||||
|
|
||||||
dx11 = 0 - x11 + extension4;
|
|
||||||
|
|
||||||
y11 = MINLONG(y20 - re_imp_cont, y23 - re_imp_acti);
|
|
||||||
|
|
||||||
ymax = MAXLONG(y20 + dy20 + re_imp_cont, y23 + dy23 + re_imp_acti);
|
|
||||||
|
|
||||||
dy11 = ymax - y11;
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("11", x11, y11, dx11, dy11);
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate Rectangle 50 just for PMOS.
|
|
||||||
// -------------------------------------------------------------
|
|
||||||
if (transistor->isPmos()) { // Calculate Rectangle 50 for PMos.
|
|
||||||
x50 = x10 - dtraccess->getSingleRdsRuleByLabel("RE_NWELL_ACTI");
|
|
||||||
y50 = y10 - dtraccess->getSingleRdsRuleByLabel("RE_NWELL_ACTI");
|
|
||||||
dx50 = dx10 + 2 * dtraccess->getSingleRdsRuleByLabel("RE_NWELL_ACTI");
|
|
||||||
dy50 = dy10 + 2 * dtraccess->getSingleRdsRuleByLabel("RE_NWELL_ACTI");
|
|
||||||
|
|
||||||
SAVE_RECTANGLE("50", x50, y50, dx50, dy50);
|
|
||||||
}
|
|
||||||
|
|
||||||
// End Calculate.
|
|
||||||
// -------------------------------------------------------------
|
|
||||||
|
|
||||||
// Translate rectangles.
|
|
||||||
// *********************
|
|
||||||
map<string, Box>::iterator i = _mapString2Box.begin(),
|
|
||||||
j = _mapString2Box.end();
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
_mapString2Box[(*i).first] = (*i).second.translate(-xmin, -ymin);
|
|
||||||
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << (*i).first <<" " << getString((*i).second) << endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
assert(BOX_IS_VALID((*i).second));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GenV1Trans::Generate(Transistor* transistor)
|
|
||||||
// *********************************************
|
|
||||||
{
|
|
||||||
UpdateSession::open();
|
|
||||||
|
|
||||||
Net* source = transistor->getNet(Name(transistor->getSourceName()));
|
|
||||||
Net* drain = transistor->getNet(Name(transistor->getDrainName()) );
|
|
||||||
Net* grid = transistor->getNet(Name(transistor->getGridName()) );
|
|
||||||
|
|
||||||
DtrAccess * dtraccess = DtrAccess::getDtrAccess();
|
|
||||||
//string mostype(1, transistor->getType()); // get Mos Type (N/P).
|
|
||||||
|
|
||||||
string mostype; // get Mos Type (N/P).
|
|
||||||
|
|
||||||
if(transistor->isNmos())
|
|
||||||
mostype='N';
|
|
||||||
else
|
|
||||||
mostype='P';
|
|
||||||
|
|
||||||
long rw_cont = getUnit(dtraccess->getSingleRdsRuleByLabel("RW_CONT"));
|
|
||||||
long rd_cont = getUnit(dtraccess->getSingleRdsRuleByLabel("RD_CONT"));
|
|
||||||
unsigned nbcontact = 0;
|
|
||||||
long tmp_xcenter = 0;
|
|
||||||
long tmp_ycenter = 0;
|
|
||||||
|
|
||||||
DataBase * db = getDataBase();
|
|
||||||
|
|
||||||
if(!db) throw Error("In getV1Trans::Generate : can't find DataBase");
|
|
||||||
|
|
||||||
//Technology * tech = db->getTechnology();
|
|
||||||
|
|
||||||
Layer* layer_20 = dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_20");
|
|
||||||
Layer* layer_30 = dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_30");
|
|
||||||
Layer* layer_40 = dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_40");
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------
|
|
||||||
// Begin Generation.
|
|
||||||
|
|
||||||
// Cenerate Components For Net Source.
|
|
||||||
// ***********************************
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "Begin for create components for net Source of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
for(size_t i=0; i<sizeof(segsforsource)/sizeof(string); i++) {
|
|
||||||
|
|
||||||
if(segsforsource[i]=="20") {
|
|
||||||
//cout << " Begin create contact for source , Under Box is " << getString(_mapString2Box[segsforsource[i])) <<endl;
|
|
||||||
Box underbox = _mapString2Box[segsforsource[i]];
|
|
||||||
CREATE_CONTACT_MATRIX_UNDER(underbox, transistor->getNbSourceColumn(), layer_20, source)
|
|
||||||
//cout << " Finish create contact for source " <<endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Contact::create(source, dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_"+segsforsource[i])
|
|
||||||
// , _mapString2Box[segsforsource[i]].getXCenter()
|
|
||||||
// , _mapString2Box[segsforsource[i]].getYCenter()
|
|
||||||
// , _mapString2Box[segsforsource[i]].getWidth()
|
|
||||||
// , _mapString2Box[segsforsource[i]].getHeight()
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "End for create components for net Source of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
|
|
||||||
// Generate Components For Net Grid.
|
|
||||||
// *********************************
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "Begin for create components for net Grid of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
for(size_t i=0; i<sizeof(segsforgrid)/sizeof(string); i++) {
|
|
||||||
if(segsforgrid[i]=="30"){
|
|
||||||
if( _mapString2Box[segsforgrid[i]].getWidth()==dtraccess->getSingleRdsRuleByLabel("RW_CONT") ) {
|
|
||||||
Contact::create(grid, dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_"+segsforgrid[i])
|
|
||||||
, _mapString2Box[segsforgrid[i]].getXCenter()
|
|
||||||
, _mapString2Box[segsforgrid[i]].getYCenter()
|
|
||||||
, _mapString2Box[segsforgrid[i]].getWidth()
|
|
||||||
, _mapString2Box[segsforgrid[i]].getHeight()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unsigned int nbcolumn = (_mapString2Box[segsforgrid[i]].getWidth()-rw_cont)/(rw_cont + rd_cont) + 1;
|
|
||||||
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "nbcolumn in rectangle 30 is " << nbcolumn <<endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
Box underbox = _mapString2Box[segsforgrid[i]];
|
|
||||||
CREATE_CONTACT_MATRIX_UNDER(underbox, nbcolumn, layer_30, grid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(_mapString2Box[segsforgrid[i]].getXMin() < _mapString2Box[segsforgrid[i]].getXMax()) {
|
|
||||||
Contact::create(grid, dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_"+segsforgrid[i])
|
|
||||||
, _mapString2Box[segsforgrid[i]].getXCenter()
|
|
||||||
, _mapString2Box[segsforgrid[i]].getYCenter()
|
|
||||||
, _mapString2Box[segsforgrid[i]].getWidth()
|
|
||||||
, _mapString2Box[segsforgrid[i]].getHeight()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "End for create components for net Grid of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
|
|
||||||
// Generate Components For Net Drain.
|
|
||||||
// **********************************
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "Begin for create components for net Drain of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
for(size_t i=0; i<sizeof(segsfordrain)/sizeof(string); i++) {
|
|
||||||
|
|
||||||
if(segsfordrain[i]=="40") {
|
|
||||||
//cout << " Begin create contact for drain, Under Box is " << getString(_mapString2Box[segsforsource[i])) <<endl;
|
|
||||||
Box underbox = _mapString2Box[segsfordrain[i]];
|
|
||||||
CREATE_CONTACT_MATRIX_UNDER(underbox, transistor->getNbDrainColumn(), layer_40, drain)
|
|
||||||
//cout << " Finish create contact for drain" <<endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Contact::create(drain, dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_"+segsfordrain[i])
|
|
||||||
, _mapString2Box[segsfordrain[i]].getXCenter()
|
|
||||||
, _mapString2Box[segsfordrain[i]].getYCenter()
|
|
||||||
, _mapString2Box[segsfordrain[i]].getWidth()
|
|
||||||
, _mapString2Box[segsfordrain[i]].getHeight()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "End for create components for net Drain of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
// Generate Components For Anonyms Nets.
|
|
||||||
// *************************************
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "Begin for create components for net Anonyme of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
Net * anonym = Net::create(transistor, Name("anonym"));
|
|
||||||
for(size_t i=0; i<sizeof(segsforanonym)/sizeof(string);i++) {
|
|
||||||
if(transistor->isNmos() && segsforanonym[i]=="50")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Contact::create(anonym, dtraccess->getSingleLayerByLabel("M1TRANS_",mostype,"_LAYER_"+segsforanonym[i])
|
|
||||||
, _mapString2Box[segsforanonym[i]].getXCenter()
|
|
||||||
, _mapString2Box[segsforanonym[i]].getYCenter()
|
|
||||||
, _mapString2Box[segsforanonym[i]].getWidth()
|
|
||||||
, _mapString2Box[segsforanonym[i]].getHeight()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "End for create components for net Anonyme of " << getString(transistor) << endl;
|
|
||||||
END_IF
|
|
||||||
|
|
||||||
// End Generation.
|
|
||||||
// -------------------------------------------------------------
|
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
|
|
||||||
// Set Transistor::_mapNet2Box.
|
|
||||||
// ****************************
|
|
||||||
(*(transistor->_getMapNet2Box()))[grid] = _mapString2Box[string("30")];
|
|
||||||
(*(transistor->_getMapNet2Box()))[source] = _mapString2Box[string("20")];
|
|
||||||
(*(transistor->_getMapNet2Box()))[drain] = _mapString2Box[string("40")];
|
|
||||||
|
|
||||||
cout<< getString(_mapString2Box[string("30")]) <<endl;
|
|
||||||
cout<< getString(_mapString2Box[string("20")]) <<endl;
|
|
||||||
cout<< getString(_mapString2Box[string("40")]) <<endl;
|
|
||||||
|
|
||||||
// Set Abutment Box.
|
|
||||||
// *****************
|
|
||||||
switch(transistor->getAbutmentType().getCode()) {
|
|
||||||
|
|
||||||
case Transistor::Type::INTERNAL :
|
|
||||||
transistor->setAbutmentBox( Box(_mapString2Box[string("20")].getXCenter()
|
|
||||||
, transistor->getBoundingBox().getYMin()
|
|
||||||
, _mapString2Box[string("40")].getXCenter()
|
|
||||||
, transistor->getBoundingBox().getYMax()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Transistor::Type::LEFT:
|
|
||||||
transistor->setAbutmentBox( Box(_mapString2Box[string("11")].getXMin()
|
|
||||||
, transistor->getBoundingBox().getYMin()
|
|
||||||
, _mapString2Box[string("40")].getXCenter()
|
|
||||||
, transistor->getBoundingBox().getYMax()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case Transistor::Type::RIGHT:
|
|
||||||
transistor->setAbutmentBox( Box(_mapString2Box[string("20")].getXCenter()
|
|
||||||
, transistor->getBoundingBox().getYMin()
|
|
||||||
, _mapString2Box[string("11")].getXMax()
|
|
||||||
, transistor->getBoundingBox().getYMax()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break ;
|
|
||||||
|
|
||||||
case Transistor::Type::SINGLE:
|
|
||||||
transistor->setAbutmentBox( Box(_mapString2Box[string("11")].getXMin()
|
|
||||||
, transistor->getBoundingBox().getYMin()
|
|
||||||
, _mapString2Box[string("11")].getXMax()
|
|
||||||
, transistor->getBoundingBox().getYMax()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
break ;
|
|
||||||
|
|
||||||
default :
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
#include "hurricane/UpdateSession.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "Capacitor.h"
|
|
||||||
#include "MetaCapacitor.h"
|
|
||||||
|
|
||||||
const Name MetaCapacitor::BottomPlateName("BOTTOMPLATE");
|
|
||||||
const Name MetaCapacitor::TopPlateName("TOPPLATE");
|
|
||||||
|
|
||||||
MetaCapacitor::MetaCapacitor(Library* library, const Name& name):
|
|
||||||
Device(library, name),
|
|
||||||
_capacitorMatrix(),
|
|
||||||
_rows(0), _columns(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
MetaCapacitor* MetaCapacitor::create(Library* library, const Name& name) {
|
|
||||||
MetaCapacitor* mCapacitor = new MetaCapacitor(library, name);
|
|
||||||
|
|
||||||
mCapacitor->_postCreate();
|
|
||||||
|
|
||||||
return mCapacitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
//création des signaux et des noeuds:
|
|
||||||
//***********************************
|
|
||||||
void MetaCapacitor::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
_bottomPlate = Net::create(this, BottomPlateName);
|
|
||||||
_bottomPlate->setExternal(true);
|
|
||||||
_topPlate = Net::create(this, TopPlateName);
|
|
||||||
_topPlate->setExternal(true);
|
|
||||||
|
|
||||||
setTerminal(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//La matrice des capas:
|
|
||||||
void MetaCapacitor::setMatrixSize(unsigned rows, unsigned columns) {
|
|
||||||
assert(_capacitorMatrix.size() == _rows);
|
|
||||||
|
|
||||||
if (_rows != rows && _columns != columns) {
|
|
||||||
UpdateSession::open();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
#ifndef METACAPACITOR_H
|
|
||||||
#define METACAPACITOR_H
|
|
||||||
|
|
||||||
#include "Device.h"
|
|
||||||
|
|
||||||
class Capacitor;
|
|
||||||
|
|
||||||
class MetaCapacitor : public Device {
|
|
||||||
public:
|
|
||||||
static const Name BottomPlateName;
|
|
||||||
static const Name TopPlateName;
|
|
||||||
static MetaCapacitor* create(Library* library, const Name& name);
|
|
||||||
void setMatrixSize(unsigned rows, unsigned columns);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _postCreate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
MetaCapacitor(Library* library, const Name& name);
|
|
||||||
|
|
||||||
typedef vector<Capacitor*> CapacitorVector;
|
|
||||||
typedef vector<CapacitorVector> CapacitorMatrix;
|
|
||||||
CapacitorMatrix _capacitorMatrix;
|
|
||||||
unsigned _rows;
|
|
||||||
unsigned _columns;
|
|
||||||
Net* _bottomPlate;
|
|
||||||
Net* _topPlate;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // METACAPACITOR_H
|
|
|
@ -1,166 +0,0 @@
|
||||||
#include "hurricane/UpdateSession.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "Transistor.h"
|
|
||||||
#include "MetaTransistor.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
Transistor::Type metaTransistorTypeToTransistorType(const MetaTransistor::Type& type) {
|
|
||||||
switch (type) {
|
|
||||||
case MetaTransistor::Type::UNDEFINED:
|
|
||||||
return Transistor::Type::UNDEFINED;
|
|
||||||
case MetaTransistor::Type::NMOS:
|
|
||||||
return Transistor::Type::NMOS;
|
|
||||||
case MetaTransistor::Type::PMOS:
|
|
||||||
return Transistor::Type::PMOS;
|
|
||||||
default:
|
|
||||||
throw Error("Unknown MetaTransistor Type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const Name MetaTransistor::DrainName("DRAIN");
|
|
||||||
const Name MetaTransistor::SourceName("SOURCE");
|
|
||||||
const Name MetaTransistor::GridName("GRID");
|
|
||||||
const Name MetaTransistor::BulkName("BULK");
|
|
||||||
const Name MetaTransistor::AnonymousName("ANONYMOUS");
|
|
||||||
|
|
||||||
MetaTransistor::Type::Type(const Code& code):
|
|
||||||
_code(code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
MetaTransistor::Type::Type(const Type& type):
|
|
||||||
_code(type._code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
MetaTransistor::Type& MetaTransistor::Type::operator=(const Type& type) {
|
|
||||||
_code = type._code;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
MetaTransistor::MetaTransistor(Library* library, const Name& name):
|
|
||||||
Device(library, name),
|
|
||||||
_drain(NULL),
|
|
||||||
_source(NULL),
|
|
||||||
_grid(NULL),
|
|
||||||
_bulk(NULL),
|
|
||||||
_anonymous(NULL),
|
|
||||||
_type(),
|
|
||||||
_m(0), _l(0.0), _w(0.0),
|
|
||||||
_transistors()
|
|
||||||
{}
|
|
||||||
|
|
||||||
MetaTransistor* MetaTransistor::create(Library* library, const Name& name) {
|
|
||||||
MetaTransistor* mTransistor = new MetaTransistor(library, name);
|
|
||||||
|
|
||||||
mTransistor->_postCreate();
|
|
||||||
|
|
||||||
return mTransistor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetaTransistor::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
_drain = Net::create(this, DrainName);
|
|
||||||
_drain->setExternal(true);
|
|
||||||
_source = Net::create(this, SourceName);
|
|
||||||
_source->setExternal(true);
|
|
||||||
_grid = Net::create(this, GridName);
|
|
||||||
_grid->setExternal(true);
|
|
||||||
_bulk = Net::create(this, BulkName);
|
|
||||||
_bulk->setExternal(true);
|
|
||||||
_anonymous = Net::create(this, AnonymousName);
|
|
||||||
|
|
||||||
setTerminal(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetaTransistor::setType(Type type) {
|
|
||||||
if (type != _type) {
|
|
||||||
UpdateSession::open();
|
|
||||||
_type = type;
|
|
||||||
Transistor::Type ttype = metaTransistorTypeToTransistorType(_type);
|
|
||||||
for (Transistors::iterator tit = _transistors.begin();
|
|
||||||
tit != _transistors.end();
|
|
||||||
tit++) {
|
|
||||||
(*tit)->setType(ttype);
|
|
||||||
}
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MetaTransistor::setM(unsigned m) {
|
|
||||||
assert(_transistors.size() == _m);
|
|
||||||
assert(getInstances().getSize() == _m);
|
|
||||||
if (_m != m) {
|
|
||||||
UpdateSession::open();
|
|
||||||
if (m > _m) {
|
|
||||||
Library* library = getLibrary();
|
|
||||||
Transformation transformation;
|
|
||||||
for (unsigned i=_m; i<m; i++) {
|
|
||||||
string transistorNameStr(getString(getName()));
|
|
||||||
transistorNameStr += "_Transistor_" + getString(i);
|
|
||||||
Name transistorName(transistorNameStr);
|
|
||||||
Transistor* transistor = Transistor::create(library, transistorName);
|
|
||||||
transistor->setType(metaTransistorTypeToTransistorType(_type));
|
|
||||||
transistor->setL(_l);
|
|
||||||
transistor->setW(_w);
|
|
||||||
_transistors.push_back(transistor);
|
|
||||||
Instance* instance = Instance::create(this, transistorName,
|
|
||||||
transistor, transformation, Instance::PlacementStatus::FIXED);
|
|
||||||
instance->getPlug(transistor->getNet(GridName))->setNet(_grid);
|
|
||||||
instance->getPlug(transistor->getNet(SourceName))->setNet(_source);
|
|
||||||
instance->getPlug(transistor->getNet(DrainName))->setNet(_drain);
|
|
||||||
instance->getPlug(transistor->getNet(BulkName))->setNet(_bulk);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (unsigned i=m; i<_m; i++) {
|
|
||||||
Transistor* transistor = _transistors.back();
|
|
||||||
transistor->destroy();
|
|
||||||
_transistors.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateSession::close();
|
|
||||||
_m = m;
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetaTransistor::setW(DbU::Unit value) {
|
|
||||||
_w = value;
|
|
||||||
for (Transistors::iterator tit = _transistors.begin();
|
|
||||||
tit != _transistors.end();
|
|
||||||
tit++) {
|
|
||||||
(*tit)->setW(_w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetaTransistor::setL(DbU::Unit value) {
|
|
||||||
_l = value;
|
|
||||||
for (Transistors::iterator tit = _transistors.begin();
|
|
||||||
tit != _transistors.end();
|
|
||||||
tit++) {
|
|
||||||
(*tit)->setL(_l);
|
|
||||||
}
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MetaTransistor::updateLayout() {
|
|
||||||
if (_m > 0) {
|
|
||||||
assert(_transistors.size() == _m);
|
|
||||||
assert(getInstances().getSize() == _m);
|
|
||||||
|
|
||||||
Transformation transformation(0, 0);
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
for_each_instance(instance, getInstances()) {
|
|
||||||
instance->setTransformation(transformation);
|
|
||||||
Box abox = instance->getAbutmentBox();
|
|
||||||
transformation = Transformation(transformation.getTx() + abox.getWidth(), 0);
|
|
||||||
end_for;
|
|
||||||
}
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
#ifndef METATRANSISTOR_H
|
|
||||||
#define METATRANSISTOR_H
|
|
||||||
|
|
||||||
#include "Device.h"
|
|
||||||
|
|
||||||
class Transistor;
|
|
||||||
|
|
||||||
class MetaTransistor : public Device {
|
|
||||||
public:
|
|
||||||
class Type {
|
|
||||||
public:
|
|
||||||
enum Code {UNDEFINED=0, NMOS=1, PMOS=2};
|
|
||||||
|
|
||||||
Type(const Code& code = UNDEFINED);
|
|
||||||
Type(const Type& type);
|
|
||||||
|
|
||||||
Type& operator=(const Type& type);
|
|
||||||
operator const Code&() const {return _code;};
|
|
||||||
|
|
||||||
const Code& getCode() const {return _code;};
|
|
||||||
|
|
||||||
private:
|
|
||||||
Code _code;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef deque<Transistor*> Transistors;
|
|
||||||
|
|
||||||
static const Name DrainName;
|
|
||||||
static const Name SourceName;
|
|
||||||
static const Name GridName;
|
|
||||||
static const Name BulkName;
|
|
||||||
static const Name AnonymousName;
|
|
||||||
|
|
||||||
static MetaTransistor* create(Library* library, const Name& name);
|
|
||||||
void updateLayout();
|
|
||||||
|
|
||||||
void setType(Type type);
|
|
||||||
void setM(unsigned m);
|
|
||||||
void setW(DbU::Unit value);
|
|
||||||
void setL(DbU::Unit value);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _postCreate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Net* _drain;
|
|
||||||
Net* _source;
|
|
||||||
Net* _grid;
|
|
||||||
Net* _bulk;
|
|
||||||
Net* _anonymous;
|
|
||||||
Type _type;
|
|
||||||
unsigned _m;
|
|
||||||
DbU::Unit _l;
|
|
||||||
DbU::Unit _w;
|
|
||||||
Transistors _transistors;
|
|
||||||
|
|
||||||
MetaTransistor(Library* library, const Name& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // METATRANSISTOR_H
|
|
|
@ -1,21 +0,0 @@
|
||||||
#include "hurricane/UpdateSession.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "Resistor.h"
|
|
||||||
|
|
||||||
Resistor::Resistor(Library* library, const Name& name):
|
|
||||||
AnalogComponent(library, name)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Resistor* Resistor::create(Library* library, const Name& name) {
|
|
||||||
Resistor* resistor = new Resistor(library, name);
|
|
||||||
|
|
||||||
resistor->_postCreate();
|
|
||||||
|
|
||||||
return resistor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resistor::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
#ifndef RESISTOR_H
|
|
||||||
#define RESISTOR_H
|
|
||||||
|
|
||||||
#include "AnalogComponent.h"
|
|
||||||
|
|
||||||
class Resistor : public AnalogComponent {
|
|
||||||
public:
|
|
||||||
static Resistor* create(Library* library, const Name& name);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _postCreate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Resistor(Library* library, const Name& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // RESISTOR_H
|
|
|
@ -1,24 +0,0 @@
|
||||||
#ifndef STEPPARAMETER_H
|
|
||||||
#define STEPPARAMETER_H
|
|
||||||
|
|
||||||
template <Type>
|
|
||||||
class StepParameter : public DeviceParameter {
|
|
||||||
public:
|
|
||||||
StepParameter(Type min, Type max, Type step):
|
|
||||||
_min(min), _max(max), _step(step) {}
|
|
||||||
Type getMin() const { return _min; }
|
|
||||||
Type getMax() const { return _max, }
|
|
||||||
Type getStep() const { return _step; }
|
|
||||||
Type getValue() const { return _value, }
|
|
||||||
void setValue(Type value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Type _min;
|
|
||||||
Type _max;
|
|
||||||
Type _step;
|
|
||||||
Type _value;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef StepParameter<int> StepIntParameter;
|
|
||||||
|
|
||||||
#endif // STEPPARAMETER_H
|
|
|
@ -1,347 +0,0 @@
|
||||||
#include "hurricane/DataBase.h"
|
|
||||||
#include "hurricane/Technology.h"
|
|
||||||
#include "hurricane/UpdateSession.h"
|
|
||||||
#include "hurricane/Pad.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "AEnv.h"
|
|
||||||
#include "ATechnology.h"
|
|
||||||
#include "Transistor.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
Layer* getLayer(Technology* technology, const string& layerStr) {
|
|
||||||
Layer* layer = technology->getLayer(layerStr);
|
|
||||||
if (!layer) {
|
|
||||||
throw Error("Unknown Layer : " + layerStr);
|
|
||||||
}
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pad* createPad(Technology* technology, Net* net, const string& layerName) {
|
|
||||||
static Box emptyBox(0, 0, 0, 0);
|
|
||||||
Layer* layer = getLayer(technology, layerName);
|
|
||||||
Pad* pad = Pad::create(net, layer, emptyBox);
|
|
||||||
return pad;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const Name Transistor::DrainName("DRAIN");
|
|
||||||
const Name Transistor::SourceName("SOURCE");
|
|
||||||
const Name Transistor::GridName("GRID");
|
|
||||||
const Name Transistor::BulkName("BULK");
|
|
||||||
const Name Transistor::AnonymousName("ANONYMOUS");
|
|
||||||
|
|
||||||
Transistor::Type::Type(const Code& code):
|
|
||||||
_code(code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Transistor::Type::Type(const Type& type):
|
|
||||||
_code(type._code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Transistor::Type& Transistor::Type::operator=(const Type& type) {
|
|
||||||
_code = type._code;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Transistor::Transistor(Library* library, const Name& name):
|
|
||||||
AnalogComponent(library, name),
|
|
||||||
_drain(NULL),
|
|
||||||
_source(NULL),
|
|
||||||
_grid(NULL),
|
|
||||||
_bulk(NULL),
|
|
||||||
_anonymous(NULL),
|
|
||||||
_type(),
|
|
||||||
_l(0),
|
|
||||||
_w(0),
|
|
||||||
//_source20(NULL),
|
|
||||||
_source22(NULL),
|
|
||||||
//_drain40(NULL),
|
|
||||||
_drain42(NULL),
|
|
||||||
_grid00(NULL), _grid01(NULL), _grid30(NULL), _grid31(NULL),
|
|
||||||
_anonymous10(NULL), _anonymous11(NULL), _anonymous12(NULL), _anonymous50(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor* Transistor::create(Library* library, const Name& name) {
|
|
||||||
Transistor* transistor = new Transistor(library, name);
|
|
||||||
|
|
||||||
transistor->_postCreate();
|
|
||||||
|
|
||||||
return transistor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Transistor::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
//ChoiceParameter<Transistor>::Choices choices;
|
|
||||||
//choices.push_back(string("N"));
|
|
||||||
//choices.push_back(string("P"));
|
|
||||||
//addParameter(ChoiceParameter<Transistor>("type", choices, 0, new CallBack<Transistor>(this, &Transistor::updateType)));
|
|
||||||
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
Technology* technology = db->getTechnology();
|
|
||||||
_drain = Net::create(this, DrainName);
|
|
||||||
_drain->setExternal(true);
|
|
||||||
_source = Net::create(this, SourceName);
|
|
||||||
_source->setExternal(true);
|
|
||||||
_grid = Net::create(this, GridName);
|
|
||||||
_grid->setExternal(true);
|
|
||||||
_bulk = Net::create(this, BulkName);
|
|
||||||
_bulk->setExternal(true);
|
|
||||||
_anonymous = Net::create(this, AnonymousName);
|
|
||||||
//_source20 = createPad(technology, _source, "cut0");
|
|
||||||
_source22 = createPad(technology, _source, "cut1");
|
|
||||||
//_drain40 = createPad(technology, _drain, "cut0");
|
|
||||||
_drain42 = createPad(technology, _drain, "cut1");
|
|
||||||
_grid00 = createPad(technology, _grid, "poly");
|
|
||||||
_grid01 = createPad(technology, _grid, "poly");
|
|
||||||
_grid30 = createPad(technology, _grid, "cut0");
|
|
||||||
_grid31 = createPad(technology, _grid, "metal1");
|
|
||||||
_anonymous10 = createPad(technology, _anonymous, "active");
|
|
||||||
if (_type == Type::NMOS) {
|
|
||||||
_anonymous11 = createPad(technology, _anonymous, "nImplant");
|
|
||||||
_anonymous12 = createPad(technology, _anonymous, "nImplant");
|
|
||||||
} else {
|
|
||||||
_anonymous11 = createPad(technology, _anonymous, "pImplant");
|
|
||||||
_anonymous12 = createPad(technology, _anonymous, "pImplant");
|
|
||||||
}
|
|
||||||
setTerminal(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Transistor::setType(Type type) {
|
|
||||||
UpdateSession::open();
|
|
||||||
if (type != _type) {
|
|
||||||
_type = type;
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
Technology* technology = db->getTechnology();
|
|
||||||
if (_type == Type::NMOS) {
|
|
||||||
_anonymous11->setLayer(getLayer(technology, "nImplant"));
|
|
||||||
_anonymous12->setLayer(getLayer(technology, "nImplant"));
|
|
||||||
} else {
|
|
||||||
_anonymous11->setLayer(getLayer(technology, "pImplant"));
|
|
||||||
_anonymous12->setLayer(getLayer(technology, "pImplant"));
|
|
||||||
}
|
|
||||||
updateLayout();
|
|
||||||
}
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Transistor::updateLayout() {
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
if (!db) {
|
|
||||||
throw Error("Error : no DataBase");
|
|
||||||
}
|
|
||||||
Technology* techno = db->getTechnology();
|
|
||||||
if (!techno) {
|
|
||||||
throw Error("Error : no Technology");
|
|
||||||
}
|
|
||||||
ATechnology* atechno = AEnv::getATechnology();
|
|
||||||
|
|
||||||
DbU::Unit widthCut0 = atechno->getPhysicalRule("minWidth", getLayer(techno, "cut0"))->getValue();
|
|
||||||
DbU::Unit spacingCut0 = atechno->getPhysicalRule("minSpacing", getLayer(techno, "cut0"))->getValue();
|
|
||||||
DbU::Unit extGateActive = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "poly"), getLayer(techno, "active"))->getValue();
|
|
||||||
DbU::Unit extPolyCut0 = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "poly"), getLayer(techno, "cut0"))->getValue();
|
|
||||||
DbU::Unit spacingActiveCut0 = atechno->getPhysicalRule("minSpacing",
|
|
||||||
getLayer(techno, "active"), getLayer(techno, "cut0"))->getValue();
|
|
||||||
DbU::Unit spacingGateCut0 = atechno->getPhysicalRule("minGateSpacing",
|
|
||||||
getLayer(techno, "cut0"), getLayer(techno, "active"))->getValue();
|
|
||||||
DbU::Unit spacingActivePoly = atechno->getPhysicalRule("minSpacing",
|
|
||||||
getLayer(techno, "active"), getLayer(techno, "poly"))->getValue();
|
|
||||||
DbU::Unit sourceDrainWidth = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "active"), getLayer(techno, "poly"))->getValue();
|
|
||||||
DbU::Unit extActiveCut0 = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "active"), getLayer(techno, "cut0"))->getValue();
|
|
||||||
DbU::Unit enclosurePPlusActive = atechno->getPhysicalRule("minEnclosure",
|
|
||||||
getLayer(techno, "nWell"), getLayer(techno, "active"))->getValue();
|
|
||||||
DbU::Unit enclosureImplantPoly = 0;
|
|
||||||
DbU::Unit enclosureGateImplant = 0;
|
|
||||||
DbU::Unit extImplantActive = 0;
|
|
||||||
DbU::Unit extImplantCut0 = 0;
|
|
||||||
|
|
||||||
if (_type == Type::NMOS) {
|
|
||||||
enclosureImplantPoly = atechno->getPhysicalRule("minEnclosure",
|
|
||||||
getLayer(techno, "nImplant"), getLayer(techno, "poly"))->getValue();
|
|
||||||
enclosureGateImplant = atechno->getPhysicalRule("minGateEnclosure",
|
|
||||||
getLayer(techno, "nImplant"), getLayer(techno, "poly"))->getValue();
|
|
||||||
extImplantActive = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "nImplant"), getLayer(techno, "active"))->getValue();
|
|
||||||
extImplantCut0 = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "nImplant"), getLayer(techno, "cut0"))->getValue();
|
|
||||||
} else {
|
|
||||||
enclosureImplantPoly = atechno->getPhysicalRule("minEnclosure",
|
|
||||||
getLayer(techno, "pImplant"), getLayer(techno, "poly"))->getValue();
|
|
||||||
enclosureGateImplant = atechno->getPhysicalRule("minGateEnclosure",
|
|
||||||
getLayer(techno, "nImplant"), getLayer(techno, "poly"))->getValue();
|
|
||||||
extImplantActive = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "pImplant"), getLayer(techno, "active"))->getValue();
|
|
||||||
extImplantCut0 = atechno->getPhysicalRule("minExtension",
|
|
||||||
getLayer(techno, "pImplant"), getLayer(techno, "cut0"))->getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
DbU::setStringMode(1);
|
|
||||||
|
|
||||||
//grid 00
|
|
||||||
DbU::Unit x00 = 0;
|
|
||||||
DbU::Unit y00 = -extGateActive;
|
|
||||||
DbU::Unit dx00 = _l;
|
|
||||||
DbU::Unit dy00 = _w + extGateActive;
|
|
||||||
Box box00(x00, y00, x00 + dx00, y00 + dy00);
|
|
||||||
_grid00->setBoundingBox(box00);
|
|
||||||
|
|
||||||
//grid30
|
|
||||||
DbU::Unit maxValue = widthCut0 + 2*extPolyCut0;
|
|
||||||
DbU::Unit x30 = 0, dx30 = 0, y30 = 0, dy30 = 0;
|
|
||||||
if (maxValue > _l) {
|
|
||||||
dx30 = widthCut0;
|
|
||||||
dy30 = dx30;
|
|
||||||
y30 = _w + max(spacingActiveCut0, spacingActivePoly + extPolyCut0);
|
|
||||||
} else {
|
|
||||||
dx30 = dx00 - 2*extPolyCut0;
|
|
||||||
dy30 = widthCut0;
|
|
||||||
y30 = _w + spacingActiveCut0;
|
|
||||||
}
|
|
||||||
x30 = x00 + dx00/2 - dx30/2;
|
|
||||||
Box box30(x30, y30, x30 + dx30, y30 + dy30);
|
|
||||||
_grid30->setBoundingBox(box30);
|
|
||||||
|
|
||||||
//grid31
|
|
||||||
DbU::Unit dx31 = dx30 + 2*extPolyCut0;
|
|
||||||
DbU::Unit dy31 = dy30 + 2*extPolyCut0;
|
|
||||||
DbU::Unit x31 = x30 - extPolyCut0;
|
|
||||||
DbU::Unit y31 = y30 - extPolyCut0;
|
|
||||||
Box box31(x31, y31, x31 + dx31, y31 + dy31);
|
|
||||||
_grid31->setBoundingBox(box31);
|
|
||||||
|
|
||||||
//grid01
|
|
||||||
DbU::Unit x01 = 0, y01 = 0, dx01 = 0, dy01 = 0;
|
|
||||||
if (y31 <= y00+dy00) {
|
|
||||||
x01 = 0; y01 = 0; dx01 = 0; dy01 = 0;
|
|
||||||
} else {
|
|
||||||
x01 = x00;
|
|
||||||
y01 = y00 + dy00;
|
|
||||||
dx01 = dx00;
|
|
||||||
dy01 = y31 - (y00 + dy00);
|
|
||||||
}
|
|
||||||
Box box01(x01, y01, x01 + dx01, y01 + dy01);
|
|
||||||
_grid01->setBoundingBox(box01);
|
|
||||||
|
|
||||||
//anonymous12
|
|
||||||
DbU::Unit x12 = min(x31, x00) - enclosureImplantPoly;
|
|
||||||
DbU::Unit y12 = min(0 - extImplantActive, y00 - enclosureImplantPoly);
|
|
||||||
DbU::Unit dx12 = max(dx31, dx00) + 2 * enclosureImplantPoly;
|
|
||||||
DbU::Unit yMax = max( max(y30 + dy30 + extImplantCut0, max(y31 + dy31, y00 + dy00) + enclosureImplantPoly), _w + extImplantActive);
|
|
||||||
DbU::Unit dy12 = yMax - y12;
|
|
||||||
|
|
||||||
Box box12(x12, y12, x12 + dx12, y12 + dy12);
|
|
||||||
_anonymous12->setBoundingBox(box12);
|
|
||||||
|
|
||||||
////_source20
|
|
||||||
DbU::Unit y20 = extActiveCut0;
|
|
||||||
DbU::Unit dy20 = _w - 2 * extActiveCut0;
|
|
||||||
unsigned sourceColumnNumber = 1;
|
|
||||||
DbU::Unit dx20 = sourceColumnNumber * widthCut0 + (sourceColumnNumber - 1) * spacingCut0;
|
|
||||||
DbU::Unit x20 = -(dx20 + spacingGateCut0);
|
|
||||||
//Box box20(x20, y20, x20 + dx20, y20 + dy20);
|
|
||||||
////_source20->setBoundingBox(box20);
|
|
||||||
|
|
||||||
////_drain40
|
|
||||||
//DbU::Unit y40 = y20;
|
|
||||||
DbU::Unit x40 = x00 + dx00 + spacingGateCut0;
|
|
||||||
unsigned drainColumnNumber = 1;
|
|
||||||
DbU::Unit dx40 = drainColumnNumber * widthCut0 + (drainColumnNumber - 1) * (spacingCut0);
|
|
||||||
//DbU::Unit dy40 = dy20;
|
|
||||||
|
|
||||||
//Box box40(x40, y40, x40 + dx40, y40 + dy40);
|
|
||||||
//_drain40->setBoundingBox(box40);
|
|
||||||
|
|
||||||
//_anonymous10
|
|
||||||
DbU::Unit y10 = 0;
|
|
||||||
DbU::Unit x10 = min(x20 - spacingActiveCut0, sourceDrainWidth);
|
|
||||||
DbU::Unit dy10 = _w;
|
|
||||||
DbU::Unit extension10 = max(x40 + dx40 + spacingActiveCut0, dx00 + sourceDrainWidth);
|
|
||||||
DbU::Unit dx10 = -x10 + extension10;
|
|
||||||
|
|
||||||
Box box10(x10, y10, x10 + dx10, y10 + dy10);
|
|
||||||
_anonymous10->setBoundingBox(box10);
|
|
||||||
|
|
||||||
//Rectangle 23
|
|
||||||
DbU::Unit x23 = x10;
|
|
||||||
DbU::Unit y23 = y10;
|
|
||||||
DbU::Unit dx23 = x10;
|
|
||||||
DbU::Unit dy23 = _w;
|
|
||||||
|
|
||||||
|
|
||||||
//_anonymous11
|
|
||||||
DbU::Unit extension11_1 = enclosureGateImplant;
|
|
||||||
DbU::Unit extension11_2 = extImplantCut0 - x20;
|
|
||||||
DbU::Unit extension11_3 = extImplantActive - x10;
|
|
||||||
|
|
||||||
DbU::Unit extension11_4 = max(max(extension11_1, extension11_2), extension11_3);
|
|
||||||
|
|
||||||
DbU::Unit x11 = -extension11_4;
|
|
||||||
|
|
||||||
extension11_1 = enclosureGateImplant + x00 + dx00;
|
|
||||||
extension11_2 = extImplantCut0 + x40 + dx40;
|
|
||||||
extension11_3 = extImplantActive + x10 + dx10;
|
|
||||||
|
|
||||||
extension11_4 = max(max(extension11_1, extension11_2), extension11_3);
|
|
||||||
|
|
||||||
DbU::Unit dx11 = -x11 + extension11_4;
|
|
||||||
|
|
||||||
DbU::Unit y11 = min(y20 - extImplantCut0, y23 - extImplantActive);
|
|
||||||
DbU::Unit dy11 = max(y20 + dy20 + extImplantCut0, y23 + dy23 + extImplantActive) - y11;
|
|
||||||
|
|
||||||
Box box11(x11, y11, x11 + dx11, y11 + dy11);
|
|
||||||
_anonymous11->setBoundingBox(box11);
|
|
||||||
|
|
||||||
if (_type == Type::PMOS) {
|
|
||||||
DbU::Unit x50 = x10 - enclosurePPlusActive;
|
|
||||||
DbU::Unit y50 = y10 - enclosurePPlusActive;
|
|
||||||
DbU::Unit dx50 = dx10 + 2 * enclosurePPlusActive;
|
|
||||||
DbU::Unit dy50 = dy10 + 2 * enclosurePPlusActive;
|
|
||||||
Box box50(x50, y50, x50 + dx50, y50 + dy50);
|
|
||||||
if (!_anonymous50) {
|
|
||||||
_anonymous50 = createPad(techno, _anonymous, "nWell");
|
|
||||||
}
|
|
||||||
_anonymous50->setBoundingBox(box50);
|
|
||||||
} else {
|
|
||||||
if (_anonymous50) {
|
|
||||||
_anonymous50->destroy();
|
|
||||||
_anonymous50 = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAbutmentBox(box12);
|
|
||||||
UpdateSession::close();
|
|
||||||
}
|
|
||||||
|
|
||||||
Record* Transistor::_getRecord() const {
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
if (record) {
|
|
||||||
record->add(getSlot("Drain", _drain));
|
|
||||||
record->add(getSlot("Source", _source));
|
|
||||||
record->add(getSlot("Grid", _grid));
|
|
||||||
record->add(getSlot("Bulk", _bulk));
|
|
||||||
record->add(getSlot("L", &_l));
|
|
||||||
record->add(getSlot("W", &_w));
|
|
||||||
//record->add(getSlot("Source20", _source20));
|
|
||||||
record->add(getSlot("Source22", _source22));
|
|
||||||
//record->add(getSlot("Drain40", _drain40));
|
|
||||||
record->add(getSlot("Drain42", _drain42));
|
|
||||||
record->add(getSlot("Grid00", _grid00));
|
|
||||||
record->add(getSlot("Grid01", _grid01));
|
|
||||||
record->add(getSlot("Grid30", _grid30));
|
|
||||||
record->add(getSlot("Grid31", _grid31));
|
|
||||||
record->add(getSlot("10", _anonymous10));
|
|
||||||
record->add(getSlot("11", _anonymous11));
|
|
||||||
record->add(getSlot("12", _anonymous12));
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
|
@ -1,462 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: Transistor.h
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#include "Vertical.h"
|
|
||||||
#include "Horizontal.h"
|
|
||||||
#include "UpdateSession.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "AnalogicalCommons.h"
|
|
||||||
#include "GenTrans.h"
|
|
||||||
|
|
||||||
#include "Transistor.h"
|
|
||||||
|
|
||||||
namespace Hurricane {
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Transistor::Polarity implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
Transistor::Polarity::Polarity(const Code& code) :_code(code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::Polarity::Polarity(const Polarity& type) :_code(type._code)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::Polarity& Transistor::Polarity::operator=(const Polarity& type) {
|
|
||||||
_code = type._code;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string Transistor::Polarity::_getString() const {
|
|
||||||
switch(_code) {
|
|
||||||
case N : return "N";
|
|
||||||
case P : return "P";
|
|
||||||
}
|
|
||||||
return "ABNORMAL";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Record* Transistor::Polarity::_getRecord() const
|
|
||||||
// *****************************************
|
|
||||||
{
|
|
||||||
Record* record = new Record(getString(this));
|
|
||||||
record->add(getSlot("Code", _code));
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Transistor::MaskVersion implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
Transistor::MaskVersion::MaskVersion(const Code& code)
|
|
||||||
// *******************************************************
|
|
||||||
:_code(code)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Transistor::MaskVersion::MaskVersion(const MaskVersion& version)
|
|
||||||
// *******************************************************************
|
|
||||||
:_code(version._code)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::MaskVersion& Transistor::MaskVersion::operator=(const MaskVersion& version)
|
|
||||||
// ******************************************************************************************
|
|
||||||
{
|
|
||||||
_code = version._code;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string Transistor::MaskVersion::_getString() const
|
|
||||||
// *************************************************
|
|
||||||
{
|
|
||||||
switch(_code) {
|
|
||||||
case VERSION1 : return "VERSION1";
|
|
||||||
}
|
|
||||||
return "ABNORMAL";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Record* Transistor::MaskVersion::_getRecord() const
|
|
||||||
// **************************************************
|
|
||||||
{
|
|
||||||
Record* record = new Record(getString(this));
|
|
||||||
record->add(getSlot("Code", _code));
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Transistor::Type implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
Transistor::Type::Type(const Code& code)
|
|
||||||
// *************************************
|
|
||||||
:_code(code)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::Type::Type(const Type& type)
|
|
||||||
// *************************************
|
|
||||||
:_code(type._code)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::Type& Transistor::Type::operator=(const Type& type)
|
|
||||||
// ************************************************************
|
|
||||||
{
|
|
||||||
_code = type._code;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string Transistor::Type::_getString() const
|
|
||||||
// *****************************************
|
|
||||||
{
|
|
||||||
switch(_code) {
|
|
||||||
case INTERNAL : return "INTERNAL";
|
|
||||||
case LEFT : return "LEFT";
|
|
||||||
case RIGHT : return "RIGHT";
|
|
||||||
case SINGLE : return "SINGLE";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "ABNORMAL";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Record* Transistor::Type::_getRecord() const
|
|
||||||
// *****************************************
|
|
||||||
{
|
|
||||||
Record* record = new Record(getString(this));
|
|
||||||
record->add(getSlot("Code", _code));
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Transistor::MaskInfo implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
Transistor::MaskInfo::MaskInfo(const double& l, const double& w, const Type::Code& type
|
|
||||||
, const unsigned& nbDrainColumn
|
|
||||||
, const unsigned& nbSourceColumn)
|
|
||||||
// ****************************************************************************************************
|
|
||||||
: _l(l)
|
|
||||||
, _w(w)
|
|
||||||
, _type(type)
|
|
||||||
, _nbDrainColumn(nbDrainColumn)
|
|
||||||
, _nbSourceColumn(nbSourceColumn)
|
|
||||||
{};
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::MaskInfo& Transistor::MaskInfo::operator=(const MaskInfo& masqueinfo)
|
|
||||||
// ************************************************************************************
|
|
||||||
{
|
|
||||||
_l = masqueinfo.getL();
|
|
||||||
_w = masqueinfo.getW();
|
|
||||||
_type= masqueinfo.getType();
|
|
||||||
_nbDrainColumn = masqueinfo.getNbDrainColumn();
|
|
||||||
_nbSourceColumn = masqueinfo.getNbSourceColumn();
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Transistor::MaskInfo::operator==(const MaskInfo& masqueinfo)
|
|
||||||
// ******************************************************************
|
|
||||||
{
|
|
||||||
if(_l == masqueinfo.getL() &&
|
|
||||||
_w == masqueinfo.getW() &&
|
|
||||||
_type== masqueinfo.getType() &&
|
|
||||||
_nbDrainColumn == masqueinfo.getNbDrainColumn() &&
|
|
||||||
_nbSourceColumn == masqueinfo.getNbSourceColumn()
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string Transistor::MaskInfo::_getString() const
|
|
||||||
// **********************************************
|
|
||||||
{
|
|
||||||
string s = "<" + _getTypeName() + " "
|
|
||||||
+ getString(_l) + " "
|
|
||||||
+ getString(_w) + " "
|
|
||||||
+ _type._getString() + " "
|
|
||||||
+ getString(_nbSourceColumn) + " "
|
|
||||||
+ getString(_nbDrainColumn)
|
|
||||||
+ ">";
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Record* Transistor::MaskInfo::_getRecord() const
|
|
||||||
// ***********************************************
|
|
||||||
{
|
|
||||||
Record * record = new Record(_getString());
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Transistor::MaskV1Info implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
Transistor::MaskV1Info::MaskV1Info(const double& l, const double& w, const Type::Code& type
|
|
||||||
, const unsigned& nbDrainColumn
|
|
||||||
, const unsigned& nbSourceColumn)
|
|
||||||
// ****************************************************************************************************
|
|
||||||
: Inherit(l
|
|
||||||
, w
|
|
||||||
, type
|
|
||||||
, nbDrainColumn
|
|
||||||
, nbSourceColumn
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Transistor::MaskInfo& Transistor::MaskV1Info::operator=(const MaskInfo& masqueinfo)
|
|
||||||
// **************************************************************************************
|
|
||||||
{
|
|
||||||
// (*(static_cast<Inherit*>(this)))=masqueinfo;
|
|
||||||
Inherit::operator=(masqueinfo);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Transistor::MaskV1Info::operator == (const MaskInfo& masqueinfo)
|
|
||||||
// **********************************************************************
|
|
||||||
{
|
|
||||||
//return (*(static_cast<Inherit*>(this)))==masqueinfo;
|
|
||||||
return Inherit::operator==(masqueinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string Transistor::MaskV1Info::_getString() const
|
|
||||||
// ************************************************
|
|
||||||
{
|
|
||||||
string s = Inherit::_getString();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
Record* Transistor::MaskV1Info::_getRecord() const
|
|
||||||
// *************************************************
|
|
||||||
{
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Transistor implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
Transistor::Transistor(Library* library, const Name& name, const Polarity& polarity) :
|
|
||||||
Inherit(library, name),
|
|
||||||
_polarity(polarity),
|
|
||||||
_masqueInfo(NULL),
|
|
||||||
_genTrans(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor* Transistor::create(Library* library, const Name& name, const Polarity& polarity) {
|
|
||||||
Transistor* transistor = new Transistor(library, name, polarity);
|
|
||||||
|
|
||||||
transistor->_postCreate();
|
|
||||||
|
|
||||||
return transistor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Transistor::_preDestroy() {
|
|
||||||
// Delete aggregated objets.
|
|
||||||
// *************************
|
|
||||||
if(_masqueInfo)
|
|
||||||
delete _masqueInfo;
|
|
||||||
|
|
||||||
if(_genTrans)
|
|
||||||
delete _genTrans;
|
|
||||||
|
|
||||||
Inherit::_preDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Transistor::_postCreate()
|
|
||||||
// *******************************
|
|
||||||
{
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
(Net::create(this, Name("DRAIN")))->setExternal(true);
|
|
||||||
(Net::create(this, Name("SOURCE")))->setExternal(true);
|
|
||||||
(Net::create(this, Name("GRID")))->setExternal(true);
|
|
||||||
(Net::create(this, Name("BULK")))->setExternal(true);
|
|
||||||
|
|
||||||
// By default, transistor's length and heigth is NULL, and is internal.
|
|
||||||
// ********************************************************************
|
|
||||||
_masqueInfo = new MaskV1Info(0.0, 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string Transistor::_getString() const {
|
|
||||||
string s = Inherit::_getString();
|
|
||||||
s.insert(s.length()-1, " " + getString(_polarity));
|
|
||||||
s.insert(s.length()-1, " " + getAbutmentType()._getString());
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Record* Transistor::_getRecord() const {
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::MaskVersion Transistor::_getMaskInfoVersion(MaskInfo* masqueinfo)
|
|
||||||
// ***************************************************************************************
|
|
||||||
{
|
|
||||||
if(!masqueinfo)
|
|
||||||
throw Error("Error : In Transistor::_getMaskInfoVersion, param masqueinfo is NULL");
|
|
||||||
|
|
||||||
if(dynamic_cast<MaskV1Info*>(masqueinfo))
|
|
||||||
return MaskVersion(MaskVersion::VERSION1);
|
|
||||||
|
|
||||||
throw Error("Error : In Transistor::_getMaskInfoVersion, can't dynamic cast param masqueinfo");
|
|
||||||
return MaskVersion(MaskVersion::VERSION1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Transistor::MaskInfo* Transistor::_createMaskInfo(const MaskVersion& version)
|
|
||||||
// *******************************************************************************
|
|
||||||
{
|
|
||||||
switch((const MaskVersion::Code&)version) {
|
|
||||||
case MaskVersion::VERSION1 :
|
|
||||||
return new MaskV1Info(0.0, 0.0);
|
|
||||||
|
|
||||||
default :
|
|
||||||
throw Error ("Error : In Transistor::_createMaskInfoBy, unknown param version");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Transistor::setMaskInfo(MaskInfo* masqueinfo)
|
|
||||||
// ***************************************************
|
|
||||||
{
|
|
||||||
if(!masqueinfo)
|
|
||||||
throw Error("Error : In Transistor::createLayout : masqueinfo is NULL");
|
|
||||||
|
|
||||||
// Set new Param.
|
|
||||||
// ***************
|
|
||||||
MaskVersion newversion = _getMaskInfoVersion(masqueinfo);
|
|
||||||
MaskVersion oldversion = _getMaskInfoVersion(_masqueInfo);
|
|
||||||
|
|
||||||
if(newversion == oldversion) { // If they are the same version.
|
|
||||||
if((*_masqueInfo)==(*masqueinfo)) // If they are identical.
|
|
||||||
return;
|
|
||||||
else
|
|
||||||
(*_masqueInfo)=(*masqueinfo);
|
|
||||||
}
|
|
||||||
else { // If change the version.
|
|
||||||
delete _masqueInfo;
|
|
||||||
_masqueInfo = _createMaskInfo(newversion);
|
|
||||||
(*_masqueInfo) == (*masqueinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Transistor::createLayout()
|
|
||||||
// ****************************
|
|
||||||
{
|
|
||||||
MaskVersion version = _getMaskInfoVersion(_masqueInfo);
|
|
||||||
MaskV1Info* masquev1info = NULL;
|
|
||||||
|
|
||||||
// Select algorithme with technology and masque version.
|
|
||||||
// *****************************************************
|
|
||||||
switch((const MaskVersion::Code&)version) {
|
|
||||||
|
|
||||||
case MaskVersion::VERSION1 :
|
|
||||||
masquev1info = dynamic_cast<MaskV1Info*>(_masqueInfo);
|
|
||||||
_genTrans = new GenV1Trans(masquev1info);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default :
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTerminal(false);
|
|
||||||
|
|
||||||
// Launch the selected algorithme.
|
|
||||||
// ******************************
|
|
||||||
_genTrans->Calculate(this);
|
|
||||||
_genTrans->Generate(this);
|
|
||||||
|
|
||||||
materialize();
|
|
||||||
|
|
||||||
delete _genTrans;
|
|
||||||
_genTrans = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Transistor::duplicateLayout(Transistor* transistor)
|
|
||||||
// *****************************************************
|
|
||||||
{
|
|
||||||
UpdateSession::open();
|
|
||||||
|
|
||||||
setTerminal(false);
|
|
||||||
|
|
||||||
Net * tmp = NULL;
|
|
||||||
Contact * con = NULL;
|
|
||||||
Segment * seg = NULL;
|
|
||||||
|
|
||||||
for_each_net(net, transistor->getNets())
|
|
||||||
if( !( tmp=getNet(net->getName()) ) ) { //
|
|
||||||
tmp = Net::create(this, net->getName());
|
|
||||||
tmp->setExternal(net->isExternal());
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_component(component, net->getComponents())
|
|
||||||
if( (con=dynamic_cast<Contact*>(component)) ){
|
|
||||||
Contact::create(tmp, component->getLayer(), con->getX(), con->getY(), con->getWidth(), con->getHeight());
|
|
||||||
}
|
|
||||||
else if( (seg=dynamic_cast<Vertical*>(component)) ) {
|
|
||||||
Vertical::create(tmp, component->getLayer(), seg->getSourceX(), seg->getWidth(), seg->getSourceY(),
|
|
||||||
seg->getTargetY());
|
|
||||||
}
|
|
||||||
else if( (seg=dynamic_cast<Horizontal*>(component)) ){
|
|
||||||
Horizontal::create(tmp, component->getLayer(), seg->getSourceY(), seg->getWidth(), seg->getSourceX(),
|
|
||||||
seg->getTargetX());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw Error ("Error : In Transistor::DuplicateLayout, find illegal elem : " + getString(component) +
|
|
||||||
"In Transistor, all component must be contact or segment" ) ;
|
|
||||||
end_for
|
|
||||||
end_for
|
|
||||||
|
|
||||||
setAbutmentBox(transistor->getAbutmentBox());
|
|
||||||
|
|
||||||
_mapNet2Box.clear();
|
|
||||||
|
|
||||||
map<Net*, Box>::iterator i = transistor->_getMapNet2Box()->begin(),
|
|
||||||
j = transistor->_getMapNet2Box()->end();
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
_mapNet2Box[getNet((*i).first->getName())]=(*i).second;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
materialize();
|
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
#ifndef TRANSISTOR_H
|
|
||||||
#define TRANSISTOR_H
|
|
||||||
|
|
||||||
#include "AnalogComponent.h"
|
|
||||||
|
|
||||||
class Transistor : public AnalogComponent {
|
|
||||||
public:
|
|
||||||
class Type {
|
|
||||||
public:
|
|
||||||
enum Code {UNDEFINED=0, NMOS=1, PMOS=2};
|
|
||||||
|
|
||||||
Type(const Code& code = UNDEFINED);
|
|
||||||
Type(const Type& type);
|
|
||||||
|
|
||||||
Type& operator=(const Type& type);
|
|
||||||
operator const Code&() const {return _code;};
|
|
||||||
|
|
||||||
const Code& getCode() const {return _code;};
|
|
||||||
|
|
||||||
private:
|
|
||||||
Code _code;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const Name DrainName;
|
|
||||||
static const Name SourceName;
|
|
||||||
static const Name GridName;
|
|
||||||
static const Name BulkName;
|
|
||||||
static const Name AnonymousName;
|
|
||||||
|
|
||||||
static Transistor* create(Library* library, const Name& name);
|
|
||||||
void updateLayout();
|
|
||||||
|
|
||||||
void setType(Type type);
|
|
||||||
void setW(DbU::Unit value) { _w = value; updateLayout(); }
|
|
||||||
void setL(DbU::Unit value) { _l = value; updateLayout(); }
|
|
||||||
|
|
||||||
virtual Record* _getRecord() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _postCreate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Net* _drain;
|
|
||||||
Net* _source;
|
|
||||||
Net* _grid;
|
|
||||||
Net* _bulk;
|
|
||||||
Net* _anonymous;
|
|
||||||
Type _type;
|
|
||||||
DbU::Unit _l;
|
|
||||||
DbU::Unit _w;
|
|
||||||
Pad *_source22;
|
|
||||||
Pad *_drain42;
|
|
||||||
Pad *_grid00, *_grid01, *_grid30, *_grid31;
|
|
||||||
Pad *_anonymous10, *_anonymous11, *_anonymous12, *_anonymous50;
|
|
||||||
|
|
||||||
Transistor(Library* library, const Name& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
//INSPECTOR_P_SUPPORT(Transistor);
|
|
||||||
|
|
||||||
#endif // TRANSISTOR_H
|
|
|
@ -1,59 +0,0 @@
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: Transistors.h
|
|
||||||
// Authors: YIFEI WU
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#ifndef HURRICANE_TRANSISTORS
|
|
||||||
#define HURRICANE_TRANSISTORS
|
|
||||||
|
|
||||||
#include "Collection.h"
|
|
||||||
|
|
||||||
namespace Hurricane {
|
|
||||||
|
|
||||||
class Transistor;
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Transistors declaration
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
typedef GenericCollection<Transistor*> Transistors;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// TransistorLocator declaration
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
typedef GenericLocator<Transistor*> TransistorLocator;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// TransistorFilter declaration
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
typedef GenericFilter<Transistor*> TransistorFilter;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// for_each_transistor declaration
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#define for_each_transistor(transistor, transistors)\
|
|
||||||
/******************************/\
|
|
||||||
{\
|
|
||||||
TransistorLocator _locator = transistors.GetLocator();\
|
|
||||||
while (_locator.IsValid()) {\
|
|
||||||
Transistor* transistor = _locator.GetElement();\
|
|
||||||
_locator.Progress();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HURRICANE_TRANSISTORS
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
INCLUDE_DIRECTORIES(${CHAMSIN_SOURCE_DIR}/src/dtr ${CHAMSIN_SOURCE_DIR}/src/analogic
|
|
||||||
${HURRICANE_INCLUDE_DIR})
|
|
||||||
|
|
||||||
#ADD_LIBRARY(device SHARED Device.cpp TrMos.cpp TrMos_PlaceRoute.cpp)
|
|
||||||
#
|
|
||||||
#TARGET_LINK_LIBRARIES(device analogic dtr hurricane)
|
|
||||||
#
|
|
||||||
#INSTALL(TARGETS device DESTINATION /lib)
|
|
|
@ -1,161 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: Device.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
#include "Device.h"
|
|
||||||
|
|
||||||
#include "Transformation.h"
|
|
||||||
#include "Point.h"
|
|
||||||
#include "Instance.h"
|
|
||||||
#include "Box.h"
|
|
||||||
#include "Error.h"
|
|
||||||
|
|
||||||
#include "Cells.h"
|
|
||||||
#include "DtrAccess.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Static data function
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
static Instance * refins = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static set<Cell*> cellSet;
|
|
||||||
|
|
||||||
|
|
||||||
static void getAllCells(Cell* cell)
|
|
||||||
// ********************************
|
|
||||||
{
|
|
||||||
cellSet.insert(cell);
|
|
||||||
|
|
||||||
if(!(cell->isLeaf())){
|
|
||||||
for_each_instance(instance, cell->getInstances())
|
|
||||||
Cell * mastercell = instance->getMasterCell();
|
|
||||||
getAllCells(mastercell);
|
|
||||||
end_for
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Device implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
Device::Device(Library* library, const Name& name)
|
|
||||||
// **************************************************************************
|
|
||||||
: Inherit(library, name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
//CDataBase* database = getCDataBase();
|
|
||||||
//CCatal* ccatal = database->getCCatal();
|
|
||||||
|
|
||||||
//CCatal::State* state = ccatal->getState(getName(), true);
|
|
||||||
//state->SetFlags(CCatal::State::LOGICAL|CCatal::State::PHYSICAL|CCatal::State::IN_MEMORY|CCatal::State::GDS, true);
|
|
||||||
//state->SetCell(this);
|
|
||||||
//state->SetLibrary(getLibrary());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::SaveLogicalView()
|
|
||||||
// ***************************
|
|
||||||
{
|
|
||||||
cellSet.clear();
|
|
||||||
getAllCells(this);
|
|
||||||
|
|
||||||
//CDataBase * db = getCDataBase();
|
|
||||||
|
|
||||||
// set<Cell*>::iterator i = cellSet.begin(), j = cellSet.end();
|
|
||||||
//
|
|
||||||
// while(i!=j) {
|
|
||||||
// db->SaveCell(*i, CCatal::State::LOGICAL );
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::_Place(Instance* ins, const Transformation::Orientation& orientation, const Point& point)
|
|
||||||
// **************************************************************************************************
|
|
||||||
{
|
|
||||||
if(!ins) {
|
|
||||||
throw Error("Can't Place Instance : ins is NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ins->isPlaced()) {
|
|
||||||
throw Error("Can't Place " + getString(ins) + " : it has already been placed");
|
|
||||||
}
|
|
||||||
|
|
||||||
Transformation transformation(Point(0,0), orientation);
|
|
||||||
Box orientedmastercellbox = transformation.getBox(ins->getMasterCell()->getAbutmentBox());
|
|
||||||
|
|
||||||
Point translation( point.getX() - orientedmastercellbox.getXMin()
|
|
||||||
, point.getY() - orientedmastercellbox.getYMin() );
|
|
||||||
|
|
||||||
Transformation transformation_ins = Transformation(translation, orientation);
|
|
||||||
|
|
||||||
ins->setTransformation(transformation_ins);
|
|
||||||
ins->setPlacementStatus(Instance::PlacementStatus::PLACED);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::_setRefIns(Instance* ins) const
|
|
||||||
// *****************************************
|
|
||||||
{
|
|
||||||
if(!ins) {
|
|
||||||
throw Error("Can't SetRefIns : ref instance is NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ins->isUnplaced()) {
|
|
||||||
throw Error("Can't SetRefIns : ref instance has't been placed");
|
|
||||||
}
|
|
||||||
|
|
||||||
refins = ins;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::_PlaceRight(Instance* ins, const Transformation::Orientation& orientation, const Point& offset)
|
|
||||||
// ********************************************************************************************************
|
|
||||||
{
|
|
||||||
if(!ins) {
|
|
||||||
throw Error("Can't PlaceRight Instance : ins is NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ins->isPlaced()) {
|
|
||||||
throw Error("Can't PlaceRight " + getString(ins) + " : it has already been placed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(!refins) {
|
|
||||||
throw Error("Can't Place Right " + getString(ins) + " : can't find refins");
|
|
||||||
}
|
|
||||||
|
|
||||||
Box refinsbox = refins->getAbutmentBox();
|
|
||||||
|
|
||||||
Transformation transformation(Point(0,0), orientation);
|
|
||||||
Box orientedmastercellbox = transformation.getBox(ins->getMasterCell()->getAbutmentBox());
|
|
||||||
|
|
||||||
Point translation( refinsbox.getXMax() - orientedmastercellbox.getXMin() + offset.getX()
|
|
||||||
, refinsbox.getYMin() - orientedmastercellbox.getYMin() + offset.getY() );
|
|
||||||
|
|
||||||
Transformation transformation_ins = Transformation(translation, orientation);
|
|
||||||
|
|
||||||
ins->setTransformation(transformation_ins);
|
|
||||||
ins->setPlacementStatus(Instance::PlacementStatus::PLACED);
|
|
||||||
|
|
||||||
refins = ins;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Device
|
|
|
@ -1,71 +0,0 @@
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: Device.h
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#ifndef DEVICE_H
|
|
||||||
#define DEVICE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "Cell.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
class Device : public Cell {
|
|
||||||
|
|
||||||
#if !defined(__DOXYGEN_PROCESSOR__)
|
|
||||||
// Types
|
|
||||||
// *****
|
|
||||||
public : typedef Cell Inherit;
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
// **********
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
// ************
|
|
||||||
protected : Device(Library* library, const Name& name);
|
|
||||||
protected : virtual void _postCreate();
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Operations
|
|
||||||
// **********
|
|
||||||
// public : virtual void Create(const char, const bool) = 0;
|
|
||||||
public : virtual void dses() = 0;
|
|
||||||
public : virtual void shape() = 0;
|
|
||||||
// public : virtual void Generate() = 0;
|
|
||||||
|
|
||||||
|
|
||||||
# if !defined(__DOXYGEN_PROCESSOR__)
|
|
||||||
public : virtual void SaveLogicalView();
|
|
||||||
public : virtual void SavePhysicalView() {};
|
|
||||||
|
|
||||||
// Accessors
|
|
||||||
// *********
|
|
||||||
|
|
||||||
// Updators
|
|
||||||
// ********
|
|
||||||
|
|
||||||
// Others
|
|
||||||
// ******
|
|
||||||
public : virtual void _Flush() = 0;
|
|
||||||
|
|
||||||
// Description of Layout
|
|
||||||
// **********************
|
|
||||||
public: void _Place(Instance* ins, const Transformation::Orientation& orientation, const Point& point);
|
|
||||||
public: void _setRefIns(Instance*) const;
|
|
||||||
public: void _PlaceRight(Instance* ins, const Transformation::Orientation& orientation, const Point& offset=Point());
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DEVICE_H
|
|
|
@ -1,417 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: TrMos.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#include "Instance.h"
|
|
||||||
#include "MetaTransistor.h"
|
|
||||||
#include "Net.h"
|
|
||||||
#include "Transistor.h"
|
|
||||||
#include "Transistors.h"
|
|
||||||
|
|
||||||
#include "UpdateSession.h"
|
|
||||||
|
|
||||||
#include "DtrAccess.h"
|
|
||||||
|
|
||||||
#include "TrMos.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// TrMos implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
TrMos::TrMos(Library* library, const Name& name):
|
|
||||||
Device(library, name),
|
|
||||||
_polarity(Transistor::N),
|
|
||||||
_isBsConnected(false),
|
|
||||||
_m(1),
|
|
||||||
_sourceIsFirst(true),
|
|
||||||
_hasDummy(false),
|
|
||||||
_hasRing(true),
|
|
||||||
_tr1(NULL),
|
|
||||||
_capaRouting(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
TrMos* TrMos::create(Library* library, const Name & name) {
|
|
||||||
TrMos* trmos= new TrMos(library, name);
|
|
||||||
trmos->_postCreate();
|
|
||||||
return trmos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrMos::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
// do something.
|
|
||||||
// Initialize pin order list and other attributes.
|
|
||||||
// **********************************************
|
|
||||||
// _lowPinOrder[0]=D;
|
|
||||||
// _lowPinOrder[1]=G;
|
|
||||||
|
|
||||||
// _highPinOrder[0]=S;
|
|
||||||
// _highPinOrder[1]=B;
|
|
||||||
|
|
||||||
_highPinOrder.push_back(D);
|
|
||||||
_highPinOrder.push_back(G);
|
|
||||||
|
|
||||||
_lowPinOrder.push_back(S);
|
|
||||||
_lowPinOrder.push_back(B);
|
|
||||||
|
|
||||||
double minWidth = (DtrAccess::getDtrAccess())->getSingleRealRuleByLabel(string("RW_ALU1"));
|
|
||||||
|
|
||||||
_widthOfSourceWire = minWidth;
|
|
||||||
_widthOfDrainWire = minWidth;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrMos::create(const Transistor::Polarity& polarity, const bool isbsconnected)
|
|
||||||
{
|
|
||||||
if( _tr1 ) {
|
|
||||||
throw Error("Can't Create Logical View of TrMos " + getString(getName()) +
|
|
||||||
" : " + "it has already been created");
|
|
||||||
}
|
|
||||||
|
|
||||||
_polarity = polarity;
|
|
||||||
_isBsConnected = isbsconnected;
|
|
||||||
|
|
||||||
// MetaTransistor is in the same library than Trmos
|
|
||||||
// ************************************************
|
|
||||||
Library * library = getLibrary();
|
|
||||||
|
|
||||||
// Create signals
|
|
||||||
// **************
|
|
||||||
Net * drain = NULL;
|
|
||||||
Net * source = NULL;
|
|
||||||
Net * grid = NULL;
|
|
||||||
Net * bulk = NULL;
|
|
||||||
|
|
||||||
(drain = Net::create(this, Name("drain")))->setExternal(true);
|
|
||||||
(source = Net::create(this, Name("source")))->setExternal(true);
|
|
||||||
(grid = Net::create(this, Name("grid")))->setExternal(true);
|
|
||||||
|
|
||||||
if(!isbsconnected) {
|
|
||||||
(bulk = Net::create(this, Name("bulk")))->setExternal(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Instancier a MetaTransistor and create the connection
|
|
||||||
// The name of MetaTransistor is nameoftrmos_tr1
|
|
||||||
// ****************************************************
|
|
||||||
|
|
||||||
_tr1 = MetaTransistor::create(library, Name( getString(getName())+"_Mos1" ), _polarity);
|
|
||||||
Instance * instance = Instance::create(this,
|
|
||||||
Name("Ins_" + getString(_tr1->getName())),
|
|
||||||
_tr1);
|
|
||||||
|
|
||||||
instance->getPlug(_tr1->getNet(Name("DRAIN")))->setNet(drain);
|
|
||||||
instance->getPlug(_tr1->getNet(Name("SOURCE")))->setNet(source);
|
|
||||||
instance->getPlug(_tr1->getNet(Name("GRID")))->setNet(grid);
|
|
||||||
|
|
||||||
if(!isbsconnected)
|
|
||||||
instance->getPlug(_tr1->getNet(Name("BULK")))->setNet(bulk);
|
|
||||||
else
|
|
||||||
instance->getPlug(_tr1->getNet(Name("BULK")))->setNet(source);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::generate(const unsigned m, const bool sourceisfirst, const bool hasring
|
|
||||||
, const unsigned nbsourcecolumn, const unsigned nbdraincolumn)
|
|
||||||
// *********************************************************************************
|
|
||||||
{
|
|
||||||
if( !_tr1 ) {
|
|
||||||
throw Error("Can't Create Physical View for " + getString(this) +
|
|
||||||
" : " + "Logical view has't been created yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// if( !(_transistorList.empty()) ) {
|
|
||||||
// throw Error("Can't Create Physical View of TrMos " + getString(getName()) + " : "
|
|
||||||
// + "it has already been created");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Check out param of realization.
|
|
||||||
// *******************************
|
|
||||||
if( m <= 0 )
|
|
||||||
throw Error("Can't generate for " + getString(this) + " : m "
|
|
||||||
+ getString(m) + " is invalid.");
|
|
||||||
|
|
||||||
if(nbsourcecolumn<1)
|
|
||||||
throw Error("Can't generate for " + getString(this)
|
|
||||||
+ " : nbsourcecolumn " + getString(nbsourcecolumn) + " is invalid.");
|
|
||||||
|
|
||||||
if(nbdraincolumn<1)
|
|
||||||
throw Error("Can't generate for" + getString(this) + " : nbdraincolumn "
|
|
||||||
+ getString(nbdraincolumn) + " is invalid.");
|
|
||||||
|
|
||||||
|
|
||||||
if(!(_transistorList.empty())) {
|
|
||||||
_Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
_m = m;
|
|
||||||
_sourceIsFirst = sourceisfirst;
|
|
||||||
_hasRing = hasring;
|
|
||||||
|
|
||||||
// Motifs are in the same library than Trmos
|
|
||||||
// *****************************************
|
|
||||||
Library * library = getLibrary();
|
|
||||||
|
|
||||||
cout << "################################################################" << endl <<
|
|
||||||
"#### BEGIN AUTOGENERATON FOR " + _getTypeName() + " " + getString(getName()) + " #####" << endl <<
|
|
||||||
"################################################################" << endl << endl;
|
|
||||||
|
|
||||||
// OpenUpdateSession();
|
|
||||||
|
|
||||||
/* (1) */
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 1 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Create Motifs according to m, and instance the Motifs according
|
|
||||||
// to the Meta-Transistor .
|
|
||||||
// Set m of MetaTransistor.
|
|
||||||
// The name of motif is nameofDevice_nameofMetaTrans_finger_index
|
|
||||||
// ****************************************************************
|
|
||||||
_tr1->setM(_m);
|
|
||||||
|
|
||||||
for(unsigned i=0; i<m; i++){
|
|
||||||
Transistor* finger = Transistor::create(library,
|
|
||||||
getString(_tr1->getName()) + "_Finger_" + getString(i),
|
|
||||||
_polarity);
|
|
||||||
|
|
||||||
_transistorList.push_back(finger);
|
|
||||||
Instance::create(_tr1, Name("Ins_" + getString(finger->getName())), finger);
|
|
||||||
}
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
|
|
||||||
cout << "*** Stage 1 : CreateLayout of " + getString(this) + " finish ***" <<endl;
|
|
||||||
cout << getString(_tr1) + " 's M is " + getString(_tr1->getM()) + ".\n"
|
|
||||||
<< getString(_m) + " Transistors are created.\n" <<endl;
|
|
||||||
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
/* (2) */
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 2 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Create connexion for each MetaTransistor.
|
|
||||||
// *****************************************
|
|
||||||
_tr1->createConnection();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 2 : CreateLayout of " + getString(this) + " finish ***" <<endl;
|
|
||||||
cout << " The connection in " + getString(_tr1) + " is created.\n"
|
|
||||||
<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Pseudo dimensionnement of metatransistor.
|
|
||||||
// In the futur, this will be the work of auto-dimensionnement tool (DSES).
|
|
||||||
// ************************************************************************
|
|
||||||
// _tr1->setLe(10);
|
|
||||||
// _tr1->setWe(11);
|
|
||||||
|
|
||||||
/* (3) */
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 3 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Set dessin Parameter of generation for each finger.
|
|
||||||
// ***************************************************
|
|
||||||
double l_finger = _tr1->getLe() ;
|
|
||||||
double w_finger = (_tr1->getWe()) / (double)(_tr1->getM()) ;
|
|
||||||
unsigned count = 0;
|
|
||||||
|
|
||||||
Transistor::MaskV1Info * masqueinfo = new Transistor::MaskV1Info(l_finger, w_finger);
|
|
||||||
masqueinfo->setNbSourceColumn(nbsourcecolumn);
|
|
||||||
masqueinfo->setNbDrainColumn(nbdraincolumn);
|
|
||||||
|
|
||||||
list<Transistor*>::iterator i = _transistorList.begin()
|
|
||||||
, j = _transistorList.end();
|
|
||||||
|
|
||||||
if(_m == 1) {
|
|
||||||
masqueinfo->setType(Transistor::Type::SINGLE);
|
|
||||||
(*(_transistorList.begin()))->setMaskInfo(masqueinfo);
|
|
||||||
} else if(_m%2==0) { // if m is pair, create two left fingers if is source first.
|
|
||||||
// and create two right fingers if is drain first.
|
|
||||||
while(i!=j) {
|
|
||||||
if(++count>2)
|
|
||||||
masqueinfo->setType(Transistor::Type::INTERNAL);
|
|
||||||
else {
|
|
||||||
if ( _sourceIsFirst )
|
|
||||||
masqueinfo->setType(Transistor::Type::LEFT);
|
|
||||||
else
|
|
||||||
masqueinfo->setType(Transistor::Type::RIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*i)->setMaskInfo(masqueinfo);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
} else if(_m%2==1) { // if m is impair, create one left finger, one right finger.
|
|
||||||
while(i!=j){
|
|
||||||
++ count ;
|
|
||||||
if (count == 1)
|
|
||||||
masqueinfo-> setType(Transistor::Type::LEFT);
|
|
||||||
else if (count == 2)
|
|
||||||
masqueinfo-> setType(Transistor::Type::RIGHT);
|
|
||||||
else
|
|
||||||
masqueinfo-> setType(Transistor::Type::INTERNAL);
|
|
||||||
|
|
||||||
(*i)->setMaskInfo(masqueinfo);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete masqueinfo;
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 3 : CreateLayout of " + getString(this) + " finish ***" <<endl;
|
|
||||||
cout << "Real l_finger is " + getString(l_finger) + "." << endl
|
|
||||||
<< "Real w_finger is " + getString(w_finger) + "." << endl
|
|
||||||
<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
/* (4) */
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 4 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
cout << "Call GenerateLayout for " + getString(_tr1)
|
|
||||||
+ " who will launch the generator of its fingers" << ".\n"
|
|
||||||
<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Call function CreateLayout of MetaTransistor to launch the generator of finger.
|
|
||||||
// *******************************************************************************
|
|
||||||
|
|
||||||
setTerminal(false);
|
|
||||||
//
|
|
||||||
// IF_DEBUG_HUR_ANALOG
|
|
||||||
// cout << endl;
|
|
||||||
// cout << "Real l of " << (long)_tr1 << getString(_tr1) + " is " + getString(_tr1->_le) + "." << endl
|
|
||||||
// << "Real w of " << (long)_tr1 << getString(_tr1) + " is " + getString(_tr1->_we) + "." << endl
|
|
||||||
// <<endl;
|
|
||||||
// END_IF
|
|
||||||
//
|
|
||||||
_tr1->createLayout();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 4 : CreateLayout of " + getString(this) + " finish ***"<<endl
|
|
||||||
<< endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
/* (5) */
|
|
||||||
// Lauch Algo of Placement and routage selected.
|
|
||||||
// *********************************************
|
|
||||||
/* to do */
|
|
||||||
|
|
||||||
_PlaceAndRoute();
|
|
||||||
|
|
||||||
cout << " Place And Route " <<endl;
|
|
||||||
|
|
||||||
for_each_instance(instance, getInstances())
|
|
||||||
//instance->setTransformation(instance->getTransformation());
|
|
||||||
instance->unmaterialize();
|
|
||||||
instance->materialize();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << getString(instance) <<" 's boundingBox is " << getString(instance->getBoundingBox())<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// CloseUpdateSession();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << getString(this) << " 's primary (without wire) boundingBox is " << getString(getBoundingBox()) <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
materialize();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << getString(this) << " 's boundingBox is " << getString(getBoundingBox()) <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
cout << endl
|
|
||||||
<< "################################################################" <<endl
|
|
||||||
<< "#### END AUTOGENERATON FOR " + _getTypeName() + " " + getString(getName()) + " #####" <<endl
|
|
||||||
<< "################################################################" <<endl
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::setLowPinOrder(const PinName pin1, const PinName pin2)
|
|
||||||
// ***************************************************************
|
|
||||||
{
|
|
||||||
_lowPinOrder[0]=pin1;
|
|
||||||
_lowPinOrder[1]=pin2;
|
|
||||||
|
|
||||||
vector<PinName>::iterator i = _lowPinOrder.begin(), j = _lowPinOrder.end();
|
|
||||||
|
|
||||||
cout << " Low Pin Order " << endl;
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
cout << *i << endl;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::setHighPinOrder(const PinName pin1, const PinName pin2)
|
|
||||||
// *****************************************************************
|
|
||||||
{
|
|
||||||
_highPinOrder[0]=pin1;
|
|
||||||
_highPinOrder[1]=pin2;
|
|
||||||
|
|
||||||
vector<PinName>::iterator i = _highPinOrder.begin(), j = _highPinOrder.end();
|
|
||||||
|
|
||||||
cout << " High Pin Order " << endl;
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
cout << *i << endl;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::_Flush()
|
|
||||||
// ****************
|
|
||||||
{
|
|
||||||
if(_transistorList.empty()) {
|
|
||||||
throw Error("Can't delete Physical View of TrMos " + getString(getName()) + " : " + "il doesn't exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
_tr1->Flush();
|
|
||||||
|
|
||||||
_transistorList.clear();
|
|
||||||
|
|
||||||
// Delete all segments of TrMos
|
|
||||||
// ****************************
|
|
||||||
/* to do */
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string TrMos::_getString() const
|
|
||||||
// ***************************************
|
|
||||||
{
|
|
||||||
string s= Inherit::_getString();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
Record* TrMos::_getRecord() const
|
|
||||||
// *********************************
|
|
||||||
{
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of namespace Device
|
|
|
@ -1,126 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: TrMos.h
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#ifndef TRMOS_H
|
|
||||||
#define TRMOS_H
|
|
||||||
|
|
||||||
#include "Net.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "Transistor.h"
|
|
||||||
|
|
||||||
//#include "MetaTransistor.h"
|
|
||||||
#include "Device.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
class TrMos : public Device {
|
|
||||||
|
|
||||||
public : enum PinName { D, G, S, B };
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
// *******************
|
|
||||||
|
|
||||||
// Structural parameter.
|
|
||||||
// ********************
|
|
||||||
private : Transistor::Polarity _polarity;
|
|
||||||
private : bool _isBsConnected;
|
|
||||||
private : unsigned _m;
|
|
||||||
|
|
||||||
// Parameter of the electric synthesis.
|
|
||||||
// ***********************************
|
|
||||||
/* to do */
|
|
||||||
|
|
||||||
// Physical parameter of realization.
|
|
||||||
// **********************************
|
|
||||||
/* Placement. */
|
|
||||||
private : bool _sourceIsFirst;
|
|
||||||
private : bool _hasDummy;
|
|
||||||
private : bool _hasRing;
|
|
||||||
|
|
||||||
/* Routing. */
|
|
||||||
private : vector<PinName> _lowPinOrder; // relative position of the connectors on the basis of the top.
|
|
||||||
private : vector<PinName> _highPinOrder;
|
|
||||||
|
|
||||||
private : map<Net*, Pin*> _mapNetToPinBoxInLeftSide;
|
|
||||||
private : map<Net*, Pin*> _mapNetToPinBoxInRightSide;
|
|
||||||
|
|
||||||
private : double _widthOfSourceWire; // by defect, minWidth, unit of valeur is Micro
|
|
||||||
private : double _widthOfDrainWire; // by defect, minWidth, unit of valeur is Micro
|
|
||||||
|
|
||||||
/* Others */
|
|
||||||
private : MetaTransistor * _tr1;
|
|
||||||
private : double _capaRouting;
|
|
||||||
private : list<Transistor*> _transistorList;
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
// ************
|
|
||||||
protected : TrMos(Library* library, const Name& name);
|
|
||||||
protected : virtual void _postCreate();
|
|
||||||
|
|
||||||
public : static TrMos* create(Library* library, const Name & name);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Operations
|
|
||||||
// **********
|
|
||||||
public : virtual void dses() { /* to do */};
|
|
||||||
public : virtual void shape() { /* to do */};
|
|
||||||
|
|
||||||
|
|
||||||
public : void create(const Transistor::Polarity& polarity, const bool isbsconnected);
|
|
||||||
public : void generate(const unsigned m, const bool sourceisfirst, const bool hasring,
|
|
||||||
const unsigned nbsourcecolumn, const unsigned nbdraincolumn);
|
|
||||||
|
|
||||||
// Accessors
|
|
||||||
// *********
|
|
||||||
public : const Transistor::Polarity& getPolarity() const { return _polarity; };
|
|
||||||
public : unsigned getM() const { return _m; };
|
|
||||||
public : const double getWidthOfSourceWire() const { return _widthOfSourceWire; };
|
|
||||||
public : const double getWidthOfDrainWire() const { return _widthOfDrainWire; };
|
|
||||||
public : MetaTransistor* getTr1() const { return _tr1; };
|
|
||||||
|
|
||||||
// Updators
|
|
||||||
// ********
|
|
||||||
public : void setMosLength(const double length) { if(_tr1) _tr1->setLe(length); }
|
|
||||||
public : void setMosWidth(const double width) { if(_tr1) _tr1->setWe(width); }
|
|
||||||
public : void setWidthOfSourceWire(const double width) { _widthOfSourceWire = width; };
|
|
||||||
public : void setWidthOfDrainWire(const double width) { _widthOfDrainWire=width; };
|
|
||||||
public : void setLowPinOrder(const PinName, const PinName) ;
|
|
||||||
public : void setHighPinOrder(const PinName, const PinName) ;
|
|
||||||
|
|
||||||
// Predicats
|
|
||||||
// *********
|
|
||||||
public : bool isBsConnected() const { return _isBsConnected; };
|
|
||||||
public : bool sourceIsFirst() const { return _sourceIsFirst; };
|
|
||||||
public : bool hasRing() const { return _hasRing; };
|
|
||||||
|
|
||||||
|
|
||||||
# if !defined(__DOXYGEN_PROCESSOR__)
|
|
||||||
|
|
||||||
// Others
|
|
||||||
// ******
|
|
||||||
public: virtual string _getTypeName() const {return _TName("TrMos"); };
|
|
||||||
public: virtual string _getString() const;
|
|
||||||
public: virtual Record* _getRecord() const;
|
|
||||||
|
|
||||||
public: vector<PinName>& getLowPinOrder() { return _lowPinOrder; };
|
|
||||||
public: vector<PinName>& getHighPinOrder() { return _highPinOrder; };
|
|
||||||
|
|
||||||
public: map<Net*, Pin*>& getMapNetToPinBoxInLeftSide() { return _mapNetToPinBoxInLeftSide; };
|
|
||||||
public: map<Net*, Pin*>& getMapNetToPinBoxInRightSide() { return _mapNetToPinBoxInRightSide; };
|
|
||||||
|
|
||||||
public : virtual void _Flush();
|
|
||||||
protected : void _PlaceAndRoute();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // TRMOS_H
|
|
|
@ -1,685 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: TrMos.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
#include "TrMos.h"
|
|
||||||
|
|
||||||
#include "Instances.h"
|
|
||||||
#include "MetaTransistor.h"
|
|
||||||
#include "Net.h"
|
|
||||||
#include "Transistors.h"
|
|
||||||
#include "Box.h"
|
|
||||||
#include "UpdateSession.h"
|
|
||||||
#include "HyperNet.h"
|
|
||||||
#include "DataBase.h"
|
|
||||||
#include "Technology.h"
|
|
||||||
#include "Vertical.h"
|
|
||||||
#include "Horizontal.h"
|
|
||||||
#include "Pin.h"
|
|
||||||
|
|
||||||
#include "RdsUnit.h"
|
|
||||||
#include "Transistor.h"
|
|
||||||
#include "DtrAccess.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "DeviceUtil.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE{
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// TrMos implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
void TrMos::_PlaceAndRoute()
|
|
||||||
// *************************
|
|
||||||
{
|
|
||||||
|
|
||||||
// get Dtr Rules And Calculate the Size of AbutmentBox of Device.
|
|
||||||
// **************************************************************
|
|
||||||
DtrAccess * dtraccess = DtrAccess::getDtrAccess();
|
|
||||||
|
|
||||||
Transistor::Polarity polarity;
|
|
||||||
if(_polarity == Transistor::Polarity::P) polarity = Transistor::Polarity::N;
|
|
||||||
else polarity = Transistor::Polarity::P;
|
|
||||||
|
|
||||||
long minImpWidth = dtraccess->getSingleRdsRuleByLabel("RW_", getString(polarity), "IMP");
|
|
||||||
long minContWidth = dtraccess->getSingleRdsRuleByLabel(string("RW_CONT"));
|
|
||||||
long minAlu1Width = dtraccess->getSingleRdsRuleByLabel(string("RW_ALU1"));
|
|
||||||
long minVia1Width = dtraccess->getSingleRdsRuleByLabel(string("RW_VIA1"));
|
|
||||||
|
|
||||||
long rdImp = dtraccess->getSingleRdsRuleByLabel(string("RD_NIMP"));
|
|
||||||
long rdActive = dtraccess->getSingleRdsRuleByLabel(string("RD_ACTI"));
|
|
||||||
long rdAlu2 = dtraccess->getSingleRdsRuleByLabel(string("RD_ALU1"));
|
|
||||||
|
|
||||||
long reImpActi = dtraccess->getSingleRdsRuleByLabel("RE_", getString(polarity), "IMP_CONT");
|
|
||||||
long reActiContact = dtraccess->getSingleRdsRuleByLabel("RE_ACTI_CONT");
|
|
||||||
long reAlu1Contact = dtraccess->getSingleRdsRuleByLabel("RE_ALU1_CONT");
|
|
||||||
long reAlu1Via1 = dtraccess->getSingleRdsRuleByLabel("RE_ALU1_VIA1");
|
|
||||||
|
|
||||||
long minActiWidth = 2*reActiContact + minContWidth;
|
|
||||||
|
|
||||||
long widthOfSourceWire = ConvertRealToRdsUnit(_widthOfSourceWire);
|
|
||||||
long widthOfDrainWire = ConvertRealToRdsUnit(_widthOfDrainWire);
|
|
||||||
|
|
||||||
long widthOfActive = MAX_INTEGER(minActiWidth, minContWidth + 2*reActiContact);
|
|
||||||
long widthOfImp = MAX_INTEGER(widthOfActive + 2*reImpActi, minImpWidth);
|
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************
|
|
||||||
// Placing .
|
|
||||||
// **************************************************************
|
|
||||||
|
|
||||||
Transformation::Orientation::Code internalTransCode = Transformation::Orientation::ID;
|
|
||||||
|
|
||||||
Unit horizontalMargin = 0; // the horizontal margin of trmos.
|
|
||||||
Unit verticalLowMargin = 0; // the vertical low margin of trmos.
|
|
||||||
Unit verticalHighMargin = 0; // the vertical high margin of trmos.
|
|
||||||
|
|
||||||
Unit fingerHeight = 0; // the height of trmos.
|
|
||||||
Instance * leftins = NULL;
|
|
||||||
Instance * rightins = NULL;
|
|
||||||
|
|
||||||
OccurrenceLocator locator = getLeafInstanceOccurrences().getLocator();
|
|
||||||
Instance * instance = dynamic_cast<Instance*>(locator.getElement().getEntity());;
|
|
||||||
fingerHeight = instance->getCell()->getBoundingBox().getHeight();
|
|
||||||
horizontalMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/4));
|
|
||||||
verticalLowMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/2));
|
|
||||||
verticalHighMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/2));
|
|
||||||
|
|
||||||
|
|
||||||
verticalLowMargin = MAX_INTEGER(verticalLowMargin, getUnit(RETURN_EVEN(rdImp + widthOfImp/2 + widthOfSourceWire
|
|
||||||
+ rdAlu2 + widthOfActive + rdActive)) );
|
|
||||||
|
|
||||||
verticalHighMargin = MAX_INTEGER(verticalHighMargin, horizontalMargin + getUnit(2*rdAlu2 + 2*widthOfDrainWire) );
|
|
||||||
horizontalMargin = MAX_INTEGER(horizontalMargin, getUnit(RETURN_EVEN(rdImp + widthOfImp/2)) );
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
|
|
||||||
if(_m == 1 ) { // If there is only one finger.
|
|
||||||
_Place( instance, Transformation::Orientation::ID, Point( horizontalMargin, verticalLowMargin ) );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// get instance who's model's abutment type is Left or Right.
|
|
||||||
// ************************************************************
|
|
||||||
for_each_occurrence(occurrence, getLeafInstanceOccurrences())
|
|
||||||
instance = dynamic_cast<Instance*>(occurrence.getEntity());
|
|
||||||
Transistor * trans = dynamic_cast<Transistor*>(instance->getMasterCell());
|
|
||||||
|
|
||||||
if ( _sourceIsFirst ) {
|
|
||||||
if(trans->isLeft() && !leftins)
|
|
||||||
leftins = instance;
|
|
||||||
else if ( trans->isLeft() && leftins)
|
|
||||||
rightins = instance;
|
|
||||||
else if ( trans->isRight())
|
|
||||||
rightins = instance;
|
|
||||||
} else {
|
|
||||||
if(trans->isRight() && !leftins)
|
|
||||||
leftins = instance;
|
|
||||||
else if (trans->isRight() && leftins )
|
|
||||||
rightins = instance;
|
|
||||||
else if (trans->isLeft())
|
|
||||||
rightins = instance;
|
|
||||||
}
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// You must place this first instance who's model is left finger in a point who's
|
|
||||||
// x, y are all pair.
|
|
||||||
// Because if you do this, you can be sure that all rectangle of this instance are
|
|
||||||
// correctly in the grille of fondor.
|
|
||||||
// ***********************************************************************************
|
|
||||||
|
|
||||||
if(_sourceIsFirst)
|
|
||||||
_Place( leftins, Transformation::Orientation::ID, Point(horizontalMargin, verticalLowMargin) );
|
|
||||||
else
|
|
||||||
_Place( leftins, Transformation::Orientation::MX, Point(horizontalMargin, verticalLowMargin) );
|
|
||||||
|
|
||||||
_setRefIns(leftins);
|
|
||||||
|
|
||||||
if(_sourceIsFirst) // internal Finger's transformation.
|
|
||||||
internalTransCode = Transformation::Orientation::MX;
|
|
||||||
else
|
|
||||||
internalTransCode = Transformation::Orientation::ID;
|
|
||||||
|
|
||||||
// Place internal finger.
|
|
||||||
// *********************
|
|
||||||
for_each_occurrence(occurrence, getLeafInstanceOccurrences())
|
|
||||||
|
|
||||||
Instance * instance = dynamic_cast<Instance*>(occurrence.getEntity());
|
|
||||||
|
|
||||||
if(instance==leftins || instance==rightins )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_PlaceRight( instance, internalTransCode);
|
|
||||||
|
|
||||||
if(internalTransCode == Transformation::Orientation::MX)
|
|
||||||
internalTransCode = Transformation::Orientation::ID;
|
|
||||||
else
|
|
||||||
internalTransCode = Transformation::Orientation::MX;
|
|
||||||
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// Place the last finger.
|
|
||||||
// **********************
|
|
||||||
Transistor * trans = dynamic_cast<Transistor*>(rightins->getMasterCell());
|
|
||||||
|
|
||||||
if( trans->isRight())
|
|
||||||
_PlaceRight( rightins, Transformation::Orientation::ID);
|
|
||||||
else
|
|
||||||
_PlaceRight( rightins, Transformation::Orientation::MX);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set AbutmentBox.
|
|
||||||
// ****************
|
|
||||||
for_each_instance(instance, getInstances())
|
|
||||||
instance->unmaterialize();
|
|
||||||
instance->materialize();
|
|
||||||
end_for
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
|
|
||||||
|
|
||||||
cout <<"Bounding box of TrMos is "<<getString(getBoundingBox())<<endl;
|
|
||||||
|
|
||||||
setAbutmentBox(Box(0, 0,
|
|
||||||
getBoundingBox().getWidth() + 2*horizontalMargin,
|
|
||||||
getBoundingBox().getHeight() + verticalLowMargin + verticalHighMargin
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************
|
|
||||||
// Routing .
|
|
||||||
// **************************************************************
|
|
||||||
|
|
||||||
Unit expectedInterval = getUnit(RETURN_EVEN((long)(getValue(horizontalMargin))/2));
|
|
||||||
Unit interval = 0;
|
|
||||||
Unit initialPosition = verticalLowMargin + fingerHeight + getUnit(rdAlu2 + widthOfDrainWire/2);
|
|
||||||
|
|
||||||
map<string, Unit> netName2PositionOfConnectorMap;
|
|
||||||
list<Box> routingZoneList;
|
|
||||||
list<Unit> sourcePositionList;
|
|
||||||
list<Unit> drainPositionList;
|
|
||||||
Unit sourceRoutingZoneWidth;
|
|
||||||
Unit drainRoutingZoneWidth;
|
|
||||||
|
|
||||||
DataBase * db = getDataBase();
|
|
||||||
if(!db) throw Error("Can't launch Trmos::PlaceAndRoute for " + getString(this) + " : can't find DataBase");
|
|
||||||
|
|
||||||
Layer * layerAlu1 = db->getTechnology()->getLayer(Name("ALU1"));
|
|
||||||
Layer * layerAlu2 = db->getTechnology()->getLayer(Name("ALU2"));
|
|
||||||
|
|
||||||
Layer * layerVia1 = db->getTechnology()->getLayer(Name("VIA1"));
|
|
||||||
Layer * layerActive = db->getTechnology()->getLayer(Name("ACTIVE"));
|
|
||||||
|
|
||||||
Layer * layerVia01 = db->getTechnology()->getLayer(Name("via01"));
|
|
||||||
Layer * layerVia12 = db->getTechnology()->getLayer(Name("via12"));
|
|
||||||
|
|
||||||
Layer * layerPoly = db->getTechnology()->getLayer(Name("POLY"));
|
|
||||||
Layer * layerNwell = db->getTechnology()->getLayer(Name("NWELL"));
|
|
||||||
Layer * layerCont = db->getTechnology()->getLayer(Name("CONT"));
|
|
||||||
|
|
||||||
Layer * layerImp = NULL;
|
|
||||||
|
|
||||||
if(_polarity == Transistor::Polarity::P)
|
|
||||||
layerImp = db->getTechnology()->getLayer(Name("NIMP"));
|
|
||||||
else
|
|
||||||
layerImp = db->getTechnology()->getLayer(Name("PIMP"));
|
|
||||||
|
|
||||||
Pin * pin = NULL; // For get the adresse of Created Pins.
|
|
||||||
|
|
||||||
long connectorPosition = 0;
|
|
||||||
|
|
||||||
|
|
||||||
cout << " Begin routage " << endl;
|
|
||||||
|
|
||||||
|
|
||||||
// Set position of four connectors.
|
|
||||||
// ********************************
|
|
||||||
vector<PinName>::iterator i = _highPinOrder.begin(),
|
|
||||||
j = _highPinOrder.end();
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
if(*i == D)
|
|
||||||
netName2PositionOfConnectorMap[string("drain")] = initialPosition;
|
|
||||||
if(*i == G)
|
|
||||||
netName2PositionOfConnectorMap[string("grid")] = initialPosition;
|
|
||||||
|
|
||||||
interval = MAX_INTEGER(expectedInterval, getUnit(widthOfDrainWire + rdAlu2));
|
|
||||||
|
|
||||||
// initialPosition += horizontalMargin/2;
|
|
||||||
initialPosition += interval;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<PinName>::iterator m = _lowPinOrder.begin(),
|
|
||||||
n = _lowPinOrder.end();
|
|
||||||
|
|
||||||
//initialPosition = verticalMargin - horizontalMargin/2;
|
|
||||||
//initialPosition = verticalLowMargin - MAX_INTEGER(expectedInterval, getUnit(rdImp + widthOfImp/2));
|
|
||||||
initialPosition = verticalLowMargin - getUnit(rdImp + widthOfImp/2);
|
|
||||||
|
|
||||||
while(m!=n) {
|
|
||||||
if(*m == S)
|
|
||||||
netName2PositionOfConnectorMap[string("source")] = initialPosition;
|
|
||||||
if(*m == B)
|
|
||||||
netName2PositionOfConnectorMap[string("bulk")] = initialPosition;
|
|
||||||
|
|
||||||
interval = MAX_INTEGER(expectedInterval, getUnit(rdAlu2 + widthOfSourceWire));
|
|
||||||
|
|
||||||
initialPosition -= interval;
|
|
||||||
m++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << " Main loop "<< endl;
|
|
||||||
|
|
||||||
// Main Routing Algorithm.
|
|
||||||
// ***********************
|
|
||||||
|
|
||||||
// Main Loop.
|
|
||||||
// **********
|
|
||||||
for_each_net(net, getNets()) // For all hypernets.
|
|
||||||
|
|
||||||
if(getString(net->getName())=="bulk" || getString(net->getName())=="BULK" )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// get Routing Zone.
|
|
||||||
// *****************
|
|
||||||
HyperNet hyperNet(Occurrence(net, Path()));
|
|
||||||
for_each_occurrence(occurrence, hyperNet.getNetOccurrences()) // For all net occurrences.
|
|
||||||
Net * net = dynamic_cast<Net*>(occurrence.getEntity());
|
|
||||||
Box routingZone;
|
|
||||||
|
|
||||||
if(net->getCell()->isLeaf()) {
|
|
||||||
Transistor * trans = dynamic_cast<Transistor*>(net->getCell());
|
|
||||||
if ( !trans )
|
|
||||||
throw Error("Can't launch Trmos::PlaceAndRoute for " + getString(this)
|
|
||||||
+ ", it is not a Transistor");
|
|
||||||
|
|
||||||
cout << getString(occurrence) << endl;
|
|
||||||
cout << getString(occurrence.getPath().getTransformation()) <<endl;
|
|
||||||
cout << getString((*(trans->_getMapNet2Box()))[net]) << endl;
|
|
||||||
|
|
||||||
// get Routing Zone.
|
|
||||||
// *****************
|
|
||||||
routingZone = occurrence.getPath().getTransformation().getBox((*(trans->_getMapNet2Box()))[net]);
|
|
||||||
routingZoneList.push_back(routingZone);
|
|
||||||
|
|
||||||
if(getString(net->getName())=="SOURCE") {
|
|
||||||
sourcePositionList.push_back(routingZone.getXCenter());
|
|
||||||
sourceRoutingZoneWidth = routingZone.getWidth();
|
|
||||||
}
|
|
||||||
else if (getString(net->getName())=="DRAIN") {
|
|
||||||
drainPositionList.push_back(routingZone.getXCenter());
|
|
||||||
drainRoutingZoneWidth = routingZone.getWidth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end_for
|
|
||||||
|
|
||||||
|
|
||||||
cout <<"Print routing zone for " <<getString(net)<<endl;
|
|
||||||
|
|
||||||
list<Box>::iterator it_begin_listbox = routingZoneList.begin(),
|
|
||||||
it_end_listbox = routingZoneList.end();
|
|
||||||
|
|
||||||
while(it_begin_listbox != it_end_listbox)
|
|
||||||
{
|
|
||||||
cout<< getString(*it_begin_listbox) <<endl;
|
|
||||||
it_begin_listbox++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout <<"End Print Routing Zone for "<<getString(net)<<endl;
|
|
||||||
|
|
||||||
// Create routing line.
|
|
||||||
// ********************
|
|
||||||
list<Box>::iterator routingzonelist_begin_it = routingZoneList.begin(),
|
|
||||||
routingzonelist_end_it = routingZoneList.end();
|
|
||||||
|
|
||||||
connectorPosition = netName2PositionOfConnectorMap[getString(net->getName())];
|
|
||||||
cout << "Connector Position is " << netName2PositionOfConnectorMap[getString(net)] << endl;
|
|
||||||
|
|
||||||
while(routingzonelist_begin_it!=routingzonelist_end_it) {
|
|
||||||
|
|
||||||
Box routingZoneBox = *routingzonelist_begin_it;
|
|
||||||
|
|
||||||
// Create vertical line and Contact.
|
|
||||||
// ********************************
|
|
||||||
if(connectorPosition > routingZoneBox.getYMin()) {
|
|
||||||
Vertical::create(net, layerAlu1, routingZoneBox.getXCenter()
|
|
||||||
, routingZoneBox.getWidth() + getUnit(2*reAlu1Contact)
|
|
||||||
, routingZoneBox.getYMin() - getUnit(reAlu1Contact)
|
|
||||||
, connectorPosition);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Vertical::create(net, layerAlu1, routingZoneBox.getXCenter()
|
|
||||||
, routingZoneBox.getWidth() + getUnit(2*reAlu1Contact)
|
|
||||||
, connectorPosition
|
|
||||||
, routingZoneBox.getYMax() + getUnit(reAlu1Contact) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
Contact::create(net, layerVia12, routingZoneBox.getXCenter()
|
|
||||||
, connectorPosition
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
);
|
|
||||||
|
|
||||||
routingzonelist_begin_it ++ ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create horizontal line.
|
|
||||||
// ***********************
|
|
||||||
long widthOfWire = 0;
|
|
||||||
|
|
||||||
if(getString(net->getName())=="source")
|
|
||||||
widthOfWire = widthOfSourceWire;
|
|
||||||
else if(getString(net->getName())=="drain")
|
|
||||||
widthOfWire = widthOfDrainWire;
|
|
||||||
else
|
|
||||||
widthOfWire = widthOfDrainWire;
|
|
||||||
|
|
||||||
|
|
||||||
Horizontal::create(net, layerAlu2, connectorPosition
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
, 0
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create Two Pins.
|
|
||||||
// ****************
|
|
||||||
pin = Pin::create(net
|
|
||||||
, Name(getString(net->getName())+"_west")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::WEST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, connectorPosition
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInLeftSide[net] = pin;
|
|
||||||
|
|
||||||
pin = Pin::create(net
|
|
||||||
, Name(getString(net->getName())+"_east")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::EAST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, connectorPosition
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInRightSide[net] = pin;
|
|
||||||
|
|
||||||
routingZoneList.clear();
|
|
||||||
|
|
||||||
// End Of Main Loop.
|
|
||||||
// *****************
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// Route Net Bulk.
|
|
||||||
// ***************
|
|
||||||
connectorPosition = netName2PositionOfConnectorMap[string("bulk")];
|
|
||||||
|
|
||||||
Net * netBulk = getNet(Name("bulk"));
|
|
||||||
|
|
||||||
if(!netBulk) // bulk and source are connected.
|
|
||||||
netBulk = getNet(Name("source"));
|
|
||||||
|
|
||||||
// Calculate the width of Contact Alu1.
|
|
||||||
// ************************************
|
|
||||||
long widthOfAlu1 = MAX_INTEGER( MAX_INTEGER(minAlu1Width, 2*reAlu1Contact + minContWidth), 2*reAlu1Via1 + minVia1Width);
|
|
||||||
|
|
||||||
Unit bulkPosition = netName2PositionOfConnectorMap[string("bulk")];
|
|
||||||
Unit sourcePosition = netName2PositionOfConnectorMap[string("source")];
|
|
||||||
|
|
||||||
Horizontal::create( netBulk
|
|
||||||
, layerImp
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, 0 - getUnit(reImpActi)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(reImpActi)
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netBulk
|
|
||||||
, layerActive
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfActive)
|
|
||||||
, 0
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netBulk
|
|
||||||
, layerAlu2
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
, 0
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create Two Pins For Net bulk.
|
|
||||||
// *****************************
|
|
||||||
if(!_isBsConnected) {
|
|
||||||
|
|
||||||
pin = Pin::create(netBulk
|
|
||||||
, Name(getString(netBulk->getName())+"_west")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::WEST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInLeftSide[netBulk] = pin;
|
|
||||||
|
|
||||||
pin = Pin::create(netBulk
|
|
||||||
, Name(getString(netBulk->getName())+"_east")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::EAST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInRightSide[netBulk] = pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( netName2PositionOfConnectorMap[string("source")] > netName2PositionOfConnectorMap[string("bulk")] ) {
|
|
||||||
// Source Is Upper Than Bulk.
|
|
||||||
|
|
||||||
cout << " Source is Upper Than Bulk" << endl;
|
|
||||||
|
|
||||||
list<Unit>::iterator i = sourcePositionList.begin(), j = sourcePositionList.end();
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
|
|
||||||
cout << " ######### Create Contact ###########" <<endl;
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia01, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerAlu1, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia12, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
);
|
|
||||||
|
|
||||||
if( _isBsConnected ) { // If bulk and Source are connected.
|
|
||||||
|
|
||||||
cout << " B S is connected in " << *i << endl;
|
|
||||||
|
|
||||||
Vertical::create(netBulk, layerAlu1, *i
|
|
||||||
, sourceRoutingZoneWidth
|
|
||||||
, bulkPosition
|
|
||||||
, sourcePosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
list<Unit>::iterator i , j;
|
|
||||||
|
|
||||||
|
|
||||||
if( _isBsConnected ) { // If bulk and Source are connected.
|
|
||||||
i = sourcePositionList.begin();
|
|
||||||
j = sourcePositionList.end();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
i = drainPositionList.begin();
|
|
||||||
j = drainPositionList.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
|
|
||||||
cout << " ######### Create Contact ###########" <<endl;
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia01, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerAlu1, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia12, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Create Ring.
|
|
||||||
// ************
|
|
||||||
if( _hasRing ) {
|
|
||||||
widthOfImp = MAX_INTEGER(minImpWidth, minActiWidth + 2*reImpActi);
|
|
||||||
|
|
||||||
Net * netRing = Net::create(this, Name("RING"));
|
|
||||||
|
|
||||||
|
|
||||||
// Create rectangle in IMPLANT.
|
|
||||||
// ***************************
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(widthOfImp/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(widthOfImp/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(widthOfImp/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(widthOfImp/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Create rectangle in Active.
|
|
||||||
// ***************************
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(minActiWidth/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(minActiWidth/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(minActiWidth/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(minActiWidth/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Caission NWELL if this is a PMOS.
|
|
||||||
// ****************************************
|
|
||||||
if(_polarity == Transistor::Polarity::P) {
|
|
||||||
Net * netCaisson = Net::create(this, Name("CAISSON"));
|
|
||||||
Contact::create(netCaisson, layerNwell
|
|
||||||
, getAbutmentBox().getXCenter()
|
|
||||||
, getAbutmentBox().getYCenter()
|
|
||||||
, getAbutmentBox().getWidth()
|
|
||||||
, getAbutmentBox().getHeight()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // END OF NAMESPACE DEVICE
|
|
|
@ -1,8 +0,0 @@
|
||||||
INCLUDE_DIRECTORIES(${CHAMSIN_SOURCE_DIR}/src/dtr ${CHAMSIN_SOURCE_DIR}/src/analogic
|
|
||||||
${HURRICANE_INCLUDE_DIR})
|
|
||||||
|
|
||||||
#ADD_LIBRARY(device SHARED Device.cpp TrMos.cpp TrMos_PlaceRoute.cpp)
|
|
||||||
#
|
|
||||||
#TARGET_LINK_LIBRARIES(device analogic dtr hurricane)
|
|
||||||
#
|
|
||||||
#INSTALL(TARGETS device DESTINATION /lib)
|
|
|
@ -1,161 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: Device.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
#include "Device.h"
|
|
||||||
|
|
||||||
#include "Transformation.h"
|
|
||||||
#include "Point.h"
|
|
||||||
#include "Instance.h"
|
|
||||||
#include "Box.h"
|
|
||||||
#include "Error.h"
|
|
||||||
|
|
||||||
#include "Cells.h"
|
|
||||||
#include "DtrAccess.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Static data function
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
static Instance * refins = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
static set<Cell*> cellSet;
|
|
||||||
|
|
||||||
|
|
||||||
static void getAllCells(Cell* cell)
|
|
||||||
// ********************************
|
|
||||||
{
|
|
||||||
cellSet.insert(cell);
|
|
||||||
|
|
||||||
if(!(cell->isLeaf())){
|
|
||||||
for_each_instance(instance, cell->getInstances())
|
|
||||||
Cell * mastercell = instance->getMasterCell();
|
|
||||||
getAllCells(mastercell);
|
|
||||||
end_for
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Device implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
Device::Device(Library* library, const Name& name)
|
|
||||||
// **************************************************************************
|
|
||||||
: Inherit(library, name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
//CDataBase* database = getCDataBase();
|
|
||||||
//CCatal* ccatal = database->getCCatal();
|
|
||||||
|
|
||||||
//CCatal::State* state = ccatal->getState(getName(), true);
|
|
||||||
//state->SetFlags(CCatal::State::LOGICAL|CCatal::State::PHYSICAL|CCatal::State::IN_MEMORY|CCatal::State::GDS, true);
|
|
||||||
//state->SetCell(this);
|
|
||||||
//state->SetLibrary(getLibrary());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::SaveLogicalView()
|
|
||||||
// ***************************
|
|
||||||
{
|
|
||||||
cellSet.clear();
|
|
||||||
getAllCells(this);
|
|
||||||
|
|
||||||
//CDataBase * db = getCDataBase();
|
|
||||||
|
|
||||||
// set<Cell*>::iterator i = cellSet.begin(), j = cellSet.end();
|
|
||||||
//
|
|
||||||
// while(i!=j) {
|
|
||||||
// db->SaveCell(*i, CCatal::State::LOGICAL );
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::_Place(Instance* ins, const Transformation::Orientation& orientation, const Point& point)
|
|
||||||
// **************************************************************************************************
|
|
||||||
{
|
|
||||||
if(!ins) {
|
|
||||||
throw Error("Can't Place Instance : ins is NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ins->isPlaced()) {
|
|
||||||
throw Error("Can't Place " + getString(ins) + " : it has already been placed");
|
|
||||||
}
|
|
||||||
|
|
||||||
Transformation transformation(Point(0,0), orientation);
|
|
||||||
Box orientedmastercellbox = transformation.getBox(ins->getMasterCell()->getAbutmentBox());
|
|
||||||
|
|
||||||
Point translation( point.getX() - orientedmastercellbox.getXMin()
|
|
||||||
, point.getY() - orientedmastercellbox.getYMin() );
|
|
||||||
|
|
||||||
Transformation transformation_ins = Transformation(translation, orientation);
|
|
||||||
|
|
||||||
ins->setTransformation(transformation_ins);
|
|
||||||
ins->setPlacementStatus(Instance::PlacementStatus::PLACED);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::_setRefIns(Instance* ins) const
|
|
||||||
// *****************************************
|
|
||||||
{
|
|
||||||
if(!ins) {
|
|
||||||
throw Error("Can't SetRefIns : ref instance is NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ins->isUnplaced()) {
|
|
||||||
throw Error("Can't SetRefIns : ref instance has't been placed");
|
|
||||||
}
|
|
||||||
|
|
||||||
refins = ins;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Device::_PlaceRight(Instance* ins, const Transformation::Orientation& orientation, const Point& offset)
|
|
||||||
// ********************************************************************************************************
|
|
||||||
{
|
|
||||||
if(!ins) {
|
|
||||||
throw Error("Can't PlaceRight Instance : ins is NULL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ins->isPlaced()) {
|
|
||||||
throw Error("Can't PlaceRight " + getString(ins) + " : it has already been placed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(!refins) {
|
|
||||||
throw Error("Can't Place Right " + getString(ins) + " : can't find refins");
|
|
||||||
}
|
|
||||||
|
|
||||||
Box refinsbox = refins->getAbutmentBox();
|
|
||||||
|
|
||||||
Transformation transformation(Point(0,0), orientation);
|
|
||||||
Box orientedmastercellbox = transformation.getBox(ins->getMasterCell()->getAbutmentBox());
|
|
||||||
|
|
||||||
Point translation( refinsbox.getXMax() - orientedmastercellbox.getXMin() + offset.getX()
|
|
||||||
, refinsbox.getYMin() - orientedmastercellbox.getYMin() + offset.getY() );
|
|
||||||
|
|
||||||
Transformation transformation_ins = Transformation(translation, orientation);
|
|
||||||
|
|
||||||
ins->setTransformation(transformation_ins);
|
|
||||||
ins->setPlacementStatus(Instance::PlacementStatus::PLACED);
|
|
||||||
|
|
||||||
refins = ins;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end namespace Device
|
|
|
@ -1,71 +0,0 @@
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: Device.h
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#ifndef DEVICE_H
|
|
||||||
#define DEVICE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "Cell.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
class Device : public Cell {
|
|
||||||
|
|
||||||
#if !defined(__DOXYGEN_PROCESSOR__)
|
|
||||||
// Types
|
|
||||||
// *****
|
|
||||||
public : typedef Cell Inherit;
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
// **********
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
// ************
|
|
||||||
protected : Device(Library* library, const Name& name);
|
|
||||||
protected : virtual void _postCreate();
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Operations
|
|
||||||
// **********
|
|
||||||
// public : virtual void Create(const char, const bool) = 0;
|
|
||||||
public : virtual void dses() = 0;
|
|
||||||
public : virtual void shape() = 0;
|
|
||||||
// public : virtual void Generate() = 0;
|
|
||||||
|
|
||||||
|
|
||||||
# if !defined(__DOXYGEN_PROCESSOR__)
|
|
||||||
public : virtual void SaveLogicalView();
|
|
||||||
public : virtual void SavePhysicalView() {};
|
|
||||||
|
|
||||||
// Accessors
|
|
||||||
// *********
|
|
||||||
|
|
||||||
// Updators
|
|
||||||
// ********
|
|
||||||
|
|
||||||
// Others
|
|
||||||
// ******
|
|
||||||
public : virtual void _Flush() = 0;
|
|
||||||
|
|
||||||
// Description of Layout
|
|
||||||
// **********************
|
|
||||||
public: void _Place(Instance* ins, const Transformation::Orientation& orientation, const Point& point);
|
|
||||||
public: void _setRefIns(Instance*) const;
|
|
||||||
public: void _PlaceRight(Instance* ins, const Transformation::Orientation& orientation, const Point& offset=Point());
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DEVICE_H
|
|
|
@ -1,77 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: DeviceUtil.h
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 28/05/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
# ifndef DEVICEUTIL_H
|
|
||||||
# define DEVICEUTIL_H
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Identifier Declaration.
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Constants.
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Macros.
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
// Macro Method "RETURN_EVEN(num)"
|
|
||||||
// This Method Macro is return a number even.
|
|
||||||
|
|
||||||
/* \num must be a integer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
# define RETURN_EVEN(num) \
|
|
||||||
(num%2)==0?num:num+1
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
// Macro Method "MAX_INTEGER(a, b)"
|
|
||||||
// This Method Macro is return the Max between a and b.
|
|
||||||
|
|
||||||
/* \a must be a integer.
|
|
||||||
* \b must be a integer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
# define MAX_INTEGER(a, b) \
|
|
||||||
a>b?a:b
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Class.
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Variables.
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Utilitarians (functions).
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
} // END OF NAMESPACE DEVICE
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// Generic Functions.
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
# endif
|
|
|
@ -1,417 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: TrMos.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#include "Instance.h"
|
|
||||||
#include "MetaTransistor.h"
|
|
||||||
#include "Net.h"
|
|
||||||
#include "Transistor.h"
|
|
||||||
#include "Transistors.h"
|
|
||||||
|
|
||||||
#include "UpdateSession.h"
|
|
||||||
|
|
||||||
#include "DtrAccess.h"
|
|
||||||
|
|
||||||
#include "TrMos.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// TrMos implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
TrMos::TrMos(Library* library, const Name& name):
|
|
||||||
Device(library, name),
|
|
||||||
_polarity(Transistor::N),
|
|
||||||
_isBsConnected(false),
|
|
||||||
_m(1),
|
|
||||||
_sourceIsFirst(true),
|
|
||||||
_hasDummy(false),
|
|
||||||
_hasRing(true),
|
|
||||||
_tr1(NULL),
|
|
||||||
_capaRouting(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
TrMos* TrMos::create(Library* library, const Name & name) {
|
|
||||||
TrMos* trmos= new TrMos(library, name);
|
|
||||||
trmos->_postCreate();
|
|
||||||
return trmos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrMos::_postCreate() {
|
|
||||||
Inherit::_postCreate();
|
|
||||||
|
|
||||||
// do something.
|
|
||||||
// Initialize pin order list and other attributes.
|
|
||||||
// **********************************************
|
|
||||||
// _lowPinOrder[0]=D;
|
|
||||||
// _lowPinOrder[1]=G;
|
|
||||||
|
|
||||||
// _highPinOrder[0]=S;
|
|
||||||
// _highPinOrder[1]=B;
|
|
||||||
|
|
||||||
_highPinOrder.push_back(D);
|
|
||||||
_highPinOrder.push_back(G);
|
|
||||||
|
|
||||||
_lowPinOrder.push_back(S);
|
|
||||||
_lowPinOrder.push_back(B);
|
|
||||||
|
|
||||||
double minWidth = (DtrAccess::getDtrAccess())->getSingleRealRuleByLabel(string("RW_ALU1"));
|
|
||||||
|
|
||||||
_widthOfSourceWire = minWidth;
|
|
||||||
_widthOfDrainWire = minWidth;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TrMos::create(const Transistor::Polarity& polarity, const bool isbsconnected)
|
|
||||||
{
|
|
||||||
if( _tr1 ) {
|
|
||||||
throw Error("Can't Create Logical View of TrMos " + getString(getName()) +
|
|
||||||
" : " + "it has already been created");
|
|
||||||
}
|
|
||||||
|
|
||||||
_polarity = polarity;
|
|
||||||
_isBsConnected = isbsconnected;
|
|
||||||
|
|
||||||
// MetaTransistor is in the same library than Trmos
|
|
||||||
// ************************************************
|
|
||||||
Library * library = getLibrary();
|
|
||||||
|
|
||||||
// Create signals
|
|
||||||
// **************
|
|
||||||
Net * drain = NULL;
|
|
||||||
Net * source = NULL;
|
|
||||||
Net * grid = NULL;
|
|
||||||
Net * bulk = NULL;
|
|
||||||
|
|
||||||
(drain = Net::create(this, Name("drain")))->setExternal(true);
|
|
||||||
(source = Net::create(this, Name("source")))->setExternal(true);
|
|
||||||
(grid = Net::create(this, Name("grid")))->setExternal(true);
|
|
||||||
|
|
||||||
if(!isbsconnected) {
|
|
||||||
(bulk = Net::create(this, Name("bulk")))->setExternal(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Instancier a MetaTransistor and create the connection
|
|
||||||
// The name of MetaTransistor is nameoftrmos_tr1
|
|
||||||
// ****************************************************
|
|
||||||
|
|
||||||
_tr1 = MetaTransistor::create(library, Name( getString(getName())+"_Mos1" ), _polarity);
|
|
||||||
Instance * instance = Instance::create(this,
|
|
||||||
Name("Ins_" + getString(_tr1->getName())),
|
|
||||||
_tr1);
|
|
||||||
|
|
||||||
instance->getPlug(_tr1->getNet(Name("DRAIN")))->setNet(drain);
|
|
||||||
instance->getPlug(_tr1->getNet(Name("SOURCE")))->setNet(source);
|
|
||||||
instance->getPlug(_tr1->getNet(Name("GRID")))->setNet(grid);
|
|
||||||
|
|
||||||
if(!isbsconnected)
|
|
||||||
instance->getPlug(_tr1->getNet(Name("BULK")))->setNet(bulk);
|
|
||||||
else
|
|
||||||
instance->getPlug(_tr1->getNet(Name("BULK")))->setNet(source);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::generate(const unsigned m, const bool sourceisfirst, const bool hasring
|
|
||||||
, const unsigned nbsourcecolumn, const unsigned nbdraincolumn)
|
|
||||||
// *********************************************************************************
|
|
||||||
{
|
|
||||||
if( !_tr1 ) {
|
|
||||||
throw Error("Can't Create Physical View for " + getString(this) +
|
|
||||||
" : " + "Logical view has't been created yet.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// if( !(_transistorList.empty()) ) {
|
|
||||||
// throw Error("Can't Create Physical View of TrMos " + getString(getName()) + " : "
|
|
||||||
// + "it has already been created");
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Check out param of realization.
|
|
||||||
// *******************************
|
|
||||||
if( m <= 0 )
|
|
||||||
throw Error("Can't generate for " + getString(this) + " : m "
|
|
||||||
+ getString(m) + " is invalid.");
|
|
||||||
|
|
||||||
if(nbsourcecolumn<1)
|
|
||||||
throw Error("Can't generate for " + getString(this)
|
|
||||||
+ " : nbsourcecolumn " + getString(nbsourcecolumn) + " is invalid.");
|
|
||||||
|
|
||||||
if(nbdraincolumn<1)
|
|
||||||
throw Error("Can't generate for" + getString(this) + " : nbdraincolumn "
|
|
||||||
+ getString(nbdraincolumn) + " is invalid.");
|
|
||||||
|
|
||||||
|
|
||||||
if(!(_transistorList.empty())) {
|
|
||||||
_Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
_m = m;
|
|
||||||
_sourceIsFirst = sourceisfirst;
|
|
||||||
_hasRing = hasring;
|
|
||||||
|
|
||||||
// Motifs are in the same library than Trmos
|
|
||||||
// *****************************************
|
|
||||||
Library * library = getLibrary();
|
|
||||||
|
|
||||||
cout << "################################################################" << endl <<
|
|
||||||
"#### BEGIN AUTOGENERATON FOR " + _getTypeName() + " " + getString(getName()) + " #####" << endl <<
|
|
||||||
"################################################################" << endl << endl;
|
|
||||||
|
|
||||||
// OpenUpdateSession();
|
|
||||||
|
|
||||||
/* (1) */
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 1 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Create Motifs according to m, and instance the Motifs according
|
|
||||||
// to the Meta-Transistor .
|
|
||||||
// Set m of MetaTransistor.
|
|
||||||
// The name of motif is nameofDevice_nameofMetaTrans_finger_index
|
|
||||||
// ****************************************************************
|
|
||||||
_tr1->setM(_m);
|
|
||||||
|
|
||||||
for(unsigned i=0; i<m; i++){
|
|
||||||
Transistor* finger = Transistor::create(library,
|
|
||||||
getString(_tr1->getName()) + "_Finger_" + getString(i),
|
|
||||||
_polarity);
|
|
||||||
|
|
||||||
_transistorList.push_back(finger);
|
|
||||||
Instance::create(_tr1, Name("Ins_" + getString(finger->getName())), finger);
|
|
||||||
}
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
|
|
||||||
cout << "*** Stage 1 : CreateLayout of " + getString(this) + " finish ***" <<endl;
|
|
||||||
cout << getString(_tr1) + " 's M is " + getString(_tr1->getM()) + ".\n"
|
|
||||||
<< getString(_m) + " Transistors are created.\n" <<endl;
|
|
||||||
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
/* (2) */
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 2 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Create connexion for each MetaTransistor.
|
|
||||||
// *****************************************
|
|
||||||
_tr1->createConnection();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 2 : CreateLayout of " + getString(this) + " finish ***" <<endl;
|
|
||||||
cout << " The connection in " + getString(_tr1) + " is created.\n"
|
|
||||||
<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Pseudo dimensionnement of metatransistor.
|
|
||||||
// In the futur, this will be the work of auto-dimensionnement tool (DSES).
|
|
||||||
// ************************************************************************
|
|
||||||
// _tr1->setLe(10);
|
|
||||||
// _tr1->setWe(11);
|
|
||||||
|
|
||||||
/* (3) */
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 3 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Set dessin Parameter of generation for each finger.
|
|
||||||
// ***************************************************
|
|
||||||
double l_finger = _tr1->getLe() ;
|
|
||||||
double w_finger = (_tr1->getWe()) / (double)(_tr1->getM()) ;
|
|
||||||
unsigned count = 0;
|
|
||||||
|
|
||||||
Transistor::MaskV1Info * masqueinfo = new Transistor::MaskV1Info(l_finger, w_finger);
|
|
||||||
masqueinfo->setNbSourceColumn(nbsourcecolumn);
|
|
||||||
masqueinfo->setNbDrainColumn(nbdraincolumn);
|
|
||||||
|
|
||||||
list<Transistor*>::iterator i = _transistorList.begin()
|
|
||||||
, j = _transistorList.end();
|
|
||||||
|
|
||||||
if(_m == 1) {
|
|
||||||
masqueinfo->setType(Transistor::Type::SINGLE);
|
|
||||||
(*(_transistorList.begin()))->setMaskInfo(masqueinfo);
|
|
||||||
} else if(_m%2==0) { // if m is pair, create two left fingers if is source first.
|
|
||||||
// and create two right fingers if is drain first.
|
|
||||||
while(i!=j) {
|
|
||||||
if(++count>2)
|
|
||||||
masqueinfo->setType(Transistor::Type::INTERNAL);
|
|
||||||
else {
|
|
||||||
if ( _sourceIsFirst )
|
|
||||||
masqueinfo->setType(Transistor::Type::LEFT);
|
|
||||||
else
|
|
||||||
masqueinfo->setType(Transistor::Type::RIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*i)->setMaskInfo(masqueinfo);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
} else if(_m%2==1) { // if m is impair, create one left finger, one right finger.
|
|
||||||
while(i!=j){
|
|
||||||
++ count ;
|
|
||||||
if (count == 1)
|
|
||||||
masqueinfo-> setType(Transistor::Type::LEFT);
|
|
||||||
else if (count == 2)
|
|
||||||
masqueinfo-> setType(Transistor::Type::RIGHT);
|
|
||||||
else
|
|
||||||
masqueinfo-> setType(Transistor::Type::INTERNAL);
|
|
||||||
|
|
||||||
(*i)->setMaskInfo(masqueinfo);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete masqueinfo;
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 3 : CreateLayout of " + getString(this) + " finish ***" <<endl;
|
|
||||||
cout << "Real l_finger is " + getString(l_finger) + "." << endl
|
|
||||||
<< "Real w_finger is " + getString(w_finger) + "." << endl
|
|
||||||
<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
/* (4) */
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 4 : CreateLayout of " + getString(this) + " Begin ***" <<endl;
|
|
||||||
cout << "Call GenerateLayout for " + getString(_tr1)
|
|
||||||
+ " who will launch the generator of its fingers" << ".\n"
|
|
||||||
<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
// Call function CreateLayout of MetaTransistor to launch the generator of finger.
|
|
||||||
// *******************************************************************************
|
|
||||||
|
|
||||||
setTerminal(false);
|
|
||||||
//
|
|
||||||
// IF_DEBUG_HUR_ANALOG
|
|
||||||
// cout << endl;
|
|
||||||
// cout << "Real l of " << (long)_tr1 << getString(_tr1) + " is " + getString(_tr1->_le) + "." << endl
|
|
||||||
// << "Real w of " << (long)_tr1 << getString(_tr1) + " is " + getString(_tr1->_we) + "." << endl
|
|
||||||
// <<endl;
|
|
||||||
// END_IF
|
|
||||||
//
|
|
||||||
_tr1->createLayout();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << "*** Stage 4 : CreateLayout of " + getString(this) + " finish ***"<<endl
|
|
||||||
<< endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
/* (5) */
|
|
||||||
// Lauch Algo of Placement and routage selected.
|
|
||||||
// *********************************************
|
|
||||||
/* to do */
|
|
||||||
|
|
||||||
_PlaceAndRoute();
|
|
||||||
|
|
||||||
cout << " Place And Route " <<endl;
|
|
||||||
|
|
||||||
for_each_instance(instance, getInstances())
|
|
||||||
//instance->setTransformation(instance->getTransformation());
|
|
||||||
instance->unmaterialize();
|
|
||||||
instance->materialize();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << getString(instance) <<" 's boundingBox is " << getString(instance->getBoundingBox())<<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// CloseUpdateSession();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << getString(this) << " 's primary (without wire) boundingBox is " << getString(getBoundingBox()) <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
materialize();
|
|
||||||
|
|
||||||
//IF_DEBUG_HUR_ANALOG
|
|
||||||
cout << getString(this) << " 's boundingBox is " << getString(getBoundingBox()) <<endl;
|
|
||||||
//END_IF
|
|
||||||
|
|
||||||
cout << endl
|
|
||||||
<< "################################################################" <<endl
|
|
||||||
<< "#### END AUTOGENERATON FOR " + _getTypeName() + " " + getString(getName()) + " #####" <<endl
|
|
||||||
<< "################################################################" <<endl
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::setLowPinOrder(const PinName pin1, const PinName pin2)
|
|
||||||
// ***************************************************************
|
|
||||||
{
|
|
||||||
_lowPinOrder[0]=pin1;
|
|
||||||
_lowPinOrder[1]=pin2;
|
|
||||||
|
|
||||||
vector<PinName>::iterator i = _lowPinOrder.begin(), j = _lowPinOrder.end();
|
|
||||||
|
|
||||||
cout << " Low Pin Order " << endl;
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
cout << *i << endl;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::setHighPinOrder(const PinName pin1, const PinName pin2)
|
|
||||||
// *****************************************************************
|
|
||||||
{
|
|
||||||
_highPinOrder[0]=pin1;
|
|
||||||
_highPinOrder[1]=pin2;
|
|
||||||
|
|
||||||
vector<PinName>::iterator i = _highPinOrder.begin(), j = _highPinOrder.end();
|
|
||||||
|
|
||||||
cout << " High Pin Order " << endl;
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
cout << *i << endl;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TrMos::_Flush()
|
|
||||||
// ****************
|
|
||||||
{
|
|
||||||
if(_transistorList.empty()) {
|
|
||||||
throw Error("Can't delete Physical View of TrMos " + getString(getName()) + " : " + "il doesn't exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
_tr1->Flush();
|
|
||||||
|
|
||||||
_transistorList.clear();
|
|
||||||
|
|
||||||
// Delete all segments of TrMos
|
|
||||||
// ****************************
|
|
||||||
/* to do */
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string TrMos::_getString() const
|
|
||||||
// ***************************************
|
|
||||||
{
|
|
||||||
string s= Inherit::_getString();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
Record* TrMos::_getRecord() const
|
|
||||||
// *********************************
|
|
||||||
{
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of namespace Device
|
|
|
@ -1,126 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: TrMos.h
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
#ifndef TRMOS_H
|
|
||||||
#define TRMOS_H
|
|
||||||
|
|
||||||
#include "Net.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "Transistor.h"
|
|
||||||
|
|
||||||
//#include "MetaTransistor.h"
|
|
||||||
#include "Device.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE {
|
|
||||||
|
|
||||||
class TrMos : public Device {
|
|
||||||
|
|
||||||
public : enum PinName { D, G, S, B };
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
// *******************
|
|
||||||
|
|
||||||
// Structural parameter.
|
|
||||||
// ********************
|
|
||||||
private : Transistor::Polarity _polarity;
|
|
||||||
private : bool _isBsConnected;
|
|
||||||
private : unsigned _m;
|
|
||||||
|
|
||||||
// Parameter of the electric synthesis.
|
|
||||||
// ***********************************
|
|
||||||
/* to do */
|
|
||||||
|
|
||||||
// Physical parameter of realization.
|
|
||||||
// **********************************
|
|
||||||
/* Placement. */
|
|
||||||
private : bool _sourceIsFirst;
|
|
||||||
private : bool _hasDummy;
|
|
||||||
private : bool _hasRing;
|
|
||||||
|
|
||||||
/* Routing. */
|
|
||||||
private : vector<PinName> _lowPinOrder; // relative position of the connectors on the basis of the top.
|
|
||||||
private : vector<PinName> _highPinOrder;
|
|
||||||
|
|
||||||
private : map<Net*, Pin*> _mapNetToPinBoxInLeftSide;
|
|
||||||
private : map<Net*, Pin*> _mapNetToPinBoxInRightSide;
|
|
||||||
|
|
||||||
private : double _widthOfSourceWire; // by defect, minWidth, unit of valeur is Micro
|
|
||||||
private : double _widthOfDrainWire; // by defect, minWidth, unit of valeur is Micro
|
|
||||||
|
|
||||||
/* Others */
|
|
||||||
private : MetaTransistor * _tr1;
|
|
||||||
private : double _capaRouting;
|
|
||||||
private : list<Transistor*> _transistorList;
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
// ************
|
|
||||||
protected : TrMos(Library* library, const Name& name);
|
|
||||||
protected : virtual void _postCreate();
|
|
||||||
|
|
||||||
public : static TrMos* create(Library* library, const Name & name);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Operations
|
|
||||||
// **********
|
|
||||||
public : virtual void dses() { /* to do */};
|
|
||||||
public : virtual void shape() { /* to do */};
|
|
||||||
|
|
||||||
|
|
||||||
public : void create(const Transistor::Polarity& polarity, const bool isbsconnected);
|
|
||||||
public : void generate(const unsigned m, const bool sourceisfirst, const bool hasring,
|
|
||||||
const unsigned nbsourcecolumn, const unsigned nbdraincolumn);
|
|
||||||
|
|
||||||
// Accessors
|
|
||||||
// *********
|
|
||||||
public : const Transistor::Polarity& getPolarity() const { return _polarity; };
|
|
||||||
public : unsigned getM() const { return _m; };
|
|
||||||
public : const double getWidthOfSourceWire() const { return _widthOfSourceWire; };
|
|
||||||
public : const double getWidthOfDrainWire() const { return _widthOfDrainWire; };
|
|
||||||
public : MetaTransistor* getTr1() const { return _tr1; };
|
|
||||||
|
|
||||||
// Updators
|
|
||||||
// ********
|
|
||||||
public : void setMosLength(const double length) { if(_tr1) _tr1->setLe(length); }
|
|
||||||
public : void setMosWidth(const double width) { if(_tr1) _tr1->setWe(width); }
|
|
||||||
public : void setWidthOfSourceWire(const double width) { _widthOfSourceWire = width; };
|
|
||||||
public : void setWidthOfDrainWire(const double width) { _widthOfDrainWire=width; };
|
|
||||||
public : void setLowPinOrder(const PinName, const PinName) ;
|
|
||||||
public : void setHighPinOrder(const PinName, const PinName) ;
|
|
||||||
|
|
||||||
// Predicats
|
|
||||||
// *********
|
|
||||||
public : bool isBsConnected() const { return _isBsConnected; };
|
|
||||||
public : bool sourceIsFirst() const { return _sourceIsFirst; };
|
|
||||||
public : bool hasRing() const { return _hasRing; };
|
|
||||||
|
|
||||||
|
|
||||||
# if !defined(__DOXYGEN_PROCESSOR__)
|
|
||||||
|
|
||||||
// Others
|
|
||||||
// ******
|
|
||||||
public: virtual string _getTypeName() const {return _TName("TrMos"); };
|
|
||||||
public: virtual string _getString() const;
|
|
||||||
public: virtual Record* _getRecord() const;
|
|
||||||
|
|
||||||
public: vector<PinName>& getLowPinOrder() { return _lowPinOrder; };
|
|
||||||
public: vector<PinName>& getHighPinOrder() { return _highPinOrder; };
|
|
||||||
|
|
||||||
public: map<Net*, Pin*>& getMapNetToPinBoxInLeftSide() { return _mapNetToPinBoxInLeftSide; };
|
|
||||||
public: map<Net*, Pin*>& getMapNetToPinBoxInRightSide() { return _mapNetToPinBoxInRightSide; };
|
|
||||||
|
|
||||||
public : virtual void _Flush();
|
|
||||||
protected : void _PlaceAndRoute();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // TRMOS_H
|
|
|
@ -1,685 +0,0 @@
|
||||||
// ****************************************************************************************************
|
|
||||||
// File: TrMos.cpp
|
|
||||||
// Authors: Wu YiFei
|
|
||||||
// Date : 21/12/2006
|
|
||||||
// ****************************************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
#include "TrMos.h"
|
|
||||||
|
|
||||||
#include "Instances.h"
|
|
||||||
#include "MetaTransistor.h"
|
|
||||||
#include "Net.h"
|
|
||||||
#include "Transistors.h"
|
|
||||||
#include "Box.h"
|
|
||||||
#include "UpdateSession.h"
|
|
||||||
#include "HyperNet.h"
|
|
||||||
#include "DataBase.h"
|
|
||||||
#include "Technology.h"
|
|
||||||
#include "Vertical.h"
|
|
||||||
#include "Horizontal.h"
|
|
||||||
#include "Pin.h"
|
|
||||||
|
|
||||||
#include "RdsUnit.h"
|
|
||||||
#include "Transistor.h"
|
|
||||||
#include "DtrAccess.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "DeviceUtil.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace DEVICE{
|
|
||||||
|
|
||||||
|
|
||||||
// ****************************************************************************************************
|
|
||||||
// TrMos implementation
|
|
||||||
// ****************************************************************************************************
|
|
||||||
void TrMos::_PlaceAndRoute()
|
|
||||||
// *************************
|
|
||||||
{
|
|
||||||
|
|
||||||
// get Dtr Rules And Calculate the Size of AbutmentBox of Device.
|
|
||||||
// **************************************************************
|
|
||||||
DtrAccess * dtraccess = DtrAccess::getDtrAccess();
|
|
||||||
|
|
||||||
Transistor::Polarity polarity;
|
|
||||||
if(_polarity == Transistor::Polarity::P) polarity = Transistor::Polarity::N;
|
|
||||||
else polarity = Transistor::Polarity::P;
|
|
||||||
|
|
||||||
long minImpWidth = dtraccess->getSingleRdsRuleByLabel("RW_", getString(polarity), "IMP");
|
|
||||||
long minContWidth = dtraccess->getSingleRdsRuleByLabel(string("RW_CONT"));
|
|
||||||
long minAlu1Width = dtraccess->getSingleRdsRuleByLabel(string("RW_ALU1"));
|
|
||||||
long minVia1Width = dtraccess->getSingleRdsRuleByLabel(string("RW_VIA1"));
|
|
||||||
|
|
||||||
long rdImp = dtraccess->getSingleRdsRuleByLabel(string("RD_NIMP"));
|
|
||||||
long rdActive = dtraccess->getSingleRdsRuleByLabel(string("RD_ACTI"));
|
|
||||||
long rdAlu2 = dtraccess->getSingleRdsRuleByLabel(string("RD_ALU1"));
|
|
||||||
|
|
||||||
long reImpActi = dtraccess->getSingleRdsRuleByLabel("RE_", getString(polarity), "IMP_CONT");
|
|
||||||
long reActiContact = dtraccess->getSingleRdsRuleByLabel("RE_ACTI_CONT");
|
|
||||||
long reAlu1Contact = dtraccess->getSingleRdsRuleByLabel("RE_ALU1_CONT");
|
|
||||||
long reAlu1Via1 = dtraccess->getSingleRdsRuleByLabel("RE_ALU1_VIA1");
|
|
||||||
|
|
||||||
long minActiWidth = 2*reActiContact + minContWidth;
|
|
||||||
|
|
||||||
long widthOfSourceWire = ConvertRealToRdsUnit(_widthOfSourceWire);
|
|
||||||
long widthOfDrainWire = ConvertRealToRdsUnit(_widthOfDrainWire);
|
|
||||||
|
|
||||||
long widthOfActive = MAX_INTEGER(minActiWidth, minContWidth + 2*reActiContact);
|
|
||||||
long widthOfImp = MAX_INTEGER(widthOfActive + 2*reImpActi, minImpWidth);
|
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************
|
|
||||||
// Placing .
|
|
||||||
// **************************************************************
|
|
||||||
|
|
||||||
Transformation::Orientation::Code internalTransCode = Transformation::Orientation::ID;
|
|
||||||
|
|
||||||
Unit horizontalMargin = 0; // the horizontal margin of trmos.
|
|
||||||
Unit verticalLowMargin = 0; // the vertical low margin of trmos.
|
|
||||||
Unit verticalHighMargin = 0; // the vertical high margin of trmos.
|
|
||||||
|
|
||||||
Unit fingerHeight = 0; // the height of trmos.
|
|
||||||
Instance * leftins = NULL;
|
|
||||||
Instance * rightins = NULL;
|
|
||||||
|
|
||||||
OccurrenceLocator locator = getLeafInstanceOccurrences().getLocator();
|
|
||||||
Instance * instance = dynamic_cast<Instance*>(locator.getElement().getEntity());;
|
|
||||||
fingerHeight = instance->getCell()->getBoundingBox().getHeight();
|
|
||||||
horizontalMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/4));
|
|
||||||
verticalLowMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/2));
|
|
||||||
verticalHighMargin = getUnit(RETURN_EVEN((long)(getValue(fingerHeight))/2));
|
|
||||||
|
|
||||||
|
|
||||||
verticalLowMargin = MAX_INTEGER(verticalLowMargin, getUnit(RETURN_EVEN(rdImp + widthOfImp/2 + widthOfSourceWire
|
|
||||||
+ rdAlu2 + widthOfActive + rdActive)) );
|
|
||||||
|
|
||||||
verticalHighMargin = MAX_INTEGER(verticalHighMargin, horizontalMargin + getUnit(2*rdAlu2 + 2*widthOfDrainWire) );
|
|
||||||
horizontalMargin = MAX_INTEGER(horizontalMargin, getUnit(RETURN_EVEN(rdImp + widthOfImp/2)) );
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
|
|
||||||
if(_m == 1 ) { // If there is only one finger.
|
|
||||||
_Place( instance, Transformation::Orientation::ID, Point( horizontalMargin, verticalLowMargin ) );
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// get instance who's model's abutment type is Left or Right.
|
|
||||||
// ************************************************************
|
|
||||||
for_each_occurrence(occurrence, getLeafInstanceOccurrences())
|
|
||||||
instance = dynamic_cast<Instance*>(occurrence.getEntity());
|
|
||||||
Transistor * trans = dynamic_cast<Transistor*>(instance->getMasterCell());
|
|
||||||
|
|
||||||
if ( _sourceIsFirst ) {
|
|
||||||
if(trans->isLeft() && !leftins)
|
|
||||||
leftins = instance;
|
|
||||||
else if ( trans->isLeft() && leftins)
|
|
||||||
rightins = instance;
|
|
||||||
else if ( trans->isRight())
|
|
||||||
rightins = instance;
|
|
||||||
} else {
|
|
||||||
if(trans->isRight() && !leftins)
|
|
||||||
leftins = instance;
|
|
||||||
else if (trans->isRight() && leftins )
|
|
||||||
rightins = instance;
|
|
||||||
else if (trans->isLeft())
|
|
||||||
rightins = instance;
|
|
||||||
}
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// You must place this first instance who's model is left finger in a point who's
|
|
||||||
// x, y are all pair.
|
|
||||||
// Because if you do this, you can be sure that all rectangle of this instance are
|
|
||||||
// correctly in the grille of fondor.
|
|
||||||
// ***********************************************************************************
|
|
||||||
|
|
||||||
if(_sourceIsFirst)
|
|
||||||
_Place( leftins, Transformation::Orientation::ID, Point(horizontalMargin, verticalLowMargin) );
|
|
||||||
else
|
|
||||||
_Place( leftins, Transformation::Orientation::MX, Point(horizontalMargin, verticalLowMargin) );
|
|
||||||
|
|
||||||
_setRefIns(leftins);
|
|
||||||
|
|
||||||
if(_sourceIsFirst) // internal Finger's transformation.
|
|
||||||
internalTransCode = Transformation::Orientation::MX;
|
|
||||||
else
|
|
||||||
internalTransCode = Transformation::Orientation::ID;
|
|
||||||
|
|
||||||
// Place internal finger.
|
|
||||||
// *********************
|
|
||||||
for_each_occurrence(occurrence, getLeafInstanceOccurrences())
|
|
||||||
|
|
||||||
Instance * instance = dynamic_cast<Instance*>(occurrence.getEntity());
|
|
||||||
|
|
||||||
if(instance==leftins || instance==rightins )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
_PlaceRight( instance, internalTransCode);
|
|
||||||
|
|
||||||
if(internalTransCode == Transformation::Orientation::MX)
|
|
||||||
internalTransCode = Transformation::Orientation::ID;
|
|
||||||
else
|
|
||||||
internalTransCode = Transformation::Orientation::MX;
|
|
||||||
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// Place the last finger.
|
|
||||||
// **********************
|
|
||||||
Transistor * trans = dynamic_cast<Transistor*>(rightins->getMasterCell());
|
|
||||||
|
|
||||||
if( trans->isRight())
|
|
||||||
_PlaceRight( rightins, Transformation::Orientation::ID);
|
|
||||||
else
|
|
||||||
_PlaceRight( rightins, Transformation::Orientation::MX);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set AbutmentBox.
|
|
||||||
// ****************
|
|
||||||
for_each_instance(instance, getInstances())
|
|
||||||
instance->unmaterialize();
|
|
||||||
instance->materialize();
|
|
||||||
end_for
|
|
||||||
|
|
||||||
UpdateSession::open();
|
|
||||||
|
|
||||||
|
|
||||||
cout <<"Bounding box of TrMos is "<<getString(getBoundingBox())<<endl;
|
|
||||||
|
|
||||||
setAbutmentBox(Box(0, 0,
|
|
||||||
getBoundingBox().getWidth() + 2*horizontalMargin,
|
|
||||||
getBoundingBox().getHeight() + verticalLowMargin + verticalHighMargin
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// **************************************************************
|
|
||||||
// Routing .
|
|
||||||
// **************************************************************
|
|
||||||
|
|
||||||
Unit expectedInterval = getUnit(RETURN_EVEN((long)(getValue(horizontalMargin))/2));
|
|
||||||
Unit interval = 0;
|
|
||||||
Unit initialPosition = verticalLowMargin + fingerHeight + getUnit(rdAlu2 + widthOfDrainWire/2);
|
|
||||||
|
|
||||||
map<string, Unit> netName2PositionOfConnectorMap;
|
|
||||||
list<Box> routingZoneList;
|
|
||||||
list<Unit> sourcePositionList;
|
|
||||||
list<Unit> drainPositionList;
|
|
||||||
Unit sourceRoutingZoneWidth;
|
|
||||||
Unit drainRoutingZoneWidth;
|
|
||||||
|
|
||||||
DataBase * db = getDataBase();
|
|
||||||
if(!db) throw Error("Can't launch Trmos::PlaceAndRoute for " + getString(this) + " : can't find DataBase");
|
|
||||||
|
|
||||||
Layer * layerAlu1 = db->getTechnology()->getLayer(Name("ALU1"));
|
|
||||||
Layer * layerAlu2 = db->getTechnology()->getLayer(Name("ALU2"));
|
|
||||||
|
|
||||||
Layer * layerVia1 = db->getTechnology()->getLayer(Name("VIA1"));
|
|
||||||
Layer * layerActive = db->getTechnology()->getLayer(Name("ACTIVE"));
|
|
||||||
|
|
||||||
Layer * layerVia01 = db->getTechnology()->getLayer(Name("via01"));
|
|
||||||
Layer * layerVia12 = db->getTechnology()->getLayer(Name("via12"));
|
|
||||||
|
|
||||||
Layer * layerPoly = db->getTechnology()->getLayer(Name("POLY"));
|
|
||||||
Layer * layerNwell = db->getTechnology()->getLayer(Name("NWELL"));
|
|
||||||
Layer * layerCont = db->getTechnology()->getLayer(Name("CONT"));
|
|
||||||
|
|
||||||
Layer * layerImp = NULL;
|
|
||||||
|
|
||||||
if(_polarity == Transistor::Polarity::P)
|
|
||||||
layerImp = db->getTechnology()->getLayer(Name("NIMP"));
|
|
||||||
else
|
|
||||||
layerImp = db->getTechnology()->getLayer(Name("PIMP"));
|
|
||||||
|
|
||||||
Pin * pin = NULL; // For get the adresse of Created Pins.
|
|
||||||
|
|
||||||
long connectorPosition = 0;
|
|
||||||
|
|
||||||
|
|
||||||
cout << " Begin routage " << endl;
|
|
||||||
|
|
||||||
|
|
||||||
// Set position of four connectors.
|
|
||||||
// ********************************
|
|
||||||
vector<PinName>::iterator i = _highPinOrder.begin(),
|
|
||||||
j = _highPinOrder.end();
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
if(*i == D)
|
|
||||||
netName2PositionOfConnectorMap[string("drain")] = initialPosition;
|
|
||||||
if(*i == G)
|
|
||||||
netName2PositionOfConnectorMap[string("grid")] = initialPosition;
|
|
||||||
|
|
||||||
interval = MAX_INTEGER(expectedInterval, getUnit(widthOfDrainWire + rdAlu2));
|
|
||||||
|
|
||||||
// initialPosition += horizontalMargin/2;
|
|
||||||
initialPosition += interval;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<PinName>::iterator m = _lowPinOrder.begin(),
|
|
||||||
n = _lowPinOrder.end();
|
|
||||||
|
|
||||||
//initialPosition = verticalMargin - horizontalMargin/2;
|
|
||||||
//initialPosition = verticalLowMargin - MAX_INTEGER(expectedInterval, getUnit(rdImp + widthOfImp/2));
|
|
||||||
initialPosition = verticalLowMargin - getUnit(rdImp + widthOfImp/2);
|
|
||||||
|
|
||||||
while(m!=n) {
|
|
||||||
if(*m == S)
|
|
||||||
netName2PositionOfConnectorMap[string("source")] = initialPosition;
|
|
||||||
if(*m == B)
|
|
||||||
netName2PositionOfConnectorMap[string("bulk")] = initialPosition;
|
|
||||||
|
|
||||||
interval = MAX_INTEGER(expectedInterval, getUnit(rdAlu2 + widthOfSourceWire));
|
|
||||||
|
|
||||||
initialPosition -= interval;
|
|
||||||
m++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << " Main loop "<< endl;
|
|
||||||
|
|
||||||
// Main Routing Algorithm.
|
|
||||||
// ***********************
|
|
||||||
|
|
||||||
// Main Loop.
|
|
||||||
// **********
|
|
||||||
for_each_net(net, getNets()) // For all hypernets.
|
|
||||||
|
|
||||||
if(getString(net->getName())=="bulk" || getString(net->getName())=="BULK" )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// get Routing Zone.
|
|
||||||
// *****************
|
|
||||||
HyperNet hyperNet(Occurrence(net, Path()));
|
|
||||||
for_each_occurrence(occurrence, hyperNet.getNetOccurrences()) // For all net occurrences.
|
|
||||||
Net * net = dynamic_cast<Net*>(occurrence.getEntity());
|
|
||||||
Box routingZone;
|
|
||||||
|
|
||||||
if(net->getCell()->isLeaf()) {
|
|
||||||
Transistor * trans = dynamic_cast<Transistor*>(net->getCell());
|
|
||||||
if ( !trans )
|
|
||||||
throw Error("Can't launch Trmos::PlaceAndRoute for " + getString(this)
|
|
||||||
+ ", it is not a Transistor");
|
|
||||||
|
|
||||||
cout << getString(occurrence) << endl;
|
|
||||||
cout << getString(occurrence.getPath().getTransformation()) <<endl;
|
|
||||||
cout << getString((*(trans->_getMapNet2Box()))[net]) << endl;
|
|
||||||
|
|
||||||
// get Routing Zone.
|
|
||||||
// *****************
|
|
||||||
routingZone = occurrence.getPath().getTransformation().getBox((*(trans->_getMapNet2Box()))[net]);
|
|
||||||
routingZoneList.push_back(routingZone);
|
|
||||||
|
|
||||||
if(getString(net->getName())=="SOURCE") {
|
|
||||||
sourcePositionList.push_back(routingZone.getXCenter());
|
|
||||||
sourceRoutingZoneWidth = routingZone.getWidth();
|
|
||||||
}
|
|
||||||
else if (getString(net->getName())=="DRAIN") {
|
|
||||||
drainPositionList.push_back(routingZone.getXCenter());
|
|
||||||
drainRoutingZoneWidth = routingZone.getWidth();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end_for
|
|
||||||
|
|
||||||
|
|
||||||
cout <<"Print routing zone for " <<getString(net)<<endl;
|
|
||||||
|
|
||||||
list<Box>::iterator it_begin_listbox = routingZoneList.begin(),
|
|
||||||
it_end_listbox = routingZoneList.end();
|
|
||||||
|
|
||||||
while(it_begin_listbox != it_end_listbox)
|
|
||||||
{
|
|
||||||
cout<< getString(*it_begin_listbox) <<endl;
|
|
||||||
it_begin_listbox++;
|
|
||||||
}
|
|
||||||
|
|
||||||
cout <<"End Print Routing Zone for "<<getString(net)<<endl;
|
|
||||||
|
|
||||||
// Create routing line.
|
|
||||||
// ********************
|
|
||||||
list<Box>::iterator routingzonelist_begin_it = routingZoneList.begin(),
|
|
||||||
routingzonelist_end_it = routingZoneList.end();
|
|
||||||
|
|
||||||
connectorPosition = netName2PositionOfConnectorMap[getString(net->getName())];
|
|
||||||
cout << "Connector Position is " << netName2PositionOfConnectorMap[getString(net)] << endl;
|
|
||||||
|
|
||||||
while(routingzonelist_begin_it!=routingzonelist_end_it) {
|
|
||||||
|
|
||||||
Box routingZoneBox = *routingzonelist_begin_it;
|
|
||||||
|
|
||||||
// Create vertical line and Contact.
|
|
||||||
// ********************************
|
|
||||||
if(connectorPosition > routingZoneBox.getYMin()) {
|
|
||||||
Vertical::create(net, layerAlu1, routingZoneBox.getXCenter()
|
|
||||||
, routingZoneBox.getWidth() + getUnit(2*reAlu1Contact)
|
|
||||||
, routingZoneBox.getYMin() - getUnit(reAlu1Contact)
|
|
||||||
, connectorPosition);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Vertical::create(net, layerAlu1, routingZoneBox.getXCenter()
|
|
||||||
, routingZoneBox.getWidth() + getUnit(2*reAlu1Contact)
|
|
||||||
, connectorPosition
|
|
||||||
, routingZoneBox.getYMax() + getUnit(reAlu1Contact) ) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
Contact::create(net, layerVia12, routingZoneBox.getXCenter()
|
|
||||||
, connectorPosition
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
);
|
|
||||||
|
|
||||||
routingzonelist_begin_it ++ ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create horizontal line.
|
|
||||||
// ***********************
|
|
||||||
long widthOfWire = 0;
|
|
||||||
|
|
||||||
if(getString(net->getName())=="source")
|
|
||||||
widthOfWire = widthOfSourceWire;
|
|
||||||
else if(getString(net->getName())=="drain")
|
|
||||||
widthOfWire = widthOfDrainWire;
|
|
||||||
else
|
|
||||||
widthOfWire = widthOfDrainWire;
|
|
||||||
|
|
||||||
|
|
||||||
Horizontal::create(net, layerAlu2, connectorPosition
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
, 0
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create Two Pins.
|
|
||||||
// ****************
|
|
||||||
pin = Pin::create(net
|
|
||||||
, Name(getString(net->getName())+"_west")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::WEST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, connectorPosition
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInLeftSide[net] = pin;
|
|
||||||
|
|
||||||
pin = Pin::create(net
|
|
||||||
, Name(getString(net->getName())+"_east")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::EAST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, connectorPosition
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
, getUnit(widthOfWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInRightSide[net] = pin;
|
|
||||||
|
|
||||||
routingZoneList.clear();
|
|
||||||
|
|
||||||
// End Of Main Loop.
|
|
||||||
// *****************
|
|
||||||
end_for
|
|
||||||
|
|
||||||
// Route Net Bulk.
|
|
||||||
// ***************
|
|
||||||
connectorPosition = netName2PositionOfConnectorMap[string("bulk")];
|
|
||||||
|
|
||||||
Net * netBulk = getNet(Name("bulk"));
|
|
||||||
|
|
||||||
if(!netBulk) // bulk and source are connected.
|
|
||||||
netBulk = getNet(Name("source"));
|
|
||||||
|
|
||||||
// Calculate the width of Contact Alu1.
|
|
||||||
// ************************************
|
|
||||||
long widthOfAlu1 = MAX_INTEGER( MAX_INTEGER(minAlu1Width, 2*reAlu1Contact + minContWidth), 2*reAlu1Via1 + minVia1Width);
|
|
||||||
|
|
||||||
Unit bulkPosition = netName2PositionOfConnectorMap[string("bulk")];
|
|
||||||
Unit sourcePosition = netName2PositionOfConnectorMap[string("source")];
|
|
||||||
|
|
||||||
Horizontal::create( netBulk
|
|
||||||
, layerImp
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, 0 - getUnit(reImpActi)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(reImpActi)
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netBulk
|
|
||||||
, layerActive
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfActive)
|
|
||||||
, 0
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netBulk
|
|
||||||
, layerAlu2
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
, 0
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create Two Pins For Net bulk.
|
|
||||||
// *****************************
|
|
||||||
if(!_isBsConnected) {
|
|
||||||
|
|
||||||
pin = Pin::create(netBulk
|
|
||||||
, Name(getString(netBulk->getName())+"_west")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::WEST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInLeftSide[netBulk] = pin;
|
|
||||||
|
|
||||||
pin = Pin::create(netBulk
|
|
||||||
, Name(getString(netBulk->getName())+"_east")
|
|
||||||
, Pin::AccessDirection(Pin::AccessDirection::EAST)
|
|
||||||
, Pin::PlacementStatus(Pin::PlacementStatus::PLACED)
|
|
||||||
, layerAlu2
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
, getUnit(widthOfSourceWire)
|
|
||||||
);
|
|
||||||
|
|
||||||
_mapNetToPinBoxInRightSide[netBulk] = pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if( netName2PositionOfConnectorMap[string("source")] > netName2PositionOfConnectorMap[string("bulk")] ) {
|
|
||||||
// Source Is Upper Than Bulk.
|
|
||||||
|
|
||||||
cout << " Source is Upper Than Bulk" << endl;
|
|
||||||
|
|
||||||
list<Unit>::iterator i = sourcePositionList.begin(), j = sourcePositionList.end();
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
|
|
||||||
cout << " ######### Create Contact ###########" <<endl;
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia01, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerAlu1, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia12, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
);
|
|
||||||
|
|
||||||
if( _isBsConnected ) { // If bulk and Source are connected.
|
|
||||||
|
|
||||||
cout << " B S is connected in " << *i << endl;
|
|
||||||
|
|
||||||
Vertical::create(netBulk, layerAlu1, *i
|
|
||||||
, sourceRoutingZoneWidth
|
|
||||||
, bulkPosition
|
|
||||||
, sourcePosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
list<Unit>::iterator i , j;
|
|
||||||
|
|
||||||
|
|
||||||
if( _isBsConnected ) { // If bulk and Source are connected.
|
|
||||||
i = sourcePositionList.begin();
|
|
||||||
j = sourcePositionList.end();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
i = drainPositionList.begin();
|
|
||||||
j = drainPositionList.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
while(i!=j) {
|
|
||||||
|
|
||||||
cout << " ######### Create Contact ###########" <<endl;
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia01, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
, getUnit(minContWidth)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerAlu1, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
, getUnit(widthOfAlu1)
|
|
||||||
);
|
|
||||||
|
|
||||||
Contact::create(netBulk, layerVia12, *i
|
|
||||||
, bulkPosition
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
, getUnit(minVia1Width)
|
|
||||||
);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Create Ring.
|
|
||||||
// ************
|
|
||||||
if( _hasRing ) {
|
|
||||||
widthOfImp = MAX_INTEGER(minImpWidth, minActiWidth + 2*reImpActi);
|
|
||||||
|
|
||||||
Net * netRing = Net::create(this, Name("RING"));
|
|
||||||
|
|
||||||
|
|
||||||
// Create rectangle in IMPLANT.
|
|
||||||
// ***************************
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(widthOfImp/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(widthOfImp/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(widthOfImp/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(widthOfImp/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerImp
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, getUnit(widthOfImp)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Create rectangle in Active.
|
|
||||||
// ***************************
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(minActiWidth/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(minActiWidth/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
Horizontal::create( netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getXMin() - getUnit(minActiWidth/2)
|
|
||||||
, getAbutmentBox().getXMax() + getUnit(minActiWidth/2)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getXMin()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
Vertical::create(netRing
|
|
||||||
, layerActive
|
|
||||||
, getAbutmentBox().getXMax()
|
|
||||||
, getUnit(minActiWidth)
|
|
||||||
, getAbutmentBox().getYMin()
|
|
||||||
, getAbutmentBox().getYMax()
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Caission NWELL if this is a PMOS.
|
|
||||||
// ****************************************
|
|
||||||
if(_polarity == Transistor::Polarity::P) {
|
|
||||||
Net * netCaisson = Net::create(this, Name("CAISSON"));
|
|
||||||
Contact::create(netCaisson, layerNwell
|
|
||||||
, getAbutmentBox().getXCenter()
|
|
||||||
, getAbutmentBox().getYCenter()
|
|
||||||
, getAbutmentBox().getWidth()
|
|
||||||
, getAbutmentBox().getHeight()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateSession::close();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // END OF NAMESPACE DEVICE
|
|
|
@ -1,45 +0,0 @@
|
||||||
#include "hurricane/DataBase.h"
|
|
||||||
#include "hurricane/Library.h"
|
|
||||||
#include "hurricane/Technology.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "crlcore/GraphicsParser.h"
|
|
||||||
#include "crlcore/SymbolicTechnologyParser.h"
|
|
||||||
#include "crlcore/RealTechnologyParser.h"
|
|
||||||
using namespace CRL;
|
|
||||||
|
|
||||||
#include "ATechnology.h"
|
|
||||||
#include "ATechnologyXmlParser.h"
|
|
||||||
|
|
||||||
#include "AEnv.h"
|
|
||||||
|
|
||||||
void AEnv::create(const char* symbTechnoFilePath,
|
|
||||||
const char* realTechnoFilePath,
|
|
||||||
const char* graphicFilePath,
|
|
||||||
const char* analogTechnoFilePath) {
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
if (db) {
|
|
||||||
throw Error("");
|
|
||||||
}
|
|
||||||
db = DataBase::create();
|
|
||||||
SymbolicTechnologyParser::load(db, symbTechnoFilePath);
|
|
||||||
RealTechnologyParser::load(db, realTechnoFilePath);
|
|
||||||
GraphicsParser::load(graphicFilePath);
|
|
||||||
|
|
||||||
Library* rootLibrary = Library::create(db, Name("RootLibrary"));
|
|
||||||
Technology* techno = db->getTechnology();
|
|
||||||
ATechnologyXmlParser::parse(analogTechnoFilePath, techno);
|
|
||||||
}
|
|
||||||
|
|
||||||
ATechnology* AEnv::getATechnology() {
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
if (!db) {
|
|
||||||
throw Error("");
|
|
||||||
}
|
|
||||||
Technology* technology = db->getTechnology();
|
|
||||||
if (!technology) {
|
|
||||||
throw Error("");
|
|
||||||
}
|
|
||||||
ATechnology* atechnology = ATechnology::getATechnology(technology);
|
|
||||||
return atechnology;
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef AENV_H_
|
|
||||||
#define AENV_H_
|
|
||||||
|
|
||||||
class ATechnology;
|
|
||||||
|
|
||||||
class AEnv {
|
|
||||||
public:
|
|
||||||
static void create(const char* symbTechnoFilePath,
|
|
||||||
const char* realTechnoFilePath,
|
|
||||||
const char* graphicFilePath,
|
|
||||||
const char* analogTechnoFilePath);
|
|
||||||
static ATechnology* getATechnology();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* AENV_H_ */
|
|
|
@ -1,248 +0,0 @@
|
||||||
#include "hurricane/Technology.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "ATechnology.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
static Name ATechnologyPropertyName("ATechnologyProperty");
|
|
||||||
|
|
||||||
void printPhysicalRule(const ATechnology::PhysicalRule* physicalRule) {
|
|
||||||
cout << " - name = " << physicalRule->_name <<
|
|
||||||
", value = " << physicalRule->_value <<
|
|
||||||
", ref = " << physicalRule->_reference << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void printPhysicalRules(const ATechnology::PhysicalRules& physicalRules) {
|
|
||||||
for (ATechnology::PhysicalRules::const_iterator prit = physicalRules.begin();
|
|
||||||
prit != physicalRules.end();
|
|
||||||
prit++) {
|
|
||||||
ATechnology::PhysicalRule* physicalRule = *prit;
|
|
||||||
printPhysicalRule(physicalRule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printPhysicalRules(const ATechnology::TwoLayersPhysicalRulesSet& physicalRules) {
|
|
||||||
for (ATechnology::TwoLayersPhysicalRulesSet::const_iterator prit = physicalRules.begin();
|
|
||||||
prit != physicalRules.end();
|
|
||||||
prit++) {
|
|
||||||
ATechnology::PhysicalRule* physicalRule = *prit;
|
|
||||||
printPhysicalRule(physicalRule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
string ATechnology::PhysicalRule::_getTypeName() const {
|
|
||||||
return "PhysicalRule";
|
|
||||||
}
|
|
||||||
|
|
||||||
string ATechnology::PhysicalRule::_getString() const {
|
|
||||||
return "<" + _getTypeName() + " " + getString(_name) + ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
Record* ATechnology::PhysicalRule::_getRecord() const {
|
|
||||||
Record* record = new Record(getString(this));
|
|
||||||
record->add(getSlot("Name", &_name));
|
|
||||||
record->add(getSlot("Value", &_value));
|
|
||||||
record->add(getSlot("Reference", &_reference));
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
string ATechnology::TwoLayersPhysicalRule::_getTypeName() const {
|
|
||||||
return "TwoLayersPhysicalRule";
|
|
||||||
}
|
|
||||||
|
|
||||||
string ATechnology::TwoLayersPhysicalRule::_getString() const {
|
|
||||||
return "<" + _getTypeName() + " " + getString(_name) + ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
Record* ATechnology::TwoLayersPhysicalRule::_getRecord() const {
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
if (record) {
|
|
||||||
record->add(getSlot("Symetric", _symetric));
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
Name ATechnology::getName() const {
|
|
||||||
return ATechnologyPropertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
string ATechnology::_getTypeName() const {
|
|
||||||
return _TName("ATechnologyProperty");
|
|
||||||
}
|
|
||||||
|
|
||||||
Record* ATechnology::_getRecord() const {
|
|
||||||
Record* record = Inherit::_getRecord();
|
|
||||||
if (record) {
|
|
||||||
record->add(getSlot("NoLayerPhysicalRules", &_noLayerPhysicalRules));
|
|
||||||
record->add(getSlot("OneLayerPhysicalRules", &_oneLayerPhysicalRules));
|
|
||||||
record->add(getSlot("TwoLayersPhysicalRules", &_twoLayersPhysicalRules));
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ATechnology::addPhysicalRule(const Name& name, DbU::Unit value, const string& reference) {
|
|
||||||
PhysicalRule searchPR(name, 0, "");
|
|
||||||
PhysicalRules::iterator prit = _noLayerPhysicalRules.find(&searchPR);
|
|
||||||
if (prit != _noLayerPhysicalRules.end()) {
|
|
||||||
throw Error("");
|
|
||||||
}
|
|
||||||
PhysicalRule* newPhysicalRule = new PhysicalRule(name, value, reference);
|
|
||||||
_noLayerPhysicalRules.insert(newPhysicalRule);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ATechnology::addPhysicalRule(const Name& name, const Name& layerName, DbU::Unit value, const string& reference) {
|
|
||||||
Layer* layer = getLayer(layerName);
|
|
||||||
OneLayerPhysicalRules::iterator olprit = _oneLayerPhysicalRules.find(layer);
|
|
||||||
if (olprit == _oneLayerPhysicalRules.end()) {
|
|
||||||
pair<OneLayerPhysicalRules::iterator, bool> result =
|
|
||||||
_oneLayerPhysicalRules.insert(OneLayerPhysicalRules::value_type(layer, PhysicalRules()));
|
|
||||||
olprit = result.first;
|
|
||||||
PhysicalRule* newPhysicalRule = new PhysicalRule(name, value, reference);
|
|
||||||
olprit->second.insert(newPhysicalRule);
|
|
||||||
} else {
|
|
||||||
PhysicalRules& physicalRules = olprit->second;
|
|
||||||
PhysicalRule searchPR(name, 0, "");
|
|
||||||
if (physicalRules.find(&searchPR) != physicalRules.end()) {
|
|
||||||
throw Error("duplicate rule");
|
|
||||||
}
|
|
||||||
PhysicalRule* newPhysicalRule = new PhysicalRule(name, value, reference);
|
|
||||||
physicalRules.insert(newPhysicalRule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ATechnology::addPhysicalRule(const Name& name, const Name& layer1Name,
|
|
||||||
const Name& layer2Name, bool symetric, DbU::Unit value,
|
|
||||||
const string& reference) {
|
|
||||||
Layer* layer1 = getLayer(layer1Name);
|
|
||||||
Layer* layer2 = getLayer(layer2Name);
|
|
||||||
LayerPair layerPair(layer1, layer2);
|
|
||||||
TwoLayersPhysicalRules::iterator tlprit = _twoLayersPhysicalRules.find(layerPair);
|
|
||||||
if (tlprit == _twoLayersPhysicalRules.end()) {
|
|
||||||
pair<TwoLayersPhysicalRules::iterator, bool> result =
|
|
||||||
_twoLayersPhysicalRules.insert(TwoLayersPhysicalRules::value_type(layerPair, TwoLayersPhysicalRulesSet()));
|
|
||||||
tlprit = result.first;
|
|
||||||
TwoLayersPhysicalRule* newPhysicalRule = new TwoLayersPhysicalRule(name, value, reference, symetric);
|
|
||||||
tlprit->second.insert(newPhysicalRule);
|
|
||||||
} else {
|
|
||||||
TwoLayersPhysicalRulesSet& physicalRules = tlprit->second;
|
|
||||||
TwoLayersPhysicalRule searchPR(name, 0, "", true);
|
|
||||||
if (physicalRules.find(&searchPR) != physicalRules.end()) {
|
|
||||||
throw Error("duplicate rule");
|
|
||||||
}
|
|
||||||
TwoLayersPhysicalRule* newPhysicalRule = new TwoLayersPhysicalRule(name, value, reference, symetric);
|
|
||||||
physicalRules.insert(newPhysicalRule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ATechnology* ATechnology::create(Technology* technology) {
|
|
||||||
ATechnology* prop = new ATechnology();
|
|
||||||
|
|
||||||
prop->_postCreate();
|
|
||||||
|
|
||||||
technology->put(prop);
|
|
||||||
|
|
||||||
return prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
ATechnology* ATechnology::getATechnology(Technology* technology) {
|
|
||||||
Property* property = technology->getProperty(ATechnologyPropertyName);
|
|
||||||
if (property) {
|
|
||||||
ATechnology* aTechnology = static_cast<ATechnology*>(property);
|
|
||||||
return aTechnology;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ATechnology::print() {
|
|
||||||
cout << "Printing ATechnology" << endl;
|
|
||||||
cout << " o No Layer Physical Rules" << endl;
|
|
||||||
printPhysicalRules(_noLayerPhysicalRules);
|
|
||||||
cout << endl;
|
|
||||||
cout << " o One Layer Physical Rules" << endl;
|
|
||||||
for (OneLayerPhysicalRules::iterator olprit = _oneLayerPhysicalRules.begin();
|
|
||||||
olprit != _oneLayerPhysicalRules.end();
|
|
||||||
olprit++) {
|
|
||||||
const Layer* layer = olprit->first;
|
|
||||||
cout << " o layer " << layer << endl;
|
|
||||||
printPhysicalRules(olprit->second);
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
cout << " o Two Layers Physical Rules" << endl;
|
|
||||||
for (TwoLayersPhysicalRules::iterator tlprit = _twoLayersPhysicalRules.begin();
|
|
||||||
tlprit != _twoLayersPhysicalRules.end();
|
|
||||||
tlprit++) {
|
|
||||||
const Layer* layer1 = tlprit->first.first;
|
|
||||||
const Layer* layer2 = tlprit->first.second;
|
|
||||||
cout << " o layer1 " << layer1 << endl;
|
|
||||||
cout << " o layer2 " << layer2 << endl;
|
|
||||||
printPhysicalRules(tlprit->second);
|
|
||||||
cout << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ATechnology::PhysicalRule* ATechnology::getPhysicalRule(const Name& name) const {
|
|
||||||
PhysicalRule searchPR(name, 0, "");
|
|
||||||
PhysicalRules::iterator prit = _noLayerPhysicalRules.find(&searchPR);
|
|
||||||
if (prit == _noLayerPhysicalRules.end()) {
|
|
||||||
throw Error("Cannot find Physical Rule " + getString(name));
|
|
||||||
}
|
|
||||||
return *prit;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ATechnology::PhysicalRule* ATechnology::getPhysicalRule(const Name& name, const Layer* layer) const {
|
|
||||||
OneLayerPhysicalRules::const_iterator olprit = _oneLayerPhysicalRules.find(layer);
|
|
||||||
if (olprit == _oneLayerPhysicalRules.end()) {
|
|
||||||
throw Error("Cannot find Physical Rules for layer " + getString(layer->getName()));
|
|
||||||
}
|
|
||||||
const PhysicalRules& physicalRules = olprit->second;
|
|
||||||
PhysicalRule searchPR(name, 0, "");
|
|
||||||
PhysicalRules::iterator prit = physicalRules.find(&searchPR);
|
|
||||||
if (prit == physicalRules.end()) {
|
|
||||||
throw Error("Cannot find Physical Rule " + getString(name));
|
|
||||||
}
|
|
||||||
return *prit;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ATechnology::PhysicalRule* ATechnology::getPhysicalRule(
|
|
||||||
const Name& name,
|
|
||||||
const Layer* layer1,
|
|
||||||
const Layer* layer2) const {
|
|
||||||
LayerPair searchLayerPair(layer1, layer2);
|
|
||||||
TwoLayersPhysicalRules::const_iterator tlprit = _twoLayersPhysicalRules.find(searchLayerPair);
|
|
||||||
if (tlprit != _twoLayersPhysicalRules.end()) {
|
|
||||||
const TwoLayersPhysicalRulesSet& physicalRules = tlprit->second;
|
|
||||||
TwoLayersPhysicalRule searchPR(name, 0, "", true);
|
|
||||||
TwoLayersPhysicalRulesSet::const_iterator prit = physicalRules.find(&searchPR);
|
|
||||||
if (prit != physicalRules.end()) {
|
|
||||||
return *prit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LayerPair reverseSearchLayerPair(layer2, layer1);
|
|
||||||
tlprit = _twoLayersPhysicalRules.find(reverseSearchLayerPair);
|
|
||||||
if (tlprit != _twoLayersPhysicalRules.end()) {
|
|
||||||
const TwoLayersPhysicalRulesSet& physicalRules = tlprit->second;
|
|
||||||
TwoLayersPhysicalRule searchPR(name, 0, "", true);
|
|
||||||
TwoLayersPhysicalRulesSet::const_iterator prit = physicalRules.find(&searchPR);
|
|
||||||
if (prit != physicalRules.end()) {
|
|
||||||
if ((*prit)->isSymetric()) {
|
|
||||||
return *prit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw Error("Cannot find Physical Rule " +
|
|
||||||
getString(name) + " for layers " +
|
|
||||||
getString(layer1->getName()) +
|
|
||||||
" and " +
|
|
||||||
getString(layer2->getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer* ATechnology::getLayer(const Name& layerName) {
|
|
||||||
Technology* technology = static_cast<Technology*>(getOwner());
|
|
||||||
Layer* layer = technology->getLayer(layerName);
|
|
||||||
if (!layer) {
|
|
||||||
throw Error("cannot find layer " + getString(layerName));
|
|
||||||
}
|
|
||||||
return layer;
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
#ifndef ATECHNOLOGY_H_
|
|
||||||
#define ATECHNOLOGY_H_
|
|
||||||
|
|
||||||
#include "hurricane/Property.h"
|
|
||||||
#include "hurricane/DbU.h"
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
namespace Hurricane {
|
|
||||||
class Technology;
|
|
||||||
class Layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ATechnology : public PrivateProperty {
|
|
||||||
public:
|
|
||||||
typedef PrivateProperty Inherit;
|
|
||||||
|
|
||||||
class PhysicalRule {
|
|
||||||
public:
|
|
||||||
PhysicalRule(const Name& name,
|
|
||||||
DbU::Unit value,
|
|
||||||
const string& reference):
|
|
||||||
_name(name),
|
|
||||||
_value(value),
|
|
||||||
_reference(reference) {}
|
|
||||||
PhysicalRule(const PhysicalRule& physicalRule):
|
|
||||||
_name(physicalRule._name),
|
|
||||||
_value(physicalRule._value),
|
|
||||||
_reference(physicalRule._reference) {}
|
|
||||||
const Name _name;
|
|
||||||
const DbU::Unit _value;
|
|
||||||
const string _reference;
|
|
||||||
double getValue() const { return _value; }
|
|
||||||
|
|
||||||
string _getTypeName() const;
|
|
||||||
string _getString() const;
|
|
||||||
Record* _getRecord() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TwoLayersPhysicalRule : public PhysicalRule {
|
|
||||||
public:
|
|
||||||
typedef PhysicalRule Inherit;
|
|
||||||
|
|
||||||
TwoLayersPhysicalRule(const Name& name,
|
|
||||||
DbU::Unit value,
|
|
||||||
const string& reference,
|
|
||||||
bool symetric):
|
|
||||||
PhysicalRule(name, value, reference),
|
|
||||||
_symetric(symetric) {}
|
|
||||||
|
|
||||||
bool isSymetric() const { return _symetric; }
|
|
||||||
const bool _symetric;
|
|
||||||
|
|
||||||
string _getTypeName() const;
|
|
||||||
string _getString() const;
|
|
||||||
Record* _getRecord() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PhysicalRuleNameCompare:
|
|
||||||
public std::binary_function<const PhysicalRule*, const PhysicalRule*, bool> {
|
|
||||||
bool operator()(const PhysicalRule* pr1, const PhysicalRule* pr2) const {
|
|
||||||
return pr1->_name < pr2->_name;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef pair<const Layer*, const Layer*> LayerPair;
|
|
||||||
|
|
||||||
typedef set<ATechnology::PhysicalRule*, PhysicalRuleNameCompare> PhysicalRules;
|
|
||||||
typedef set<ATechnology::TwoLayersPhysicalRule*, PhysicalRuleNameCompare> TwoLayersPhysicalRulesSet;
|
|
||||||
typedef map<const Layer*, PhysicalRules> OneLayerPhysicalRules;
|
|
||||||
typedef map<LayerPair, TwoLayersPhysicalRulesSet> TwoLayersPhysicalRules;
|
|
||||||
|
|
||||||
static ATechnology* create(Hurricane::Technology* technology);
|
|
||||||
static ATechnology* getATechnology(Hurricane::Technology* technology);
|
|
||||||
const PhysicalRule* getPhysicalRule(const Name& name) const;
|
|
||||||
const PhysicalRule* getPhysicalRule(const Name& name, const Layer* layer) const;
|
|
||||||
const PhysicalRule* getPhysicalRule(const Name& name, const Layer* layer1, const Layer* layer2) const;
|
|
||||||
void addPhysicalRule(const Name& name, DbU::Unit value, const string& reference);
|
|
||||||
void addPhysicalRule(const Name& name, const Name& layerName, DbU::Unit value, const string& reference);
|
|
||||||
void addPhysicalRule(const Name& name, const Name& layer1Name,
|
|
||||||
const Name& layer2Name, bool symetric, DbU::Unit value, const string& reference);
|
|
||||||
Layer* getLayer(const Name& layerName);
|
|
||||||
void print();
|
|
||||||
|
|
||||||
virtual Name getName() const;
|
|
||||||
|
|
||||||
virtual string _getTypeName() const;
|
|
||||||
virtual Record* _getRecord() const;
|
|
||||||
|
|
||||||
ATechnology():
|
|
||||||
Inherit(),
|
|
||||||
_noLayerPhysicalRules(),
|
|
||||||
_oneLayerPhysicalRules(),
|
|
||||||
_twoLayersPhysicalRules() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PhysicalRules _noLayerPhysicalRules;
|
|
||||||
OneLayerPhysicalRules _oneLayerPhysicalRules;
|
|
||||||
TwoLayersPhysicalRules _twoLayersPhysicalRules;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Inspector Support for : "ATechnology::LayerPair".
|
|
||||||
|
|
||||||
template<>
|
|
||||||
inline std::string getString<ATechnology::LayerPair> (ATechnology::LayerPair lp) {
|
|
||||||
return "<LayerPair layer1=" + getString(lp.first) + ", layer2=" + getString(lp.second) + ">";
|
|
||||||
}
|
|
||||||
|
|
||||||
INSPECTOR_P_SUPPORT(ATechnology);
|
|
||||||
INSPECTOR_P_SUPPORT(ATechnology::PhysicalRule);
|
|
||||||
INSPECTOR_P_SUPPORT(ATechnology::TwoLayersPhysicalRule);
|
|
||||||
|
|
||||||
#endif /* ATECHNOLOGY_H_*/
|
|
|
@ -1,122 +0,0 @@
|
||||||
#include <libxml/parser.h>
|
|
||||||
#include <libxml/tree.h>
|
|
||||||
|
|
||||||
#include "hurricane/Technology.h"
|
|
||||||
|
|
||||||
#include "ATechnology.h"
|
|
||||||
|
|
||||||
#include "ATechnologyXmlParser.h"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
void syntaxError(const string& reason) {
|
|
||||||
throw Error(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
DbU::Unit getUnitValue(double physicalValue) {
|
|
||||||
return DbU::grid(DbU::physicalToGrid(physicalValue, DbU::Micro));
|
|
||||||
}
|
|
||||||
|
|
||||||
void readPhysicalRules(xmlNode* node, ATechnology* aTechnology) {
|
|
||||||
if (node->type == XML_ELEMENT_NODE && node->children) {
|
|
||||||
for (xmlNode* ruleNode = node->children;
|
|
||||||
ruleNode;
|
|
||||||
ruleNode = ruleNode->next) {
|
|
||||||
if (ruleNode->type == XML_ELEMENT_NODE) {
|
|
||||||
if (xmlStrEqual(ruleNode->name, (xmlChar*)"arule")) {
|
|
||||||
xmlChar* ruleNameC = xmlGetProp(ruleNode, (xmlChar*)"name");
|
|
||||||
xmlChar* valueC = xmlGetProp(ruleNode, (xmlChar*)"value");
|
|
||||||
xmlChar* refC = xmlGetProp(ruleNode, (xmlChar*)"ref");
|
|
||||||
xmlChar* layer1C = xmlGetProp(ruleNode, (xmlChar*)"layer1");
|
|
||||||
xmlChar* layer2C = xmlGetProp(ruleNode, (xmlChar*)"layer2");
|
|
||||||
if (ruleNameC && valueC && refC && layer1C && layer2C) {
|
|
||||||
string ruleName((const char*)ruleNameC);
|
|
||||||
double value = atof((const char*)valueC);
|
|
||||||
DbU::Unit unitValue = getUnitValue(value);
|
|
||||||
cerr << value << ", " << unitValue << endl;
|
|
||||||
string reference((const char*)refC);
|
|
||||||
Name layer1Name((const char*)layer1C);
|
|
||||||
Name layer2Name((const char*)layer2C);
|
|
||||||
aTechnology->addPhysicalRule(ruleName, layer1Name, layer2Name, false, unitValue, reference);
|
|
||||||
}
|
|
||||||
} else if (xmlStrEqual(ruleNode->name, (xmlChar*)"rule")) {
|
|
||||||
xmlChar* ruleNameC = xmlGetProp(ruleNode, (xmlChar*)"name");
|
|
||||||
xmlChar* valueC = xmlGetProp(ruleNode, (xmlChar*)"value");
|
|
||||||
xmlChar* refC = xmlGetProp(ruleNode, (xmlChar*)"ref");
|
|
||||||
xmlChar* layerC = xmlGetProp(ruleNode, (xmlChar*)"layer");
|
|
||||||
xmlChar* layer1C = xmlGetProp(ruleNode, (xmlChar*)"layer1");
|
|
||||||
xmlChar* layer2C = xmlGetProp(ruleNode, (xmlChar*)"layer2");
|
|
||||||
if (ruleNameC && valueC && refC) {
|
|
||||||
string ruleName((const char*)ruleNameC);
|
|
||||||
double value = atof((const char*)valueC);
|
|
||||||
DbU::Unit unitValue = getUnitValue(value);
|
|
||||||
string reference((const char*)refC);
|
|
||||||
if (layerC) {
|
|
||||||
Name layerName((const char*)layerC);
|
|
||||||
aTechnology->addPhysicalRule(ruleName, layerName, unitValue, reference);
|
|
||||||
} else if (layer1C && layer2C) {
|
|
||||||
Name layer1Name((const char*)layer1C);
|
|
||||||
Name layer2Name((const char*)layer2C);
|
|
||||||
aTechnology->addPhysicalRule(ruleName, layer1Name, layer2Name, true, unitValue, reference);
|
|
||||||
} else {
|
|
||||||
aTechnology->addPhysicalRule(ruleName, unitValue, reference);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
syntaxError("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ATechnology* parseFileAsTechnology(const char* filePath, Technology* technology) {
|
|
||||||
ATechnology* aTechnology = ATechnology::create(technology);
|
|
||||||
|
|
||||||
|
|
||||||
xmlDocPtr doc; /* the resulting document tree */
|
|
||||||
|
|
||||||
doc = xmlReadFile(filePath, NULL, 0);
|
|
||||||
if (doc == NULL) {
|
|
||||||
fprintf(stderr, "Failed to parse %s\n", filePath);
|
|
||||||
exit(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Get the design element node */
|
|
||||||
xmlNode* rootElement = xmlDocGetRootElement(doc);
|
|
||||||
if (rootElement->type == XML_ELEMENT_NODE &&
|
|
||||||
xmlStrEqual(rootElement->name, (xmlChar*)"technology")) {
|
|
||||||
xmlNode* child = rootElement->children;
|
|
||||||
for (xmlNode* node = child; node; node = node->next) {
|
|
||||||
if (node->type == XML_ELEMENT_NODE) {
|
|
||||||
if (xmlStrEqual(node->name, (xmlChar*)"physical_rules")) {
|
|
||||||
readPhysicalRules(node, aTechnology);
|
|
||||||
} else {
|
|
||||||
syntaxError("unknown tag");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ATechnology* ATechnologyXmlParser::parse(const char* filePath, Technology* technology) {
|
|
||||||
|
|
||||||
LIBXML_TEST_VERSION
|
|
||||||
|
|
||||||
ATechnology* aTechnology = parseFileAsTechnology(filePath, technology);
|
|
||||||
|
|
||||||
xmlCleanupParser();
|
|
||||||
/*
|
|
||||||
* this is to debug memory for regression tests
|
|
||||||
*/
|
|
||||||
|
|
||||||
xmlMemoryDump();
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef ATECHNOLOGYXMLPARSER_H_
|
|
||||||
#define ATECHNOLOGYXMLPARSER_H_
|
|
||||||
|
|
||||||
namespace Hurricane {
|
|
||||||
class Technology;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ATechnology;
|
|
||||||
|
|
||||||
class ATechnologyXmlParser {
|
|
||||||
public:
|
|
||||||
static ATechnology* parse(const char* filePath, Hurricane::Technology* technology);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*ATECHNOLOGYXMLPARSER_H_*/
|
|
|
@ -1,8 +0,0 @@
|
||||||
INCLUDE_DIRECTORIES(${LIBXML2_INCLUDE_DIR} ${HURRICANE_INCLUDE_DIR} ${CORIOLIS_INCLUDE_DIR})
|
|
||||||
|
|
||||||
ADD_LIBRARY(atechnology SHARED
|
|
||||||
AEnv.cpp ATechnology.cpp ATechnologyXmlParser.cpp)
|
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(atechnology ${HURRICANE_LIBRARIES} ${CORIOLIS_LIBRARIES} ${LIBXML2_LIBRARIES})
|
|
||||||
|
|
||||||
INSTALL(TARGETS atechnology DESTINATION /lib)
|
|
|
@ -1,16 +0,0 @@
|
||||||
include(${QT_USE_FILE})
|
|
||||||
|
|
||||||
qt4_wrap_cpp(MOC_TRANSISTOR TransistorViewer.h)
|
|
||||||
qt4_wrap_cpp(MOC_CAPACITOR CapacitorViewer.h)
|
|
||||||
|
|
||||||
include_directories(${HURRICANE_INCLUDE_DIR} ${HURRICANE_GRAPHICAL_INCLUDE_DIR}
|
|
||||||
${CORIOLIS_INCLUDE_DIR} ${CHAMSIN_SOURCE_DIR}/src/technology
|
|
||||||
${CHAMSIN_SOURCE_DIR}/src/analogic ${CHAMSIN_SOURCE_DIR}/src/device)
|
|
||||||
|
|
||||||
add_executable(transview TransistorViewer.cpp ${MOC_TRANSISTOR} TransistorTest.cpp)
|
|
||||||
add_executable(capaview CapacitorViewer.cpp ${MOC_CAPACITOR} CapacitorTest.cpp)
|
|
||||||
|
|
||||||
target_link_libraries(transview atechnology analogic ${HURRICANE_LIBRARIES} ${HURRICANE_GRAPHICAL_LIBRARIES} ${QT_LIBRARIES})
|
|
||||||
target_link_libraries(capaview atechnology analogic ${HURRICANE_LIBRARIES} ${HURRICANE_GRAPHICAL_LIBRARIES} ${QT_LIBRARIES})
|
|
||||||
|
|
||||||
install(TARGETS transview capaview DESTINATION /bin)
|
|
|
@ -1,57 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
#include "hurricane/Warning.h"
|
|
||||||
#include "hurricane/Error.h"
|
|
||||||
#include "hurricane/DataBase.h"
|
|
||||||
#include "hurricane/Library.h"
|
|
||||||
#include "hurricane/viewer/CellViewer.h"
|
|
||||||
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "AEnv.h"
|
|
||||||
#include "ATechnology.h"
|
|
||||||
#include "Transistor.h"
|
|
||||||
#include "CapacitorViewer.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
int returnCode;
|
|
||||||
try {
|
|
||||||
|
|
||||||
QApplication* qa = new QApplication(argc, argv);
|
|
||||||
|
|
||||||
if (argc != 5) {
|
|
||||||
cerr << "capview symbtechno.xml s2rtechno.xml graphic.xml anatechno.xml";
|
|
||||||
exit(56);
|
|
||||||
}
|
|
||||||
AEnv::create(argv[1], argv[2], argv[3], argv[4]);
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
Library* rootLibrary = db->getRootLibrary();
|
|
||||||
Library* userLibrary = Library::create(rootLibrary, Name("USER"));
|
|
||||||
|
|
||||||
ATechnology* aTechnology = AEnv::getATechnology();
|
|
||||||
if (!aTechnology) {
|
|
||||||
exit(56);
|
|
||||||
}
|
|
||||||
|
|
||||||
CapacitorViewer* viewer = new CapacitorViewer(userLibrary);
|
|
||||||
|
|
||||||
viewer->show();
|
|
||||||
|
|
||||||
returnCode = qa->exec();
|
|
||||||
delete viewer;
|
|
||||||
delete qa;
|
|
||||||
|
|
||||||
} catch (Hurricane::Warning& w) {
|
|
||||||
cerr << w.what() << endl;
|
|
||||||
} catch (Hurricane::Error& e) {
|
|
||||||
cerr << e.what() << endl;
|
|
||||||
exit (1);
|
|
||||||
} catch (...) {
|
|
||||||
cout << "Abnormal termination\n" << endl;
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
return returnCode;
|
|
||||||
}
|
|
|
@ -1,118 +0,0 @@
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QSlider>
|
|
||||||
#include <QDockWidget>
|
|
||||||
#include <QComboBox>
|
|
||||||
|
|
||||||
#include "Capacitor.h"
|
|
||||||
#include "hurricane/DataBase.h"
|
|
||||||
#include "hurricane/viewer/CellWidget.h"
|
|
||||||
#include "hurricane/viewer/HInspectorWidget.h"
|
|
||||||
#include "hurricane/viewer/HPalette.h"
|
|
||||||
#include "AEnv.h"
|
|
||||||
#include "ATechnology.h"
|
|
||||||
|
|
||||||
#include "CapacitorViewer.h"
|
|
||||||
|
|
||||||
|
|
||||||
CapacitorViewer::CapacitorViewer(Library* library) {
|
|
||||||
|
|
||||||
ATechnology* aTechnology = AEnv::getATechnology();
|
|
||||||
if (!aTechnology) {
|
|
||||||
exit(56);
|
|
||||||
}
|
|
||||||
|
|
||||||
DbU::Unit capacitorMinL = aTechnology->getPhysicalRule("topPlateMIMminWidth")->getValue();
|
|
||||||
DbU::Unit capacitorMaxL = 10 * capacitorMinL;
|
|
||||||
DbU::Unit capacitorMinW = aTechnology->getPhysicalRule("topPlateMIMminWidth")->getValue();
|
|
||||||
DbU::Unit capacitorMaxW = 10 * capacitorMinW;
|
|
||||||
|
|
||||||
_capacitor = Capacitor::create(library, Name("TEST"));
|
|
||||||
_capacitor->setL(capacitorMinL);
|
|
||||||
_capacitor->setW(capacitorMinW);
|
|
||||||
_cellWidget = new CellWidget;
|
|
||||||
_palette = new HPalette ();
|
|
||||||
_cellWidget->bindToPalette ( _palette );
|
|
||||||
_cellWidget->setCell(_capacitor);
|
|
||||||
_cellWidget->fitToContents();
|
|
||||||
setCentralWidget(_cellWidget);
|
|
||||||
QSlider* wSlider = new QSlider(Qt::Horizontal);
|
|
||||||
wSlider->setRange(capacitorMinW, 4 * capacitorMinW);
|
|
||||||
wSlider->setPageStep(DbU::grid(1));
|
|
||||||
wSlider->setSliderPosition(capacitorMinW);
|
|
||||||
QSlider* lSlider = new QSlider(Qt::Horizontal);
|
|
||||||
lSlider->setRange(capacitorMinL, 4 * capacitorMinL);
|
|
||||||
lSlider->setPageStep(DbU::grid(1));
|
|
||||||
lSlider->setSliderPosition(capacitorMinL);
|
|
||||||
|
|
||||||
QWidget* slidersWidget = new QWidget;
|
|
||||||
QGridLayout* layout = new QGridLayout;
|
|
||||||
layout->addWidget(wSlider, 0, 0);
|
|
||||||
layout->addWidget(lSlider, 1, 0);
|
|
||||||
slidersWidget->setLayout(layout);
|
|
||||||
|
|
||||||
QDockWidget *dockWidget = new QDockWidget(tr("Dock Widget"), this);
|
|
||||||
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea |
|
|
||||||
Qt::RightDockWidgetArea);
|
|
||||||
dockWidget->setWidget(slidersWidget);
|
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
|
|
||||||
|
|
||||||
|
|
||||||
QDockWidget* layerMapDock = new QDockWidget ( tr("Layers") );
|
|
||||||
layerMapDock->setFeatures ( QDockWidget::DockWidgetVerticalTitleBar
|
|
||||||
| QDockWidget::DockWidgetMovable
|
|
||||||
| QDockWidget::DockWidgetFloatable
|
|
||||||
);
|
|
||||||
layerMapDock->setObjectName ( "HPalette" );
|
|
||||||
layerMapDock->setWidget ( _palette );
|
|
||||||
layerMapDock->setAllowedAreas ( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
|
|
||||||
addDockWidget ( Qt::RightDockWidgetArea, layerMapDock );
|
|
||||||
|
|
||||||
_runInspectorOnDataBase= new QAction ( tr("Inspect &DataBase"), this );
|
|
||||||
_runInspectorOnDataBase->setStatusTip ( tr("Run Inspector on Hurricane DataBase") );
|
|
||||||
|
|
||||||
_runInspectorOnCell= new QAction ( tr("Inspect &Cell"), this );
|
|
||||||
_runInspectorOnCell->setStatusTip ( tr("Run Inspector on the current Cell") );
|
|
||||||
|
|
||||||
connect(wSlider, SIGNAL(valueChanged(int)), this, SLOT(wvalueChanged(int)));
|
|
||||||
connect(lSlider, SIGNAL(valueChanged(int)), this, SLOT(lvalueChanged(int)));
|
|
||||||
connect(_runInspectorOnDataBase, SIGNAL(triggered()) , this, SLOT(runInspectorOnDataBase()));
|
|
||||||
connect(_runInspectorOnCell , SIGNAL(triggered()) , this, SLOT(runInspectorOnCell ()));
|
|
||||||
|
|
||||||
QMenu* toolsMenu = menuBar()->addMenu(tr("Tool"));
|
|
||||||
toolsMenu->addAction(_runInspectorOnDataBase);
|
|
||||||
toolsMenu->addAction(_runInspectorOnCell);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CapacitorViewer::wvalueChanged(int value) {
|
|
||||||
_capacitor->setW(value);
|
|
||||||
_cellWidget->redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CapacitorViewer::lvalueChanged(int value) {
|
|
||||||
_capacitor->setL(value);
|
|
||||||
_cellWidget->redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CapacitorViewer::runInspectorOnDataBase() {
|
|
||||||
runInspector(getRecord(DataBase::getDB()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CapacitorViewer::runInspectorOnCell() {
|
|
||||||
Cell* cell = _cellWidget->getCell();
|
|
||||||
if (cell) {
|
|
||||||
runInspector(getRecord(cell));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CapacitorViewer::runInspector(Record* record) {
|
|
||||||
static HInspectorWidget* inspector = NULL;
|
|
||||||
|
|
||||||
if (record) {
|
|
||||||
inspector = new HInspectorWidget ();
|
|
||||||
|
|
||||||
inspector->setRootRecord ( record );
|
|
||||||
inspector->show ();
|
|
||||||
} else {
|
|
||||||
cerr << "[ERROR] Attempt to run Inspector on NULL record." << endl;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
#ifndef _CAPACITORVIEWER_H
|
|
||||||
#define _CAPACITORVIEWER_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
|
|
||||||
namespace Hurricane {
|
|
||||||
class Library;
|
|
||||||
class Record;
|
|
||||||
class CellWidget;
|
|
||||||
class HPalette;
|
|
||||||
class HMousePosition;
|
|
||||||
}
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
class Capacitor;
|
|
||||||
|
|
||||||
class CapacitorViewer : public QMainWindow {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
CapacitorViewer(Library* library);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void lvalueChanged(int value);
|
|
||||||
void wvalueChanged(int value);
|
|
||||||
void runInspectorOnDataBase();
|
|
||||||
void runInspectorOnCell();
|
|
||||||
|
|
||||||
private:
|
|
||||||
CapacitorViewer();
|
|
||||||
void createActions();
|
|
||||||
void createMenus();
|
|
||||||
void createLayout();
|
|
||||||
void runInspector(Record* record);
|
|
||||||
|
|
||||||
CellWidget* _cellWidget;
|
|
||||||
Capacitor* _capacitor;
|
|
||||||
QAction* _runInspectorOnDataBase;
|
|
||||||
QAction* _runInspectorOnCell;
|
|
||||||
QMenu* _viewMenu;
|
|
||||||
QMenu* _toolsMenu;
|
|
||||||
HPalette* _palette;
|
|
||||||
HMousePosition* _mousePosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _CAPACITORVIEWER_H */
|
|
|
@ -1,57 +0,0 @@
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
|
|
||||||
#include "hurricane/Warning.h"
|
|
||||||
#include "hurricane/Error.h"
|
|
||||||
#include "hurricane/DataBase.h"
|
|
||||||
#include "hurricane/Library.h"
|
|
||||||
#include "hurricane/viewer/CellViewer.h"
|
|
||||||
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
#include "AEnv.h"
|
|
||||||
#include "ATechnology.h"
|
|
||||||
#include "Transistor.h"
|
|
||||||
#include "TransistorViewer.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
|
||||||
int returnCode;
|
|
||||||
try {
|
|
||||||
|
|
||||||
QApplication* qa = new QApplication(argc, argv);
|
|
||||||
|
|
||||||
if (argc != 5) {
|
|
||||||
cerr << "transview symbtechno.xml s2rtechno.xml graphic.xml anatechno.xml";
|
|
||||||
exit(56);
|
|
||||||
}
|
|
||||||
AEnv::create(argv[1], argv[2], argv[3], argv[4]);
|
|
||||||
DataBase* db = DataBase::getDB();
|
|
||||||
Library* rootLibrary = db->getRootLibrary();
|
|
||||||
Library* userLibrary = Library::create(rootLibrary, Name("USER"));
|
|
||||||
|
|
||||||
ATechnology* aTechnology = AEnv::getATechnology();
|
|
||||||
if (!aTechnology) {
|
|
||||||
exit(56);
|
|
||||||
}
|
|
||||||
|
|
||||||
TransistorViewer* viewer = new TransistorViewer(userLibrary);
|
|
||||||
|
|
||||||
viewer->show();
|
|
||||||
|
|
||||||
returnCode = qa->exec();
|
|
||||||
delete viewer;
|
|
||||||
delete qa;
|
|
||||||
|
|
||||||
} catch (Hurricane::Warning& w) {
|
|
||||||
cerr << w.what() << endl;
|
|
||||||
} catch (Hurricane::Error& e) {
|
|
||||||
cerr << e.what() << endl;
|
|
||||||
exit (1);
|
|
||||||
} catch (...) {
|
|
||||||
cout << "Abnormal termination\n" << endl;
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
return returnCode;
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QSlider>
|
|
||||||
#include <QDockWidget>
|
|
||||||
#include <QComboBox>
|
|
||||||
|
|
||||||
#include "MetaTransistor.h"
|
|
||||||
#include "hurricane/viewer/CellWidget.h"
|
|
||||||
#include "AEnv.h"
|
|
||||||
#include "ATechnology.h"
|
|
||||||
|
|
||||||
#include "TransistorViewer.h"
|
|
||||||
|
|
||||||
|
|
||||||
TransistorViewer::TransistorViewer(Library* library) {
|
|
||||||
|
|
||||||
ATechnology* aTechnology = AEnv::getATechnology();
|
|
||||||
if (!aTechnology) {
|
|
||||||
exit(56);
|
|
||||||
}
|
|
||||||
|
|
||||||
DbU::Unit transistorMinL = aTechnology->getPhysicalRule("transistorMinL")->getValue();
|
|
||||||
DbU::Unit transistorMaxL = aTechnology->getPhysicalRule("transistorMaxL")->getValue();
|
|
||||||
DbU::Unit transistorMinW = aTechnology->getPhysicalRule("transistorMinW")->getValue();
|
|
||||||
DbU::Unit transistorMaxW = aTechnology->getPhysicalRule("transistorMaxW")->getValue();
|
|
||||||
|
|
||||||
_transistor = MetaTransistor::create(library, Name("TEST"));
|
|
||||||
_transistor->setType(MetaTransistor::Type::NMOS);
|
|
||||||
_transistor->setL(transistorMinL);
|
|
||||||
_transistor->setW(transistorMinW);
|
|
||||||
_transistor->setM(1);
|
|
||||||
_cellWidget = new CellWidget;
|
|
||||||
_cellWidget->setCell(_transistor);
|
|
||||||
_cellWidget->fitToContents();
|
|
||||||
setCentralWidget(_cellWidget);
|
|
||||||
QSlider* wSlider = new QSlider(Qt::Horizontal);
|
|
||||||
wSlider->setRange(transistorMinW, 4 * transistorMinW);
|
|
||||||
wSlider->setPageStep(DbU::grid(1));
|
|
||||||
wSlider->setSliderPosition(transistorMinW);
|
|
||||||
QSlider* lSlider = new QSlider(Qt::Horizontal);
|
|
||||||
lSlider->setRange(transistorMinL, 4 * transistorMinL);
|
|
||||||
lSlider->setPageStep(DbU::grid(1));
|
|
||||||
lSlider->setSliderPosition(transistorMinL);
|
|
||||||
QSlider* mSlider = new QSlider(Qt::Horizontal);
|
|
||||||
mSlider->setRange(1, 5);
|
|
||||||
mSlider->setPageStep(1);
|
|
||||||
mSlider->setSliderPosition(1);
|
|
||||||
QStringList choices;
|
|
||||||
choices << "NMOS" << "PMOS";
|
|
||||||
QComboBox* choiceBox = new QComboBox;
|
|
||||||
choiceBox->addItems(choices);
|
|
||||||
|
|
||||||
QWidget* slidersWidget = new QWidget;
|
|
||||||
QGridLayout* layout = new QGridLayout;
|
|
||||||
layout->addWidget(wSlider, 0, 0);
|
|
||||||
layout->addWidget(lSlider, 1, 0);
|
|
||||||
layout->addWidget(mSlider, 2, 0);
|
|
||||||
layout->addWidget(choiceBox, 3, 0);
|
|
||||||
slidersWidget->setLayout(layout);
|
|
||||||
|
|
||||||
QDockWidget *dockWidget = new QDockWidget(tr("Dock Widget"), this);
|
|
||||||
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea |
|
|
||||||
Qt::RightDockWidgetArea);
|
|
||||||
dockWidget->setWidget(slidersWidget);
|
|
||||||
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
|
|
||||||
|
|
||||||
connect(wSlider, SIGNAL(valueChanged(int)), this, SLOT(wvalueChanged(int)));
|
|
||||||
connect(lSlider, SIGNAL(valueChanged(int)), this, SLOT(lvalueChanged(int)));
|
|
||||||
connect(mSlider, SIGNAL(valueChanged(int)), this, SLOT(mvalueChanged(int)));
|
|
||||||
connect(choiceBox, SIGNAL(currentIndexChanged(int)), this, SLOT(transistorTypeChanged(int)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransistorViewer::wvalueChanged(int value) {
|
|
||||||
_transistor->setW(value);
|
|
||||||
_cellWidget->redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransistorViewer::lvalueChanged(int value) {
|
|
||||||
_transistor->setL(value);
|
|
||||||
_cellWidget->redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransistorViewer::mvalueChanged(int value) {
|
|
||||||
_transistor->setM(value);
|
|
||||||
_cellWidget->redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TransistorViewer::transistorTypeChanged(int value) {
|
|
||||||
if (value == 0) {
|
|
||||||
_transistor->setType(MetaTransistor::Type::NMOS);
|
|
||||||
_cellWidget->redraw();
|
|
||||||
} else if (value == 1) {
|
|
||||||
_transistor->setType(MetaTransistor::Type::PMOS);
|
|
||||||
_cellWidget->redraw();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
#ifndef _TRANSISTORVIEWER_H
|
|
||||||
#define _TRANSISTORVIEWER_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
|
|
||||||
namespace Hurricane {
|
|
||||||
class Library;
|
|
||||||
class CellWidget;
|
|
||||||
}
|
|
||||||
using namespace Hurricane;
|
|
||||||
|
|
||||||
class MetaTransistor;
|
|
||||||
|
|
||||||
class TransistorViewer : public QMainWindow {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
TransistorViewer(Library* library);
|
|
||||||
private slots:
|
|
||||||
void lvalueChanged(int value);
|
|
||||||
void wvalueChanged(int value);
|
|
||||||
void transistorTypeChanged(int value);
|
|
||||||
void mvalueChanged(int value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TransistorViewer();
|
|
||||||
CellWidget* _cellWidget;
|
|
||||||
MetaTransistor* _transistor;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _TRANSISTORVIEWER_H */
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- mode: CMAKE explicit-buffer-name: "CMakeLists.txt<crlcore>" -*-
|
||||||
|
|
||||||
project(CRLCORE)
|
project(CRLCORE)
|
||||||
|
|
||||||
|
@ -5,9 +6,8 @@
|
||||||
|
|
||||||
OPTION(BUILD_DOC "Build the documentation (latex+doxygen)" OFF)
|
OPTION(BUILD_DOC "Build the documentation (latex+doxygen)" OFF)
|
||||||
|
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{BOOTSTRAP_TOP}/share/cmake/Modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||||
find_package(Bootstrap REQUIRED)
|
find_package(Bootstrap REQUIRED)
|
||||||
setup_project_paths(VLSISAPD)
|
|
||||||
setup_project_paths(CORIOLIS)
|
setup_project_paths(CORIOLIS)
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${CRLCORE_SOURCE_DIR}/cmake_modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "${CRLCORE_SOURCE_DIR}/cmake_modules/")
|
||||||
print_cmake_module_path()
|
print_cmake_module_path()
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
# -*- mode: CMAKE explicit-buffer-name: "CMakeLists.txt<cumulus>" -*-
|
||||||
|
|
||||||
project(CUMULUS)
|
project(CUMULUS)
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.4.0)
|
cmake_minimum_required(VERSION 2.4.0)
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{BOOTSTRAP_TOP}/share/cmake/Modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||||
find_package(Bootstrap REQUIRED)
|
find_package(Bootstrap REQUIRED)
|
||||||
setup_project_paths(VLSISAPD)
|
|
||||||
setup_project_paths(CORIOLIS)
|
setup_project_paths(CORIOLIS)
|
||||||
|
|
||||||
set_cmake_policies()
|
set_cmake_policies()
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
# -*- mode: CMAKE explicit-buffer-name: "CMakeLists.txt<equinox>" -*-
|
||||||
|
|
||||||
project(EQUINOX)
|
project(EQUINOX)
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.4.0)
|
cmake_minimum_required(VERSION 2.4.0)
|
||||||
|
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{BOOTSTRAP_TOP}/share/cmake/Modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||||
find_package(Bootstrap REQUIRED)
|
find_package(Bootstrap REQUIRED)
|
||||||
setup_project_paths(VLSISAPD)
|
|
||||||
setup_project_paths(CORIOLIS)
|
setup_project_paths(CORIOLIS)
|
||||||
|
|
||||||
set_cmake_policies()
|
set_cmake_policies()
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- mode: CMAKE explicit-buffer-name: "CMakeLists.txt<hurricane>" -*-
|
||||||
|
|
||||||
project(HURRICANE)
|
project(HURRICANE)
|
||||||
|
|
||||||
|
@ -5,10 +6,9 @@
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.4.0)
|
cmake_minimum_required(VERSION 2.4.0)
|
||||||
|
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{BOOTSTRAP_TOP}/share/cmake/Modules")
|
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{CORIOLIS_TOP}/share/cmake/Modules")
|
||||||
find_package(Bootstrap REQUIRED)
|
find_package(Bootstrap REQUIRED)
|
||||||
setup_project_paths(BOOTSTRAP)
|
setup_project_paths(CORIOLIS)
|
||||||
setup_project_paths(VLSISAPD)
|
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${HURRICANE_SOURCE_DIR}/cmake_modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "${HURRICANE_SOURCE_DIR}/cmake_modules/")
|
||||||
|
|
||||||
set_cmake_policies()
|
set_cmake_policies()
|
||||||
|
@ -30,10 +30,10 @@
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(cmake_modules)
|
add_subdirectory(cmake_modules)
|
||||||
add_subdirectory(tests)
|
#add_subdirectory(tests)
|
||||||
if(BUILD_DOC AND DOXYGEN_FOUND)
|
if(BUILD_DOC AND DOXYGEN_FOUND)
|
||||||
add_subdirectory(doc)
|
add_subdirectory(doc)
|
||||||
endif(BUILD_DOC AND DOXYGEN_FOUND)
|
endif(BUILD_DOC AND DOXYGEN_FOUND)
|
||||||
|
|
||||||
enable_testing()
|
#enable_testing()
|
||||||
add_test(HurricaneTest ${PROJECT_BINARY_DIR}/tests/htest)
|
#add_test(HurricaneTest ${PROJECT_BINARY_DIR}/tests/htest)
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 3525 7425 4275 8475
|
||||||
|
6 3750 7725 4125 8175
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3825 8100 3825 7800 4050 7800
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3825 7950 3975 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
3600 7500 4200 7500 4200 8400 3600 8400 3600 7500
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3600 9300 3600 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2700 8400 4575 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2625 7125 4575 7125 4575 9375 2625 9375 2625 7125
|
After Width: | Height: | Size: 733 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 825 6525 1575 7575
|
||||||
|
6 975 6825 1350 7275
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
1275 7200 1275 6900 1050 6900
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
1275 7050 1125 7050
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
1500 6600 900 6600 900 7500 1500 7500 1500 6600
|
||||||
|
-6
|
||||||
|
6 1425 6525 2175 7575
|
||||||
|
6 1650 6825 2025 7275
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
1725 7200 1725 6900 1950 6900
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
1725 7050 1875 7050
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
1500 6600 2100 6600 2100 7500 1500 7500 1500 6600
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
1500 8400 1500 6300
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
600 7500 2475 7500
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
525 6225 2475 6225 2475 8550 525 8550 525 6225
|
After Width: | Height: | Size: 637 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 3225 8325 3975 9375
|
||||||
|
6 3450 8625 3825 9075
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3525 8700 3525 9000 3750 9000
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3525 8850 3675 8850
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
3300 9300 3900 9300 3900 8400 3300 8400 3300 9300
|
||||||
|
-6
|
||||||
|
6 3225 7425 3975 8475
|
||||||
|
6 3450 7725 3825 8175
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3525 8100 3525 7800 3750 7800
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3525 7950 3675 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
3300 7500 3900 7500 3900 8400 3300 8400 3300 7500
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3300 9300 3300 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2400 8400 4275 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2325 7125 4275 7125 4275 9450 2325 9450 2325 7125
|
After Width: | Height: | Size: 828 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 3300 7425 4050 8475
|
||||||
|
6 3525 7725 3900 8175
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3600 8100 3600 7800 3825 7800
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3600 7950 3750 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
3375 7500 3975 7500 3975 8400 3375 8400 3375 7500
|
||||||
|
-6
|
||||||
|
6 2400 8325 3450 9075
|
||||||
|
6 2700 8475 3150 8850
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3075 8775 2775 8775 2775 8550
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
2925 8775 2925 8625
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
2475 9000 2475 8400 3375 8400 3375 9000 2475 9000
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3375 9300 3375 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2475 8400 4275 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2325 7125 4275 7125 4275 9375 2325 9375 2325 7125
|
After Width: | Height: | Size: 831 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 2925 7425 3675 8475
|
||||||
|
6 3150 7725 3525 8175
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3225 8100 3225 7800 3450 7800
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3225 7950 3375 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
3000 7500 3600 7500 3600 8400 3000 8400 3000 7500
|
||||||
|
-6
|
||||||
|
6 2325 8325 3075 9375
|
||||||
|
6 2475 8625 2850 9075
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
2775 8700 2775 9000 2550 9000
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
2775 8850 2625 8850
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
3000 9300 2400 9300 2400 8400 3000 8400 3000 9300
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3000 9300 3000 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2100 8400 3975 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2025 7125 3975 7125 3975 9375 2025 9375 2025 7125
|
|
@ -0,0 +1,85 @@
|
||||||
|
%PDF-1.4
|
||||||
|
%Çì<C387>¢
|
||||||
|
5 0 obj
|
||||||
|
<</Length 6 0 R/Filter /FlateDecode>>
|
||||||
|
stream
|
||||||
|
xœ<EFBFBD>R1nÃ0Üù
|
||||||
|
Î\R)ù<05>}@Ѻƒ] éÐïWm4r2†à;Ü‘'Jº
Œdßö[áéœqþFû®³Î„…ðú'¸€Q%\Áª`.7 I|‚RB!¥:‰,U-tË‘d”Fn:Yã×~AÚÏÏÍŸ´µÂHZ<48>¼mÝžºŒ.}ú÷<C3BA>L¥Ô«^]2¸¹,mÙ-<2D>+YqÑ?ÅË÷!µ‰Ö9ó泩©÷]¼ÿ4¨Pç6-Û¹¤ý2C®Çó@š ƬnhLÖ½ˆnÈuã+vä<76>9<EFBFBD>aÌõQI[õ…Ðš’¤¼ß̽i‚$Œ‰,Â<>9ˆ¬rÝø
|
||||||
|
QùñüU9ŽÃendstream
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
282
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<</Type/Page/MediaBox [0 0 118 136]
|
||||||
|
/Parent 3 0 R
|
||||||
|
/Resources<</ProcSet[/PDF]
|
||||||
|
/ExtGState 8 0 R
|
||||||
|
>>
|
||||||
|
/Contents 5 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<< /Type /Pages /Kids [
|
||||||
|
4 0 R
|
||||||
|
] /Count 1
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
1 0 obj
|
||||||
|
<</Type /Catalog /Pages 3 0 R
|
||||||
|
/Metadata 9 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<</Type/ExtGState
|
||||||
|
/OPM 1>>endobj
|
||||||
|
8 0 obj
|
||||||
|
<</R7
|
||||||
|
7 0 R>>
|
||||||
|
endobj
|
||||||
|
9 0 obj
|
||||||
|
<</Type/Metadata
|
||||||
|
/Subtype/XML/Length 1429>>stream
|
||||||
|
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
|
||||||
|
<?adobe-xap-filters esc="CRLF"?>
|
||||||
|
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9.1-13, framework 1.6'>
|
||||||
|
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>
|
||||||
|
<rdf:Description rdf:about='3cc76253-91d4-11ee-0000-52f3c0b8f8af' xmlns:pdf='http://ns.adobe.com/pdf/1.3/' pdf:Producer='GPL Ghostscript 8.70'/>
|
||||||
|
<rdf:Description rdf:about='3cc76253-91d4-11ee-0000-52f3c0b8f8af' xmlns:xmp='http://ns.adobe.com/xap/1.0/'><xmp:ModifyDate>2013-11-30T13:05:22+01:00</xmp:ModifyDate>
|
||||||
|
<xmp:CreateDate>2013-11-30T13:05:22+01:00</xmp:CreateDate>
|
||||||
|
<xmp:CreatorTool>fig2dev Version 3.2 Patchlevel 5</xmp:CreatorTool></rdf:Description>
|
||||||
|
<rdf:Description rdf:about='3cc76253-91d4-11ee-0000-52f3c0b8f8af' xmlns:xapMM='http://ns.adobe.com/xap/1.0/mm/' xapMM:DocumentID='3cc76253-91d4-11ee-0000-52f3c0b8f8af'/>
|
||||||
|
<rdf:Description rdf:about='3cc76253-91d4-11ee-0000-52f3c0b8f8af' xmlns:dc='http://purl.org/dc/elements/1.1/' dc:format='application/pdf'><dc:title><rdf:Alt><rdf:li xml:lang='x-default'>transf-R2.fig</rdf:li></rdf:Alt></dc:title><dc:creator><rdf:Seq><rdf:li>jpc@lepka \(Jean-Paul Chaput\)</rdf:li></rdf:Seq></dc:creator></rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
|
||||||
|
|
||||||
|
<?xpacket end='w'?>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<</Producer(GPL Ghostscript 8.70)
|
||||||
|
/CreationDate(D:20131130130522+01'00')
|
||||||
|
/ModDate(D:20131130130522+01'00')
|
||||||
|
/Title(transf-R2.fig)
|
||||||
|
/Creator(fig2dev Version 3.2 Patchlevel 5)
|
||||||
|
/Author(jpc@lepka \(Jean-Paul Chaput\))>>endobj
|
||||||
|
xref
|
||||||
|
0 10
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000576 00000 n
|
||||||
|
0000002215 00000 n
|
||||||
|
0000000517 00000 n
|
||||||
|
0000000386 00000 n
|
||||||
|
0000000015 00000 n
|
||||||
|
0000000367 00000 n
|
||||||
|
0000000640 00000 n
|
||||||
|
0000000681 00000 n
|
||||||
|
0000000710 00000 n
|
||||||
|
trailer
|
||||||
|
<< /Size 10 /Root 1 0 R /Info 2 0 R
|
||||||
|
/ID [<354D61171374F7A9723F4C5D6FB5D249><354D61171374F7A9723F4C5D6FB5D249>]
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
2443
|
||||||
|
%%EOF
|
After Width: | Height: | Size: 834 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 3000 7425 3750 8475
|
||||||
|
6 3225 7725 3600 8175
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3300 8100 3300 7800 3525 7800
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3300 7950 3450 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
3075 7500 3675 7500 3675 8400 3075 8400 3075 7500
|
||||||
|
-6
|
||||||
|
6 3000 8325 4050 9075
|
||||||
|
6 3300 8550 3750 8925
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3375 8625 3675 8625 3675 8850
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3525 8625 3525 8775
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
3975 8400 3975 9000 3075 9000 3075 8400 3975 8400
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3075 9300 3075 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2175 8400 4050 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2100 7125 4050 7125 4050 9375 2100 9375 2100 7125
|
After Width: | Height: | Size: 811 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 2625 7425 3375 8475
|
||||||
|
6 2775 7725 3150 8175
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3075 8100 3075 7800 2850 7800
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3075 7950 2925 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
3300 7500 2700 7500 2700 8400 3300 8400 3300 7500
|
||||||
|
-6
|
||||||
|
6 3225 7425 3975 8475
|
||||||
|
6 3450 7725 3825 8175
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3525 8100 3525 7800 3750 7800
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3525 7950 3675 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
3300 7500 3900 7500 3900 8400 3300 8400 3300 7500
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3300 9300 3300 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2400 8400 4275 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2325 7125 4275 7125 4275 9450 2325 9450 2325 7125
|
After Width: | Height: | Size: 823 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 2700 8325 3750 9075
|
||||||
|
6 3000 8550 3450 8925
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3375 8625 3075 8625 3075 8850
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3225 8625 3225 8775
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
2775 8400 2775 9000 3675 9000 3675 8400 2775 8400
|
||||||
|
-6
|
||||||
|
6 3600 7425 4350 8475
|
||||||
|
6 3825 7725 4200 8175
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3900 8100 3900 7800 4125 7800
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3900 7950 4050 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
3675 7500 4275 7500 4275 8400 3675 8400 3675 7500
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3675 9300 3675 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2775 8400 4575 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2625 7125 4575 7125 4575 9450 2625 9450 2625 7125
|
After Width: | Height: | Size: 846 B |
|
@ -0,0 +1,38 @@
|
||||||
|
#FIG 3.2 Produced by xfig version 3.2.5a
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Inches
|
||||||
|
Letter
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
0 32 #ffffdd
|
||||||
|
6 3525 7725 4575 8475
|
||||||
|
6 3825 7875 4275 8250
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3900 8175 4200 8175 4200 7950
|
||||||
|
2 1 0 4 18 18 45 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
4050 8175 4050 8025
|
||||||
|
-6
|
||||||
|
2 2 0 4 18 18 50 -1 30 0.000 0 0 -1 0 0 5
|
||||||
|
4500 8400 4500 7800 3600 7800 3600 8400 4500 8400
|
||||||
|
-6
|
||||||
|
6 3525 7425 4275 8475
|
||||||
|
6 3750 7725 4125 8175
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 3
|
||||||
|
3825 8100 3825 7800 4050 7800
|
||||||
|
2 1 0 4 0 18 55 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3825 7950 3975 7950
|
||||||
|
-6
|
||||||
|
2 2 0 4 0 0 60 -1 7 0.000 0 0 -1 0 0 5
|
||||||
|
3600 7500 4200 7500 4200 8400 3600 8400 3600 7500
|
||||||
|
-6
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
3600 9300 3600 7200
|
||||||
|
2 1 0 1 0 5 70 -1 -1 0.000 0 0 -1 1 0 2
|
||||||
|
0 0 1.00 60.00 120.00
|
||||||
|
2700 8400 4575 8400
|
||||||
|
2 2 0 0 32 32 100 -1 40 0.000 0 0 -1 0 0 5
|
||||||
|
2625 7125 4575 7125 4575 9450 2625 9450 2625 7125
|
After Width: | Height: | Size: 775 B |
|
@ -1,11 +1,11 @@
|
||||||
|
# -*- mode: CMAKE explicit-buffer-name: "CMakeLists.txt<ispd>" -*-
|
||||||
|
|
||||||
project(ISPD)
|
project(ISPD)
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.4.0)
|
cmake_minimum_required(VERSION 2.4.0)
|
||||||
|
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "$ENV{BOOTSTRAP_TOP}/share/cmake/Modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||||
find_package(Bootstrap REQUIRED)
|
find_package(Bootstrap REQUIRED)
|
||||||
setup_project_paths(VLSISAPD)
|
|
||||||
setup_project_paths(CORIOLIS)
|
setup_project_paths(CORIOLIS)
|
||||||
|
|
||||||
set_cmake_policies()
|
set_cmake_policies()
|
||||||
|
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.4.0)
|
cmake_minimum_required(VERSION 2.4.0)
|
||||||
|
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{BOOTSTRAP_TOP}/share/cmake/Modules/")
|
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}/$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||||
find_package(Bootstrap REQUIRED)
|
find_package(Bootstrap REQUIRED)
|
||||||
setup_project_paths(VLSISAPD)
|
|
||||||
setup_project_paths(CORIOLIS)
|
setup_project_paths(CORIOLIS)
|
||||||
|
|
||||||
set_cmake_policies()
|
set_cmake_policies()
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Katabatic {
|
||||||
|
|
||||||
|
/*! \class AutoContactHTee
|
||||||
|
*
|
||||||
|
* \brief AutoContact H-Tee (two H, one V)
|
||||||
|
*
|
||||||
|
* AutoContact to build an horizontal tee (two H, one V).
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function AutoContactHTee* AutoContactHTee::create ( GCell* gcell, Net* net, const Layer* layer );
|
||||||
|
//! \param gcell The GCell into which create the AutoContact.
|
||||||
|
//! \param net The Net to which this AutoContact belongs.
|
||||||
|
//! \param layer The Layer of the AutoContact.
|
||||||
|
//! \return The created AutoContactHTee.
|
||||||
|
//!
|
||||||
|
//! Create a new AutoContactHTee.
|
||||||
|
|
||||||
|
//! \function void AutoContactHTee::updateTopology ();
|
||||||
|
//! Restore the topology (i.e. connexity) of the contact after any number
|
||||||
|
//! of connected segments has changed layer (at least one, up to three).
|
||||||
|
//!
|
||||||
|
//! For any configuration, the connexity can be restored by making only
|
||||||
|
//! one dogleg.
|
||||||
|
//!
|
||||||
|
//! We distinguish two kind of layer changes:
|
||||||
|
//! -# The two horizontals (\c h1 and \c h2) are still on the same layer
|
||||||
|
//! (either they both moved or the vertical only has moved, see figures
|
||||||
|
//! 2 & 4).
|
||||||
|
//! In that case, the dogleg is made on the vertical.
|
||||||
|
//! -# The two horizontals no longer are on the same layer (figures 1 & 3).
|
||||||
|
//! In that case, the dogleg is made on the horizontal which is at the
|
||||||
|
//! greater distance (in a layer sense) from the vertical.
|
||||||
|
//!
|
||||||
|
//! \image html updateTopologyHTee.png "Update H-Tee Topology"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Katabatic {
|
||||||
|
|
||||||
|
/*! \class AutoContactTerminal
|
||||||
|
*
|
||||||
|
* \brief AutoContact Terminal (S/T is a Terminal)
|
||||||
|
*
|
||||||
|
* AutoContact that are directly attached by either source or target
|
||||||
|
* or both to a terminal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function AutoContactTerminal* AutoContactTerminal::create ( GCell* gcell, Component* rp, const Layer* layer, const DbU::Unit x, const DbU::Unit y, const DbU::Unit width, const DbU::Unit height );
|
||||||
|
//! \param gcell The GCell into which create the AutoContact.
|
||||||
|
//! \param rp The Component on which to anchor the AutoContact.
|
||||||
|
//! \param layer The Layer of the AutoContact.
|
||||||
|
//! \param x The absolute X position.
|
||||||
|
//! \param y The absolute Y position.
|
||||||
|
//! \param width The width of the AutoContact.
|
||||||
|
//! \param height The height of the AutoContact.
|
||||||
|
//! \return The created AutoContact.
|
||||||
|
//!
|
||||||
|
//! Create a new AutoContactTerminal anchored on \c rp. <code>(x,y)</code> gives
|
||||||
|
//! the \e absolute position.
|
||||||
|
//!
|
||||||
|
//! The anchor component \c rp is most often a Hurricane::RoutingPad (occurrencing
|
||||||
|
//! a Hurricane::Segment) or directly a Hurricane::Segment, in case of RoutingPad
|
||||||
|
//! layer promotion.
|
||||||
|
|
||||||
|
//! \function AutoContactTerminal* AutoContactTerminal::create ( GCell* gcell, Component* rp, const Layer* layer, Point point, const DbU::Unit width, const DbU::Unit height );
|
||||||
|
//! \param gcell The GCell into which create the AutoContact.
|
||||||
|
//! \param rp The RoutingPad on which to anchor the AutoContact.
|
||||||
|
//! \param layer The Layer of the AutoContact.
|
||||||
|
//! \param point The absolute position.
|
||||||
|
//! \param width The width of the AutoContact.
|
||||||
|
//! \param height The height of the AutoContact.
|
||||||
|
//! \return The created AutoContact.
|
||||||
|
//!
|
||||||
|
//! Create a new AutoContactTerminal anchored on \c rp. \c point gives
|
||||||
|
//! the \e absolute position.
|
||||||
|
|
||||||
|
//! \function void AutoContactTerminal::updateTopology ();
|
||||||
|
//! Restore the topology (i.e. connexity) of the contact after the incident
|
||||||
|
//! segment has changed layer.
|
||||||
|
//!
|
||||||
|
//! Based on the layer depth delta between the terminal and the segment
|
||||||
|
//! three case can occurs:
|
||||||
|
//! - The delta is \b zero, then just sets the layer of the contact
|
||||||
|
//! to the common metal layer.
|
||||||
|
//! - The delta is \b one, then sets the contact layer to VIA connecting
|
||||||
|
//! the two layers.
|
||||||
|
//! - The delta is \b two, then create a dogleg to restore the connexity.
|
||||||
|
//! Depending on whether the terminal was attached to the source or
|
||||||
|
//! target, sets the layer of the segments.
|
||||||
|
//! - A delta of more than \b two is an error, and must never occurs.
|
||||||
|
//!
|
||||||
|
//! As, by default, the perpandicular is set in the layer above the
|
||||||
|
//! parallel, it may be necessary to adjust his layer as well (to the
|
||||||
|
//! one below).
|
||||||
|
//!
|
||||||
|
//! \image html updateTopologyTerminal.png "Update Terminal Topology"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Katabatic {
|
||||||
|
|
||||||
|
/*! \class AutoContactTurn
|
||||||
|
*
|
||||||
|
* \brief AutoContact Turn (one H, one V)
|
||||||
|
*
|
||||||
|
* AutoContact to make a turn (one H, one V).
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function AutoContactTurn* AutoContactTurn::create ( GCell* gcell, Net* net, const Layer* layer );
|
||||||
|
//! \param gcell The GCell into which create the AutoContact.
|
||||||
|
//! \param net The Net to which this AutoContact belongs.
|
||||||
|
//! \param layer The Layer of the AutoContact.
|
||||||
|
//! \return The created AutoContactTurn.
|
||||||
|
//!
|
||||||
|
//! Create a new AutoContactTurn.
|
||||||
|
|
||||||
|
//! \function void AutoContactTurn::updateTopology ();
|
||||||
|
//! Restore the topology (i.e. connexity) of the contact after one or both
|
||||||
|
//! connected segments has changed layer.
|
||||||
|
//!
|
||||||
|
//! Based on the layer depth delta between the two perpandiculars segments.
|
||||||
|
//! Three case can occurs:
|
||||||
|
//! - The delta is \b zero, then just sets the layer of the contact
|
||||||
|
//! to the common metal layer (turn in same layer).
|
||||||
|
//! - The delta is \b one, then sets the contact layer to VIA connecting
|
||||||
|
//! the two layers.
|
||||||
|
//! - The delta <b>cannot be equal to two</b>, due to the alternatives
|
||||||
|
//! routing directions, it would mean a \e turn connecting two \e horizontals
|
||||||
|
//! (or verticals) in different layers.
|
||||||
|
//! - The delta is \b three, then create a dogleg to restore the connexity.
|
||||||
|
//! The dogleg will be created on the connected segment which as been
|
||||||
|
//! <em>layer invalidated</em>. If both of them have been invalidated,
|
||||||
|
//! the horizontal one is preferred.
|
||||||
|
//! - A delta of more than \b three is an error, and must never occurs.
|
||||||
|
//!
|
||||||
|
//! \image html updateTopologyTurn.png "Update Turn Topology"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
// -*- C++ -*-
|
||||||
|
|
||||||
|
namespace Katabatic {
|
||||||
|
|
||||||
|
/*! \class AutoContactVTee
|
||||||
|
*
|
||||||
|
* \brief AutoContact V-Tee (one H, two V)
|
||||||
|
*
|
||||||
|
* AutoContact to build a vertical tee (two V, one H).
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! \function AutoContactVTee* AutoContactVTee::create ( GCell* gcell, Net* net, const Layer* layer );
|
||||||
|
//! \param gcell The GCell into which create the AutoContact.
|
||||||
|
//! \param net The Net to which this AutoContact belongs.
|
||||||
|
//! \param layer The Layer of the AutoContact.
|
||||||
|
//! \return The created AutoContactVTee.
|
||||||
|
//!
|
||||||
|
//! Create a new AutoContactVTee.
|
||||||
|
|
||||||
|
//! \function void AutoContactVTee::updateTopology ();
|
||||||
|
//! Restore the topology (i.e. connexity) of the contact after any number
|
||||||
|
//! of connected segments has changed layer (at least one, up to three).
|
||||||
|
//!
|
||||||
|
//! For a detailed explanation, see AutoContactHTee::updateTopology() and
|
||||||
|
//! sawp horizontal & vertical...
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|