risc-processor-211 / CPEN Lab 5 / datapath_tb.v
datapath_tb.v
Raw
module datapath_tb();

    //Signals for regfile testbench
    reg err;
    reg [15:0] datapath_in;
    reg [2:0] writenum, readnum;
    reg [1:0] shift, ALUop;
    reg write, clk, loada, loadb, loadc, loads, asel, bsel, vsel;
    wire [15:0] datapath_out;
    wire Z_out;

datapath DUT (datapath_in, writenum, write, readnum, clk,       //reference to main datapath file being testbenched
    loada, loadb, loadc, loads, asel, bsel, vsel, shift, ALUop, datapath_out, Z_out);

task datapathcheck;

    input [15:0] expected_datapath_out; //providing what output should be
    input expected_z_out;               //providing what Z should be

    begin
    
        if(datapath_tb.DUT.datapath_out !== expected_datapath_out) begin //outputs error if output isn't matching expected
            $display("ERROR: output is %b, expected %b",
            datapath_tb.DUT.datapath_out, expected_datapath_out);
            err = 1'b1; end

        if(datapath_tb.DUT.Z_out !== expected_z_out) begin  //outputs error if Z isnt matching
            $display("ERROR: Z is %b, expected %b",
            datapath_tb.DUT.Z_out, expected_z_out);
            err = 1'b1; end
    end
endtask

initial begin
    clk = 1'b0; #5; //repeating clock in 5ps second intervals

    forever begin
        clk = 1'b1; #5;
        clk = 1'b0; #5;
    end
end

initial begin
    err = 1'b0; 
    $display("Testing input 32");
    datapath_in = 16'b0000000000100000; 
    vsel = 1'b1; //use datapath_in
    write = 1'b1; //allow writing
    writenum = 3'b101; //write to reg 5
    readnum = 3'b101;  //read from reg 5
    loada = 1'b1; loadb = 1'b1; loadc = 1'b1; loads = 1'b1; //allow the datapath_in inputs through
    shift = 2'b00; //no shift
    asel = 1'b0; bsel = 1'b0; ALUop = 2'b11; //use datapath_in inputs and inverse input
#26;
    datapathcheck(16'b1111111111011111, 1'b0); 
#4;
    $display("Testing input 108");
    datapath_in = 16'b0000000001101100;
    vsel = 1'b1;
    write = 1'b1;
    writenum = 3'b111; //reg 7 read and write
    readnum = 3'b111; 
    loada = 1'b1; loadb = 1'b1; loadc = 1'b1; loads = 1'b1;
    shift = 2'b10; //shift right
    asel = 1'b0; bsel = 1'b0; ALUop = 2'b10; //ANDing inputs
#26;
    datapathcheck(16'b0000000000100100, 1'b0);
#4;
    $display("Testing input 6");
    datapath_in = 16'b0000000000000110;
    vsel = 1'b1;
    write = 1'b1;
    writenum = 3'b000; //reg 0 read and write
    readnum = 3'b000; 
    loada = 1'b1; loadb = 1'b1; loadc = 1'b1; loads = 1'b1;
    shift = 2'b01;  //shift left
    asel = 1'b1; bsel = 1'b0; ALUop = 2'b00; //use zeros as left input //add the two inputs
#26;
    datapathcheck(16'b0000000000001100, 1'b0);
#4;
    $display("Testing input 1");
    datapath_in = 16'b0000000000000001;
    vsel = 1'b0; //use datapath_out
    write = 1'b1;
    writenum = 3'b010; //reg 2 read and write
    readnum = 3'b010; 
    loada = 1'b1; loadb = 1'b1; loadc = 1'b1; loads = 1'b1;
    shift = 2'b10;  //shift right
    asel = 1'b0; bsel = 1'b0; ALUop = 2'b01; //subtract the two inputs
#26;
    datapathcheck(16'b0000000000000110, 1'b0);

#4;
    $display("Testing input 99");
    datapath_in = 16'b0000000001100011;
    vsel = 1'b1;
    write = 1'b1;
    writenum = 3'b001; //reg 1 read and write
    readnum = 3'b001; 
    loada = 1'b1; loadb = 1'b1; loadc = 1'b1; loads = 1'b1;
    shift = 2'b00; //no shift
    asel = 1'b0; bsel = 1'b0; ALUop = 2'b01; //subtract the two inputs 
#26;
    datapathcheck(16'b0000000000000000, 1'b1); //output is zero so Z is 1
#4;
    $display("Testing input 4");
    datapath_in = 16'b0000000000000100; 
    vsel = 1'b1;
    write = 1'b1;
    writenum = 3'b010; //reg 2 read and write
    readnum = 3'b010; 
    loada = 1'b1; loadb = 1'b1; loadc = 1'b0; loads = 1'b0; //dont allow updated datapath_in and Z data
    shift = 2'b00; //no shift
    asel = 1'b0; bsel = 1'b0; ALUop = 2'b01; //subtraction
#26;
    datapathcheck(16'b0000000000000000, 1'b1); //outputs are old outputs from previous test
#4;
    $display("Testing input 4");
    datapath_in = 16'b0000000000000100;
    vsel = 1'b1;
    write = 1'b1;
    writenum = 3'b100; //reg 4 write
    readnum = 3'b011;  //reg 3 read
    loada = 1'b1; loadb = 1'b1; loadc = 1'b1; loads = 1'b1;
    shift = 2'b00; //no shift
    asel = 1'b0; bsel = 1'b0; ALUop = 2'b01; //subtraction
#26;
    datapathcheck({16{1'bx}}, 1'b0); //output is don't care since reading from non-written register
#4;

  if(~err) $display("PASSED");
  else $display("FAILED");

#290;

end
endmodule