M Makefile => Makefile +0 -2
@@ 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 \
M src/cpu.sv => src/cpu.sv +3 -3
@@ 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])
);
M src/cpu_types.sv => src/cpu_types.sv +4 -0
@@ 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;
D src/jumps.sv => src/jumps.sv +0 -49
@@ 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
M src/stages/decode.sv => src/stages/decode.sv +20 -75
@@ 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
M src/stages/execute.sv => src/stages/execute.sv +24 -5
@@ 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
M src/stages/fetch.sv => src/stages/fetch.sv +1 -2
@@ 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
M tests/comp_list.lst => tests/comp_list.lst +0 -1
@@ 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