From 66d141635b81de276634d3d9f97fe46c0ffb2f32 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 15 Dec 2023 22:00:56 +0100 Subject: [PATCH] feat: move jumping to execute stage --- Makefile | 2 - src/cpu.sv | 6 +-- src/cpu_types.sv | 4 ++ src/jumps.sv | 49 ---------------------- src/stages/decode.sv | 95 +++++++++---------------------------------- src/stages/execute.sv | 29 ++++++++++--- src/stages/fetch.sv | 3 +- tests/comp_list.lst | 1 - 8 files changed, 52 insertions(+), 137 deletions(-) delete mode 100644 src/jumps.sv diff --git a/Makefile b/Makefile index d007b42..de5248f 100755 --- a/Makefile +++ b/Makefile @@ -41,7 +41,6 @@ run_program: ./programs/bin/$(PROGRAM).dat testbench/tb_cpu_program.sv src/*.sv src/register_file.sv \ src/program_counter.sv \ src/forwarder.sv \ - src/jumps.sv \ src/stages/*.sv \ src/ram.sv \ src/cpu.sv \ @@ -61,7 +60,6 @@ run_program: ./programs/bin/$(PROGRAM).dat testbench/tb_cpu_program.sv src/*.sv src/register_file.sv \ src/program_counter.sv \ src/forwarder.sv \ - src/jumps.sv \ src/stages/*.sv \ src/ram.sv \ src/cpu.sv \ diff --git a/src/cpu.sv b/src/cpu.sv index 2ab97b8..d32b092 100755 --- a/src/cpu.sv +++ b/src/cpu.sv @@ -95,25 +95,25 @@ module cpu( .clk(clk), .pc(pc), .mem_instruction(instruction), - .jump(jump), .stage_out(stages_out[FETCH]) ); decode decode_inst( .clk(clk), + .jump(jump), .data_in_pipeline(data_in_pipeline), .reg_a_1(reg_a_1), .reg_a_2(reg_a_2), .reg_rd1(reg_rd1), .reg_rd2(reg_rd2), - .jump(jump), - .pc_next(jumping_pc_next), .stage_in(stages_in[DECODE]), .stage_out(stages_out[DECODE]) ); execute execute_inst( .clk(clk), + .jump(jump), + .jump_pc(jumping_pc_next), .stage_in(stages_in[EXECUTE]), .stage_out(stages_out[EXECUTE]) ); diff --git a/src/cpu_types.sv b/src/cpu_types.sv index 03e6709..5f0c8ac 100755 --- a/src/cpu_types.sv +++ b/src/cpu_types.sv @@ -26,6 +26,10 @@ package cpu_types; bit reg_we; + pc_source_t pc_src; + bit jump_instruction; + bit jump_negate_zero; + reg_rd_source_t reg_rd_src; } decoded_instruction_t; diff --git a/src/jumps.sv b/src/jumps.sv deleted file mode 100644 index 2d1c3c1..0000000 --- a/src/jumps.sv +++ /dev/null @@ -1,49 +0,0 @@ -import cpu_types::*; - -module jumps( - input [31:0] pc, - input [31:0] immediate, - input pc_source_t pc_src, - input jump_negate_zero, - input jump_instruction, - - input [2:0] alu_op, - input [31:0] alu_a, alu_b, - input alu_sign, - input alu_b_add_one, - input alu_b_negate, - - output [31:0] pc_next, - output jumping -); - wire [31:0] alu_out; - wire alu_zero; - - wire branch_taken; - - assign jumping = branch_taken || pc_src == PC_ALU; - - assign branch_taken = jump_instruction && (alu_zero ^ jump_negate_zero); - always_comb begin - pc_next = 32'bX; - case (pc_src) - PC_PLUS : begin - if (branch_taken) - pc_next = pc + immediate; - end - PC_ALU : pc_next = alu_out; - endcase - end - - alu #(.WIDTH(32)) alu_inst( - .a(alu_a), - .b(alu_b), - .out(alu_out), - - .op(alu_op), - .b_add_one(alu_b_add_one), - .b_negate(alu_b_negate), - .sign(alu_sign), - .zero_flag(alu_zero) - ); -endmodule diff --git a/src/stages/decode.sv b/src/stages/decode.sv index e832a67..1433d2a 100644 --- a/src/stages/decode.sv +++ b/src/stages/decode.sv @@ -1,20 +1,19 @@ import cpu_types::*; module decode( - input clk, + input clk, - input forwarding_data_status_t data_in_pipeline, + input forwarding_data_status_t data_in_pipeline, - output [4:0] reg_a_1, - output [4:0] reg_a_2, - input [31:0] reg_rd1, - input [31:0] reg_rd2, + output [4:0] reg_a_1, + output [4:0] reg_a_2, + input [31:0] reg_rd1, + input [31:0] reg_rd2, - output jump, - output [31:0] pc_next, + input jump, - input stage_status_t stage_in, - output stage_status_t stage_out + input stage_status_t stage_in, + output stage_status_t stage_out ); wire [2:0] alu_op; @@ -22,12 +21,6 @@ module decode( wire alu_negate; wire alu_sign; - wire [31:0] immediate; - wire jump_instruction, jump_negate_zero; - wire jump_taken; - - wire pc_src; - wire [4:0] reg_rd; wire reg_we; @@ -49,13 +42,6 @@ module decode( assign stage_out.reg_rd1 = forwarded_reg_rd1; assign stage_out.reg_rd2 = forwarded_reg_rd2; - assign stage_out.instruction.immediate = immediate; - assign stage_out.instruction.alu_1_src = alu_1_src; - assign stage_out.instruction.alu_2_src = alu_2_src; - assign stage_out.instruction.alu_op = alu_op; - assign stage_out.instruction.alu_add_one = alu_add_one; - assign stage_out.instruction.alu_negate = alu_negate; - assign stage_out.instruction.alu_sign = alu_sign; assign stage_out.instruction.memory_we = memory_we; control_unit control_unit_inst( @@ -63,24 +49,24 @@ module decode( .ebreak(stage_out.instruction.ebreak), - .immediate(immediate), + .immediate(stage_out.instruction.immediate), - .alu_op(alu_op), - .alu_add_one(alu_add_one), - .alu_negate(alu_negate), - .alu_sign(alu_sign), + .alu_op(stage_out.instruction.alu_op), + .alu_add_one(stage_out.instruction.alu_add_one), + .alu_negate(stage_out.instruction.alu_negate), + .alu_sign(stage_out.instruction.alu_sign), .memory_mask(stage_out.instruction.memory_mask), .memory_sign_extension(stage_out.instruction.memory_sign_extension), .memory_we(memory_we), - .jump_instruction(jump_instruction), - .jump_negate_zero(jump_negate_zero), + .jump_instruction(stage_out.instruction.jump_instruction), + .jump_negate_zero(stage_out.instruction.jump_negate_zero), - .pc_src(pc_src), - .alu_src_1(alu_1_src), - .alu_src_2(alu_2_src), + .pc_src(stage_out.instruction.pc_src), + .alu_src_1(stage_out.instruction.alu_1_src), + .alu_src_2(stage_out.instruction.alu_2_src), .reg_rd_src(stage_out.instruction.reg_rd_src), .reg_rs1(reg_a_1), @@ -109,47 +95,6 @@ module decode( .data(forwarded_reg_rd2) ); - // TODO: this is there twice instead of just once - // the second is in execute stage. Maybe merge these? - // alu source 1 - reg [31:0] alu_1, alu_2; - always_comb begin - case (alu_1_src) - REG_FILE_RS1 : alu_1 = forwarded_reg_rd1; - PC : alu_1 = stage_in.pc; - endcase - end - - // alu source 2 - always_comb begin - case (alu_2_src) - REG_FILE_RS2 : alu_2 = forwarded_reg_rd2; - IMMEDIATE : alu_2 = immediate; - endcase - end - - // // jumping logic - wire jumps_jumping; - jumps jumps_inst( - .pc(stage_in.pc), - .immediate(immediate), - .pc_src(pc_src), - .jump_negate_zero(jump_negate_zero), - .jump_instruction(jump_instruction), - - .alu_op(alu_op), - .alu_a(alu_1), - .alu_b(alu_2), - .alu_sign(alu_sign), - .alu_b_add_one(alu_add_one), - .alu_b_negate(alu_negate), - - .pc_next(pc_next), - .jumping(jumps_jumping) - ); - - assign jump = !stalling && jumps_jumping; - // stalling logic // if should use reg_rd1 => wait until stall_1 == 0 // if should use reg_rd2 => wait until stall_2 == 0 @@ -159,7 +104,7 @@ module decode( wire stalling; assign stalling = (uses_reg_rd1 && stall_1) || (uses_reg_rd2 && stall_2); - assign stage_out.valid = !stalling && stage_in.valid; + assign stage_out.valid = !jump && !stalling && stage_in.valid; assign stage_out.ready = !stalling || !stage_in.valid; // if input is not valid, do not care about stalling... endmodule diff --git a/src/stages/execute.sv b/src/stages/execute.sv index fd3702f..4b6986d 100644 --- a/src/stages/execute.sv +++ b/src/stages/execute.sv @@ -1,13 +1,18 @@ import cpu_types::*; module execute( - input clk, + input clk, - input stage_status_t stage_in, - output stage_status_t stage_out + output jump, + output reg [31:0] jump_pc, + + input stage_status_t stage_in, + output stage_status_t stage_out ); - reg [31:0] alu_1, alu_2; + reg [31:0] alu_1, alu_2; wire [31:0] alu_out; + wire branch_taken; + wire alu_zero; assign stage_out.instruction = stage_in.instruction; assign stage_out.pc = stage_in.pc; @@ -21,6 +26,20 @@ module execute( assign stage_out.valid = stage_in.valid; assign stage_out.ready = 1; + assign jump = stage_in.valid && (branch_taken || stage_in.instruction.pc_src == PC_ALU); + + assign branch_taken = stage_in.instruction.jump_instruction && (alu_zero ^ stage_in.instruction.jump_negate_zero); + always_comb begin + jump_pc = 32'bX; + case (stage_in.instruction.pc_src) + PC_PLUS : begin + if (branch_taken) + jump_pc = stage_in.pc + stage_in.instruction.immediate; + end + PC_ALU : jump_pc = alu_out; + endcase + end + // alu source 1 always_comb begin case (stage_in.instruction.alu_1_src) @@ -46,6 +65,6 @@ module execute( .b_add_one(stage_in.instruction.alu_add_one), .b_negate(stage_in.instruction.alu_negate), .sign(stage_in.instruction.alu_sign), - .zero_flag() + .zero_flag(alu_zero) ); endmodule diff --git a/src/stages/fetch.sv b/src/stages/fetch.sv index 1dd962d..505f314 100644 --- a/src/stages/fetch.sv +++ b/src/stages/fetch.sv @@ -4,13 +4,12 @@ module fetch( input clk, input [31:0] pc, input [31:0] mem_instruction, - input jump, output stage_status_t stage_out ); assign stage_out.instruction.instruction = mem_instruction; assign stage_out.pc = pc; - assign stage_out.valid = 1; // !jump; -- TODO make jumps one cycle after + assign stage_out.valid = 1; assign stage_out.ready = 1; endmodule diff --git a/tests/comp_list.lst b/tests/comp_list.lst index a10acaa..3ac08d1 100755 --- a/tests/comp_list.lst +++ b/tests/comp_list.lst @@ -6,7 +6,6 @@ src/register_file.sv src/program_counter.sv src/forwarder.sv -src/jumps.sv src/stages/fetch.sv src/stages/decode.sv -- 2.48.1