Add register renaming to issue stage

Renaming can be turned on or off with the `ENABLE_RENAME` parameter in
`ariane_pkg.sv`.
This commit is contained in:
Stefan Mach 2018-04-18 14:32:17 +02:00 committed by Florian Zaruba
parent 46399072da
commit c3a4caad8a
No known key found for this signature in database
GPG key ID: E742FFE8EC38A792
5 changed files with 260 additions and 52 deletions

View file

@ -43,6 +43,7 @@ package ariane_pkg;
| (1 << 20) // U - User mode implemented
| (0 << 23) // X - Non-standard extensions present
| (1 << 63); // RV64
localparam ENABLE_RENAME = 1'b0;
// 32 registers + 1 bit for re-naming = 6
localparam REG_ADDR_SIZE = 6;

View file

@ -29,7 +29,7 @@ module issue_read_operands #(
input logic debug_gpr_we_i,
input logic [63:0] debug_gpr_wdata_i,
output logic [63:0] debug_gpr_rdata_o,
// coming from scoreboard
// coming from rename
input scoreboard_entry_t issue_instr_i,
input logic issue_instr_valid_i,
output logic issue_ack_o,

View file

@ -93,48 +93,31 @@ module issue_stage #(
logic [63:0] rs2_sb_iro;
logic rs2_valid_iro_sb;
scoreboard_entry_t issue_instr_sb_rename;
logic issue_instr_valid_sb_rename;
logic issue_ack_rename_sb;
scoreboard_entry_t issue_instr_rename_sb;
logic issue_instr_valid_rename_sb;
logic issue_ack_sb_rename;
scoreboard_entry_t issue_instr_rename_iro;
logic issue_instr_valid_rename_iro;
logic issue_ack_iro_rename;
scoreboard_entry_t issue_instr_sb_iro;
logic issue_instr_valid_sb_iro;
logic issue_ack_iro_sb;
// ---------------------------------------------------------
// 1. Issue instruction and read operand
// ---------------------------------------------------------
issue_read_operands i_issue_read_operands (
.flush_i ( flush_unissued_instr_i ),
.issue_instr_i ( issue_instr_rename_iro ),
.issue_instr_valid_i ( issue_instr_valid_rename_iro ),
.issue_ack_o ( issue_ack_iro_rename ),
.rs1_o ( rs1_iro_sb ),
.rs1_i ( rs1_sb_iro ),
.rs1_valid_i ( rs1_valid_sb_iro ),
.rs2_o ( rs2_iro_sb ),
.rs2_i ( rs2_sb_iro ),
.rs2_valid_i ( rs2_valid_iro_sb ),
.rd_clobber_i ( rd_clobber_sb_iro ),
.*
);
// ---------------------------------------------------------
// 2. Re-name
// 1. Re-name
// ---------------------------------------------------------
re_name i_re_name (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
.issue_instr_i ( issue_instr_sb_rename ),
.issue_instr_valid_i ( issue_instr_valid_sb_rename ),
.issue_ack_o ( issue_ack_rename_sb ),
.issue_instr_o ( issue_instr_rename_iro ),
.issue_instr_valid_o ( issue_instr_valid_rename_iro ),
.issue_ack_i ( issue_ack_iro_rename )
.flush_i ( flush_i ),
.issue_instr_i ( decoded_instr_i ),
.issue_instr_valid_i ( decoded_instr_valid_i ),
.issue_ack_o ( decoded_instr_ack_o ),
.issue_instr_o ( issue_instr_rename_sb ),
.issue_instr_valid_o ( issue_instr_valid_rename_sb ),
.issue_ack_i ( issue_ack_sb_rename )
);
// ---------------------------------------------------------
// 3. Manage issued instructions in a scoreboard
// 2. Manage instructions in a scoreboard
// ---------------------------------------------------------
scoreboard #(
.NR_ENTRIES ( NR_ENTRIES ),
@ -149,9 +132,12 @@ module issue_stage #(
.rs2_o ( rs2_sb_iro ),
.rs2_valid_o ( rs2_valid_iro_sb ),
.issue_instr_o ( issue_instr_sb_rename ),
.issue_instr_valid_o ( issue_instr_valid_sb_rename ),
.issue_ack_i ( issue_ack_rename_sb ),
.decoded_instr_i ( issue_instr_rename_sb ),
.decoded_instr_valid_i ( issue_instr_valid_rename_sb ),
.decoded_instr_ack_o ( issue_ack_sb_rename ),
.issue_instr_o ( issue_instr_sb_iro ),
.issue_instr_valid_o ( issue_instr_valid_sb_iro ),
.issue_ack_i ( issue_ack_iro_sb ),
.trans_id_i ( trans_id_i ),
.wbdata_i ( wbdata_i ),
@ -159,4 +145,22 @@ module issue_stage #(
.*
);
// ---------------------------------------------------------
// 3. Issue instruction and read operand, also commit
// ---------------------------------------------------------
issue_read_operands i_issue_read_operands (
.flush_i ( flush_unissued_instr_i ),
.issue_instr_i ( issue_instr_sb_iro ),
.issue_instr_valid_i ( issue_instr_valid_sb_iro ),
.issue_ack_o ( issue_ack_iro_sb ),
.rs1_o ( rs1_iro_sb ),
.rs1_i ( rs1_sb_iro ),
.rs1_valid_i ( rs1_valid_sb_iro ),
.rs2_o ( rs2_iro_sb ),
.rs2_i ( rs2_sb_iro ),
.rs2_valid_i ( rs2_valid_iro_sb ),
.rd_clobber_i ( rd_clobber_gpr_sb_iro ),
.*
);
endmodule

