~ruther/verilog-riscv-semestral-project

6da6eb9e4ee2ac5f96d5bed40c4c46d57a64c79f — Rutherther 1 year, 3 months ago 4dcef02 feat/pipeline
docs: better document the stage code, organize it better
M src/cpu.sv => src/cpu.sv +10 -0
@@ 33,6 33,12 @@ module cpu(
  wire [31:0] jumping_pc_next;

  stage_status_t stages_in[1:4];

  /// verilator doesn't like that data taken from stages_out[i]
  // are used in stages_out[i + 1]. But that shouldn't really matter
  // as there is not really a cyclic dependency.
  // It just seems that verilator is not very good at "separating"
  // array elements
/* verilator lint_off UNOPTFLAT */
  stage_status_t stages_out[0:3];
/* verilator lint_on UNOPTFLAT */


@@ 76,6 82,10 @@ module cpu(
      pc_next = pc;
  end

  // data for forwarding from the stages
  // Note: this is a record instead of an array
  // just because verilator didn't like it as an array
  // consider switching back to array.
  forwarding_data_status_t data_in_pipeline;
  assign data_in_pipeline.execute_out = stages_out[EXECUTE].data;
  assign data_in_pipeline.access_out = stages_out[ACCESS].data;

M src/forwarder.sv => src/forwarder.sv +1 -0
@@ 14,6 14,7 @@ module forwarder(
  // these will be used instead of the register_file_data
  //
  // if there are multiple matches, the first one is taken
  // to get the most recent data

  always_comb begin
    stall = 0;

M src/stages/decode.sv => src/stages/decode.sv +6 -4
@@ 17,8 17,6 @@ module decode(
  output        stage_status_t stage_out
);

  parameter FORWARDING_STAGES = 3; // , execute(out), memory(out), writeback(in)

  wire [2:0] alu_op;
  wire       alu_add_one;
  wire       alu_negate;


@@ 42,6 40,7 @@ module decode(
  wire        memory_we;

  assign stage_out.data.address = reg_we && !stalling ? reg_rd : 0;
  assign stage_out.data.valid = 0; // the data cannot be valid at this point;

  assign stage_out.pc = stage_in.pc;



@@ 110,6 109,8 @@ 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


@@ 158,6 159,7 @@ module decode(

  wire stalling;
  assign stalling = (uses_reg_rd1 && stall_1) || (uses_reg_rd2 && stall_2);
  assign stage_out.valid = !stalling;
  assign stage_out.ready = !stalling;
  assign stage_out.valid = !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 +7 -5
@@ 9,15 9,17 @@ module execute(
  reg [31:0] alu_1, alu_2;
  wire [31:0] alu_out;

  assign stage_out.instruction = stage_in.instruction;
  assign stage_out.pc = stage_in.pc;
  assign stage_out.reg_rd1 = stage_in.reg_rd1;
  assign stage_out.reg_rd2 = stage_in.reg_rd2;
  assign stage_out.pc = stage_in.pc;
  assign stage_out.instruction = stage_in.instruction;
  assign stage_out.valid = stage_in.valid;
  assign stage_out.ready = 1;
  assign stage_out.data.valid = stage_in.valid && (stage_in.instruction.reg_rd_src != RD_MEMORY);

  assign stage_out.data.address = stage_in.valid ? stage_in.data.address : 0;
  assign stage_out.data.data = stage_in.instruction.reg_rd_src == RD_PC_PLUS ? stage_in.pc + 4 : alu_out;
  assign stage_out.data.valid = stage_in.valid && (stage_in.instruction.reg_rd_src != RD_MEMORY);

  assign stage_out.valid = stage_in.valid;
  assign stage_out.ready = 1;

  // alu source 1
  always_comb begin

M src/stages/fetch.sv => src/stages/fetch.sv +2 -1
@@ 9,7 9,8 @@ module fetch(
  output       stage_status_t stage_out
);
  assign stage_out.instruction.instruction = mem_instruction;
  assign stage_out.valid = !jump;
  assign stage_out.pc = pc;

  assign stage_out.valid = !jump;
  assign stage_out.ready = 1;
endmodule

M src/stages/memory_access.sv => src/stages/memory_access.sv +2 -1
@@ 49,6 49,7 @@ module memory_access(
  assign stage_out.reg_rd1 = stage_in.reg_rd1;
  assign stage_out.reg_rd2 = stage_in.reg_rd2;

  assign stage_out.data.valid = stage_in.valid;
  assign stage_out.data.address = stage_in.valid ? stage_in.data.address : 0;
  assign stage_out.data.data =
    stage_in.instruction.reg_rd_src == RD_MEMORY ?


@@ 58,7 59,7 @@ module memory_access(
            .sext(stage_in.instruction.memory_sign_extension)
        ) :
        stage_in.data.data;
  assign stage_out.data.valid = stage_in.valid;

  assign stage_out.valid = stage_in.valid;
  assign stage_out.ready = 1;
endmodule

Do not follow this link