Move result zero/non-zero test to the execute stage

This reduces the amount of logic required and should speed the processor
up slightly, as the critical path had moved from the execute stage to
the branching logic in the mem/fetch stages.
This commit is contained in:
Graham Edgecombe 2017-12-30 14:12:23 +00:00
parent 6c964c75e5
commit 8024a6075f
5 changed files with 19 additions and 11 deletions

View file

@ -88,6 +88,7 @@ module rv32 (
/* execute -> mem control */
logic execute_branch_predicted_taken;
logic execute_valid;
logic execute_alu_non_zero;
logic execute_mem_read;
logic execute_mem_write;
logic [1:0] execute_mem_width;
@ -291,6 +292,7 @@ module rv32 (
/* control out */
.branch_predicted_taken_out(execute_branch_predicted_taken),
.valid_out(execute_valid),
.alu_non_zero_out(execute_alu_non_zero),
.mem_read_out(execute_mem_read),
.mem_write_out(execute_mem_write),
.mem_width_out(execute_mem_width),
@ -316,6 +318,7 @@ module rv32 (
/* control in */
.branch_predicted_taken_in(execute_branch_predicted_taken),
.valid_in(execute_valid),
.alu_non_zero_in(execute_alu_non_zero),
.read_in(execute_mem_read),
.write_in(execute_mem_write),
.width_in(execute_mem_width),

View file

@ -31,6 +31,9 @@ module rv32_alu (
input [31:0] rs2_value_in,
input [31:0] imm_value_in,
/* control out */
output logic non_zero_out,
/* data out */
output logic [31:0] result_out
);
@ -95,6 +98,8 @@ module rv32_alu (
`RV32_ALU_OP_SLTU: result_out = {31'b0, ltu};
endcase
end
assign non_zero_out = |result_out;
endmodule
`endif

View file

@ -30,24 +30,19 @@ endmodule
module rv32_branch_unit (
/* control in */
input predicted_taken_in,
input alu_non_zero_in,
input [1:0] op_in,
/* data in */
input [31:0] result_in,
/* control out */
output logic mispredicted_out
);
logic non_zero;
logic taken;
assign non_zero = |result_in;
always_comb begin
case (op_in)
`RV32_BRANCH_OP_NEVER: taken = 0;
`RV32_BRANCH_OP_ZERO: taken = ~non_zero;
`RV32_BRANCH_OP_NON_ZERO: taken = non_zero;
`RV32_BRANCH_OP_ZERO: taken = ~alu_non_zero_in;
`RV32_BRANCH_OP_NON_ZERO: taken = alu_non_zero_in;
`RV32_BRANCH_OP_ALWAYS: taken = 1;
endcase
end

View file

@ -53,6 +53,7 @@ module rv32_execute (
/* control out */
output logic branch_predicted_taken_out,
output logic valid_out,
output logic alu_non_zero_out,
output logic mem_read_out,
output logic mem_write_out,
output logic [1:0] mem_width_out,
@ -88,6 +89,7 @@ module rv32_execute (
end
/* ALU */
logic alu_non_zero;
logic [31:0] alu_result;
rv32_alu alu (
@ -103,6 +105,9 @@ module rv32_execute (
.rs2_value_in(rs2_value),
.imm_value_in(imm_value_in),
/* control out */
.non_zero_out(alu_non_zero),
/* data out */
.result_out(alu_result)
);
@ -151,6 +156,7 @@ module rv32_execute (
if (!stall_in) begin
branch_predicted_taken_out <= branch_predicted_taken_in;
valid_out <= valid_in;
alu_non_zero_out <= alu_non_zero;
mem_read_out <= mem_read_in;
mem_write_out <= mem_write_in;
mem_width_out <= mem_width_in;

View file

@ -17,6 +17,7 @@ module rv32_mem (
/* control in */
input branch_predicted_taken_in,
input valid_in,
input alu_non_zero_in,
input read_in,
input write_in,
input [1:0] width_in,
@ -56,11 +57,9 @@ module rv32_mem (
rv32_branch_unit branch_unit (
/* control in */
.predicted_taken_in(branch_predicted_taken_in),
.alu_non_zero_in(alu_non_zero_in),
.op_in(branch_op_in),
/* data in */
.result_in(result_in),
/* control out */
.mispredicted_out(branch_mispredicted_out)
);