脚本化使用 Xschem 创建反相器:schematic 与 symbol 的完整流程

本教程通过 Tcl 直接生成 Xschem 文本文件,创建一个逻辑反相器 schematic,以及与它配对的层级 symbol。为了避免依赖未知 PDK 的引脚坐标,schematic 采用 SPICE 行为电压源表达反相逻辑,不冒充晶体管级 CMOS 实现。文末给出迁移到晶体管级设计的检查步骤。本文示例未在实际 Xschem 环境执行验证。

一、原理与输出文件

Xschem 官方手册说明了 .sch/.sym 文本格式;官方符号生成器教程展示了脚本输出 symbol 的方法。本例使用 tclsh 写文件,不通过鼠标操作,也不依赖未经核实的 GUI Tcl 命令。生成 inv.sch、inv.sym、top.sch 三个文件,同一目录保存。

二、完整 Tcl 生成器

保存为 generate_inv.tcl。代码中的花括号是 Tcl 语法,复制时应保留普通花括号。Xschem 的标准 devices 库必须能解析输入、输出和双向端口符号,以及 code_shown.sym。

generate_inv.tcl
set out ./inv_demo
file mkdir $out
foreach name {inv.sch inv.sym top.sch} {
  if {[file exists [file join $out $name]]} {
    error "Output exists: $name; use a new directory"
  }
}
proc save_text {path text} {
  set f [open $path w]
  puts $f $text
  close $f
}

save_text [file join $out inv.sch] {v {xschem version=3.4.5 file_version=1.2}
G {}
K {}
V {}
S {}
E {}
C {devices/ipin.sym} -100 0 0 0 {name=pA lab=A}
C {devices/opin.sym} 100 0 0 0 {name=pY lab=Y}
C {devices/iopin.sym} 0 -100 0 0 {name=pVDD lab=VDD}
C {devices/iopin.sym} 0 100 0 0 {name=pVSS lab=VSS}
C {devices/code_shown.sym} -180 180 0 0 {name=BEHAVIOR only_toplevel=false value="BINV Y VSS V=V(VDD,VSS)-V(A,VSS)"}
}

save_text [file join $out inv.sym] {v {xschem version=3.4.5 file_version=1.2}
G {}
K {type=subcircuit
format="@name @pinlist @symname"
template="name=X1"}
V {}
S {}
E {}
L 4 -30 -30 -30 30 {}
L 4 -30 -30 25 0 {}
L 4 -30 30 25 0 {}
A 4 30 0 5 0 360 {}
L 4 -60 0 -30 0 {}
L 4 35 0 60 0 {}
L 4 0 -50 0 -30 {}
L 4 0 30 0 50 {}
T {@name} -25 -65 0 0 0.2 0.2 {}
T {A} -55 -20 0 0 0.2 0.2 {}
T {Y} 45 -20 0 0 0.2 0.2 {}
T {VDD} 5 -50 0 0 0.15 0.15 {}
T {VSS} 5 35 0 0 0.15 0.15 {}
B 5 -62.5 -2.5 -57.5 2.5 {name=A dir=in}
B 5 57.5 -2.5 62.5 2.5 {name=Y dir=out}
B 5 -2.5 -52.5 2.5 -47.5 {name=VDD dir=inout}
B 5 -2.5 47.5 2.5 52.5 {name=VSS dir=inout}
}

save_text [file join $out top.sch] {v {xschem version=3.4.5 file_version=1.2}
G {}
K {}
V {}
S {}
E {}
C {inv.sym} 0 0 0 0 {name=X1}
}
puts "Generated inv.sch, inv.sym and top.sch in $out"

三、运行与打开

Terminal
tclsh generate_inv.tcl
cd inv_demo
xschem inv.sch
# 在另一个会话中检查 symbol 的层级实例
xschem top.sch

检查三个文件都存在,然后打开 inv.sch 核对四个端口名称。打开 top.sch 后检查 X1 是否显示为反相器,并通过层级进入它对应的 inv.sch。若本地文件未找到,应先检查启动目录和 symbol 搜索路径;脚本不负责安装 Xschem、Tcl 或配置库。

四、理解 schematic 的实现

本例把 SPICE 行为源放在 code_shown.sym 的 value 中,并设置 only_toplevel=false,使它用于层级内实现。电气表达式为 V(Y,VSS)=V(VDD,VSS)-V(A,VSS)。当 VDD=1.8V、VSS=0V 时,A=0V 对应 Y=1.8V,A=1.8V 对应 Y=0V。

这是连续线性电压映射,不是具有阈值、延迟和饱和特性的真实 CMOS 反相器:输入超出供电范围时,输出也可超出范围;电源引脚只是表达式参考,不反映真实供电电流。该模型仅用于学习脚本生成与层级接口。

五、理解 symbol 的实现

L、A、T 分别用于线条、圆弧和文字;B 5 矩形定义电气引脚。反相圆圈本身不会产生电气反相功能。四个 B 5 引脚依次为 A、Y、VDD、VSS,中心坐标为 (-60,0)、(60,0)、(0,-50)、(0,50)。

K 区 type=subcircuit 表示存在对应 schematic 的层级块;format 使用 @name、@pinlist、@symname 生成子电路调用。inv.sym 与 inv.sch 使用相同基名,端口名称须一致。官方教程指出,pinlist 展开顺序取决于 symbol 的引脚顺序,不能仅凭图形左右位置推断。

六、先检查网表,再谈仿真

top.sch 中 X1 未接线,是层级查看用页面,不是完整 testbench。对它生成 SPICE 网表时应检查 inv 子电路内容、接口顺序和 BINV 行;不要直接将悬空顶层实例作为仿真电路。

Expected subcircuit — 示意,非实测
.subckt inv A Y VDD VSS
BINV Y VSS V=V(VDD,VSS)-V(A,VSS)
.ends inv

实际网表的大小写及端口排列以产物为准,X 调用的参数顺序必须匹配 .subckt 定义。确认 BINV 确实位于 inv 内部,没有被仅顶层输出规则过滤,并确认没有重复的子电路定义。

七、独立 ngspice testbench

下面手写网表先验证行为表达式。它没有自动使用生成的 Xschem 网表;后续应将其中 inv 定义替换为实际生成且已检查的子电路,才算端到端验证。

tb_inv.cir
* Teaching model, not a transistor-level simulation
.subckt inv A Y VDD VSS
BINV Y VSS V=V(VDD,VSS)-V(A,VSS)
.ends inv
VDD VDD 0 1.8
VIN A 0 PULSE(0 1.8 1n 100p 100p 5n 10n)
X1 A Y VDD 0 inv
.tran 10p 30n
.control
run
plot v(A) v(Y)
.endc
.end

保存后运行 ngspice tb_inv.cir。预期两个波形反相;本文没有实际运行,也不报告仿真通过或性能指标。

八、升级为晶体管级 CMOS schematic

保留 inv.sym 的四端口接口,将 inv.sch 中行为源替换为 PMOS、NMOS 和连线。连接目标如下:

不能把一个 PDK 的坐标和 MOS 的 M 行格式照搬到另一个 PDK。实际器件可能使用 X 子电路调用,需以 symbol 的 format 为依据。完成后必须检查连接、端口顺序、工艺角落和负载,并做瞬态与直流验证。

九、工程化验收清单

参考资料

Xschem 官方手册:文件格式、symbol 属性与网表

官方教程:Symbol and Schematic Generators

官方教程:primitive、subcircuit 与 pinlist