zyz

人生如逆旅,我亦是行人

转载请注明出处

理解前向传播与反向传播:可微 EDA 论文阅读基础

核心概念:流水线 不要把复杂的函数看作一个整体公式,而是要把它们拆解成由 “加、减、乘、除” 构成的计算图流水线。 前向传播:算函数结果 本质:将当前变量的具体值带入计算图,从左向右,一步步计算并保存所有的中间变量,直到得出最终的函数结果。 意义:评估当前的状态。 后向传播:算移动方向 本质:利用微积分的链式法则,从右向左,将最终结果产生的“梯度”,一层层按比例分配回最初的输入变量上。 意义:计算出每一个变量对最终结果的影响力(偏导数)。 具体示例 以 $f(x, y) = x^2 + xy + x + y$ 为例,其对应的计算图为: 假设我们的目标是最小化 $f(x, y)$,各变量初始值分别为: $x$: 2.00 $y$: 3.00 $\eta$: 0.05 $\eta$ 为学习率,决定每一步应该迈多大。 梯度只是告诉了我们移动方向,其本身不一定是一个合适的移动距离,例如某个地方梯度很大,如果直接按照梯度大小更新,可能一步跨得太远;某个地方梯度很小,又可能几乎不动,这就会导致震荡,所以我们需要学习率来缩放梯度。 一个合适的学习率有助于快速且稳定的靠近最优解。现在通常是“先人为给一个初始学习率,再让优化器(Adam, AdamW等)自动调整”。 前向传播 从左到右依次传播,得到最终的函数结果: 反向传播 从右到左依次传播,一层层按比例分配回最初的输入变量上,计算出每个变量对最终结果的影响力: 详细推导过程为: 根据梯度公式:$\nabla f(x, y)=\left(\frac{\partial f}{\partial x}, \frac{\partial f}{\partial y}\right)$,计算出当前点的梯度为:$\nabla f(2, 3)=(8.00, 3.00)$,根据偏导数的定义,可知该梯度表示在当前点上: 沿 $x$ 正方向,函数值每单位大约增加 $8.00$ 沿 $y$ 正方向,函数值每单位大约增加 $3.00$ 根据方向导数的定义可知,沿着梯度方向$(8.00, 3.00)$移动可以使得函数增长最快! 更新变量值 移动步长 = 学习率 $\times$ 梯度,那么在当前点的移动步长$Curr_{step} = 0.

Tmux 使用教程

tmux 是一个终端复用器,全称可以理解为 terminal multiplexer。 简单说,它可以让你在一个终端里管理多个终端会话,并且这些会话可以在你断开 SSH、关闭 Cursor/VSCode 终端后继续运行。 使用该工具最主要的原因有: 防止远程任务因为断连而中断 可以随时离开和恢复会话 一个窗口里管理多个终端(就不用开多个SSH终端啦!一个终端内即可创建多个窗口、面板) 基础概念 tmux中有三个核心概念:Session, Window, Pane, 可以查下面的示意图来理解这3个概念. 可以发现在tmux中执行任何操作都需要先按下Ctrl + b, 因为这是tmux默认的前缀功能键后续简称为preFix(该功能键可以进行修改), 其作用就是激活tmux的命令模式, 让用户可以通过接下来的命令操作tmux的Session, Window, Pane. 常用命令 Session管理 新建会话: tmux new -s <会话名称> 断开会话: preFix + d 列出会话: tmux ls 进入/重连会话: tmux a -t <会话名称> 杀死会话: tmux kill-session -t <会话名称> 其他命令 想要丝滑的使用tmux,就必须进行个性化配置,直接复制下面的内容给AI,与AI一起生成适配你的配置文件吧! 1 2 3 4 5 6 7 8 9 10 11 12 13 14 依次跟我讨论下面问题的答案, 帮我生成一份最适配我的tmux配置文档(所有推荐的按键设置都应该符合直觉, 操作丝滑): - 是否更改`preFix` - 创建/切换/关闭 Pane - 调整Pane大小 - 创建/关闭/切换/重命名 Window - 如何切换到指定Window - Window编号从0开始还是从1开始 - 关闭Window后, Window是否自动重新排序 - 关闭Window/Pane确认机制 - 如何开启/退出复制模式 - 如何开始复制,复制中如何移动, 如何复制粘贴 - 状态栏(是否需要显示CPU, 内存使用情况等) - 是否启用鼠标 - 是否支持配置重载

