~ruther/verilog-riscv-semestral-project

66d141635b81de276634d3d9f97fe46c0ffb2f32 — Rutherther 1 year, 3 months ago 7581533
feat: move jumping to execute stage
8 files changed, 52 insertions(+), 137 deletions(-)

M Makefile
M src/cpu.sv
M src/cpu_types.sv
D src/jumps.sv
M src/stages/decode.sv
M src/stages/execute.sv
M src/stages/fetch.sv
M tests/comp_list.lst
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

Do not follow this link