Add operand forwarding to the execute stage

This commit is contained in:
Graham Edgecombe 2017-12-03 17:34:41 +00:00
parent 5516973b5f
commit 8e2ce65ad9
3 changed files with 47 additions and 2 deletions

13
rv32.sv
View file

@ -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),

View file

@ -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;

View file

@ -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 */