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