csdl_hlcsdl.itcl 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. # --------------------------------------------------------*-Tcl-*-
  2. #
  3. # hlcsdl.tcl
  4. #
  5. # High Level Cross Section Description Language (HLCSDL)
  6. #
  7. # This file contains Incr Tcl class declarations for defining
  8. # simple transmission line cross sections. It utilitizes
  9. # classes from the Low Level CSDL (LLCSDL) in stackup.itcl
  10. #
  11. # Each of the classes here is sort of a container for a number
  12. # of LLCSDL classes. The LLCSDL classes are constructed in
  13. # the global namespace (by naming them with ${auto}) so that
  14. # they can easily reference each other.
  15. #
  16. # Classes defined:
  17. # GroundPlane
  18. # DielectricLayer
  19. # RectangleDielectric
  20. # RectangleConductors
  21. # TrapezoidConductors
  22. # CircleConductors
  23. #
  24. # Bob Techentin
  25. # January 30, 2001
  26. #
  27. # Copyright 2001-2004 Mayo Foundation. All Rights Reserved.
  28. # $Id: csdl_hlcsdl.itcl,v 1.6 2004/07/28 15:40:14 techenti Exp $
  29. #
  30. # ----------------------------------------------------------------
  31. package require Itcl
  32. # package require LLCSDL
  33. package provide csdl 1.0.1
  34. # ----------------------------------------------------------------
  35. #
  36. # HLCSDL Structure
  37. #
  38. # ----------------------------------------------------------------
  39. itcl::class HLCSDLstructure {
  40. public variable xOffset 0.0
  41. public variable yOffset 0.0
  42. variable name
  43. variable structure
  44. variable shape
  45. constructor {} {
  46. scan $this "::%s" name
  47. lappend Stackup::structureList $this
  48. }
  49. destructor {
  50. # Delete any and all structures and shapes
  51. catch {foreach obj $structure {itcl::delete object $obj}}
  52. catch {foreach obj $shape {itcl::delete object $obj}}
  53. # Remove ourselves from the Stackup
  54. catch {
  55. set i [lsearch $::Stackup::structureList $this]
  56. set ::Stackup::structureList \
  57. [lreplace $::Stackup::structureList $i $i]
  58. }
  59. }
  60. method width {} {$structure width}
  61. method height {} {$structure height}
  62. method accept { visitor x y } {
  63. # Cleverly call a visitor based on our class name
  64. scan [$this info class] "::%s" myClass
  65. $visitor visit$myClass $this $x $y
  66. # Navigate to the structure(s)
  67. $structure accept $visitor $x $y
  68. }
  69. }
  70. # ----------------------------------------------------------------
  71. #
  72. # GroundPlane
  73. #
  74. # ----------------------------------------------------------------
  75. itcl::class GroundPlane {
  76. inherit HLCSDLstructure
  77. public variable thickness 1.0
  78. constructor { args } {
  79. eval configure $args
  80. set shape [Layer ${this}_#auto -thickness $thickness \
  81. -name $name -color blue -description "Ground Plane $name"]
  82. set structure [Ground ${this}_#auto -shape $shape]
  83. }
  84. }
  85. itcl::configbody GroundPlane::thickness {
  86. if { [info exists shape] } {
  87. $shape configure -thickness $thickness
  88. }
  89. }
  90. # ----------------------------------------------------------------
  91. #
  92. # DielectricLayer
  93. #
  94. # ----------------------------------------------------------------
  95. itcl::class DielectricLayer {
  96. inherit HLCSDLstructure
  97. public variable permittivity 1.0
  98. public variable permeability 1.0
  99. public variable lossTangent 0.0
  100. public variable thickness 1.0
  101. constructor { args } {
  102. eval configure $args
  103. set shape [Layer ${this}_#auto -thickness $thickness \
  104. -name $name -description "Dielectric $name"]
  105. set structure [Dielectric ${this}_#auto -shape $shape \
  106. -permittivity $permittivity -permeability $permeability \
  107. -lossTangent $lossTangent -shape $shape]
  108. }
  109. }
  110. itcl::configbody DielectricLayer::permittivity {
  111. if { [info exists structure] } {
  112. $structure configure -permittivity $permittivity
  113. }
  114. }
  115. itcl::configbody DielectricLayer::permeability {
  116. if { [info exists structure] } {
  117. $structure configure -permeability $permeability
  118. }
  119. }
  120. itcl::configbody DielectricLayer::lossTangent {
  121. if { [info exists structure] } {
  122. $structure configure -lossTangent $lossTangent
  123. }
  124. }
  125. itcl::configbody DielectricLayer::thickness {
  126. if { [info exists shape] } {
  127. $shape configure -thickness $thickness
  128. }
  129. }
  130. # ----------------------------------------------------------------
  131. #
  132. # RectangleDielectric
  133. #
  134. # ----------------------------------------------------------------
  135. itcl::class RectangleDielectric {
  136. inherit HLCSDLstructure
  137. public variable number 1
  138. public variable pitch 1.0
  139. public variable height 1.0
  140. public variable width 1.0
  141. public variable permittivity 1.0
  142. public variable permeability 1.0
  143. public variable lossTangent 0.0
  144. variable dielectric ""
  145. constructor { args } {
  146. eval configure $args
  147. set shape [Rectangle ${this}_#auto -height $height -width $width \
  148. -name "$name"]
  149. update
  150. for {set i 0} {$i<$number} {incr i} {
  151. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  152. set y0 [expr { [length $yOffset] }]
  153. lappend structure [Dielectric ${this}_#auto \
  154. -permittivity $permittivity -permeability $permeability \
  155. -x $x0 -y $y0 -lossTangent $lossTangent -shape $shape ]
  156. }
  157. }
  158. method width {} {
  159. return [expr { [length $xOffset] + ($number-1)*[length $pitch] + \
  160. $width }]
  161. }
  162. method height {} {
  163. set max 0.0
  164. foreach obj $structure {
  165. if { [$obj height] > $max } {
  166. set max [$obj height]
  167. }
  168. }
  169. return $max
  170. }
  171. method accept { visitor x y } {
  172. # Cleverly call a visitor based on our class name
  173. scan [$this info class] "::%s" myClass
  174. $visitor visit$myClass $this $x $y
  175. # Navigate to each structure
  176. for {set i 0} {$i<$number} {incr i} {
  177. set x0 [expr { [length $x] + [length $xOffset] + \
  178. [length $pitch]*$i }]
  179. set y0 [expr { $y + [length $yOffset] }]
  180. [lindex $structure $i] accept $visitor $x0 $y0
  181. }
  182. }
  183. }
  184. itcl::configbody RectangleDielectric::number {
  185. if { [info exists structure] } {
  186. foreach obj $structure {
  187. itcl::delete object $obj
  188. }
  189. set structure [list]
  190. for {set i 0} {$i<$number} {incr i} {
  191. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  192. set y0 $yOffset
  193. lappend structure [Dielectric ${this}_#auto \
  194. -permittivity $permittivity -permeability $permeability \
  195. -x $x0 -y $y0 -lossTangent $lossTangent -shape $shape \
  196. -description "${name}-${i}"]
  197. }
  198. }
  199. }
  200. itcl::configbody RectangleDielectric::pitch {
  201. if { [info exists structure] } {
  202. for {set i 0} {$i<$number} {incr i} {
  203. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  204. [lindex $structure $i] configure -x $x0
  205. }
  206. }
  207. }
  208. itcl::configbody RectangleDielectric::height {
  209. if { [info exists shape] } {
  210. $shape configure -height $height
  211. }
  212. }
  213. itcl::configbody RectangleDielectric::width {
  214. if { [info exists shape] } {
  215. $shape configure -width $width
  216. }
  217. }
  218. itcl::configbody RectangleDielectric::permittivity {
  219. if { [info exists structure] } {
  220. foreach obj $structure {
  221. $obj configure -permittivity $permittivity
  222. }
  223. }
  224. }
  225. itcl::configbody RectangleDielectric::permeability {
  226. if { [info exists structure] } {
  227. foreach obj $structure {
  228. $obj configure -permeability $permeability
  229. }
  230. }
  231. }
  232. itcl::configbody RectangleDielectric::lossTangent {
  233. if { [info exists structure] } {
  234. foreach obj $structure {
  235. $obj configure -lossTangent $lossTangent
  236. }
  237. }
  238. }
  239. # ----------------------------------------------------------------
  240. #
  241. # RectangleConductors
  242. #
  243. # ----------------------------------------------------------------
  244. itcl::class RectangleConductors {
  245. inherit HLCSDLstructure
  246. public variable number 1
  247. public variable pitch 1.0
  248. public variable height 1.0
  249. public variable width 1.0
  250. public variable conductivity 1.0
  251. variable conductor ""
  252. constructor { args } {
  253. eval configure $args
  254. set shape [Rectangle ${this}_#auto -height $height -width $width \
  255. -name "$name"]
  256. for {set i 0} {$i<$number} {incr i} {
  257. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  258. set y0 [length $yOffset]
  259. lappend structure [Conductor ${this}_#auto \
  260. -x $x0 -y $y0 \
  261. -conductivity $conductivity -shape $shape \
  262. -description "${name}-${i}"]
  263. }
  264. }
  265. method width {} {
  266. return [expr { [length $xOffset] + ($number-1)*[length $pitch] + \
  267. $width }]
  268. }
  269. method height {} {
  270. set max 0.0
  271. foreach obj $structure {
  272. if { [$obj height] > $max } {
  273. set max [$obj height]
  274. }
  275. }
  276. return $max
  277. }
  278. method accept { visitor x y } {
  279. # Cleverly call a visitor based on our class name
  280. scan [$this info class] "::%s" myClass
  281. $visitor visit$myClass $this $x $y
  282. # Navigate to each structure
  283. for {set i 0} {$i<$number} {incr i} {
  284. set x0 [expr { [length $x] + [length $xOffset] + \
  285. [length $pitch]*$i }]
  286. set y0 [expr { $y + [length $yOffset] }]
  287. [lindex $structure $i] accept $visitor $x0 $y0
  288. }
  289. }
  290. }
  291. itcl::configbody RectangleConductors::number {
  292. if { [info exists structure] } {
  293. foreach obj $structure {
  294. itcl::delete object $obj
  295. }
  296. set structure [list]
  297. for {set i 0} {$i<$number} {incr i} {
  298. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  299. set y0 $yOffset
  300. lappend structure [Conductor ${this}_#auto \
  301. -x $x0 -y $y0 \
  302. -conductivity $conductivity -shape $shape \
  303. -description "${name}-${i}"]
  304. }
  305. }
  306. }
  307. itcl::configbody RectangleConductors::pitch {
  308. if { [info exists structure] } {
  309. for {set i 0} {$i<$number} {incr i} {
  310. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  311. [lindex $structure $i] configure -x $x0
  312. }
  313. }
  314. }
  315. itcl::configbody RectangleConductors::height {
  316. if { [info exists shape] } {
  317. $shape configure -height $height
  318. }
  319. }
  320. itcl::configbody RectangleConductors::width {
  321. if { [info exists shape] } {
  322. $shape configure -width $width
  323. }
  324. }
  325. itcl::configbody RectangleConductors::conductivity {
  326. if { [info exists structure] } {
  327. foreach obj $structure {
  328. $obj configure -conductivity $conductivity
  329. }
  330. }
  331. }
  332. # ----------------------------------------------------------------
  333. #
  334. # TrapezoidConductors
  335. #
  336. # ----------------------------------------------------------------
  337. itcl::class TrapezoidConductors {
  338. inherit HLCSDLstructure
  339. public variable number 1
  340. public variable pitch 1.0
  341. public variable height 1.0
  342. public variable topWidth 1.0
  343. public variable bottomWidth 1.0
  344. public variable conductivity 1.0
  345. variable conductor
  346. constructor { args } {
  347. eval configure $args
  348. set shape [Trapezoid ${this}_#auto -height $height \
  349. -topWidth $topWidth -bottomWidth $bottomWidth \
  350. -name "$name"]
  351. for {set i 0} {$i<$number} {incr i} {
  352. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  353. set y0 [length $yOffset]
  354. lappend structure [Conductor ${this}_#auto \
  355. -x $x0 -y $y0 \
  356. -conductivity $conductivity -shape $shape \
  357. -description "${name}-${i}"]
  358. }
  359. }
  360. method width {} {
  361. return [expr { [length $xOffset] + ($number-1)*[length $pitch] + \
  362. ([length $topWidth] + [length $bottomWidth]) * 0.5 }]
  363. }
  364. method height {} {
  365. set max 0.0
  366. foreach obj $structure {
  367. if { [$obj height] > $max } {
  368. set max [$obj height]
  369. }
  370. }
  371. return $max
  372. }
  373. method accept { visitor x y } {
  374. # Cleverly call a visitor based on our class name
  375. scan [$this info class] "::%s" myClass
  376. $visitor visit$myClass $this $x $y
  377. # Navigate to each structure
  378. for {set i 0} {$i<$number} {incr i} {
  379. set x0 [expr {[length $x] + [length $xOffset] + \
  380. [length $pitch]*$i}]
  381. set y0 [expr { [length $y] + [length $yOffset] }]
  382. [lindex $structure $i] accept $visitor $x0 $y0
  383. }
  384. }
  385. }
  386. itcl::configbody TrapezoidConductors::number {
  387. if { [info exists structure] } {
  388. foreach obj $structure {itcl::delete object $obj}
  389. set structure [list]
  390. for {set i 0} {$i<$number} {incr i} {
  391. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  392. set y0 [length $yOffset]
  393. lappend structure [Conductor ${this}_#auto \
  394. -x $x0 -y $y0 \
  395. -conductivity $conductivity -shape $shape \
  396. -description "${name}-${i}"]
  397. }
  398. }
  399. }
  400. itcl::configbody TrapezoidConductors::pitch {
  401. if { [info exists structure] } {
  402. for {set i 0} {$i<$number} {incr i} {
  403. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  404. [lindex $structure $i] configure -x $x0
  405. }
  406. }
  407. }
  408. itcl::configbody TrapezoidConductors::height {
  409. if { [info exists shape] } {
  410. $shape configure -height $height
  411. }
  412. }
  413. itcl::configbody TrapezoidConductors::topWidth {
  414. if { [info exists shape] } {
  415. $shape configure -topWidth $topWidth
  416. }
  417. }
  418. itcl::configbody TrapezoidConductors::bottomWidth {
  419. if { [info exists shape] } {
  420. $shape configure -bottomWidth $bottomWidth
  421. }
  422. }
  423. itcl::configbody TrapezoidConductors::conductivity {
  424. if { [info exists structure] } {
  425. foreach obj $structure {
  426. $obj configure -conductivity $conductivity
  427. }
  428. }
  429. }
  430. # ----------------------------------------------------------------
  431. #
  432. # CircleConductors
  433. #
  434. # ----------------------------------------------------------------
  435. itcl::class CircleConductors {
  436. inherit HLCSDLstructure
  437. public variable number 1
  438. public variable pitch 1.0
  439. public variable diameter 1.0
  440. public variable conductivity 1.0
  441. variable conductor
  442. constructor { args } {
  443. eval configure $args
  444. set shape [Circle ${this}_#auto -diameter $diameter \
  445. -name "$name"]
  446. for {set i 0} {$i<$number} {incr i} {
  447. set x0 [expr {[length $xOffset] - $diameter + [length $pitch]*$i}]
  448. set y0 [length $yOffset]
  449. lappend structure [Conductor ${this}_#auto \
  450. -x $x0 -y $y0 \
  451. -conductivity $conductivity -shape $shape \
  452. -description "${name}-${i}"]
  453. }
  454. }
  455. method width {} {
  456. return [expr { [length $xOffset] + ($number-1)*[length $pitch] \
  457. + $diameter }]
  458. }
  459. method height {} {
  460. set max 0.0
  461. foreach obj $structure {
  462. if { [$obj height] > $max } {
  463. set max [$obj height]
  464. }
  465. }
  466. return $max
  467. }
  468. method accept { visitor x y } {
  469. # Cleverly call a visitor based on our class name
  470. scan [$this info class] "::%s" myClass
  471. $visitor visit$myClass $this $x $y
  472. # Navigate to each structure
  473. for {set i 0} {$i<$number} {incr i} {
  474. set x0 [expr {[length $x] + [length $xOffset] + \
  475. [length $pitch]*$i}]
  476. set y0 [expr { [length $y] + [length $yOffset] }]
  477. [lindex $structure $i] accept $visitor $x0 $y0
  478. }
  479. }
  480. }
  481. itcl::configbody CircleConductors::number {
  482. if { [info exists structure] } {
  483. foreach obj $structure {itcl::delete object $obj}
  484. set structure [list]
  485. for {set i 0} {$i<$number} {incr i} {
  486. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  487. set y0 [length $yOffset]
  488. lappend structure [Conductor ${this}_#auto \
  489. -x $x0 -y $y0 \
  490. -conductivity $conductivity -shape $shape \
  491. -description "${name}-${i}"]
  492. }
  493. }
  494. }
  495. itcl::configbody CircleConductors::pitch {
  496. if { [info exists structure] } {
  497. for {set i 0} {$i<$number} {incr i} {
  498. set x0 [expr {[length $xOffset] + [length $pitch]*$i}]
  499. [lindex $structure $i] configure -x $x0
  500. }
  501. }
  502. }
  503. itcl::configbody CircleConductors::diameter {
  504. if { [info exists shape] } {
  505. $shape configure -diameter $diameter
  506. }
  507. }
  508. itcl::configbody CircleConductors::conductivity {
  509. if { [info exists structure] } {
  510. foreach obj $structure {
  511. $obj configure -conductivity $conductivity
  512. }
  513. }
  514. }
  515. # --------------------------------------------------------------------
  516. #
  517. # itcl::class Stackup
  518. #
  519. # Defines a layer stackup - the overall definition of a
  520. # transmission line cross section. The layer Stackup is
  521. # essentially a static class. There is only one.
  522. #
  523. # Structures add themselves to the structure list as they are
  524. # constructed. The order of this list is important, as
  525. # the Y coordinate of each of the structures depends upon the
  526. # structures before it in the Stackup.
  527. #
  528. # options
  529. #
  530. # -structureList
  531. # Ordered list of structures in the layer stackup.
  532. #
  533. # -couplingLength
  534. # Coupling length of the transmission line
  535. #
  536. # - defaultLengthUnits
  537. # Default length units applied to the cross section.
  538. #
  539. # --------------------------------------------------------------------
  540. itcl::class Stackup {
  541. public common structureList {}
  542. public common couplingLength 0.0
  543. public common riseTime 0.0
  544. public common frequency 1e9
  545. public common defaultLengthUnits ""
  546. proc width {} {
  547. set max 0
  548. foreach s $structureList {
  549. set w [$s width]
  550. if {$w > $max} {
  551. set max $w
  552. }
  553. }
  554. return $max
  555. }
  556. proc height { } {
  557. set h 0
  558. # Add up the heights of the Layers
  559. foreach struct $structureList {
  560. if {[$struct isa GroundPlane] || [$struct isa DielectricLayer]} {
  561. set h [expr {$h + [$struct height]}]
  562. }
  563. }
  564. # Add on final structure even if it isn't
  565. # a Layer (like microstrip conductors)
  566. if { ! [$struct isa GroundPlane] && ! [$struct isa DielectricLayer]} {
  567. set h [expr {$h + [$struct height]}]
  568. }
  569. return $h
  570. }
  571. proc accept { visitor args } {
  572. eval $visitor visitStackup ::Stackup $args
  573. }
  574. }