根据AVR微控制器的数据表以及AVR架构指令集的数据表,某些指令(例如ADD
(可以在仅1个时钟转换到ALU期间获取存储在GP寄存器中的2个操作数。ADD
指令的指令词包括 GP 寄存器的 2 个地址;每个 5 位宽,一个用于目标/源,一个用于源。但是,这如何在硬件级别实现呢?当 2 寄存器的 5 位尝试通过同一直接寻址总线访问 GP 寄存器时,它们不会相互干扰吗?
多端口寄存器文件广泛用于CPU设计。 正如维基百科所说:
现代基于集成电路的寄存器文件通常通过具有多个端口的快速静态RAM来实现。
快速的谷歌搜索发现了一些幻灯片,其中包含有关多端口SRAM单元的一些栅极/晶体管级详细信息,以及如何从中构建寄存器文件的框图。
这根本不是AVR独有的。 流水线RISC CPU通常设计为在没有停滞的情况下每个时钟执行(至少(1条指令,寄存器文件每个周期处理2次读取+1次写入。 例如MIPS和其他经典的5级RISC流水线。 AVR只是这些想法的8位版本。
@Margaret Bloom指出,多端口寄存器文件并不是唯一的实现策略。 鉴于AVR的时钟速度较慢,寄存器文件可以是单端口的,并且只是时钟更快。
现代超标量 CPU 具有更宽的寄存器文件。
例如,(https://www.agner.org/optimize/blog/read.php?i=857( 英特尔 Skylake 可以维持每个时钟周期读取至少 7 个 GP 整数寄存器的吞吐量,同时在同一时钟周期内写入 3 个寄存器。 (并写入 FLAGS 3 次,这要归功于寄存器重命名打破了 WAW(写后写(危害。 虽然这并不算是分开的;生成寄存器和 FLAGS 输出的 uops 可以使用相同的物理寄存器条目来保存两者。 RAT 会跟踪来自何处的内容。
(在现代英特尔上,不同的环路每个时钟周期可以轻松写入 4 个寄存器;我链接的实验主要是测试每个时钟可以获得多少寄存器读取,以及未融合域 uop 吞吐量。