123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666 |
- # --------------------------------------------------------------------
- #
- # mmtl_welement.itcl
- #
- # The class in this file can generate an HSPICE W-element
- # from the CSDL description, and MMTL results.
- #
- # General usage is to create a Welement object, and call
- # the welementString method. The method requires two
- # sources of data: first the file name containing the
- # MMTL results; and second the name of the Stackup object
- # which will be visited to get additional information.
- #
- # The MMTL results file provides electrostatic inductance
- # (B) and inductance (L) matrices.
- #
- # The Stackup object provides conductor areas and
- # conductivities which are used to compute DC and AC
- # resistance.
- #
- #
- # Bob Techentin
- # June 11, 2002
- #
- # Copyright 2002-2004 Mayo Foundation. All Rights Reserved.
- # $Id: bem_welement.itcl,v 1.6 2004/09/10 19:23:02 techenti Exp $
- #
- # --------------------------------------------------------------------
- # --------------------------------------------------------------------
- #
- # Like several other components of the MMTL simulation suite,
- # the Welement class acts as a visitor to the CSDL cross section
- # description.
- #
- # Much of the functionality is based on the Tcl script named
- # mmtl2hspicew or sim2hspicew, circa 1998.
- #
- # --------------------------------------------------------------------
- package provide bem 1.0
- # --------------------------------------------------------------------
- #
- # itcl::class Welement
- #
- # This class is a visitor to the CSDL structures. It can generate
- # an HSPICE W-element from an MMTL results file and a layer Stackup.
- #
- # --------------------------------------------------------------------
- itcl::class Welement {
- #inherit CSDLvisitor
- public variable welement
- public variable headerText
- public variable signalName
- public variable signalNames
- public variable conductorArea
- public variable conductorCircumference
- public variable conductorConductivity
- public variable N
- public variable L0
- public variable C0
- public variable R0
- public variable G0
- public variable Rs
- public variable Gd
- method dump {} {
- puts "welement: $welement"
- puts "headertext: $headerText"
- puts "signalnames: $signalNames"
- catch {parray conductorArea}
- catch {parray conductorCircumference}
- catch {parray conductorConductivity}
- puts "N: $N"
- catch {parray L0}
- catch {parray C0}
- catch {parray R0}
- catch {parray G0}
- catch {parray Rs}
- catch {parray Gd}
- }
- # Produce and return a W element description
- # (as a string)
- method welementString { mmtlResultsFile }
- # Helper methods
- private method addLine { string }
- private method addMatrix { string }
- private method warningMessage { msgText }
- private method initialize { }
- private method readMMTLfile { filename }
- private method computeLosses { }
- # HLCSDL - Stackup Structures
- method visitStackup { stackup x y }
- method visitGroundPlane { groundPlane x y }
- method visitDielectricLayer { dielectricLayer x y }
- method visitRectangleDielectric { rectangleDielectric x y }
- method visitRectangleConductors { rectangleConductors x y }
- method visitTrapezoidConductors { trapezoidConductors x y }
- method visitCircleConductors { circleConductors x y }
- # LLCSDO - low level structures
- method visitDielectric { dielectric x y }
- method visitConductor { conductor x y }
- method visitGround { ground x y }
- method visitRectangle { rectangle x y }
- method visitTrapezoid { trapezoid x y }
- method visitCircle { circle x y }
- method visitLayer { layer x y }
- }
- #-------------------------------------------------------------
- #
- # Helper Methods
- #
- #-------------------------------------------------------------
- #-------------------------------------------------------------
- #
- # NAME welementString
- #
- # DESCRIPTION
- #
- # Returns a string representing the W-element description
- # of the layer stackup described by the specified layer
- # stackup and MMTL results file.
- #
- #-------------------------------------------------------------
- itcl::body Welement::welementString {mmtlResultsFile} {
- initialize
- #-------------------------------------------------------------
- # read the MMTL results
- #-------------------------------------------------------------
- readMMTLfile $mmtlResultsFile
- #-------------------------------------------------------------
- # Add AC and DC resistance from the layer stackup
- #-------------------------------------------------------------
- computeLosses
- #-------------------------------------------------------------
- # Build the W-element string
- #-------------------------------------------------------------
- addLine "*--------------------------------------------"
- addLine "*"
- addLine "* RLCG parameters for W-Element"
- addLine "* frequency-dependent transmission line"
- addLine "*"
- addLine "*"
- addLine "* MMTL File Name: $mmtlResultsFile"
- addLine "* [clock format [clock seconds]]"
- addLine "*"
- addLine "*--------------------------------------------"
- addLine "*"
- foreach textLine $headerText {
- addLine "* | $textLine"
- }
- addLine "* |"
- addLine "* | Signal Names (in order):"
- foreach name $signalNames {
- addLine "* | $name"
- }
- addLine "*"
- addLine "*--------------------------------------------"
- addLine "*"
- addLine "* N = number of signal conductors"
- addLine "*"
- addLine "*--------------------------------------------"
- addLine "$N"
- foreach matrixName {L0 C0 R0 G0 Rs Gd} {
- addLine ""
- addLine "*--------------------------------------------"
- addLine "*"
- addLine "* $matrixName"
- addLine "*"
- addLine "*--------------------------------------------"
- addMatrix $matrixName
- }
- addLine ""
- }
- #-------------------------------------------------------------
- #
- # NAME addLine
- #
- # DESCRIPTION
- #
- # Adds a line to the W-element string, including a
- # newline. Just a helper function.
- #
- #-------------------------------------------------------------
- itcl::body Welement::addLine { string } {
- append welement "$string\n"
- }
- #-------------------------------------------------------------
- #
- # NAME addMatrix
- #
- # DESCRIPTION
- #
- # This proc formats the 2D matrix (really an array) by
- # indexing through i and j and appending to the
- # w-element text.
- #
- #-------------------------------------------------------------
- itcl::body Welement::addMatrix { matrixName } {
- upvar $matrixName m
- for {set i 0} {$i<$N} {incr i} {
- for {set j 0} {$j<=$i} {incr j} {
- append welement [format "%g\t" $m($i,$j)]
- }
- append welement "\n"
- }
- }
- #-------------------------------------------------------------
- #
- # NAME warningMessage
- #
- # DESCRIPTION
- #
- # This method formats and appends a warning message to
- # the "headerText", which is included in the W-element
- # RLCG output file.
- #
- #-------------------------------------------------------------
- itcl::body Welement::warningMessage { msgText } {
- set fullText "Warning: $msgText"
- lappend headerText $fullText
- }
- #-------------------------------------------------------------
- #
- # NAME Welement::initialize
- #
- # DESCRIPTION
- #
- # This method initializes the object's global data,
- # removing any previous data.
- #
- #-------------------------------------------------------------
- itcl::body Welement::initialize { } {
- #-------------------------------------------------------------
- # Initialize all variables
- #-------------------------------------------------------------
- set welement ""
- set headerText {}
- set signalNames {}
- array unset conductorArea *
- array unset conductorCircumference *
- array unset conductorConductivity *
- set N ""
- foreach name [array names L0] {
- unset L0($name)
- }
- foreach name [array names C0] {
- unset C0($name)
- }
- foreach name [array names R0] {
- unset R0($name)
- }
- foreach name [array names G0] {
- unset G0($name)
- }
- foreach name [array names Rs] {
- unset Rs($name)
- }
- foreach name [array names Gd] {
- unset Gd($name)
- }
- }
- #-------------------------------------------------------------
- #
- # NAME readMMTLfile
- #
- # DESCRIPTION
- #
- # This method reads the specified MMTL results file and
- # sets C0, L0, and R0 arrays. It copies leading text from
- # the SIM results into the headerText variable and defines
- # the number of conductors, N. This proc also sets default
- # values for all matrics, including G0, Rs, and Gd.
- #
- #-------------------------------------------------------------
- itcl::body Welement::readMMTLfile { filename } {
- #-------------------------------------------------------------
- # Set up header text
- #-------------------------------------------------------------
- lappend headerText " MMTL Simulation data from"
- lappend headerText " $filename"
- set readingHeader 1
- #-------------------------------------------------------------
- # Locate and open the MMTL results file
- #-------------------------------------------------------------
- if {! [file isfile $filename]} {
- error "Error: MMTL results file '$filename' does not exist"
- }
- if { [catch {open $filename "r"} inFile ] } {
- error "Error: cannot open MMTL results file '$filename'"
- }
- #-------------------------------------------------------------
- # Process the File Header
- #
- # Read and ignore everything up to the first "Mutual" line,
- # except that we capture number of signal lines.
- #-------------------------------------------------------------
- gets $inFile textLine
- while { ! [string match "Mutual*" $textLine] } {
- if { [eof $inFile] } {
- error "Error: Invalid MMTL results File '$filename'"
- }
- lappend headerText "$textLine"
- if {[regexp "Number of Signal Lines" $textLine]} {
- regsub ".*=" $textLine "" N
- }
- gets $inFile textLine
- }
- #-------------------------------------------------------------
- # Process remainder of MMTL file, searching for keywords
- # at the beginning of each matrix section. Each section
- # is led by a line like:
- # B(Active Signal, Passive Signal)
- # followed by NxN matrix entries.
- #
- # Note that the signal names are in order for generated
- # cross sections, but they could also be arbitrarily named,
- # so we save the signal names in the headerText. We also
- # store the order of the signal names so that we can later
- # reconstruct each signal's position in the matrix.
- #
- # Note that we could calculate capacitance matrix from the
- # electrostatic induction matrix, B, but the HSPICE W element
- # is really expecting the B matrix for C0. Self Capacitance
- # (diagonal elements) of the capacitance matrix would be
- # the sum of the row (e.g., C11=B11+B12), while mutual
- # capacitance (off-diagonal elements) would be the negative
- # of the corresponding induction value (e.g., C12=-B12).
- #-------------------------------------------------------------
- while {! [eof $inFile]} {
- regexp {[^[:space:]]*} $textLine token
- switch $token {
- "B(Active" {
- # Copy "B" matrix into C0
- for {set i 0} {$i<$N} {incr i} {
- for {set j 0} {$j<$N} {incr j} {
- gets $inFile textLine
- regsub ".*=" $textLine "" C0($i,$j)
- }
- # Capture the signal name, too.
- scan $textLine "B(%s" sigName
- lappend signalNames $sigName
- }
- }
- "L(Active" {
- # Copy "L" matrix into L0
- for {set i 0} {$i<$N} {incr i} {
- for {set j 0} {$j<$N} {incr j} {
- gets $inFile textLine
- regsub ".*=" $textLine "" L0($i,$j)
- }
- }
- }
- "Rdc(Active" {
- # Copy "Rdc" matrix into R0
- for {set i 0} {$i<$N} {incr i} {
- for {set j 0} {$j<$N} {incr j} {
- gets $inFile textLine
- regsub ".*=" $textLine "" R0($i,$j)
- }
- }
- }
- }
- # Read next line of file
- gets $inFile textLine
- } ;# end of while {! eof $inFile}
- #-------------------------------------------------------------
- # Done with the MMTL results file
- #-------------------------------------------------------------
- close $inFile
- #-------------------------------------------------------------
- # Set all missing matrix elements to default (0.0)
- #-------------------------------------------------------------
- for {set i 0} {$i<$N} {incr i} {
- for {set j 0} {$j<$N} {incr j} {
- if { ! [info exists L0($i,$j)] } { set L0($i,$j) 0.0 }
- if { ! [info exists R0($i,$j)] } { set R0($i,$j) 0.0 }
- if { ! [info exists G0($i,$j)] } { set G0($i,$j) 0.0 }
- if { ! [info exists Rs($i,$j)] } { set Rs($i,$j) 0.0 }
- if { ! [info exists Gd($i,$j)] } { set Gd($i,$j) 0.0 }
- }
- }
- }
- #-------------------------------------------------------------
- #
- # NAME Welement::computeLosses
- #
- # DESCRIPTION
- #
- # This method computes the loss factors for the MMTL
- # simulation results (which are loss free) by visiting
- # the specified layer stackup, and computing both DC and
- # AC losses from the conductor circumference, area
- # and conductivity.
- #
- # The loss values are stored in R0 and Rs.
- #
- #-------------------------------------------------------------
- itcl::body Welement::computeLosses { } {
- set PI 3.141592654
- set MU_0 1.25663706E-6
- #--------------------------------------------------------------
- # Visit the layer stackup to capture conductor
- # areas and conductivities
- #--------------------------------------------------------------
- ::Stackup::accept $this 0 0
- #--------------------------------------------------------------
- # Capture length units from stackup for conversion to SI
- #--------------------------------------------------------------
- set units $::Stackup::defaultLengthUnits
- #--------------------------------------------------------------
- # Iterate over all conductors.
- # Note that we're just computing the diagonal elements
- # of the R0 and Rs matrices, so we only have one loop.
- #--------------------------------------------------------------
- for {set i 0} {$i<$N} {incr i} {
- #--------------------------------------------------------------
- # Convert the MMTL signal name to the csdl signal name.
- # MMTL Signal names are of the form <name><type><num> where
- # <name> corresponds to the HLCSDL object name,
- # <type> is "R", "T", or "C" for the type of conductor, and
- # <num> is an increasing integer, just like $i here.
- #--------------------------------------------------------------
- set name [lindex $signalNames $i]
- puts -nonewline "changing conductor $i named $name"
- regsub {[RTC]\d+$} $name "" name
- puts " to $name"
- #--------------------------------------------------------------
- # Get usefull quantities
- #--------------------------------------------------------------
- set area $conductorArea($name)
- set circ $conductorCircumference($name)
- set cond $conductorConductivity($name)
- #--------------------------------------------------------------
- # Convert to SI units.
- # We know that area and circ are in default units and must
- # be converted. But we convert cond only if necessary.
- #--------------------------------------------------------------
- set area [units::convert "$area$units^2" "meters^2"]
- set circ [units::convert "$circ$units" "meters"]
- if { ! [string is double $cond] } {
- set cond [units::convert $cond "siemens/meter"]
- }
- #--------------------------------------------------------------
- # Compute values according to formulas
- #
- # Rdc = 1/(area*conductivity) ohms/meter
- # Rac = sqrt(PI*MU_0/conductivity)/(circumference) siemens/meter^2
- #--------------------------------------------------------------
- set rdc [expr {1.0/($area*$cond)}]
- set rac [expr {sqrt(($PI*$MU_0)/$cond)/($circ)}]
- #--------------------------------------------------------------
- # Check for disparity between newly computed Rdc value
- # and any value that might have come from MMTL (lossy version)
- # Generate a warning if there is a > 10% difference.
- #--------------------------------------------------------------
- if { [info exists R0($i,$i)] } {
- set ratio [expr {abs($R0($i,$i)/$rdc)}]
- if { ($ratio<0.9) || ($ratio>1.1) } {
- warningMessage "Using Formula for Rdc($i,$i)=$rdc, replacing MMTL value of $R0($i,$i)"
- }
- }
- #--------------------------------------------------------------
- # Assign values
- #--------------------------------------------------------------
- set R0($i,$i) $rdc
- set Rs($i,$i) $rac
- }
- #--------------------------------------------------------------
- # Set off-diagonals to zero
- #--------------------------------------------------------------
- for {set i 0} {$i<$N} {incr i} {
- for {set j 0} {$j<$N} {incr j} {
- if { $i != $j } {
- set R0($i,$j) 0.0
- set Rs($i,$j) 0.0
- }
- }
- }
- }
- #-------------------------------------------------------------
- #
- # NAME do_help
- #
- # DESCRIPTION
- #
- # Returns help text about the sim2hspicew utility.
- # This can be "put" on stdout, or displayed in a gui
- # window.
- #
- #-------------------------------------------------------------
- proc do_help { } {
- return {
- SIM 2 HSPICE W-Element Converter
- This script constructs an HSPICE W-Elelement model rlcg description
- based on the B, L, and Rdc matrices in SIM results files. It can
- read files of types:
- result BEM SIM (result) results
- electro_results_2dly 2DLY SIM results
- electro_results_2dlf 2DLF SIM results
- The capacitance matrix C0 is copied from SIM's Electrostatic
- Induction matrix B. (B is NOT converted into a capacitance matrix by
- summing the rows for the diagonal elements and changing the sign on
- the off-diagonal elements.) The inductance matrix L0 is copied
- directly from SIM's Inductance matrix, L. If the SIM results file
- contains Rdc (BEM SIM only), then these values are used for R0.
- If one of the cross section generating programs was used to generate
- the SIM data file (i.e. there is also an nsim_log file in the same
- directory), the script will read the geometry information and apply
- formulas for calculating R0 and Rs. If the formula value and the SIM
- value for R0 differ by more than 10%, a warning message is issued, but
- the formula values are always used.
- The formulas are:
- R0 = Rdc = 1 / (width * height) ohms/meter
- Rs = Rac = sqrt(PI * MU_0 / c) / (width + height) henrys/meter
- Where PI=3.141592654, MU_0=1.25663706E-6 henrys/meter (permeability of
- free-space), and c is the metal conductivity, which defaults to 5.92e7
- siemens/meter (copper).
- The W-element RLCG data is written (by default) the file hspice-w.rlcg
- in the same directory as the sim results. The rlcg file contains a
- header describing its origins and any warning messages that might have
- been generated during its construction.
- Command Line Swtiches
- -help - prints this message
- -c - generate output (rlcg file) on stdout
- -o filename - write the rlcg file to the specified file
- }
- # end of help text
- }
- # HLCSDL - Stackup Structures
- itcl::body Welement::visitStackup { stackup x y } {
- foreach struct $Stackup::structureList {
- $struct accept $this 0 0
- }
- }
- itcl::body Welement::visitGroundPlane { groundPlane x y } {}
- itcl::body Welement::visitDielectricLayer { dielectricLayer x y } {}
- itcl::body Welement::visitRectangleDielectric { rectangleDielectric x y } {}
- #---------------------------------------------------------------
- # Save the name of the HLCSDL object, as we'll need it
- # later to correlate with the signal names fromm the
- # MMTL results file.
- #---------------------------------------------------------------
- itcl::body Welement::visitRectangleConductors { rectangleConductors x y } {
- set signalName $rectangleConductors
- }
- itcl::body Welement::visitTrapezoidConductors { trapezoidConductors x y } {
- set signalName $trapezoidConductors
- }
- itcl::body Welement::visitCircleConductors { circleConductors x y } {
- set signalName $circleConductors
- }
- # LLCSDO - low level structures
- itcl::body Welement::visitDielectric { dielectric x y } {}
- #---------------------------------------------------------------
- #
- # Welement::visitConductor
- #
- # Each time we visit a conductor, store the conductor
- # area and conductivity for later AC/DC resistance
- # calculations. Store them based
- #
- #---------------------------------------------------------------
- itcl::body Welement::visitConductor { conductor x y } {
- # Save conductor values
- set shape [$conductor cget -shape]
- set conductorArea($signalName) [$shape area]
- set conductorCircumference($signalName) [$shape circumference]
- set conductorConductivity($signalName) [$conductor cget -conductivity]
- }
- itcl::body Welement::visitGround { ground x y} {}
- itcl::body Welement::visitRectangle { rectangle xp yp } {}
- itcl::body Welement::visitTrapezoid { trapezoid xp yp } {}
- itcl::body Welement::visitCircle { circle xp yp } {}
- itcl::body Welement::visitLayer { layer x y } {}
|