From 8024a6075ff182f3ef4bcd59e4d8e9ea1cf9ac2d Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Sat, 30 Dec 2017 14:12:23 +0000 Subject: [PATCH] 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. --- rv32.sv | 3 +++ rv32_alu.sv | 5 +++++ rv32_branch.sv | 11 +++-------- rv32_execute.sv | 6 ++++++ rv32_mem.sv | 5 ++--- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/rv32.sv b/rv32.sv index 251db6d..59b716c 100644 --- a/rv32.sv +++ b/rv32.sv @@ -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), diff --git a/rv32_alu.sv b/rv32_alu.sv index a5c7936..32726bb 100644 --- a/rv32_alu.sv +++ b/rv32_alu.sv @@ -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 diff --git a/rv32_branch.sv b/rv32_branch.sv index b15d042..c15fda7 100644 --- a/rv32_branch.sv +++ b/rv32_branch.sv @@ -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 diff --git a/rv32_execute.sv b/rv32_execute.sv index 1c5c18b..d72d8c5 100644 --- a/rv32_execute.sv +++ b/rv32_execute.sv @@ -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; diff --git a/rv32_mem.sv b/rv32_mem.sv index 9ddf7ab..43d43e1 100644 --- a/rv32_mem.sv +++ b/rv32_mem.sv @@ -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) );