From 8e2ce65ad9101cb602fc5074ce5f3e5ad0b47294 Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Sun, 3 Dec 2017 17:34:41 +0000 Subject: [PATCH] Add operand forwarding to the execute stage --- rv32.sv | 13 +++++++++++++ rv32_decode.sv | 4 ++++ rv32_execute.sv | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/rv32.sv b/rv32.sv index 7f75807..8b2d36c 100644 --- a/rv32.sv +++ b/rv32.sv @@ -47,6 +47,8 @@ module rv32 ( .rd_value_in(writeback_rd_value), /* control out */ + .rs1_out(decode_rs1), + .rs2_out(decode_rs2), .alu_op_out(decode_alu_op), .alu_sub_sra_out(decode_alu_sub_sra), .alu_src1_out(decode_alu_src1), @@ -68,6 +70,8 @@ module rv32 ( ); /* decode -> execute control */ + logic [4:0] decode_rs1; + logic [4:0] decode_rs2; logic [3:0] decode_alu_op; logic decode_alu_sub_sra; logic decode_alu_src1; @@ -91,6 +95,8 @@ module rv32 ( .clk(clk), /* control in */ + .rs1_in(decode_rs1), + .rs2_in(decode_rs2), .alu_op_in(decode_alu_op), .alu_sub_sra_in(decode_alu_sub_sra), .alu_src1_in(decode_alu_src1), @@ -104,12 +110,19 @@ module rv32 ( .rd_in(decode_rd), .rd_writeback_in(decode_rd_writeback), + /* control in (from writeback) */ + .writeback_rd_in(writeback_rd), + .writeback_rd_writeback_in(writeback_rd_writeback), + /* data in */ .pc_in(decode_pc), .rs1_value_in(decode_rs1_value), .rs2_value_in(decode_rs2_value), .imm_in(decode_imm), + /* data in (from writeback) */ + .writeback_rd_value_in(writeback_rd_value), + /* control out */ .mem_read_en_out(execute_mem_read_en), .mem_write_en_out(execute_mem_write_en), diff --git a/rv32_decode.sv b/rv32_decode.sv index 6c069c1..5ee51a9 100644 --- a/rv32_decode.sv +++ b/rv32_decode.sv @@ -21,6 +21,8 @@ module rv32_decode ( /* control out */ output valid_out, + output [4:0] rs1_out, + output [4:0] rs2_out, output [3:0] alu_op_out, output alu_sub_sra_out, output alu_src1_out, @@ -75,6 +77,8 @@ module rv32_decode ( ); always_ff @(posedge clk) begin + rs1_out <= rs1; + rs2_out <= rs2; rd_out <= rd; pc_out <= pc_in; diff --git a/rv32_execute.sv b/rv32_execute.sv index cbac248..15c4db3 100644 --- a/rv32_execute.sv +++ b/rv32_execute.sv @@ -8,6 +8,8 @@ module rv32_execute ( input clk, /* control in */ + input [4:0] rs1_in, + input [4:0] rs2_in, input [3:0] alu_op_in, input alu_sub_sra_in, input alu_src1_in, @@ -21,12 +23,19 @@ module rv32_execute ( input [4:0] rd_in, input rd_writeback_in, + /* control in (from writeback) */ + input [4:0] writeback_rd_in, + input writeback_rd_writeback_in, + /* data in */ input [31:0] pc_in, input [31:0] rs1_value_in, input [31:0] rs2_value_in, input [31:0] imm_in, + /* data in (from writeback) */ + input [31:0] writeback_rd_value_in, + /* control out */ output mem_read_en_out, output mem_write_en_out, @@ -41,6 +50,25 @@ module rv32_execute ( output [31:0] rs2_value_out, output [31:0] branch_pc_out ); + logic [31:0] rs1_value; + logic [31:0] rs2_value; + + always_comb begin + if (rd_writeback_out && rd_out == rs1_in && |rs1_in) + rs1_value = result_out; + else if (writeback_rd_writeback_in && writeback_rd_in == rs1_in && |rs1_in) + rs1_value = writeback_rd_value_in; + else + rs1_value = rs1_value_in; + + if (rd_writeback_out && rd_out == rs2_in && |rs2_in) + rs2_value = result_out; + else if (writeback_rd_writeback_in && writeback_rd_in == rs2_in && |rs2_in) + rs2_value = writeback_rd_value_in; + else + rs2_value = rs2_value_in; + end + rv32_alu alu ( .clk(clk), @@ -52,8 +80,8 @@ module rv32_execute ( /* data in */ .pc_in(pc_in), - .rs1_value_in(rs1_value_in), - .rs2_value_in(rs2_value_in), + .rs1_value_in(rs1_value), + .rs2_value_in(rs2_value), .imm_in(imm_in), /* data out */