我通过我的 comp-arch 课程绞尽脑汁,并重新阅读了 wiki 关于硬件寄存器的文章(它们是触发器,我明白了),但一年后,我仍然不明白寄存器的物理意义,除此之外细节。它在处理器的什么位置?他们看起来怎么样?他们多大?
试探性地(假设这不值得提出第二个问题),我还问:来自系统其余部分的数据如何进入寄存器?
我通过我的 comp-arch 课程绞尽脑汁,并重新阅读了 wiki 关于硬件寄存器的文章(它们是触发器,我明白了),但一年后,我仍然不明白寄存器的物理意义,除此之外细节。它在处理器的什么位置?他们看起来怎么样?他们多大?
试探性地(假设这不值得提出第二个问题),我还问:来自系统其余部分的数据如何进入寄存器?
我仍然不明白物理上的寄存器是什么......它在处理器上的什么地方?他们看起来怎么样?他们多大?
从物理上讲,它是由构成处理器中所有其他逻辑的相同结构制成的。取决于实现方式,可以是在硅晶片上创建的晶体管,也可以是分立晶体管,或者真空管、霓虹灯、机电继电器等。
现代 CPU 可能有数十亿个微型晶体管和多个内核,这使得发现单个寄存器及其与其他部分的关系变得很棘手。然而,相同的原理也适用于更简单的 CPU,例如Intel 8080A,如下所示。
标记为“16 位寄存器阵列”的区域包含构成 BC、DE、HL、SP 和 PC 寄存器的触发器。它们靠近 ALU 和地址缓冲区,以便与这些子部分进行快速通信。寄存器可以通过三态缓冲器连接到内部 8 位总线,以访问累加器、ALU 和外部数据总线,或连接到地址缓冲器以寻址外部存储器。
芯片尺寸为 4.28 mm x 4.18 mm,因此整个寄存器阵列占用的面积约为 1.2 mm 2。
去除金属化层并放大后,我们可以看到寄存器的精细结构。由此应该可以识别单个晶体管并得出每个寄存器的等效电子电路。
当然,这种模式是特定于这个特定芯片的结构和布局的——另一个 CPU 可能看起来完全不同。但不变的是功能。不管它在物理上是如何实现的,寄存器在逻辑上仍然做同样的工作。
你已经把大部分都记下来了。让我们从这里开始:计算机处理器中有数十亿个晶体管。其中许多晶体管用于创建寄存器。这是寄存器构建块的基本描述,从最小到最大:
晶体管:
有许多不同类型的晶体管。为简单起见,以下描述将仅使用 MOSFET。MOSFET 是一种电压控制开关——您可能已经对它们有一个基本的了解。
与非门:
与非门是一种“通用”逻辑门。“通用”是指您可以使用它们来构建任何其他类型的逻辑门。NAND门由MOSFET组成,如下所示:
拖鞋:
触发器是一种设备,最简单的形式是由两个 NAND 门组成:
添加另一个连接以充当反相器的 NAND 门以及另外两个 NAND 门以允许启用信号将上述“Set-Reset”触发器转换为“D-type”触发器:
这是一个基本锁存器,每当切换“时钟”(或“启用”)引脚时,它会在输出“Q”处锁存输入“D”的当前状态。这种 D 型触发器是一个 1 位寄存器,这意味着它可以在其输出上存储一位数据。
登记:
寄存器只是这些触发器的集合,如下所示:
上图显示了 4 个触发器,这意味着可以存储 4 位数据。这是一个 4 位寄存器。数据总线由 D0 到 D3 四个输入组成。当信号 D0 到 D3 被施加到输入并且“CP”(时钟脉冲)输入被切换时,触发器(寄存器)的输出保持与 D0 到 D3 相同的状态。时钟脉冲被施加,即使在输入改变之后。它们将保持锁定状态,直到“CP”再次切换到 D0 到 D3 输入的新值。
您可以根据需要将尽可能多的这些触发器放在一起,以创建不同大小的寄存器。现在计算机的两种常见尺寸是 32 位(意味着处理器内的每个寄存器中有 32 个触发器)和 64 位(每个寄存器 64 个触发器)。
涉及的内容更多,但希望这能让您对物理世界中的寄存器有一个基本的了解。如果您有兴趣深入研究并投入一些实际时间来学习,我强烈推荐YouTube 上Ben Eater 的“构建 8 位面包板计算机”系列。
其他人已经完成了让我印象深刻的回答你的第一个问题的合理工作,所以我将专注于你的第二个问题。这是构建 CPU 的一种方法的粗略想法。
这是假设 x86 的一般顺序的 CPU,其中许多操作指定源和目标寄存器,其中源字段真正指定源和目标。也就是你把指定的源寄存器和目的寄存器作为输入,按照指令的规定修改它们,把结果存入指定的目的。
所以在这张图片中,我没有尝试显示指令解码器,只显示三个主要字段:源、目标和操作码字段。源和目标字段各自选择一个寄存器来读取,并馈送到所有功能单元。然后操作码字段选择保留哪些结果。目标字段也被馈送到解复用器以选择将结果写入哪个寄存器。
对于源 1、源 2 和目标具有单独字段的 CPU,目标字段将连接到解复用器,源 1 和源 2 字段将连接到前两个多路复用器。
旁注:将操作数提供给所有执行单元并使用多路复用器选择保留哪些操作数的技术主要用于相对较小的 CPU,至少在我的经验中是这样。举几个例子,这在 6502 和(至少某些版本的)Xilinx Picoblaze 中都使用了。
对于“更大”的 CPU,您可以使用连接到操作码字段的解复用器,为每个执行单元提供一条启用线。在这种情况下,您可以在输出和连线或结果上使用下拉。
当然,现代高端 CPU 的结构要复杂得多。特别是,在同时执行多条指令的情况下,您的结果通常会被写入一大堆重命名寄存器,每个执行单元都有一个单独的解复用器1,因此在一个周期中,您可能会做一个加法,将其结果存放在一个寄存器中,然后也是一个将其结果存放在不同寄存器中的乘法。
哦,当然,这只是显示真实指令的一个子集。在真正的 CPU 中,您通常会拥有更多的数量。同样,您可能很容易拥有超过 8 个寄存器。不过,这并不会真正影响结构,只会影响复用器/解复用器的宽度。
1. 好吧,由于这些宽多路复用器和解复用器可能相当昂贵,因此您通常实际上并没有为每个执行单元单独设置解复用器。相反,你可能有,比如说,六组左右的执行单元,每组都有一个 demux 来选择它的目的地,最多允许六个指令并行执行。
看看 Ben Eater 关于从逻辑门构建 8 位计算机的 YouTube 系列。我觉得这很有趣,我想你也可能会。
https://www.youtube.com/playlist?list=PLowKtXNTBypGqImE405J2565dvjafglHU
他构建的计算机包含两个寄存器,他解释了它是如何从逻辑门开始工作的。他的频道上有另一个视频更进一步:如何用晶体管构建逻辑门(按标题;我还没看过):
https://www.youtube.com/watch?v=sTu3LwpF6XI
计算机构建系列只是观看您感兴趣的部分。我就是这么看的,虽然最后我都看过了。如果你不想,你不必端到端地观看它。