可跑通的ADS射频仿真实例:S参数、匹配与功放谐波平衡
简介:面向射频与微波电路设计学习者的 ADS 仿真实例合集,围绕阻抗匹配、滤波器、低噪放、功分器、功率放大器与耦合器等典型模块展开,适合希望从原理走向电路建模、仿真与优化的初中级工程师及电子类专业学生查练。压缩包为 rar 格式,共约 2000 个文件、106.9MB,涵盖大量 ADS 工程与设计文件(如 ds、proj_a、wrkstate)、原理图与网络及数据文件(net、dat、s2p)、元件库与脚本(ael、oalib、lib)、图片、配置说明和仿真结果等,目录组织较完整,便于按模块检索与复现。已有 3091 人学习下载,说明其案例覆盖面与参考价值较高。读者可借助 Smith 图、S 参数分析、谐波平衡与优化控件等实例,理解匹配网络、通带与阻带指标、噪声系数、功率分配均匀性、插入损耗和隔离度等设计要点,并积累从建模、仿真设置到结果对比与问题排查的实践经验。
1. 一份能实际跑通的 ADS 射频仿真实例,比十篇教程都省时间
刚接触 ADS 射频电路仿真的人,常遇到一个尴尬:照着书把元件摆好了,控制器也放上去了,仿真一跑却是全零曲线,或者干脆报错停在中途。课本讲的是原理,工具讲的是菜单,中间那段「参数到底填多少、扫描怎么配、结果在哪里看」没人讲。这个压缩包给的是一批能直接打开的工程实例:S 参数扫描、匹配网络、微带线计算、功放谐波平衡,每条链路都把控制器、变量和数据显示模板配好了。它的价值不在文件本身,而在于给了一条能对照的完整数据链。适合刚接手射频仿真、需要快速对齐工作流的人,也适合手上已经有老工程、想照着改成自己模板的熟手。
2. 工作区结构先摸清:解压之后的每个目录都在干什么
拿到压缩包,第一反应通常是双击解压,然后随便找一个 .prj 打开。结果往往是:打开哪个都能进,但进去哪个都不对,元件一片红,或者仿真按钮点下去毫无反应。射频仿真实例的价值不在「能打开」,而在数据链是完整的——原理图、变量表、仿真控制器、数据集、显示模板,五个环节必须对得上,缺一环就是空图。先把目录结构看明白,后面的排错效率能高出一倍。
2.1 老 .prj 与新 workspace:两代工程格式的差别
ADS 的工程格式换过代。早期是单文件 .prj,双击进入 Project,里面按 network 组织设计;后来改成工作区(workspace)目录机制,一个xxx_wrk文件夹就是一个工作区,原理图、版图、符号放在设计库目录里,仿真数据集放在data/,仿真过程中产生的中间文件放在simulation/。这批实例里两种格式都可能存在,尤其是年份较早的资料,清一色是 .prj。
新版 ADS 打开老 .prj 会提示转换,这一步不建议图快。转换过程中如果库名对不上,元件会变成红色方块,看起来像原理图坏了,实际上只是库引用没挂上。正确做法是转换前先把原始压缩包再解一份出来做备份,转换后的工作区单独放一个目录,出问题随时回退。我一般会把原始包和解压后的目录分开存,中间加一层日期命名,这样过一次版本对比不至于抓瞎。
| 路径 / 文件 | 里面是什么 | 能不能删 |
|---|---|---|
xxx_wrk/ | 工作区根目录,所有设计都在这下面 | 不能 |
xxx_wrk/de/ | 设计库,原理图、版图、符号、用户元件 | 不能 |
xxx_wrk/data/ | 数据集*.ds,每次仿真写一份新的 | 可以删,但要重跑 |
xxx_wrk/simulation/ | 仿真中间件、缓存、状态文件 | 可以删,会自动重建 |
*.dds | 数据显示模板,画什么曲线全靠它 | 不能删,删了等于重画 |
*.prj | 老版本单文件工程 | 不能删 |
提示:
data/目录里的.ds文件名默认和仿真控制器同名加序号,删掉之后重跑会重新生成,但.dds里绑定的数据集名字如果没跟着改,曲线还是空的。这两件事要一起处理。
2.2 解压与清点:别在中文路径下开工
老版本 ADS 对非 ASCII 路径和空格的支持很差,路径里带中文或者空格,常见表现是库找不到、仿真中途退出、数据集写不进去。这属于典型的玄学问题——同一份工程,换台机器就好了。所以先把实例放到一段纯英文短路径下,再谈别的。
# 1. 建一个纯英文的落地目录,别放在桌面或下载文件夹里 mkdir -p /opt/rf_lab/ads_examples # 2. 解压(unar 对中文文件名兼容性好一些,没有的话用 unrar x 也行) cd /opt/rf_lab unar -q ADS射频电路仿真实例.rar -o /opt/rf_lab/ads_examples # 3. 清点:先看目录层级,确认是不是多层嵌套 cd /opt/rf_lab/ads_examples find . -maxdepth 3 -type d | head -40 # 4. 按类型统计,心里有个数 find . -iname "*.prj" | wc -l # 老工程数量 find . -iname "*.dds" | wc -l # 显示模板数量 find . -iname "*.ds" | wc -l # 已有数据集数量 find . -iname "*_wrk" -type d # 已经是新格式的工作区第 3 步是为了确认有没有多套一层同名目录。压缩包套娃是常见情况,解出来是ads_examples/ADS射频电路仿真实例/...,后面所有相对路径都要多写一层,很容易在脚本里翻车。第 4 步的.prj数量和_wrk目录数量基本能判断这批实例是新是老:两者都有的话,优先跑新格式,老工程挑一两个有代表性的转换过来对照。
2.3 打开之后先确认三件事
工程打开、原理图能正常显示,只说明文件没坏,不代表能跑。我习惯打开后固定做三个检查。
第一看库。菜单里找库管理入口(不同版本位置不一样,有的在 Options 下,有的在 DesignKit 里),确认微带、系统、射频这几个常用库都挂上了。原理图里元件显示成正常图形而不是红框,基本就没问题。
第二看变量表。实例里大量参数是靠VAR块和VarEqn驱动的,比如线宽W、电长度E、偏置电压Vbias。打开变量表确认每个变量都有值,没有出现undefined。有些老工程把变量写在顶层原理图,子电路里引用,跨层引用一旦断掉,仿真能启动但结果是废的。
第三看数据集时间戳。data/下如果已经有一批.ds,先看一眼修改时间,判断是随包带的示例结果还是空的占位文件。带结果的最好,可以先打开.dds看曲线长什么样,再去改参数复现,这比自己从零搭一遍快得多。
3. S 参数链路先跑通:SP 控制器、Smith 圆图和微带线三家对齐
中间章节从最简单的链路开始。S 参数仿真是射频里最基础也最容易被轻视的一环——看起来只是放两个端口、扫一段频率,实际上端口编号、扫描变量、参考阻抗、单位这四样任何一个错了,曲线都会以一种「看着像对、其实全错」的方式呈现出来。先把这条链路跑通,后面做匹配、做谐波平衡才有参照。
3.1 SP 控制器与 Term 的编号配对
原理图上放两个Term,一个当输入一个当输出,各填一个编号,再放一个 SP 控制器,指定扫描变量指向频率。逻辑就这么简单,但编号必须和 SP 控制器的端口数对应上,否则数据集里只有 S(1,1),S(2,1) 根本没有。
下面是把原理图导出成网表之后的样子,字段名在不同版本里略有出入,逻辑一致:
Term Term1 Num=1 Z=50 Ohm END Term Term2 Num=2 Z=50 Ohm END SP SP1 SweepVar="freq" Start=1 GHz Stop=6 GHz Step=10 MHz StatusLevel=2 ENDNum是端口编号,从 1 开始连续编号,中间不能跳号。Z是参考阻抗,默认 50 欧,做差分或者特定系统阻抗时才改,改了之后所有 S 参数的定义口径都跟着变,所以别在中途随手改。SweepVar指向扫描变量,最直接的是"freq",配合Start、Stop、Step三个字段;如果实例里另外画了一个 SweepPlan 元件,那SweepVar就要指到那个 plan 上,此时控制器自带的起止频率字段是失效的——这是新手最容易卡住的地方,改了频率范围没反应,八成是扫描变量指错了对象。
StatusLevel控制仿真过程中往状态窗口打多少信息。调试阶段调到 2 或更高,能看到每一段频率的求解情况;正式跑批量扫描时调回 0 或 1,日志会清爽很多。
3.2 在 Smith 圆图上按顺序挪,而不是乱试
实例里带匹配网络的工程,数据显示模板一般都预置了 Smith 圆图。看圆图要看的不是「点在哪」,而是「往哪个方向挪」。串联元件沿等电阻圆走,并联元件沿等电导圆走,这个规则背下来不难,难的是实际调的时候手忙脚乱,串一个并一个,最后不知道是哪一步起了作用。
我的顺序是固定的:先把串联元件设成零(短路),只调并联支节,把实部拉到接近 50 欧;再回头调串联元件,把虚部压到零附近;最后微调两条线的电长度,把中心频率对准。每一步只动一个变量,动完立刻重跑,看轨迹怎么变。听起来慢,实际上比无头苍蝇式地凑参数快得多。
注意:Smith 圆图上的轨迹是频率扫描的结果,不是单点。看的时候要盯住目标频点那一小段,而不是整条曲线。整条曲线漂亮但目标频点偏离 50 欧,这种「看起来很美」的结果在实际电路里毫无意义。
实例里如果有TLIN(理想传输线)和MLIN(微带线)两套等价实现,建议先用TLIN调拓扑,电长度E直接填角度,物理直观;拓扑定了再换成MLIN,用线宽和线长去落地。反过来的做法是先调线宽,调到最后拓扑还是错的,白费工夫。
3.3 MSUB 与线宽:把「差不多 50 欧」变成能算的数
微带线的坑全在单位上。MSUB基板定义里H(介质厚度)的默认单位是 mil,25 mil 约等于 0.635 mm。很多人习惯按毫米思考,直接往H里填 1.6,以为是 1.6 mm,实际是 1.6 mil,线宽算出来差一个量级,特性阻抗自然离谱。
MSUB MSUB1 H=25 mil Er=4.6 Mur=1 Cond=5.8E7 Hu=3.9e+034 mil T=1.4 mil TanD=0.02 Rough=0 mil END| 参数 | 含义 | 常见取值 / 说明 |
|---|---|---|
H | 介质厚度 | FR4 常用 1.6 mm(约 63 mil)或 0.635 mm(25 mil) |
Er | 相对介电常数 | FR4 约 4.2 到 4.6,高频板材更低 |
Mur | 相对磁导率 | 非磁性材料填 1 |
Cond | 导体电导率 | 铜约 5.8E7 S/m |
T | 导体厚度 | 1 oz 铜约 1.4 mil |
TanD | 损耗角正切 | FR4 约 0.02,高频板材可低到 0.002 |
Rough | 表面粗糙度 | 影响高频损耗,低频可填 0 |
Hu | 上方空气层厚度 | 默认给一个极大值即可 |
一个可以用来验算的锚点:FR4、Er=4.6、H=1.6 mm,50 欧微带线线宽大约 3.0 mm;同样材料换成 H=0.635 mm,线宽大约 1.2 mm。线宽和介质厚度大致成比例,这个关系可以用来快速判断自己的参数有没有填错量级。算出来的线宽如果和这两个数差得远,先别怀疑公式,回头查单位。
实例里如果有MLIN加MSTEP、MCORN这类不连续结构,注意它们默认是不参与优化的。要做尺寸优化,得在优化控制器里显式把对应参数加进优化变量列表,否则跑完优化发现尺寸一点没变,会以为优化器坏了。
4. 功放实例的谐波平衡:HB 与 XDB 里真正要调的参数
从线性走到非线性,仿真方法就得换。S 参数是频域线性分析,放大器一旦推到大信号区,增益压缩、谐波再生、直流功耗,全都不在线性框架里。这批实例里功放相关的工程用的是谐波平衡(HB),配合 XDB 控制器找压缩点。这一段的门槛不在原理图,在参数和口径。
4.1 HB 控制器:阶数、迭代上限和频率表
HB 控制器的核心字段是频率表和阶数。Freq[1]填基波频率,Order[1]填这个基波要考虑的谐波阶数;双音或者多音测试就继续往下填Freq[2]、Order[2]。阶数不是越高越好,阶数高意味着未知量多、迭代慢、更容易不收敛,通常先给 3 到 5 阶看趋势,需要看三阶互调产物时再把交调阶数单独提上去。
迭代上限(有的版本写成MaxIters,有的放在高级页签里)默认值对弱非线性电路够用,一旦电路里有强反馈或者偏置网络比较复杂,就容易在中途停下来。我的做法是先跑 DC 分析确认工作点正常,再跑 HB;DC 都不收敛的电路,HB 一定不会收敛,先解决前者。
另一个常被忽略的点是节点初始条件。射频功率放大器的偏置节点上经常挂着大电感和大电容,启动瞬间的冲击会让迭代发散。加一个数值很大的并联电阻(比如 1 GΩ)到地,或者给关键节点指定初始电压,都能把收敛性拉回来。这类做法在实例里不一定都标出来,属于血泪经验,遇到不收敛时值得先试。
4.2 1dB 压缩点与 PAE:口径不对,数字白算
XDB 控制器只做一件事:扫输入功率,找出增益相对小信号下降 1 dB 的那个点。看着简单,实际有三个地方容易出错。
输入功率的变量名必须和原理图里的源对上。源上填的是Pin,控制器扫描变量就得是Pin;填的是Pavs(可用功率),扫描变量就得跟着改。名字对不上,控制器会老老实实按一个不存在的变量扫,结果是每个点都一样。
增益的定义要统一。是转换功率增益、工作功率增益还是可用功率增益,三者在匹配良好时差别不大,失配严重时能差出好几个 dB。实例里如果在 MeasEqn 里自定义了增益表达式,改参数的时候别把它删了。
PAE 的算法要落到具体公式上。下面这段是常见写法,放在 MeasEqn 里,把输出功率、直流功耗和效率串起来:
Pout_W = 0.5*real(Vout*conj(Iout)) ! 负载上实际得到的射频功率 Pdc_W = real(Vbias*conj(Ibias)) ! 直流偏置消耗的功率 PAE = 100*(Pout_W - Pin_W)/Pdc_W ! 效率,单位 %Vout、Iout取负载端的电压电流相量,Vbias、Ibiis取偏置端的直流量。注意分子里减掉的是输入射频功率而不是零,漏掉这一项,算出来的是漏极效率不是功率附加效率,两者在增益不高的时候能差十几个百分点。
4.3 批量读数据集:一个能复用的 Python 小工具
实例跑完一轮,data/下会堆一批.ds。想在报告里做对比,最省事的路径是从实例里导出 Touchstone(.s2p)或者 CSV,再用脚本批量读。下面这个脚本处理 Touchstone,两种常见格式(MA 和 DB)都能吃:
import math, glob, os def to_complex(a, b, fmt): """把 Touchstone 的一对数转成复数,fmt 支持 MA / DB / RI""" if fmt == "RI": return complex(a, b) mag = 10 ** (a / 20.0) if fmt == "DB" else a return mag * complex(math.cos(math.radians(b)), math.sin(math.radians(b))) def read_s2p(path): """读两端口 Touchstone,返回 [(freq_Hz, S11, S21, S12, S22), ...]""" fmt, scale, buf, rows = "MA", 1e9, [], [] with open(path, "r", errors="ignore") as f: for line in f: line = line.split("!", 1)[0].strip() # 去掉注释 if not line: continue if line.startswith("#"): # 选项行 t = line[1:].upper().split() if "HZ" in t: scale = 1.0 if "KHZ" in t: scale = 1e3 if "MHZ" in t: scale = 1e6 if "GHZ" in t: scale = 1e9 for k in ("DB", "MA", "RI"): if k in t: fmt = k continue buf.extend(float(x) for x in line.split()) for i in range(0, len(buf) - 8, 9): # 每行 1 频点 + 8 个数据 n = i f = buf[n] * scale rows.append((f, to_complex(buf[n+1], buf[n+2], fmt), to_complex(buf[n+3], buf[n+4], fmt), to_complex(buf[n+5], buf[n+6], fmt), to_complex(buf[n+7], buf[n+8], fmt))) return rows def s21_db_at(path, target_ghz): """取最接近目标频点的 |S21|,单位 dB""" rows = read_s2p(path) if not rows: return None f, s11, s21, s12, s22 = min(rows, key=lambda r: abs(r[0] - target_ghz * 1e9)) return f / 1e9, 20 * math.log10(abs(s21) + 1e-15) for fn in sorted(glob.glob("./data/*.s2p")): name = os.path.basename(fn) print(name, s21_db_at(fn, 2.4))脚本里几个关键点。第二行的注释剥离是必须的,Touchstone 允许在任意行尾跟!注释,不去掉会直接抛类型错误。scale的默认值给了 1e9,因为大多数射频实例的单位行写的是 GHz,但别依赖默认,读到#开头那行就必须把单位定下来。主循环里range(0, len(buf) - 8, 9)的步长是 9:一个频点加四组复数,共 9 个数。如果文件是三端口或者混了噪声参数块,这个结构要另写,不能硬套。
min(rows, key=...)取最近频点,而不是精确匹配,因为扫描步长很少刚好落在 2.4 GHz 上。加1e-15是防止全反射时log10(0)报错。这套写法我在几个不同的实例上跑过,只要导出时选的是标准 Touchstone,基本不用改。
5. 避坑与排查:跑不通时按这五条顺序查
实例跑不通的时候,最忌讳的是到处乱试。射频仿真报错信息往往只给一个笼统的「仿真失败」,具体原因藏在状态窗口的滚动日志里。下面五条按出现频率排,从最常见的开始查,多数问题在前两条就能解决。
5.1 元件变红、库找不到
现象:原理图打开后一片红色方框或者问号,状态窗口提示找不到元件定义。
原因:工程引用的库没挂上。老 .prj 转换到新工作区时,库名映射会断;或者实例里带了自定义库文件(用户自己建的元件库),而你只拷了原理图没拷库。
解决:先确认压缩包里有没有.def、lib之类的库文件目录,整个拷过来再挂。然后在库管理里手动把路径加进去,重启生效。转换过来的工程如果一直修不好,用原始 .prj 在新版本里重新打开一次,让转换流程完整走完,比在转换后的残缺工程上补要快。
5.2 仿真跑完,曲线是空的
现象:仿真正常结束,状态窗口没有报错,但数据显示窗口里一条曲线都没有,或者只有坐标轴。
原因:三种可能。数据集没生成(data/下没有新的.ds);显示模板绑定的数据集名字和实际生成的对不上;.dds里引用的测量表达式算不出来。
解决:先看data/目录里.ds的修改时间,确认真的跑了;再看.dds里表达式引用的数据集名称,从菜单里重新绑一次;最后把表达式简化成最基本的dB(S(1,1))试一下,能画出来说明是自定义表达式的问题。
5.3 HB 不收敛
现象:跑了很久最后提示迭代次数用完,或者直接退出。
原因:直流工作点本身就没收敛;谐波阶数给太高;输入功率推到强非线性区;偏置网络里的大电感电容导致启动冲击。
解决:先单独跑 DC 分析看工作点;把阶数从 5 降到 3 试;输入功率从小往大分段扫,找到开始发散的那个功率点;给偏置节点加大电阻到地做数值泄放。这四步做完还不收敛,再去看是不是模型本身有问题——某些厂商模型在特定偏置下确实会发散,这时候换一个同类型模型对照。
5.4 单位与线宽对不上
现象:微带线仿真出来的特性阻抗和理论值差一个量级,或者优化器跑了几十次线宽还是几千微米。
原因:MSUB里H的单位是 mil,填了毫米的数值。或者优化变量里混进了带单位的表达式,优化器按无量纲处理。
解决:把MSUB的每个字段连单位一起核对一遍,尤其是H和T。优化变量统一在VAR块里定义成纯数值,单位在引用处写死,别把1.6 mm直接写进优化目标里。
5.5 路径、空格与老工程转换
现象:换个目录就报错,或者同一份工程在别人机器上能跑,在你这里不行。
原因:ADS 对非 ASCII 路径和空格的处理一直不算好,老版本尤其明显;另外不同大版本之间,部分元件的参数名会变。
解决:路径只留英文、数字、下划线,目录层级尽量压到三层以内。老工程用对应的版本打开,不要强行用最新版,实在要用就先在旧版里另存一份。这条没什么技术含量,但确实是踩坑最多的一条。
6. 把实例改成自己的模板:参数化改造和一条对照习惯
实例跑通只是起点。真正省时间的是把一套跑通的工程变成自己的模板,下次换个频段、换个板材,改几个数就能出结果,而不是从头再摆一遍元件。
6.1 用 VAR 把硬编码数字抽出来
改造的第一步是把散落在各处的数字收进VAR块。原则很简单:凡是会在不同项目之间变化的量,全部提出来。频率、线宽、介质厚度、偏置电压、匹配元件的初值,一个都别留在元件属性里。
| 变量名 | 含义 | 典型取值 |
|---|---|---|
f0 | 中心频率 | 2.4 GHz |
W50 | 50 欧线宽 | 由 MSUB 和H决定 |
H_sub | 介质厚度 | 1.6 mm |
Er_sub | 介电常数 | 4.4 |
Vbias | 偏置电压 | 由器件数据手册决定 |
Pin_list | 功率扫描点 | 用 SweepPlan 或sweep()驱动 |
命名上我习惯带单位暗示:H_sub是厚度,W50是线宽,f0是频率,看名字就知道量纲,改的时候不容易张冠李戴。变量集中在顶层原理图定义,子电路引用,改一处全局生效。这一步做完,换板材只需要改H_sub和Er_sub两个值。
6.2 每次改完强制走一遍的对照流程
参数化之后最怕的是「改了一处忘了另一处」,结果仿出来的曲线看着合理,实际是两套参数混在一起。我的做法是固定三步对照:先看变量表里有没有出现未被引用的孤儿变量;再看数据集里生成的曲线条数和扫描点数对不对得上;最后把新旧两版的关键指标摆在一起,增益、带宽、压缩点,至少三项一致才算改对了。
这套流程听起来啰嗦,但省下的是返工时间。有一次我改板材厚度,忘了同步改匹配支节的线长,仿真出来 S11 依然在 -15 dB 以下,乍看完全正常,直到把两版叠加对比,才发现中心频率悄悄偏了 200 MHz。那次之后我给自己定了个规矩:任何参数改动,都必须留一版旧数据集,不许覆盖。
从那以后我每次拿到一份新的实例,都强制先把最小链路跑通、把关键指标记在一张纸上,再去动大信号部分。有了基准,后面所有的改动才有意义。希望帮到你。
本文还有配套的精品资源,点击获取