View file

@ -23,11 +23,12 @@ import ariane_pkg::*;
module re_name (
input logic clk_i, // Clock
input logic rst_ni, // Asynchronous reset active low
// coming from scoreboard
input logic flush_i, // Flush renaming state
// from/to scoreboard
input scoreboard_entry_t issue_instr_i,
input logic issue_instr_valid_i,
output logic issue_ack_o,
// coming from scoreboard
// from/to issue and read operands
output scoreboard_entry_t issue_instr_o,
output logic issue_instr_valid_o,
input logic issue_ack_i
@ -38,28 +39,46 @@ module re_name (
assign issue_ack_o = issue_ack_i;
// keep track of re-naming data structures
logic [31:0] re_name_table_n, re_name_table_q;
logic [31:0] re_name_table_gpr_n, re_name_table_gpr_q;
// -------------------
// Re-naming
// -------------------
always_comb begin
// MSB of the renamed source register addresses
logic name_bit_rs1, name_bit_rs2, name_bit_rd;
// default assignments
re_name_table_n = re_name_table_q;
issue_instr_o = issue_instr_i;
re_name_table_gpr_n = re_name_table_gpr_q;
issue_instr_o = issue_instr_i;
if (issue_ack_i) begin
// if we acknowledge the instruction tic the corresponding register
re_name_table_n[issue_instr_i.rd] = re_name_table_q[issue_instr_i.rd] ^ 1'b1;
// if we acknowledge the instruction tic the corresponding destination register
re_name_table_gpr_n[issue_instr_i.rd] = re_name_table_gpr_q[issue_instr_i.rd] ^ 1'b1;
end
// re-name the source registers
issue_instr_o.rs1 = { re_name_table_q[issue_instr_i.rs1], issue_instr_i.rs1 };
issue_instr_o.rs2 = { re_name_table_q[issue_instr_i.rs1], issue_instr_i.rs2 };
// select name bit according to the register file used for source operands
name_bit_rs1 = re_name_table_gpr_q[issue_instr_i.rs1];
name_bit_rs2 = re_name_table_gpr_q[issue_instr_i.rs2];
// select name bit according to the state it will have after renaming
name_bit_rd = re_name_table_gpr_q[issue_instr_i.rd] ^ (issue_instr_i.rd != '0); // don't rename x0
// re-name the source registers
issue_instr_o.rs1 = { ENABLE_RENAME & name_bit_rs1, issue_instr_i.rs1[4:0] };
issue_instr_o.rs2 = { ENABLE_RENAME & name_bit_rs2, issue_instr_i.rs2[4:0] };
// re-name the destination register
issue_instr_o.rd = { ENABLE_RENAME & name_bit_rd, issue_instr_i.rd[4:0] };
// we don't want to re-name gp register zero, it is non-writeable anyway
re_name_table_gpr_n[0] = 1'b0;
// Handle flushes
if (flush_i) begin
re_name_table_gpr_n = '0;
end
// we don't want to re-name register zero, it is non-writeable anyway
re_name_table_n[0] = 1'b0;
end
// -------------------
@ -67,9 +86,9 @@ module re_name (
// -------------------
always_ff @(posedge clk_i or negedge rst_ni) begin
if (~rst_ni) begin
re_name_table_q <= '0;
re_name_table_gpr_q <= '0;
end else begin
re_name_table_q <= re_name_table_n;
re_name_table_gpr_q <= re_name_table_gpr_n;
end
end
endmodule

View file

@ -28,6 +28,8 @@ class instruction_trace_item;
string priv_lvl;
branchpredict_t bp;
logic [4:0] rs1, rs2, rs3, rd;
// constructor creating a new instruction trace item, e.g.: a single instruction with all relevant information
function new (time simtime, longint unsigned cycle, scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] reg_file [32], logic [63:0] result, logic [63:0] paddr, priv_lvl_t priv_lvl, branchpredict_t bp);
this.simtime = simtime;
@ -40,6 +42,10 @@ class instruction_trace_item;
this.paddr = paddr;
this.bp = bp;
this.priv_lvl = getPrivLevel(priv_lvl);
this.rs1 = sbe.rs1[4:0];
this.rs2 = sbe.rs2[4:0];
this.rs3 = instr[31:27];
this.rd = sbe.rd[4:0];
endfunction
// convert register address to ABI compatible form
function string regAddrToStr(logic [5:0] addr);
@ -241,6 +247,7 @@ class instruction_trace_item;
function string printRInstr(input string mnemonic);
<<<<<<< HEAD
result_regs.push_back(sbe.rd);
read_regs.push_back(sbe.rs1);
read_regs.push_back(sbe.rs2);
@ -257,18 +264,109 @@ class instruction_trace_item;
return $sformatf("%-16s %s, %0d", mnemonic, regAddrToStr(sbe.rd), $signed(sbe.result));
return $sformatf("%-16s %s, %s, %0d", mnemonic, regAddrToStr(sbe.rd), regAddrToStr(sbe.rs1), $signed(sbe.result));
=======
result_regs.push_back(rd);
result_fpr.push_back(1'b0);
read_regs.push_back(rs1);
read_fpr.push_back(1'b0);
read_regs.push_back(rs2);
read_fpr.push_back(1'b0);
return $sformatf("%-12s %4s, %s, %s", mnemonic, regAddrToStr(rd), regAddrToStr(rs1), regAddrToStr(rs2));
endfunction // printRInstr
function string printRFInstr(input string mnemonic, input bit use_rnd);
result_regs.push_back(rd);
result_fpr.push_back(is_rd_fpr(sbe.op));
read_regs.push_back(rs1);
read_fpr.push_back(is_rs1_fpr(sbe.op));
read_regs.push_back(rs2);
read_fpr.push_back(is_rs2_fpr(sbe.op));
if (use_rnd && instr[14:12]!=3'b111)
return $sformatf("%-12s %4s, %s, %s, %s", $sformatf("%s.%s",mnemonic, fpFmtToStr(instr[26:25])), is_rd_fpr(sbe.op)?fpRegAddrToStr(rd):regAddrToStr(rd), is_rs1_fpr(sbe.op)?fpRegAddrToStr(rs1):regAddrToStr(rs1), is_rs2_fpr(sbe.op)?fpRegAddrToStr(rs2):regAddrToStr(rs2), fpRmToStr(instr[14:12]));
else
return $sformatf("%-12s %4s, %s, %s", $sformatf("%s.%s",mnemonic, fpFmtToStr(instr[26:25])), is_rd_fpr(sbe.op)?fpRegAddrToStr(rd):regAddrToStr(rd), is_rs1_fpr(sbe.op)?fpRegAddrToStr(rs1):regAddrToStr(rs1), is_rs2_fpr(sbe.op)?fpRegAddrToStr(rs2):regAddrToStr(rs2));
endfunction // printRFInstr
function string printRFInstr1Op(input string mnemonic, input bit use_rnd);
result_regs.push_back(rd);
result_fpr.push_back(is_rd_fpr(sbe.op));
read_regs.push_back(rs1);
read_fpr.push_back(is_rs1_fpr(sbe.op));
if (use_rnd && instr[14:12]!=3'b111)
return $sformatf("%-12s %4s, %s, %s", $sformatf("%s.%s",mnemonic, fpFmtToStr(instr[26:25])), is_rd_fpr(sbe.op)?fpRegAddrToStr(rd):regAddrToStr(rd), is_rs1_fpr(sbe.op)?fpRegAddrToStr(rs1):regAddrToStr(rs1), fpRmToStr(instr[14:12]));
else
return $sformatf("%-12s %4s, %s", $sformatf("%s.%s",mnemonic, fpFmtToStr(instr[26:25])), is_rd_fpr(sbe.op)?fpRegAddrToStr(rd):regAddrToStr(rd), is_rs1_fpr(sbe.op)?fpRegAddrToStr(rs1):regAddrToStr(rs1));
endfunction // printRFInstr1Op
function string printR4Instr(input string mnemonic);
result_regs.push_back(rd);
result_fpr.push_back(1'b1);
read_regs.push_back(rs1);
read_fpr.push_back(1'b1);
read_regs.push_back(rs2);
read_fpr.push_back(1'b1);
read_regs.push_back(rs3);
read_fpr.push_back(1'b1);
return $sformatf("%-12s %4s, %s, %s, %s, %s", $sformatf("%s.%s",mnemonic, fpFmtToStr(instr[26:25])), fpRegAddrToStr(rd), fpRegAddrToStr(rs1), fpRegAddrToStr(rs2), fpRegAddrToStr(instr[31:27]), fpRmToStr(instr[14:12]));
endfunction // printR4Instr
function string printFpSpecialInstr();
result_regs.push_back(rd);
result_fpr.push_back(is_rd_fpr(sbe.op));
read_regs.push_back(rs1);
read_fpr.push_back(is_rs1_fpr(sbe.op));
case (sbe.op)
FCVT_F2F : return $sformatf("%-12s %4s, %s, %s", $sformatf("fcvt.%s.%s", fpFmtToStr(instr[26:25]), fpFmtToStr(instr[21:20])), fpRegAddrToStr(rd), fpRegAddrToStr(rs1), fpRmToStr(instr[14:12]));
FCVT_F2I : return $sformatf("%-12s %4s, %s, %s", $sformatf("fcvt.%s.%s", intFmtToStr(instr[21:20]), fpFmtToStr(instr[26:25])), regAddrToStr(rd), fpRegAddrToStr(rs1), fpRmToStr(instr[14:12]));
FCVT_I2F : return $sformatf("%-12s %4s, %s, %s", $sformatf("fcvt.%s.%s", fpFmtToStr(instr[26:25]), intFmtToStr(instr[21:20])), fpRegAddrToStr(rd), regAddrToStr(rs1), fpRmToStr(instr[14:12]));
FMV_F2X : return $sformatf("%-12s %4s, %s", $sformatf("fmv.x.%s", fmvFpFmtToStr(instr[26:25])), regAddrToStr(rd), fpRegAddrToStr(rs1));
FMV_X2F : return $sformatf("%-12s %4s, %s", $sformatf("fmv.x.%s", fmvFpFmtToStr(instr[26:25])), regAddrToStr(rd), fpRegAddrToStr(rs1));
endcase
endfunction
function string printIInstr(input string mnemonic);
result_regs.push_back(rd);
result_fpr.push_back(1'b0);
read_regs.push_back(rs1);
read_fpr.push_back(1'b0);
if (rs1 == 0)
return $sformatf("%-12s %4s, %0d", mnemonic, regAddrToStr(rd), $signed(sbe.result));
return $sformatf("%-12s %4s, %s, %0d", mnemonic, regAddrToStr(rd), regAddrToStr(rs1), $signed(sbe.result));
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
endfunction // printIInstr
function string printIuInstr(input string mnemonic);
<<<<<<< HEAD
result_regs.push_back(sbe.rd);
read_regs.push_back(sbe.rs1);
return $sformatf("%-16s %s, %s, 0x%0x", mnemonic, regAddrToStr(sbe.rd), regAddrToStr(sbe.rs1), sbe.result);
=======
result_regs.push_back(rd);
result_fpr.push_back(1'b0);
read_regs.push_back(rs1);
read_fpr.push_back(1'b0);
return $sformatf("%-12s %4s, %s, 0x%0x", mnemonic, regAddrToStr(rd), regAddrToStr(rs1), sbe.result);
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
endfunction // printIuInstr
function string printSBInstr(input string mnemonic);
<<<<<<< HEAD
read_regs.push_back(sbe.rs1);
read_regs.push_back(sbe.rs2);
@ -276,13 +374,31 @@ class instruction_trace_item;
return $sformatf("%-16s %s, pc + %0d", mnemonic, regAddrToStr(sbe.rs1), $signed(sbe.result));
else
return $sformatf("%-16s %s, %s, pc + %0d", mnemonic, regAddrToStr(sbe.rs1), regAddrToStr(sbe.rs2), $signed(sbe.result));
=======
read_regs.push_back(rs1);
read_fpr.push_back(1'b0);
read_regs.push_back(rs2);
read_fpr.push_back(1'b0);
if (rs2 == 0)
return $sformatf("%-12s %4s, pc + %0d", mnemonic, regAddrToStr(rs1), $signed(sbe.result));
else
return $sformatf("%-12s %4s, %s, pc + %0d", mnemonic, regAddrToStr(rs1), regAddrToStr(rs2), $signed(sbe.result));
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
endfunction // printIuInstr
function string printUInstr(input string mnemonic);
<<<<<<< HEAD
result_regs.push_back(sbe.rd);
return $sformatf("%-16s %s, 0x%0h", mnemonic, regAddrToStr(sbe.rd), sbe.result[31:12]);
=======
result_regs.push_back(rd);
result_fpr.push_back(1'b0);
return $sformatf("%-12s %4s, 0x%0h", mnemonic, regAddrToStr(rd), sbe.result[31:12]);
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
endfunction // printUInstr
function string printJump();
@ -290,7 +406,7 @@ class instruction_trace_item;
case (instr[6:0])
OPCODE_JALR: begin
// is this a return?
if (sbe.rd == 'b0 && (sbe.rs1 == 'h1 || sbe.rs1 == 'h5)) begin
if (rd == 'b0 && (rs1 == 'h1 || rs1 == 'h5)) begin
return this.printMnemonic("ret");
end else begin
return this.printIInstr("jalr");
@ -298,7 +414,7 @@ class instruction_trace_item;
end
OPCODE_JAL: begin
if (sbe.rd == 'b0)
if (rd == 'b0)
return this.printUJInstr("j");
else
return this.printUJInstr("jal");
@ -309,16 +425,27 @@ class instruction_trace_item;
function string printUJInstr(input string mnemonic);
<<<<<<< HEAD
result_regs.push_back(sbe.rd);
// jump instruction
if (sbe.rd == 0)
return $sformatf("%-16s pc + %0d", mnemonic, $signed(sbe.result));
else
return $sformatf("%-16s %s, pc + %0d", mnemonic, regAddrToStr(sbe.rd), $signed(sbe.result));
=======
result_regs.push_back(rd);
result_fpr.push_back(1'b0);
// jump instruction
if (rd == 0)
return $sformatf("%-12s pc + %0d", mnemonic, $signed(sbe.result));
else
return $sformatf("%-12s %4s, pc + %0d", mnemonic, regAddrToStr(rd), $signed(sbe.result));
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
endfunction // printUJInstr
function string printCSRInstr(input string mnemonic);
<<<<<<< HEAD
result_regs.push_back(sbe.rd);
if (instr[14] == 0) begin
read_regs.push_back(sbe.rs1);
@ -338,6 +465,29 @@ class instruction_trace_item;
return $sformatf("%-16s %d, %s", mnemonic, $unsigned(sbe.rs1), csrAddrToStr(sbe.result[11:0]));
end else if (sbe.rs1 == 0) begin
return $sformatf("%-16s %s, %s", mnemonic, regAddrToStr(sbe.rd), csrAddrToStr(sbe.result[11:0]));
=======
result_regs.push_back(rd);
result_fpr.push_back(1'b0);
if (instr[14] == 0) begin
read_regs.push_back(rs1);
read_fpr.push_back(1'b0);
if (rd != 0 && rs1 != 0) begin
return $sformatf("%-12s %4s, %s, %s", mnemonic, regAddrToStr(rd), regAddrToStr(rs1), csrAddrToStr(sbe.result[11:0]));
// don't display instructions which write to zero
end else if (rd == 0) begin
return $sformatf("%-12s %4s, %s", mnemonic, regAddrToStr(rs1), csrAddrToStr(sbe.result[11:0]));
end else if (rs1 == 0) begin
return $sformatf("%-12s %4s, %s", mnemonic, regAddrToStr(rd), csrAddrToStr(sbe.result[11:0]));
end
end else begin
if (rd != 0 && rs1 != 0) begin
return $sformatf("%-12s %4s, %d, %s", mnemonic, regAddrToStr(rd), $unsigned(rs1), csrAddrToStr(sbe.result[11:0]));
// don't display instructions which write to zero
end else if (rd == 0) begin
return $sformatf("%-14s %2d, %s", mnemonic, $unsigned(rs1), csrAddrToStr(sbe.result[11:0]));
end else if (rs1 == 0) begin
return $sformatf("%-12s %4s, %s", mnemonic, regAddrToStr(rd), csrAddrToStr(sbe.result[11:0]));
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
end
end
endfunction // printCSRInstr
@ -356,12 +506,29 @@ class instruction_trace_item;
default: return printMnemonic("INVALID");
endcase
<<<<<<< HEAD
result_regs.push_back(sbe.rd);
read_regs.push_back(sbe.rs1);
// save the immediate for calculating the virtual address
this.imm = sbe.result;
return $sformatf("%-16s %s, %0d(%s)", mnemonic, regAddrToStr(sbe.rd), $signed(sbe.result), regAddrToStr(sbe.rs1));
=======
if (instr[6:0] == OPCODE_LOAD_FP)
mnemonic = $sformatf("f%s",mnemonic);
result_regs.push_back(rd);
result_fpr.push_back(is_rd_fpr(sbe.op));
read_regs.push_back(rs1);
read_fpr.push_back(1'b0);
// save the immediate for calculating the virtual address
this.imm = sbe.result;
if (instr[6:0] == OPCODE_LOAD_FP)
return $sformatf("%-12s %4s, %0d(%s)", mnemonic, fpRegAddrToStr(rd), $signed(sbe.result), regAddrToStr(rs1));
else
return $sformatf("%-12s %4s, %0d(%s)", mnemonic, regAddrToStr(rd), $signed(sbe.result), regAddrToStr(rs1));
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
endfunction
function string printStoreInstr();
@ -375,12 +542,29 @@ class instruction_trace_item;
default: return printMnemonic("INVALID");
endcase
<<<<<<< HEAD
read_regs.push_back(sbe.rs2);
read_regs.push_back(sbe.rs1);
// save the immediate for calculating the virtual address
this.imm = sbe.result;
return $sformatf("%-16s %s, %0d(%s)", mnemonic, regAddrToStr(sbe.rs2), $signed(sbe.result), regAddrToStr(sbe.rs1));
=======
if (instr[6:0] == OPCODE_STORE_FP)
mnemonic = $sformatf("f%s",mnemonic);
read_regs.push_back(rs2);
read_fpr.push_back(is_rs2_fpr(sbe.op));
read_regs.push_back(rs1);
read_fpr.push_back(1'b0);
// save the immediate for calculating the virtual address
this.imm = sbe.result;
if (instr[6:0] == OPCODE_STORE_FP)
return $sformatf("%-12s %4s, %0d(%s)", mnemonic, fpRegAddrToStr(rs2), $signed(sbe.result), regAddrToStr(rs1));
else
return $sformatf("%-12s %4s, %0d(%s)", mnemonic, regAddrToStr(rs2), $signed(sbe.result), regAddrToStr(rs1));
>>>>>>> 385359f... :sparkles: Add register renaming to issue stage
endfunction // printSInstr