英特尔8087浮点芯片核心的加法器

Hacker News Top 新闻

摘要

本文逆向工程分析了1980年英特尔8087浮点协处理器的核心69位加法器,阐释了其架构和进位链技术。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/13 17:18

# 英特尔 8087 浮点芯片核心的加法器 来源:https://www.righto.com/2026/06/intel-8087-adder-reverse-engineered.html 1980 年,英特尔发布了 8087 浮点协处理器,这款芯片能将数学运算速度提升高达 100 倍。除了算术运算和平方根,8087 还能计算包括正切、指数和对数在内的超越函数。而这一切都依赖于一个 69 位的加法器:正如其专利 (https://patents.google.com/patent/USRE33629E) 所描述的,“浮点执行单元的算术核心围绕着一个由加法器及其相关寄存器、移位器和控制电路构成的纳米机器”。在本文中,我将解释这个加法器的电路结构。 下面的显微照片展示了 8087 芯片的裸片。在裸片边缘,发丝般的键合线将芯片连接到它的 40 个外部引脚。裸片上复杂的图案由金属布线以及下方的多晶硅和硅层形成。在芯片顶部,总线接口单元连接到系统的其余部分,与主 8086 处理器和内存协调工作。芯片的指令由中间巨大的微码 ROM 定义。 ![](https://static.righto.com/images/8087-adder/8087-die-labeled.jpg) 英特尔 8087 浮点单元芯片的裸片,标注了相关的功能模块。裸片尺寸为 5mm×6mm。点击查看大图。 裸片的下半部分是“数据通路”,即执行计算的电路;它分为指数数据通路(处理浮点数的指数)和尾数数据通路(处理小数部分,或称有效数字)。加法器(红色)位于尾数数据通路的中间;要对指数执行加法,必须先将指数复制到尾数数据通路。 ## 加法器的结构 构建一个二进制加法器很容易;难点在于让它变快。关键问题是如何处理从一个位到下一个位的进位。每个进位可能依赖于所有较低位的进位,但你不能等待进位在所有 69 位上像链式反应一样逐级传播(这就像用竖式加法计算 999999+1:你需要不断地进位、进位、进位……)。 8087 的加法器通过将加法分解为 4 位一组的块来提升性能,并使用两种技术使块内的计算变得快速。进位需要在块之间传播,但这将进位步骤的数量减少了四倍。 ![](https://static.righto.com/images/8087-adder/overall-diagram.jpg) 8087 加法器中一个 4 位块的简化示意图。 上图展示了一个 4 位块的结构,进位生成电路暂时被抽象出来。加法器有两个输入:一个(`F`)来自芯片的尾数总线,这是一条连接尾数数据通路各组件的总线;第二个输入(`B`)来自一个称为 B 寄存器的寄存器。和的每一位都是通过异或 `F` 输入、`B` 输入以及该位的进位得到的。¹ 稍后会解释,中间值(`F XOR B`)被称为“传播”。每个块的进位输出连接到下一个块的进位输入。那么进位电路内部发生了什么? 1959 年,曼彻斯特大学的研究人员为名为 Atlas 的计算机开发了一种快速进位技术。这种技术被称为曼彻斯特进位链,它通过并行设置开关,然后让进位在开关控制下快速通过导线传播来计算进位值。尽管进位仍然需要逐位传播,但它是沿着导线以信号速度传播的,而不受逻辑门的延迟影响。² 曼彻斯特进位链建立在“生成”“传播”和“删除”(也称为“杀死”)三个概念之上,这些概念在将两个位和一个进位相加时产生。如果你加 `1+1`,无论是否有进位输入,都会*生成*一个进位输出。相反,如果你加 `0+0`,无论进位输入如何,都不会有进位输出;任何进位输入都会被*删除*。有趣的情况是加 `0+1`:只有在有进位输入时才会产生进位输出;也就是说,进位输入被*传播*到进位输出。在逻辑上,生成信号是两位输入的与,删除信号是或非,传播信号是异或。重要的是,这些信号可以在恒定时间内对所有位位置并行计算。 ![](https://static.righto.com/images/8087-adder/manchester.jpg) 曼彻斯特进位链背后的思路。注意低位在左边,因此进位从左向右流动。 曼彻斯特进位链如上图构建,每个位的开关根据生成/传播/删除值设置。一旦开关设置好,进位状态就会快速流过电路,产生每个位置的进位值,没有任何逻辑延迟。如果传播开关闭合,前一个进位就会通过。但如果生成或删除开关闭合,进位则分别被置位或清零。一旦进位值可用,最终的和就可以通过异或门并行计算。 8087 使用了一种针对曼彻斯特进位链优化的电路,将生成和删除情况合并。下面展示了加法器进位链的一级。对于传播情况,进位输入 `Cin` 通过顶部开关,传播到进位输出 `Cout`。对于生成和删除情况,底部开关闭合,传递输入位 `F`。诀窍在于:生成情况对应 `1+1`,因此 `F` 为 1,导致 `Cout` 被置位;删除情况对应 `0+0`,因此 `F` 为 0,`Cout` 被清零。(注意,这两种情况下两个输入 `F` 和 `B` 相同,因此使用 `F` 而不是 `B` 是任意的。) ![](https://static.righto.com/images/8087-adder/mux-stage.jpg) 曼彻斯特进位链的一级。 图中的中间部分展示了开关如何对应一个多路选择器(mux):如果 `prop` 置位,选择顶部信号 `Cin`;如果 `prop` 清零,选择底部信号 `F`。右侧部分展示了使用两个 NMOS 晶体管的物理实现。这些晶体管充当开关(传输门),由 gate 上的 `prop` 信号控制。 问题是传输门并非完美开关,每一步都会损失一点电压。为了解决这个问题,进位链被分割成 4 位一组(如前所示),每个块产生一个“新鲜”的进位。这种刷新是通过一个“进位跳过”电路完成的,该电路可以跳过块内的进位处理。具体来说,进位跳过机制检查块内所有位置是否都是传播。在这种情况下,进位输出将与进位输入具有相同的值(因为进位输入传播通过了块的所有位位置)。进位跳过电路检测到这种情况,并产生一个与进位输入匹配的进位输出信号。 综合起来,下面的原理图显示了一个典型的 4 位块的加法器电路。四个多路选择器构成了曼彻斯特进位链,而或非门检测进位跳过情况。 ![](https://static.righto.com/images/8087-adder/block-schematic.jpg) 加法器 4 位块的反向工程原理图。 为了优化性能,出于电气原因还存在一个复杂情况。³ 8087 使用 NMOS 晶体管,它将信号拉低的速度远快于将信号拉高。为了提升性能,进位线在加法开始前被预充电到 5V,然后电路在需要时将线拉低。为了以无进位状态开始,所有进位线都被取反,因此初始的 5V 状态对应无进位,而接地状态对应有进位。 块中的最后一个多路选择器有四个输入而不是两个⁴。第三个输入在进位跳过情况下将(取反的)进位线拉低⁵。第四个输入是 `precharge` 信号;它将 5V 施加到进位线上以进行预充电。(控制电路在加法周期开始时激活预充电信号。)注意,这只预充电了一条进位线;为了预充电其余进位线,传播信号在预充电期间被强制拉高。 ![](https://static.righto.com/images/8087-adder/prop-schematic.jpg) 传播电路的反向工程原理图。这里展示的是任意位 `n`。 生成 `propagate` 信号的电路(上图)在概念上是两个输入的异或,但(当然)存在一些复杂情况。当 `precharge` 信号为高时,`propagate` 被强制拉高,将所有进位线连接在一起,以便预充电可以传播到所有进位线。第二个特点是 `B` 输入可以被 `forceZero` 信号阻塞,因此添加的是值 0 而不是 `B` 值。 总之,加法器被划分为 4 位一组。每个块使用曼彻斯特进位链和进位跳过电路来优化性能。然而,即使有这些优化,大量的块仍然要求 8087 花费两个时钟周期来完成一次加法。 ## 硅片中的加法器 下图展示了 4 位块的电路如何在裸片上呈现。这些块垂直堆叠,形成了早期裸片照片中所见的完整加法器。在这张图片中,金属层可见为白色线条,大部分遮挡了下方的电路。8087 只有单一金属层,这限制了布局。注意金属布线非常密集,几乎占据了整个区域。左侧的粗垂直金属迹线是地线,而右侧的粗金属迹线是电源线,为加法器电路供电。水平迹线提供了加法器块内部的布线,并允许尾数总线穿过加法器。两侧的垂直线条是加法器的控制信号(`precharge` 和 `forceZero`),以及连接到芯片底部电路的连接。 ![](https://static.righto.com/images/8087-adder/adder-block-metal.jpg) 加法器中的 4 位块。 下面的照片展示了金属层下方的硅和多晶硅电路。(为了拍摄这张照片,我用酸溶解了金属层。)细线是多晶硅布线,而粉红色凸起的区域是掺杂硅。当多晶硅穿过掺杂硅时,就形成了一个晶体管。电路复杂且不规则,通过上方的水平金属线连接。白色的电路是硅与金属布线之间的接触点,而白色方块是多晶硅与金属之间的接触点。大致来说,如果将上方的电路分成四等份,每个四分之一负责一位。进位跳过电路位于中间。 ![](https://static.righto.com/images/8087-adder/adder-block-die.jpg) 去除金属层后加法器中的 4 位块。 图像的左侧和右侧没有晶体管,只有多晶硅线在垂直金属布线下方穿过。这些多晶硅线中的许多被加宽以降低其电阻,从而调整性能。这些区域的硅被“浪费”了,只是为垂直布线提供通道。 尽管 8087 名义上使用 64 位的尾数(有效数字),但加法器略大:它接收 69 位输入并产生 70 位输出。一个原因是 8087 使用了三个额外的低位用于舍入,称为 Guard、Round 和 Sticky。这些位确保值总是向正确的方向舍入。舍入位的处理相当复杂,具有多种模式,但从加法器的角度来看,它们只是三个输入位⁶。 如下所述,来自 B 寄存器的值可以加倍,这需要多一位。最后,尾数总线和 B 值可以被取反(这用于减法等情况)。负值以二进制补码表示,这需要多一位。总体而言,加法器的输入是 69 位宽。 当将两个大数相加时,结果可能需要多一位。因此,加法器的输出是 70 位宽。和移位器(下面解释)可以将输出右移两位,将结果缩减为 68 位。这仍然比 64 位加上 3 个舍入位多一位;这个“额外”位由几个专用寄存器支持,例如 `tmpC` 寄存器⁷ 和跳过移位器。 ## 外围电路 加法器的输入和输出连接到一些专用寄存器和电路。我将把对这些电路的详细解释留到另一篇文章中,但这里先做一个简要描述⁸。加法器有两个输入:一个来自尾数总线,另一个来自 B 寄存器。加法器的输出存储在求和寄存器中。为了加快乘法速度,8087 使用了基 4 的布斯乘法 (https://www.geoffknagge.com/fyp/booth.shtml), 每次乘以两位。乘数存储在跳过移位器中,这是一个允许一次移出两位的寄存器。基于这些位,会添加 `2B`、`B`、`0` 或 `-B` 之一(`-B` 路径也用于减法)。加法器的输出由和移位器(不要与跳过移位器混淆)右移两位,并存储在求和寄存器中。 ![](https://static.righto.com/images/8087-adder/adder-regs.jpg) 加法器及相关寄存器。基于专利 (https://patents.google.com/patent/USRE33629E)。 除法通过重复的减法、加法和移位来实现。结果的位积累在商寄存器中。平方根的实现类似于笔算开平方,不过是二进制的。跳过移位器从左侧提供两位,这些位被附加到加法器输入的右侧。类似于除法,执行一次减法或加法,平方根在 B 寄存器中形成。 乘法、除法和平方根需要多个步骤来处理所有位。为了性能,这种循环是在硬件中实现的,而不是在微码中。这些指令需要大量的微码来准备参数、处理指数、处理特殊情况以及存储结果,但内部循环是硬件实现的。 ## 结论 8087 专利 (https://patents.google.com/patent/US4484259A) 阐述了加法器的重要性:“最终,所有算术运算都被归结为...”

相似文章

当GPU读取内存时会发生什么

Hacker News Top

这篇博文详细介绍了NVIDIA RTX 4090上GPU内存读取指令的硬件路径,解释了CUDA内核如何通过L1缓存和DRAM等组件访问内存,以提供性能洞察。