我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

模拟集成电路设计题号对照表:教材改版后的解答索引映射与校验

模拟集成电路设计题号对照表:教材改版后的解答索引映射与校验 简介这份面向模拟集成电路学习者与考研复习人群的Razavi《模拟CMOS集成电路设计》习题解答聚焦教材课后题求解与版本对照适合在听课、刷题和期末/考研复盘时查漏补缺。压缩包内共1个PDF文件约12.95MB内容以章节题解为主体整体按章节组织并带有书签便于跳转开篇附有新版与预览版题号、图号及公式编号的修正清单覆盖第3章至第8章的部分题目便于按章检索和核对引用变化。已有4018人学习说明其在模拟CMOS设计习题资料中具有较高参考度。读者可据此理解器件模型、单级与差分放大器、频率响应、反馈、噪声等典型题目的分析思路借助图形与公式梳理推导过程遇到新旧教材题号不一致时也可通过映射表快速定位答案减少版本差异带来的查阅障碍。1. 一份题号对照表的分量模拟集成电路设计里最容易被忽略的失败模式模拟集成电路设计这门课有个反直觉的失败模式你手里的习题解答一个字都没错你却还是算不出来。原因不在推导而在翻页你按新版教材的编号找过去撞上的是旧版里的另一道题。教材修订时题目被重新排序答案还躺在原处于是“答案正确”和“答案可用”之间裂开一道缝。这份资源做的就是缝补它把新版题号、图号、公式号逐条映射回解答手册里答案真正所在的位置。听上去枯燥但它决定了整套解答能不能用一旦它出错后面的推导越认真错得越离谱。2. 题号重排为什么一次章节插入会让整本解答“对不上号”2.1 题号是位置不是身份教材里的编号写成 4.18、6.13 这种形式读起来像名字实际是坐标小数点前是章后面是这一章里的第几道。它假定“这一章的题目集合”是稳定的一旦有人在章首插入一道新题后面所有题目的坐标集体加一。和往数组头部插入一个元素是同一回事时间复杂度 O(n)影响范围是整个数组。内容型标识不会这样。假如一道题的身份由题干和推导链算出一个摘要值那么无论它排在第几位身份都不变。教材修订偏偏不采用这种方案因为修订做的主要工作不是改写内容而是重新组织内容调整顺序、拆分小节、把某几道题合并成一道位置一旦改动位置型编号就必然失效。所以那次改版真正的伤落在“解答手册的索引”上题目本身并没有变。答案没有错只是索引错了。这一点想通之后看待勘误表的角度就变了。它不是补丁而是一张坐标转换表把新坐标系里的点翻译成旧坐标系里对应的点。前者是读者手上的教材后者是答案实际的存放位置。2.2 图号与公式号比题号更脆的第二层指针题号是对外接口你一眼就能看出对不上。图号和公式号是内部指针藏在解答正文里失效时不会有任何提示。一道题的解答写着“由式 (6.23) 可得”新版里这个公式被移到了 (6.20)你按 (6.20) 去翻翻到的是另一条结论代进去算量纲对得上数量级也像就是答案差一截。这类失效最麻烦的地方在于它不会报错它只会让你得到一个看起来合理的错误结果。图号同理。解答里说“参考 Fig. 4.35 的小信号模型”新版里那张图变成了 Fig. 4.38Fig. 4.35 现在画的是另一个电路。你照着错的图列 KCL方程列得漂漂亮亮端口接反了。页码引用也一样p. 4.6 和 p. 4.17 之间的对调在纸质书上是半页之遥在理解上是两个完全不同的推导起点。要把这类问题找出来靠人眼逐条比对不现实得先把解答文本里的所有内部引用扫一遍。常见的做法是用正则把图号、公式号、题号引用都抓成候选集合再和教材里实际存在的编号做差集import re # 抓三类内部引用图号、公式号、题号 # 注意公式可能写成 (6.23)、eq. 6.23、eqn (6.23)先统一成 数字.数字 REF re.compile( r(?:Fig(?:ure)?\.?\s*(\d\.\d)) # Fig. 4.38 / Figure 4.38 r|(?:eq(?:n|uation)?\.?\s*\(?(\d\.\d)\)?) # eq (6.23) / equation 6.23 r|(?:problem\s(\d\.\d)), # problem 4.5 re.I ) def scan_refs(text: str) - set: 返回文本里出现过的全部编号形如 {4.38, 6.23} out set() for m in REF.finditer(text): # 三个分组只会命中一个取非 None 的那个 out.add(next(g for g in m.groups() if g)) return out manual_doc the solution referred to Fig. 4.35 and eq (6.53). print(scan_refs(manual_doc)) # {4.35, 6.53}这段扫描只做一件事把“可能已经过期”的指针全部列出来。它不会告诉你哪个错了但能把人工核对的范围从整本手册收缩到几十个候选点上。剩下的判断交给映射表。注意正则里的分组顺序要和模式顺序严格对应中间插一个捕获组就会让next(g for g in m.groups() ...)取到错的值这是这类脚本最常见的翻车点。2.3 插章引发的全局位移新增两章之后后面三章集体后移题号重排还只是章内位移真正放大影响的是章节层面的插入。新版在中间位置塞进了两章全新内容一章讲振荡器一章讲锁相环。这两章不是原来某章的扩写是独立成章的新增于是原本排在第 14、15、16 位的三章整体被推到第 16、17、18 位。这种位移有个特点它是全局的、有规律的也正因如此最容易被漏掉。章内重排你翻一次就发现了跨章位移不会——因为你在第 18 章查题时看到的编号 18.3 完全合理你不会意识到它在旧手册里叫 16.3。更隐蔽的是解答正文里的交叉引用一道第 18 章的题可能写着“参见第 16 章的推导”这个“第 16 章”在新版语境下指的是现在的第 18 章本身直接形成了自指。照着这句话去翻你会翻回自己脚下。处理这类位移的办法不是逐条改而是把它当成一条全局替换规则来验证先把解答手册里所有chapter N形式的引用抽出来按 N 分桶凡是 N ≥ 16 的统一加二再看替换之后有没有出现自指或越界。输入正文里给出的那几条本质就是这条规则在个别位置上的显式说明比如第 18 章第 3 题原为第 16 章第 3 题第 18 章第 8 题原为第 16 章第 8 题配图的编号也从 16.x 系列整体挪到 18.x 系列。顺带说一句新增的这两章不是随手加的。振荡器和锁相环在方法论上和前面所有章节都不一样前面讲的是单级、开环、小信号近似下的增益和带宽这两章讲的是闭环系统的稳定性判据和相位噪声一整套新的分析框架。这也解释了为什么旧手册里根本没有它们的答案只能靠自己推。3. 勘误表的数据结构NEW 与 PREVIEW 两列如何构成一张可查的置换表3.1 映射而不是重写一张部分函数的成本优势这张对照表的形式极简左边一列是新版题号右边一列是旧版题号中间用空白隔开。逐行读下来它定义的是一个部分函数定义域是新版教材里所有发生变动的题号值域是解答手册里实际存放该题答案的题号。查询方向是单向的从左往右读拿新题号找旧题号然后去旧手册里翻。为什么用映射而不是干脆按新版重出一本解答成本是一方面重写意味着每道题都要重新排版、重新核对图和公式、重新走一遍校对流程工作量线性增长而且每重写一次就引入一批新的笔误。映射表的成本只和“变动量”成正比没变的题目一个字都不用碰。更关键的是误差可控重写引入的错误是隐式的你不知道哪一页错了映射表引入的错误是显式的你查表查不到立刻就发现了。这种思路在工程上到处都是。数据库做 schema 迁移时老数据不动加一层视图做转换编译器做版本兼容时不改底层实现加一层适配就连操作系统的系统调用表也是靠一层薄薄的转发维持向后兼容。它们的共同点是把“重新组织”和“重新实现”这两件事拆开前者用元数据描述后者保持不动。解答手册的编号体系本质上就是一份需要迁移的数据。用代码表达这张表就是一个字典键是新题号值是旧题号。真正麻烦的地方在于原表的排版是给人看的分组、空行、全角符号、带撇号的编号混在一起要落成字典得先做一遍解析import re # 一行形如 4.18 4.5 Fig. 4.38 Fig. 4.35 Fig. 4.39 Fig. 4.36 LINE re.compile(r^(\d\.\d)\s(\d\.\d\?)(.*)$) QUOTED re.compile(r([^])) def parse_section(lines): lines: 某一章 NEW/PREVIEW 表格的原始文本行 返回 (rename, patches) rename : {新题号: 旧题号} patches: {新题号: [(新标签, 旧标签), ...]} rename, patches {}, {} for raw in lines: s raw.strip() # 跳过表头、分隔线、空行 if not s or s.startswith(-) or s.startswith(NEW): continue m LINE.match(s) if not m: continue new_no, old_no, tail m.group(1), m.group(2), m.group(3) # 3.2 这种带撇号的旧编号要归一化否则键值永远匹配不上 rename[new_no] old_no.rstrip() tags QUOTED.findall(tail) if tags: # 引号内的标签按出现顺序两两配对前者是新标签后者是要被替换掉的旧标签 patches[new_no] list(zip(tags[0::2], tags[1::2])) return rename, patches rename, patches parse_section([ 4.18 4.5 Fig. 4.38 Fig. 4.35 Fig. 4.39 Fig. 4.36, 4.14 4.1 (4.52) (4.51) (4.53) (4.52), ]) print(rename) # {4.18: 4.5, 4.14: 4.1} print(patches[4.18]) # [(Fig. 4.38, Fig. 4.35), (Fig. 4.39, Fig. 4.36)]解析本身不复杂复杂的是那些“表里没写但必须知道”的约定下一节单独说。3.2 引号里的第三列局部引用补丁按什么规则配对一行对照里除了两个题号后面还可能跟着成对的引号内容。这些引号在表达另一层信息这道题的解答正文里有哪些标签需要替换。比如 4.18 那一行引号里依次是图 4.38、图 4.35、图 4.39、图 4.36含义是解答里原本写的 Fig. 4.35 和 Fig. 4.36现在要读作 Fig. 4.38 和 Fig. 4.39。配对规则没有写在表里得从语义反推引号内容按从左到右的顺序两两成组每组里前一个是新标签后一个是被替换掉的旧标签。这个顺序约定是整个解析能自动化的唯一依据因为标签本身已经变了你没法靠字符串相似度去匹配Fig. 4.35 和 Fig. 4.38 长得一点都不像。换句话说这张表是“人类可读、机器难解析”的典型样本它把关键的配对信息编码在了位置顺序里而不是显式字段里。代码里的zip(tags[0::2], tags[1::2])就是把这条约定固化下来偶数位取新标签奇数位取旧标签。如果某一行引号数量是奇数说明原文排版有问题或者这一行混进了其他类型的说明文字这时候不能静默跳过要打出来人工看。血泪经验是这类表里最容易出错的不是逻辑而是某一行少了个引号导致后面所有配对整体错位一格替换完全乱套。替换的执行也有讲究。不能简单做字符串的replace因为Fig. 4.3是Fig. 4.35的前缀全局替换会把本该保留的地方一起改掉。稳妥的做法是按标签长度从长到短排序或者干脆用词边界限定的正则把每个标签当成完整 token 去匹配。3.3 缺省即不变闭世界假设撑起了整张表的体积对照表开头有一句话信息量比整张表加起来还大没有列出的章节和题目保持不变。这句话把整张表的语义从“枚举”变成了“差量”也就是说只描述变化的部分没提到的默认维持原状。如果没有这句缺省规则表就必须把全部三百多道题逐条列出来哪怕其中绝大多数是原封不动的体积膨胀十倍不止而且每多列一行就多一次出错机会。有了它表的规模只和改动量成正比。这是个典型的闭世界假设未被声明为变动的一律视为未变动。这种设计在配置系统里很常见但它的风险也同样常见——缺省语义容易被读者忽略。有人翻表翻了半天没找到某道题会以为“这道题被删了”实际上它只是没变。更糟的是如果缺省规则本身在某次修订中被悄悄改掉比如新版本开始“只列出变动且未删除的题”那整张表的读法就得跟着改而表面上看不出来。验证办法有两个。第一检查映射的定义域和值域是否构成双射在新版和旧版之间如果只是重排没有增删两个题号集合的势应该相等映射应该是一一对应的。第二检查纯位移段的单调性。像连续十几行都是“新题号比旧题号大 7”这种属于整段平移如果中间突然有一行破坏了这个规律要么是真的插了一道新题要么是录入错了。这两种情况都得人工确认。def check_offset(rename: dict): 检查整体平移段统计新旧题号之差找出偏离主流的行 from collections import Counter diffs Counter() detail {} for new_no, old_no in rename.items(): ch_n, q_n (int(x) for x in new_no.split(.)) ch_o, q_o (int(x) for x in old_no.split(.)) if ch_n ! ch_o: continue # 跨章映射单独处理不参与平移统计 d q_n - q_o diffs[d] 1 detail.setdefault(d, []).append(new_no) main diffs.most_common(1)[0][0] # 偏离主偏移量的行多半是新增题、删除题或者录入错误 return main, {d: v for d, v in detail.items() if d ! main}跑完之后主偏移量通常是 7 或 8 这样的整数偏离它的那几行就是需要逐个看的异常点。4. 对号入座之后这些习题真正在考什么机制4.1 从工作区到小信号等效gm 的三种写法为什么必须都掌握题号对上了只是第一步接下来要面对的是题目本身。整套习题的主线其实只有一条把一个非线性器件在工作点附近线性化然后在等效电路上做线性分析。MOS 管有三个工作区截止、线性也叫三极管区、饱和只有饱和区才能当放大器用因为那里漏极电流对漏源电压的一阶导近似为零输出电阻足够大。饱和区的平方律写成 ID ½·μn·Cox·(W/L)·(VGS − VTH)²·(1 λ·VDS)其中 λ 是沟道长度调制系数它决定了本征增益的上限。对这个式子求偏导就得到跨导 gm。麻烦在于 gm 有三种等价写法表达式形式适用场景过驱动电压形式gm 2·ID / (VGS − VTH)已知偏置电流和过驱动电压手算首选工艺参数形式gm μn·Cox·(W/L)·(VGS − VTH)调尺寸时用直接看出 W/L 的影响电流形式gm √(2·μn·Cox·(W/L)·ID)已知电流和尺寸设计迭代时最常用三种写法在数学上完全等价但在工程直觉上完全不同。第一种告诉你给定电流过驱动压得越小 gm 越大代价是线性度变差、匹配变差第二种告诉你想提高 gm加宽管子比加压更温和第三种告诉你gm 和电流的平方根成正比所以靠加倍电流只能换来 1.41 倍的 gm功耗效率是递减的。这就是为什么习题里反复让你从不同已知量出发推 gm。它考的不是代数是你对“哪个变量是自由变量”的判断。手算时优先用第一种因为过驱动电压是设计者最先确定的量它直接对应着摆幅预算。4.2 极点分裂与米勒补偿公式号一动推导链就断了单级共源放大器的增益和带宽好算难的是两级。两级运放如果不加补偿两个极点靠得太近相位在单位增益频率附近掉得很快闭环直接振荡。米勒补偿的做法是在第一级输出和第二级输出之间跨接一个电容利用米勒效应把它等效到第一级输入端变成一个大电容从而把主极点推向低频。补偿前后两个极点的位置发生“分裂”主极点 p1 被压低次极点 p2 被推高单位增益带宽近似为 GBW ≈ gm1 / Cc。为了让相位裕度落在 60 度附近次极点通常要放在 2 到 3 倍 GBW 之外。这条关系是整套频率补偿设计的骨架也是习题里出现频率最高的推导。问题在于这条骨架是靠一串公式编号串起来的主极点由哪条式子给出、次极点的近似式在第几章、右半平面零点由哪条式子描述、它和次极点的相对位置如何决定相位裕度。教材改版时如果这些公式整体位移了解答里“由式 (6.52) 可得”就会指向另一条式子比如新版的 6.49推导链在中间断掉而你从结果上根本看不出来——因为断掉的那一步往往只是一个近似缺了它后面的式子照样能算出一个数字。所以核对公式引用这件事不能只看“这个编号存不存在”要看“这条公式在上下文里量纲对不对、结论方向对不对”。一个可操作的验证方式是把补偿参数扫一遍看数值结果是否落在合理区间import math def two_stage_pm(gm1, gm2, Cc, CL, C10.2e-12): 两级运放的一阶极点估算用于验证公式引用是否自洽。 gm1/gm2: 两级跨导 (S)Cc: 米勒电容 (F)CL: 负载电容 (F)C1: 第一级输出节点寄生 (F) 返回 (主极点, 次极点, 单位增益带宽, 相位裕度估计) gbw gm1 / Cc # 单位增益带宽 p1 1.0 / (gm2 * Cc * CL / Cc) # 主极点被米勒电容压低 p2 gm2 / CL # 次极点被推到高频 # 相位裕度 ≈ 90° - arctan(GBW/p2) - arctan(GBW/p1)此处 p1 远低于 GBW 可忽略 pm 90.0 - math.degrees(math.atan(gbw / p2)) return p1, p2, gbw, pm for cc in (0.5e-12, 1.0e-12, 2.0e-12, 3.0e-12): p1, p2, gbw, pm two_stage_pm(gm11e-3, gm24e-3, Cccc, CL2e-12) print(fCc{cc*1e12:.1f}pF GBW{gbw/1e6:.1f}MHz p2{p2/1e6:.1f}MHz PM≈{pm:.0f}°)跑出来的趋势应该是Cc 越大GBW 越低次极点相对 GBW 越远相位裕度越高。如果换了公式引用之后这个单调关系反过来了说明你引用的那条式子根本不是次极点的表达式。用数值趋势做交叉验证比死记编号可靠得多。注意上面这段是一阶估算忽略了输出电阻、右半平面零点和负载的容性反馈。真实设计的相位裕度要靠交流仿真确认手算只是用来判断“方向对不对”。4.3 新增的振荡器与锁相环为什么它们不能塞进原来的章节新版单独开出两章讲振荡器和锁相环这个安排本身透露了方法论的分界线。前面所有章节的分析前提是系统开环信号小工作点固定于是可以线性化。这两章的知识点并不落在这个前提下。振荡器的核心是正反馈。两级或多级放大器接成环路环路增益在某个频率上相移达到 180 度、幅度大于 1电路就起振。巴克豪森判据只是必要条件真正决定起振的是小信号下的负阻。以交叉耦合对为例一对 NMOS 交叉连接从差分端口看进去的等效电阻是 −2/gm只要这个负阻的绝对值小于 LC 谐振回路的等效并联电阻能量就在增长幅度一直长到非线性把 gm 压下来、负阻刚好抵消损耗为止。这里的关键词是“大信号”和“非线性”你没法用一条小信号传递函数描述到底。锁相环更是彻底的闭环系统。鉴频鉴相器比较参考时钟和反馈时钟的相位差电荷泵把相位差转成电流环路滤波器积分成控制电压压控振荡器把电压转成频率分频器再送回输入端。环路的稳定性由开环传递函数的相位裕度决定而环路带宽、阻尼因子、锁定时间、相位噪声抑制之间是一组互相拉扯的取舍。这套分析框架和前面讲单级增益、极点分裂的那套完全是两套语言。所以旧版解答手册里根本没有对应内容能做的就是自己把推导走一遍先写环路方程再求开环增益然后分别看低频和高频的渐近行为最后确定环路滤波器的零极点位置。这两章虽然难度更高但好处是题目数量相对少每道题的“分量”更重一道题往往就把整个系统的设计流程走完了。5. 排查整理这套对照解答时最容易翻车的五处5.1 拿新题号直接翻旧手册现象很直接按教材上的 3.4 去旧手册找翻出来的解答讲的是另一个电路参数对不上你以为是印刷错误其实是拿错了题。原因在于题号是位置型的新旧版之间整体平移了若干位输入正文里第 3 章几乎整章都是平移关系新 3.1 对应旧 3.8新 3.2 对应旧 3.9一路顺延。解决办法是养成“先查表再翻页”的习惯把映射后的题号写在草稿纸角上翻完再回来对一遍确认讲的是同一个电路拓扑。5.2 引用悬空图号公式号没跟着换现象是推导过程能走通但每一步的结果都比预期差一点而且差得很有规律往往是一个系数或者一个数量级。原因几乎总是内嵌的图号或公式号没更新解答里指的是旧版的图你照着新版同号图去建模端口接法变了。解决办法是做替换时按“标签长度从长到短”排序避免前缀冲突替换完再全局搜一遍旧的编号确认没有残留。前面那段扫描脚本就是干这个的。5.3 跨章引用与带撇号编号两个沉默的陷阱跨章引用的问题在第 2 章已经说过凡是旧手册里写着“见第 14 章”“见第 15 章”“见第 16 章”的地方新版里分别要读作第 16、17、18 章。带撇号的编号是另一个陷阱输入正文里出现过 3.2 这样的写法用来区分同一道题在修订过程中的两个版本。解析时如果不剥掉撇号3.17 → 3.2和3.17 → 3.2会被当成两条不同的记录查表时按3.2去查查不到然后误判成“这道题没有答案”。解决方式是在解析阶段就做归一化同时把原始写法记在旁注里方便回溯。5.4 新增章节没有旧答案可抄现象是查表查不到新版第 14、15 章振荡器、锁相环的题号在 PREVIEW 列里完全空缺。原因很简单这两章是全新的旧手册里不存在对应内容不是“漏录”。处理方式和前面几条完全不同前面是索引问题这一条是内容问题索引再怎么修都没用只能自己去推。建议的做法是先把这两章的核心结论列出来巴克豪森判据、交叉耦合对负阻、环路传递函数、环路带宽与阻尼因子的关系遇到具体题目时先判断它落在哪条主线上再顺着主线补推导别指望能直接抄到答案。5.5 把“表里没有”当成“题目被删了”现象是翻遍对照表找不到某道题于是判断这道题在新版里被删除了。原因在于整张表默认采用闭世界假设只列出发生变动的部分绝大多数题目原地不动根本不会出现在表里它们的答案仍然是旧手册里的同号题。解决办法只有一条把“未列出即不变”这句话当成表的元规则记住查不到的时候不是去找删除标记而是直接按同号去旧手册翻翻到了就说明它没变。这条听起来像废话实际做整理时出错率极高因为人的直觉总是倾向于“没找到就是没有”。6. 设计取舍为什么“保留旧编号 一张映射表”优于全部重编站在做资源整理的角度看这道选择题比它表面上有意思。全部重编看起来最干净题号对上了图号公式号一起改读者拿到手就能直接用不需要在两张表之间跳来跳去。代价是每道题都要重走一遍排版和校对工作量线性增长而且每重写一次就引入一批新的笔误——这类笔误比索引失效更难发现因为它在语义上完全自洽。映射表的取舍恰恰相反。它保留了答案在旧坐标系里的事实只在上面盖一层薄薄的转换层破坏性最小改动量只和变动量成正比没变的题目一个字都不用碰。它的代价是把复杂度转移给了读者你必须先查表才能翻到正确的那一页。这个代价换来的收益是可审计性——映射表本身是一份可读、可校验、可版本化的元数据你能逐条核对而重写之后的新手册是个黑匣子你不知道哪一页在重排时被悄悄改错了。这个思路在软件工程里反复出现数据库迁移用视图兼容旧查询而不是重写全表编译器做版本兼容时加一层适配而不是改所有下游系统调用表靠一层转发维持向后兼容。它们的共同判断标准只有一条——变更的收益是否大于让所有人重学一遍的成本。真正需要警惕的是元数据腐烂。映射表是建立在教材某一版之上的教材再改一版这张表就得跟着迭代而它不像代码那样有编译器帮你检查。所以我一般会做两件事一是把解析和校验写成脚本每次拿到新表都能自动跑一遍单调性检查和双射检查二是把“未列出即不变”这条元规则写在最显眼的位置因为它是整张表能成立的前提一旦被忽略后面所有推理都建在沙子上。从那以后我每次拿到这种带编号体系的资料都会先把映射关系单独抽出来落成数据跑一遍一致性校验再开始读内容。这个习惯救过我好几次尤其是在公式编号也一起变的情况下人的眼睛真的靠不住。希望帮到你。这份对照表和配套的解答一起放在下载包里拿到之后建议先从第 3 章和第 4 章的映射段入手把它们先转成字典再顺着查表去读后面的推导会比一页页硬翻省力得多。本文还有配套的精品资源点击获取
返回列表