Move result/mem_read_value mux to the mem stage
This should reduce the logic required to forward the writeback rd_value to the execute stage, which is on the critical path.
This commit is contained in:
parent
8e2ce65ad9
commit
dd6e01fb5c
3 changed files with 40 additions and 98 deletions
56
rv32.sv
56
rv32.sv
|
|
@ -5,15 +5,14 @@
|
|||
`include "rv32_execute.sv"
|
||||
`include "rv32_fetch.sv"
|
||||
`include "rv32_mem.sv"
|
||||
`include "rv32_writeback.sv"
|
||||
|
||||
module rv32 (
|
||||
input clk,
|
||||
output [7:0] leds
|
||||
);
|
||||
always_ff @(posedge clk) begin
|
||||
if (writeback_rd_writeback && writeback_rd == 31)
|
||||
leds <= writeback_rd_value[7:0];
|
||||
if (mem_rd_writeback && mem_rd == 31)
|
||||
leds <= mem_rd_value[7:0];
|
||||
end
|
||||
|
||||
rv32_fetch fetch (
|
||||
|
|
@ -37,14 +36,16 @@ module rv32 (
|
|||
rv32_decode decode (
|
||||
.clk(clk),
|
||||
|
||||
/* control in */
|
||||
.rd_in(writeback_rd),
|
||||
.rd_writeback_in(writeback_rd_writeback),
|
||||
/* control in (from writeback) */
|
||||
.rd_in(mem_rd),
|
||||
.rd_writeback_in(mem_rd_writeback),
|
||||
|
||||
/* data in */
|
||||
.pc_in(fetch_pc),
|
||||
.instr_in(fetch_instr),
|
||||
.rd_value_in(writeback_rd_value),
|
||||
|
||||
/* data in (from writeback) */
|
||||
.rd_value_in(mem_rd_value),
|
||||
|
||||
/* control out */
|
||||
.rs1_out(decode_rs1),
|
||||
|
|
@ -111,8 +112,8 @@ module rv32 (
|
|||
.rd_writeback_in(decode_rd_writeback),
|
||||
|
||||
/* control in (from writeback) */
|
||||
.writeback_rd_in(writeback_rd),
|
||||
.writeback_rd_writeback_in(writeback_rd_writeback),
|
||||
.writeback_rd_in(mem_rd),
|
||||
.writeback_rd_writeback_in(mem_rd_writeback),
|
||||
|
||||
/* data in */
|
||||
.pc_in(decode_pc),
|
||||
|
|
@ -121,7 +122,7 @@ module rv32 (
|
|||
.imm_in(decode_imm),
|
||||
|
||||
/* data in (from writeback) */
|
||||
.writeback_rd_value_in(writeback_rd_value),
|
||||
.writeback_rd_value_in(mem_rd_value),
|
||||
|
||||
/* control out */
|
||||
.mem_read_en_out(execute_mem_read_en),
|
||||
|
|
@ -170,19 +171,16 @@ module rv32 (
|
|||
.branch_pc_in(execute_branch_pc),
|
||||
|
||||
/* control out */
|
||||
.read_en_out(mem_read_en),
|
||||
.branch_taken_out(mem_branch_taken),
|
||||
.rd_out(mem_rd),
|
||||
.rd_writeback_out(mem_rd_writeback),
|
||||
|
||||
/* data out */
|
||||
.result_out(mem_result),
|
||||
.read_value_out(mem_read_value),
|
||||
.rd_value_out(mem_rd_value),
|
||||
.branch_pc_out(mem_branch_pc)
|
||||
);
|
||||
|
||||
/* mem -> writeback control */
|
||||
logic mem_read_en;
|
||||
logic [4:0] mem_rd;
|
||||
logic mem_rd_writeback;
|
||||
|
||||
|
|
@ -190,38 +188,10 @@ module rv32 (
|
|||
logic mem_branch_taken;
|
||||
|
||||
/* mem -> writeback data */
|
||||
logic [31:0] mem_result;
|
||||
logic [31:0] mem_read_value;
|
||||
logic [31:0] mem_rd_value;
|
||||
|
||||
/* mem -> fetch data */
|
||||
logic [31:0] mem_branch_pc;
|
||||
|
||||
rv32_writeback writeback (
|
||||
.clk(clk),
|
||||
|
||||
/* control in */
|
||||
.mem_read_en_in(mem_read_en),
|
||||
.rd_in(mem_rd),
|
||||
.rd_writeback_in(mem_rd_writeback),
|
||||
|
||||
/* data in */
|
||||
.result_in(mem_result),
|
||||
.mem_read_value_in(mem_read_value),
|
||||
|
||||
/* control out */
|
||||
.rd_out(writeback_rd),
|
||||
.rd_writeback_out(writeback_rd_writeback),
|
||||
|
||||
/* data out */
|
||||
.rd_value_out(writeback_rd_value)
|
||||
);
|
||||
|
||||
/* writeback -> decode control */
|
||||
logic [4:0] writeback_rd;
|
||||
logic writeback_rd_writeback;
|
||||
|
||||
/* writeback -> decode data */
|
||||
logic [31:0] writeback_rd_value;
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
|
|
|||
54
rv32_mem.sv
54
rv32_mem.sv
|
|
@ -22,14 +22,12 @@ module rv32_mem (
|
|||
input [31:0] branch_pc_in,
|
||||
|
||||
/* control out */
|
||||
output read_en_out,
|
||||
output branch_taken_out,
|
||||
output [4:0] rd_out,
|
||||
output rd_writeback_out,
|
||||
|
||||
/* data out */
|
||||
output [31:0] result_out,
|
||||
output [31:0] read_value_out,
|
||||
output [31:0] rd_value_out,
|
||||
output [31:0] branch_pc_out
|
||||
);
|
||||
logic [31:0] data_mem [255:0];
|
||||
|
|
@ -112,33 +110,35 @@ module rv32_mem (
|
|||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
read_en_out <= read_en_in;
|
||||
rd_out <= rd_in;
|
||||
rd_writeback_out <= rd_writeback_in;
|
||||
result_out <= result_in;
|
||||
|
||||
case (width_in)
|
||||
RV32_MEM_WIDTH_WORD: begin
|
||||
read_value_out <= read_value;
|
||||
end
|
||||
RV32_MEM_WIDTH_HALF: begin
|
||||
case (result_in[0])
|
||||
1'b0: read_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:16]};
|
||||
1'b1: read_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:0]};
|
||||
endcase
|
||||
end
|
||||
RV32_MEM_WIDTH_BYTE: begin
|
||||
case (result_in[1:0])
|
||||
2'b00: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:24]};
|
||||
2'b01: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[23]}}, read_value[23:16]};
|
||||
2'b10: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:8]};
|
||||
2'b11: read_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[7]}}, read_value[7:0]};
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
read_value_out <= 32'bx;
|
||||
end
|
||||
endcase
|
||||
if (read_en_in) begin
|
||||
case (width_in)
|
||||
RV32_MEM_WIDTH_WORD: begin
|
||||
rd_value_out <= read_value;
|
||||
end
|
||||
RV32_MEM_WIDTH_HALF: begin
|
||||
case (result_in[0])
|
||||
1'b0: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:16]};
|
||||
1'b1: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:0]};
|
||||
endcase
|
||||
end
|
||||
RV32_MEM_WIDTH_BYTE: begin
|
||||
case (result_in[1:0])
|
||||
2'b00: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:24]};
|
||||
2'b01: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[23]}}, read_value[23:16]};
|
||||
2'b10: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:8]};
|
||||
2'b11: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[7]}}, read_value[7:0]};
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
rd_value_out <= 32'bx;
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
rd_value_out <= result_in;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
`ifndef RV32_WRITEBACK
|
||||
`define RV32_WRITEBACK
|
||||
|
||||
module rv32_writeback (
|
||||
input clk,
|
||||
|
||||
/* control in */
|
||||
input mem_read_en_in,
|
||||
input [4:0] rd_in,
|
||||
input rd_writeback_in,
|
||||
|
||||
/* data in */
|
||||
input [31:0] result_in,
|
||||
input [31:0] mem_read_value_in,
|
||||
|
||||
/* control out */
|
||||
output [4:0] rd_out,
|
||||
output rd_writeback_out,
|
||||
|
||||
/* data out */
|
||||
output [31:0] rd_value_out
|
||||
);
|
||||
assign rd_out = rd_in;
|
||||
assign rd_writeback_out = rd_writeback_in;
|
||||
assign rd_value_out = mem_read_en_in ? mem_read_value_in : result_in;
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
Loading…
Reference in a new issue