寄存器重命名

本文详细介绍了寄存器重命名技术在乱序执行流水线中的作用,包括消除指令间的数据相关性和保证指令执行异常情况下的现场精确。讨论了软件和硬件寄存器重命名的两种方法,并详细解释了重命名寄存器和结构寄存器的分离及合并方式。

寄存器重命名技术在乱序执行流水线中有两个作用。一是消除指令之间的寄存器读后写相关(WAR),和写后写相关(WAW);二是当指令执行发生例外或转移指令猜测错误而取消后面的指令时可以保证现场的精确。

寄存器重命名的思路很简单:就是当一条指令写一个结果寄存器时不直接写到这个结果寄存器,而是先写到一个中间寄存器过渡一下,当这条指令提交的时候再写到结果寄存器中。


指令重命名有两种方法:软件重命名和硬件重命名方法。


  • 软件寄存器重命名方法  是在编译的过程中消除指令集的数据相关的方法:

例如,具体示例如下,Addy 摘自胡老总《计算机体系结构》(相同颜色为 寄存器相关):

通过软件方法,在编译过程中将寄存器相关的部分,通过软件寄存器重命名的方法解决部分寄存器相关,增大了指令间的并行性。

如下图所示为 软件修改结果。



  • 硬件寄存器重命名方法   大致可以分成两种,一是把重命名寄存器和结构寄存器分开;二是不把重命名寄存器和结构寄存器分开。

          重命名寄存器(程序员不可见微结构寄存器)和结构寄存器(程序员可见寄存器)。

        重命名寄存器和结构寄存器独立方式 如图:


• 重命名寄存器的状态

          EMPTY:表示该寄存器没有被重命名(重命名后又已经被释放)。
          MAPPED:表示已经被重命名但结果没有写回。
          WRITEBACK:表示结果已经写回重命名寄存器但没有Commit到结构寄存器。

• 结构寄存器的状态

         VALID:表示相应寄存器的值可用。
         INVALID:表示相应寄存器的值不可用。

• 映射关系
        可以在结构寄存器中增加一个指向重命名寄存器的重命名寄存器号域。


    重命名寄存器和结构寄存器合并方式(寄存器堆)如图:


• 核心是重命名表
       可以用CAM或RAM的方法,以CAM的方法为例。
       项数与物理寄存器一样。
       主要包括三个域:
           name:相应的逻辑寄存器号。
           state:状态,EMPTY:表示该寄存器没有被重命名(重命名后又已经被释放);MAPPED:表示已经被重命名但结果没有写回;WRITEBACK:表示结果已经写回重命名寄存器但没有Commit到结构寄存器;COMMIT:表示结果已经被确认。
          valid:在一个逻辑寄存器对应多个物理寄存器的情况下表示最新映。

### 寄存器重命名的实现方法与Verilog中的应用 寄存器重命名是一种用于消除指令间伪依赖的技术,在硬件设计中广泛应用于提高流水线效率。通过引入物理寄存器来替代逻辑寄存器,可以有效减少写后读(WAR)和读后写(RAW)冲突的影响[^2]。 #### 原理概述 在寄存器重命名过程中,每条指令的目标寄存器会被映射到一个新的物理寄存器上,而不是直接覆盖原有的逻辑寄存器值。这种映射关系由重命名表(Renaming Table 或 RAT, Register Alias Table)维护,并随着指令执行动态更新[^3]。对于后续需要使用该目标寄存器作为源操作数的指令,则可以通过查询RAT获取最新的物理寄存器地址[^1]。 #### Verilog 中的具体实现方式 以下是基于上述理论的一个简单 Verilog 实现框架: ```verilog module register_renaming ( input wire clk, input wire reset, // 输入端口:新指令的信息 input wire [4:0] src_reg_1_in, // 源寄存器1编号 (逻辑寄存器号) input wire [4:0] src_reg_2_in, // 源寄存器2编号 (逻辑寄存器号) input wire [4:0] dest_reg_in, // 目标寄存器编号 (逻辑寄存器号) output reg [7:0] phys_src_reg_1_out, // 映射后的物理寄存器1地址 output reg [7:0] phys_src_reg_2_out, // 映射后的物理寄存器2地址 output reg [7:0] new_phys_dest_reg_out // 新分配的物理寄存器地址 ); // 物理寄存器数量定义 localparam NUM_PHYS_REGS = 64; // 定义重命名表 (RAT),存储逻辑寄存器 -> 物理寄存器的映射 reg [7:0] rat_table [0:31]; // 假设有32个逻辑寄存器 // 自由物理寄存器队列 reg [7:0] free_list [$]; initial begin for (int i = 0; i < NUM_PHYS_REGS; i++) begin free_list.push_back(i); // 初始化自由列表 end end always @(posedge clk or posedge reset) begin if (reset) begin // 复位处理 for (int j = 0; j < 32; j++) begin rat_table[j] <= 8'd0; end free_list.clear(); for (int k = 0; k < NUM_PHYS_REGS; k++) begin free_list.push_back(k); end end else begin // 查找并替换源寄存器对应的物理寄存器 phys_src_reg_1_out <= rat_table[src_reg_1_in]; phys_src_reg_2_out <= rat_table[src_reg_2_in]; // 分配新的物理寄存器给目标寄存器 if (!free_list.empty()) begin new_phys_dest_reg_out <= free_list.pop_front(); // 获取一个可用的物理寄存器 rat_table[dest_reg_in] <= new_phys_dest_reg_out; // 更新RAT表 end end end endmodule ``` 此模块实现了基本的功能需求,包括: - **输入解析**:接收当前指令所需的逻辑寄存器编号。 - **查找映射**:利用RAT查找对应于逻辑寄存器的实际物理寄存器地址。 - **资源管理**:从空闲物理寄存器池中取出下一个可使用的寄存器,并将其绑定至指定逻辑寄存器。 #### 关键技术点解释 1. **重命名表初始化** 在系统启动时或者遇到复位信号时,需重新设置所有的逻辑寄存器指向固定的初始物理寄存器位置[^4]。 2. **自由物理寄存器跟踪** 使用 FIFO 队列记录尚未被占用的物理寄存器索引,以便快速响应新请求的同时保持状态一致性。 3. **同步更新机制** 当前周期完成的新映射应当立即反映在未来所有涉及相同逻辑寄存器的操作之中。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值