双发射流水线:一个周期发射两条独立指令
超标量(Superscalar)处理器是现代CPU的核心技术——它在一个时钟周期内同时发射多条指令到不同的执行单元。与增加时钟频率不同,超标量通过指令级并行(ILP)提升性能。
| 特性 | 标量流水线 | 双发射超标量 | 4发射超标量 |
|---|---|---|---|
| 理论IPC | 1 | 2 | 4 |
| 执行单元数 | 1 | 2 | 4+ |
| 寄存器堆端口 | 2R1W | 4R2W | 8R4W |
| 硬件复杂度 | 1× | ~2.5× | ~6× |
| 实际IPC | 0.7-0.9 | 1.2-1.8 | 2.0-3.5 |
双发射处理器在发射阶段(Issue)检查两条指令是否可以同时执行:
// Lesson 31: Superscalar Dual-Issue Pipeline
// 双发射顺序流水线:每周期发射0/1/2条指令
module superscalar_dual #(
parameter DATA_W = 32
)(
input wire clk, rst_n,
input wire [DATA_W-1:0] imem_rdata_i,
input wire [DATA_W-1:0] pc_i,
input wire imem_valid_i,
input wire [4:0] rs1_idx_i, rs2_idx_i, rs3_idx_i, rs4_idx_i,
input wire [DATA_W-1:0] rf_rs1_i, rf_rs2_i, rf_rs3_i, rf_rs4_i,
input wire [6:0] opcode1_i, opcode2_i,
input wire issue1_valid_i, issue2_valid_i,
output reg [DATA_W-1:0] alu_result1_o, alu_result2_o,
output reg issue1_o, issue2_o,
output reg stall_o
);
localparam [3:0] OP_ADD=0, OP_SUB=1, OP_AND=2, OP_OR=3,
OP_XOR=4, OP_SLL=5, OP_SRL=6, OP_SLT=7;
reg [3:0] op1, op2;
reg [DATA_W-1:0] op_a1, op_b1, op_a2, op_b2;
reg raw_hazard;
// RAW冒险检测:inst2读inst1写的寄存器
always @(*) begin
raw_hazard = 1'b0;
if (issue1_valid_i && issue2_valid_i) begin
if ((rs3_idx_i == rs1_idx_i && rs1_idx_i != 5'd0) ||
(rs4_idx_i == rs1_idx_i && rs1_idx_i != 5'd0) ||
(rs3_idx_i == rs2_idx_i && rs2_idx_i != 5'd0) ||
(rs4_idx_i == rs2_idx_i && rs2_idx_i != 5'd0))
raw_hazard = 1'b1;
end
end
// 发射逻辑:无冒险→双发射,有冒险→单发射+停顿
always @(*) begin
stall_o = 1'b0; issue1_o = 1'b0; issue2_o = 1'b0;
if (issue1_valid_i && issue2_valid_i && !raw_hazard) begin
issue1_o = 1'b1; issue2_o = 1'b1; // 双发射!
end else if (issue1_valid_i) begin
issue1_o = 1'b1;
if (issue2_valid_i && raw_hazard)
stall_o = 1'b1; // inst2停顿
end
end
// 双ALU执行单元
always @(*) begin
op_a1 = rf_rs1_i; op_b1 = rf_rs2_i;
case (op1)
OP_ADD: alu_result1_o = op_a1 + op_b1;
OP_SUB: alu_result1_o = op_a1 - op_b1;
OP_AND: alu_result1_o = op_a1 & op_b1;
OP_OR: alu_result1_o = op_a1 | op_b1;
OP_XOR: alu_result1_o = op_a1 ^ op_b1;
OP_SLL: alu_result1_o = op_a1 << op_b1[4:0];
OP_SRL: alu_result1_o = op_a1 >> op_b1[4:0];
OP_SLT: alu_result1_o = ($signed(op_a1) < $signed(op_b1))
? 1 : 0;
default: alu_result1_o = op_a1 + op_b1;
endcase
end
// ALU2结构相同...
endmodule
| 处理器 | 发射宽度 | 执行单元 | 流水线级数 | IPC |
|---|---|---|---|---|
| ARM Cortex-A53 | 2 | 2 ALU + 1 FPU | 8 | ~1.5 |
| ARM Cortex-A76 | 4 | 4 ALU + 2 FPU | 13 | ~3.0 |
| RISC-V Rocket | 1 | 1 ALU | 5 | ~0.7 |
| RISC-V BOOM | 3-4 | 3 ALU + 2 FPU | 10-15 | ~2.5 |
| Apple M1 Firestorm | 8 | 8+ 执行单元 | 14 | ~5.0 |
| Intel Alder Lake P-core | 6 | 6 ALU + 3 FPU | 17 | ~4.0 |