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

View file

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

View file

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

View file

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

View file

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