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

    reg err;
    reg [15:0] mdata, sximm5, sximm8, PC;
    reg [2:0] writenum, readnum;
    reg [1:0] shift, ALUop;
    reg write, clk, loada, loadb, loadc, loads, asel, bsel;
    reg [3:0] vsel;
    reg [15:0] datapath_out;
    wire [2:0] Z_out;

//reference to main datapath file being testbenched

datapath DUT (mdata, sximm5, sximm8, PC, writenum, write, readnum, clk,
                loada, loadb, loadc, loads, vsel, asel, bsel, 
                shift, ALUop, Z_out, datapath_out);

task datapathcheck;

    input [15:0] expected_datapath_out; //providing what output should be
    input [2:0] 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 inversing PC input");
    mdata = 16'b0000000000000000;
    sximm8 = 16'b0011100000000000;
    PC = 16'b0000000000000000;
    datapath_out = 16'b0000000111100000;
    vsel = 4'b0001; 
    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 PC input and inverse input
#26;
    datapathcheck(16'b1111111000011111, 3'b000); 
#4;
    $display("Testing ANDing LSR mdata input");
    mdata = 16'b0000000000000000;
    sximm8 = 16'b0011100000000000;
    PC = 16'b0000000000000000;
    datapath_out = 16'b0000000111100000;
    vsel = 4'b1000; 
    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'b0000000000000000, 3'b001);
#4;
    $display("Testing adding LSL sximm8 input");
    mdata = 16'b0000000000000000;
    sximm8 = 16'b0011100000000000;
    PC = 16'b0000000000000000;
    datapath_out = 16'b0000000111100000;
    vsel = 4'b0100; 
    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'b0; bsel = 1'b0; ALUop = 2'b00; //use zeros as left input //add the two inputs
#26;
    datapathcheck(16'b0000010110100000, 3'b110);
#4;
    $display("Testing subtracting LSR PC input");
    mdata = 16'b0000000000000000;
    sximm8 = 16'b0011100000000000;
    PC = 16'b0000000000000000;
    datapath_out = 16'b0000000111100000;
    vsel = 4'b0010; 
    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'b0000000000001000, 3'b000);
#4;
    $display("Testing non-loaded input");
    mdata = 16'b0000000000000000;
    sximm8 = 16'b0011100000000000;
    PC = 16'b0000000000000000;
    datapath_out = 16'b0000000111100000;
    vsel = 4'b0010; 
    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'b0000000000001000, 3'b000); //outputs are old outputs from previous test
#4;
    $display("Testing of reading of empty register");
    mdata = 16'b0000000000000000;
    sximm8 = 16'b0011100000000000;
    PC = 16'b0000000000000000;
    datapath_out = 16'b0000000111100000;
    vsel = 4'b0010; 
    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}}, 3'bxxx); //output is don't care since reading from non-written register
#4;

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


#320;

$stop;

end
endmodule