~ruther/verilog-riscv-semestral-project

2929a779a9d6e451c15f91ac7124f4081e2a04b4 — Rutherther 1 year, 5 months ago 27fcb8d
test: add basic testbenches
3 files changed, 242 insertions(+), 0 deletions(-)

A testbench/tb_alu.sv
A testbench/tb_control_unit.sv
A testbench/tb_register_file.sv
A testbench/tb_alu.sv => testbench/tb_alu.sv +69 -0
@@ 0,0 1,69 @@
module tb_alu();
  reg [31:0] a, b;
  reg [2:0]  op;
  reg        sign, add_one, negate;


  wire [31:0] out;
  wire        zero_flag;

  alu uut(
    .op(op),
    .a(a),
    .b(b),
    .out(out),
    .b_negate(negate),
    .b_add_one(add_one),
    .sign(sign),
    .zero_flag(zero_flag)
  );

  initial begin
    $dumpfile("alu_tb.vcd");
    $dumpvars;

    a = 30;
    b = 20;
    op = 3'b000;
    negate = 1'b0;
    add_one = 1'b0;
    sign = 1'b0;

    // add

    #10 // subtract
      negate = 1'b1;
    add_one = 1'b1;

    #10 // shift left
      a = 1;
    b = 2;
    negate = 1'b0;
    add_one = 1'b0;

    op = 3'b001;

    #10 // signed comparison a < b
      op = 3'b010;
    #10
      a = -10;
    b = 10;
    #10 // unsigned comparison
      op = 3'b011;
    #10 // xor
      op = 3'b100;
    #10 // shift right logical
      a = -1;
    b = 2;
    op = 3'b101;
    #10 // shift right arithmetical
      sign = 1'b1;
    #10 // or
      sign = 1'b0;
      op = 3'b110;
    #10 // and
      op = 3'b111;

    #10 $finish;
  end
endmodule

A testbench/tb_control_unit.sv => testbench/tb_control_unit.sv +110 -0
@@ 0,0 1,110 @@
import cpu_types::*;

module tb_control_unit();
  reg [31:0] instruction;

  wire       memory_we;

  pc_source_t pc_src;

  wire jump_instruction;
  wire jump_negate_zero;

  wire [31:0] immediate;

  alu_1_source_t alu_src_1;
  alu_2_source_t alu_src_2;

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

  wire [4:0]  reg_rs1;
  wire [4:0]  reg_rs2;

  reg_rd_source_t reg_rd_src;
  wire [4:0]  reg_rd;
  wire        reg_we;

  control_unit uut(
    .instruction(instruction),
    .memory_we(memory_we),
    .pc_src(pc_src),
    .jump_instruction(jump_instruction),
    .jump_negate_zero(jump_negate_zero),
    .immediate(immediate),
    .alu_src_1(alu_src_1),
    .alu_src_2(alu_src_2),
    .alu_op(alu_op),
    .alu_signed(alu_signed),
    .alu_negate(alu_negate),
    .alu_add_one(alu_add_one),
    .reg_rs1(reg_rs1),
    .reg_rs2(reg_rs2),
    .reg_rd_src(reg_rd_src),
    .reg_rd(reg_rd),
    .reg_we(reg_we)
  );

  initial begin
    $dumpfile("control_unit.vcd");
    $dumpvars;

    // addi
    //            imm[11:0] rs1       add     rd        alu imm op
    instruction = {12'h111, 5'b00010, 3'b000, 5'b00001, 7'b0010011};

    #5 // add
    //        funct7 (add) rs2      rs1       add/sub rd        alu reg op
    instruction = {7'b0, 5'b00010, 5'b00011, 3'b000, 5'b00001, 7'b0110011};

    #5 // sub
    //             funct7 (sub) rs2      rs1       add/sub rd        alu reg op
    instruction = {7'b0100000, 5'b00011, 5'b00010, 3'b000, 5'b00001, 7'b0110011};

    #5 // load byte
    //             imm[11:0] rs1      byte    rd        load
    instruction = {12'h111, 5'b00010, 3'b000, 5'b00001, 7'b0000011};

    #5 // load word
    //             imm[11:0] rs1      word    rd        load
    instruction = {12'h111, 5'b00010, 3'b010, 5'b00001, 7'b0000011};

    #5 // store byte
    //             imm[11:5]   rs2       rs1       byte    imm[4:0]  store
    instruction = {7'b0000001, 5'b00001, 5'b00010, 3'b000, 5'b00001, 7'b0100011};

    #5 // store word
    //             imm[11:5]   rs2       rs1       word    imm[4:0]  store
    instruction = {7'b0000001, 5'b00001, 5'b00010, 3'b010, 5'b00001, 7'b0100011};

    #5 // beq
    //          imm[12|10:5]   rs2       rs1       beq  imm[4:1|11]  branch
    instruction = {7'b1100000, 5'b00001, 5'b00010, 3'b000, 5'b00011, 7'b1100011};

    #5 // bge
    instruction = {7'b0000001, 5'b00001, 5'b00010, 3'b101, 5'b00001, 7'b1100011};

    #5 // bltu
    instruction = {7'b0000001, 5'b00001, 5'b00010, 3'b110, 5'b00001, 7'b1100011};

    #5 // jal
    //            imm[20|10:1|11|19:12]      rd        jal
    instruction = {20'b10000000001100000001, 5'b00001, 7'b1101111};

    #5 // jalr
    //            imm[12|10:5]  rs1       000     rd        jalr
    instruction = {12'b0000001, 5'b00001, 3'b000, 5'b00001, 7'b1100111};

    #5 // auipc
    instruction = {20'hA000A, 5'b00001, 7'b0010111};

    #5 // lui
    instruction = {20'hA000A, 5'b00001, 7'b0110111};


    #5 $finish;
  end

endmodule

A testbench/tb_register_file.sv => testbench/tb_register_file.sv +63 -0
@@ 0,0 1,63 @@
module tb_register_file();

  reg clk;
  reg [4:0] a1, a2, a3;

  wire [31:0] rd1, rd2;

  reg         we3;
  reg [31:0]  wd3;

  register_file uut(
    .clk(clk),
    .a1(a1),
    .a2(a2),
    .a3(a3),
    .we3(we3),
    .wd3(wd3),
    .rd1(rd1),
    .rd2(rd2)
  );

  initial begin
    clk = 0;
    forever #5 clk = ~clk;
  end

  initial begin
    $dumpfile("register_file.vcd");
    $dumpvars;
    a1 = 0;
    a2 = 0;
    a3 = 0;

    #10 // r0 is always 0, even on write
      a3 = 0;
    wd3 = 200;
    we3 = 1;

    #10 // r1 is writable
      a3 = 1;
    a1 = 1;

    #10 // r2 is writable
      a3 = 2;
    a2 = 2;

    #10 // r1 is overridable
      a3 = 1;
    wd3 = 100;

    #10 // r1 is not overriden if not we
      wd3 = 150;
      we3 = 0;

    #10
      a2 = 1;
    a1 = 2;

    #10 $finish;
  end


endmodule

Do not follow this link