芯片设计文件格式:LEF 与 DEF

LEF文件 LEF是库交换格式 (Library Exchange Format)的缩写,该文件由foundry提供,是P&R所必须的库文件。 目前,LEF文件主要分为两种: 工艺LEF: 描述“制造工艺规则”,便于EDA工具做GR/DR/DRC检查等。 单元LEF: 描述“cell 的几何形状和引脚” LEF的具体信息可以查看此链接. DEF文件 DEF最早是布图规划是生成的,作为输入文件相继输入布局布线后完善,最终将转为GDS版图进行物理验证,通过后将进行流片。 其用来描述一个芯片设计在某个物理实现阶段中的版图信息,简单来说: .def 文件描述的是:这个 design 里面有哪些 instance、pin、net,以及它们在版图中的位置、方向、布线、floorplan 等物理信息。 标准.def文件由以下部分组成。 标题声明 1 2 3 4 5 6 VERSION 5.8 ; DIVIDERCHAR "/" ; BUSBITCHARS "[]" ; DESIGN BM64 ; UNITS DISTANCE MICRONS 1000 ; DIEAREA ( 0 0 ) ( 346182 346182 ) ; 该部分需要重点关注的: VERSION: 表示语法版本, EDA工具根据这个版本去理解语法规则 UNITS DISTANCE MICRONS: 表示 DEF 中的距离单位采用 database unit,简称 DBU, 在该示例中 1 micron = 1000 DBU DIEAREA: 表示芯片边界, 该实例中左下角为(0, 0), 右上角为(346182 DBU, 346182 DBU); 换算成micron为(346.

Codex Best Practices

核心思想为: 为每次任务提供正确的上下文 将复杂任务进行拆解 将持久的指导写入AGENTS.md 将重复工作转换为siklls 使用MCP与外部系统连接 自动化稳定的流程 Context and prompts 一个好的prompt应该包括以下4点: Goal: 你想要修改或建立什么? Context: 哪些文件、文件夹、文档、示例或错误对这项任务有帮助?推荐通过@这些文件来提供上下文。 Constraints: 本次任务应遵循哪些标准、架构、安全要求或惯例? Done when: 本次任务完成的标准。比如测试通过、行为改变,或者某个漏洞被修复。 此外,注意选择合适的推理能力: 低: 适用于范围明确且要求快速响应的任务 中和高: 适用于复杂的任务 超高: 适用于长时间、复杂、推理繁重的任务 Plan first for difficult tasks 对于复杂、模糊的任务,应该在进行编码前先做plan 可以采用以下方式来制作plan: 使用计划模式: 输入 /plan 或按下 shift + tab 即可切换为 plan 模式。(这是最简单有效的方式,强力推荐) 让Codex主动询问: 让codex主动对任务不清楚,描述模糊的地方对你进行提问,把你模糊的想法变成具体的东西,然后才开始写代码 使用 PLANS.md: 对于特别特别复杂的任务,可以按照官方提供的模板编写 PLANS.md Make guidance reusable with AGENTS.md AGENTS.md 就是面向 agents 的 README,它可以让我们不用重复写相同的提示,让anget行为更稳定。Codex每次执行任务前会自动读取该文件,作为系统级指导。 一个好的 AGENTS.md 应该包括以下内容: 仓库结构和重要目录 构建、测试、运行命令 代码规范(使用什么标准,函数和变量命名规则等) 工作流程(如何提交PR,commit规范,review要求) 特殊注意事项 刚开始的 AGENTS.md 应该简洁准确,然后再慢慢将 agent 反复犯的错制作为规则添加进去。需要注意的是 AGENTS.

芯片设计核心概念:建立时间与保持时间

在数字电路(特别是触发器 Flip-Flop)中,为了准确采样数据,输入信号必须在时钟采样沿的前后一段时间内保持绝对稳定。 这段时间构成了“采样窗口”。如果不遵守这个规则,就会发生时序违例(Timing Violation),导致输出出现亚稳态(未知的乱码)。 📸 秒懂比喻:拍一张清晰的照片 时钟有效沿 (Clock Edge): 按下相机快门的那一瞬间。 建立时间 (Setup Time): 摄影师喊“1,2,3”之前,你必须提前摆好姿势并保持不动的时间(提前准备好)。 保持时间 (Hold Time): 按下快门之后,“咔嚓”声结束前,你还必须继续保持不动的时间(不能马上跑开)。 亚稳态 (Metastability): 如果你在按快门前没站稳,或者刚按完快门你就动了,拍出来的照片就是模糊的(芯片不知道存的是0还是1)。 理想情况 Setup 违例 Hold 违例 $T_{seteup}$和$T_{hold}$如何确定? $T_{seteup}$和$T_{hold}$是触发器(Flip-Flop)物理器件本身的固有属性,它们的大小是由代工厂(Foundry,比如台积电 TSMC、中芯国际 SMIC)决定的,记录在时序库文件(.lib 文件,Liberty format) 中。 具体来说,Foundry 会对这些标准单元进行大量的 SPICE 仿真,把不同输入转换时间(Transition/Slew)和输出负载下的 $T_{setup}$ 和 $T_{hold}$ 值制成一张张二维查找表(Look-up Table),保存在 .lib 文件中。EDA 工具在计算时,是去 .lib 里查表得出的。 如何修复 Setup 违例? Setup 违例通常是因为数据跑得太慢,修复的核心思路:让数据跑得更快,或者给数据更多的时间。 优化组合逻辑: 这是前端设计中最治本的方法。减少两个触发器之间的逻辑门级数,或者在长路径中间插入新的寄存器,把一条长路切分成两段短路。 缩短物理线长: 在布局阶段,通过算法将有数据交互的 Cell 摆放得更近,能最显著地降低延迟。这是最根本的物理修复手段。 用更快的标准单元: 将路径上的逻辑门替换为阈值电压更低(Low-Vt,速度快但漏电大)的单元,或者换用尺寸更大、驱动能力更强的单元(Upsize),以加快信号翻转速度。 降低时钟频率: 如果所有手段用尽依然无法满足,最后的妥协方案就是降频(增大时钟周期)。 如何修复 Hold 违例? Hold违例通常是因为数据跑得太快,核心思路:让数据跑得慢一点。 插入缓冲器或延迟单元: 这是最常用、最有效的方法。在数据跑得太快的路径上人为串联几个 Buffer 或 Delay Cell,强行增加物理延迟,让数据晚一点冲到终点。 更换更慢的标准单元: 将路径上的单元替换为高阈值电压(High-Vt,速度慢但极省电)的单元,或者换用尺寸较小、驱动能力较弱的单元(Downsize)。该方法还能优化芯片功耗和面积。 Global Placement 阶段为什么只关注 Setup 违例? 在GP阶段,EDA 工具通常会忽略或关闭 Hold 修复功能,全力以赴解决 Setup 问题。原因主要有:

Zotero + Obsidian 文献阅读与笔记工作流

以前一直都是在 ReadPaper 上阅读文献,然后在 Obsidian 总结文献内容,翻译软件使用的是 沙拉查词插件 + Quicker。自从 Google 浏览器升级后,已经无法使用沙拉查词插件了 且 ReadPaper自带的翻译有次数限制(也不好用),故打算切换文献阅读软件为 Zotero(该软件有翻译插件,通过配置 API 可调用Gemini、GPT 来实现准确的翻译)。此外,Obsidian 中也有插件可以直接导出 Zotero 内的指定文献中的批注,从而能够在 Obsidian 中快速梳理文献内容并形成笔记(再也不用手动截图文献中的批注啦!)。 Zotero配置 配置步骤如下所示: 在 Zotero官网 下载软件并进行安装 点击 编辑→设置→高级 修改数据库存储位置(这一步可选,默认是将数据放在 C 盘的) 打开 https://zotero-chinese.com/plugins/ 下载插件: Translate for Zotero、Better BibTeX for Zotero 打开 Google AI Studio ,申请 Gemini 密钥 (GPI或其他AI的申请地址自行Google) 点击 编辑→设置→翻译 下划到服务,选择你要使用的翻译服务并填入对应密钥 在 翻译 这一栏上划到通用,取消勾选 自动翻译选择 内容,这样设置后,只有按下 Ctrl+T 时才会翻译选中内容(这一步可选) Obsidian配置 配置步骤如下所示: 在 Obsidian 中下载第三方插件 Zotero Integration 在插件配置中,对于 PDF Utility 一栏点击后面的 Download;Database 一栏选择 Zotero;Note Import Location 一栏选择你要存放导出内容的目录

Velox_控制模块

概述 配置模块的作用为提供一个类型安全、集中式管理应用程序配置项的方式,允许开发者定义任意类型的配置变量,为它们设置默认值,并通过YAML文件方便地加载和修改这些配置。 该模块的核心设计思想是将每一个配置项抽象为一个ConfigVar对象。所有这些对象都由一个单例管理的Config类进行统一存储和访问。这种设计避免了配置项散落在代码各处,使得配置的管理、维护和查阅变得非常方便。 该模块主要由以下几部分构成: ConfigVarBase: 一个抽象基类,定义了所有配置变量的通用接口,如获取名称、描述、类型名以及与字符串的双向转换(序列化/反序列化)。 ConfigVar<T>: 继承自ConfigVarBase的模板类。它是配置变量的具体实现,能够存储任意类型 T 的值。它还实现了一个回调机制,当配置值发生变化时,可以通知所有监听者。 TypeConverter: 一系列模板类及其偏特化,用于在各种C++类型(包括基本类型、STL容器如vector, list, map, set等)和字符串之间进行转换。该模块默认使用 boost::lexical_cast 进行基础类型转换,并为复杂容器类型提供了基于 yaml-cpp 的序列化和反序列化实现。对于自定义类型,只需完成对应的偏特化即可进行转换。 Config: 一个管理类,它包含一个静态的unordered_map用于存储所有的配置变量。它提供了全局的静态方法来创建、获取和加载配置项,是与本模块交互的主要入口。 本模块通过yaml-cpp库解析YAML文件,再将从.yml中解析出来的结构化数据更新到对应的ConfigVar变量中。 主要特性 类型安全: 每个配置项在定义时都强绑定一个类型,在获取时会进行动态类型检查,防止了类型不匹配导致的运行时错误。 集中式管理: 所有配置项都通过一个全局的Config管理器进行注册和访问,便于追踪和管理。 支持复杂数据结构: 内置了对 std::vector, std::list, std::set, std::unordered_set, std::map, std::unordered_map 等常用STL容器的序列化和反序列化支持。 基于YAML: 使用广泛流行的YAML格式作为配置文件,语法清晰,支持复杂数据结构。 动态更新与回调: 支持在运行时通过加载YAML文件来更新配置值。当某个配置值发生变化时,可以触发预先注册的回调函数,使应用程序能够动态地响应配置变化。 重要函数介绍 Config类 getDatas() 1 2 3 4 5 6 7 8 9 using ConfigVarMap = std::unordered_map<std::string, ConfigVarBase::ptr>; /** * @brief 返回所有的配置项 */ static ConfigVarMap& getDatas() { static ConfigVarMap s_datas; return s_datas; } 这里的数据存储的是基类指针ConfigVarBase::ptr,这是典型的多态设计。因为ConfigVar<T> 是模板类,如果用的是std::unordered_map<std::string, ConfigVar<T>::ptr>;则只能放一种类型的配置变量(比如 int、std::string)。
0%