Added mem[0x000] to log message when printing registers. Replaced 8 delay with explicit 5x 2 delays. (NOTE: Needed an extra one for ensuring write-back when comparing results. Fixed bug where the wrong registers were being added together when creating the comparison point in the testbench. Fixed testbench bug where S4 was checked twice and S5 not checked at all. Updated display message on test failure to reflect that it is the pipelined version, not the single-cycle.
137 lines
4.4 KiB
Systemverilog
137 lines
4.4 KiB
Systemverilog
`include "assignment3.sv"
|
|
|
|
`timescale 1us/10ns
|
|
|
|
`define PRINT_REGISTERS(regs)\
|
|
$display("\tt0-t8: \t0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x\n\ts0-s8: \t0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x 0x%0x\n\tmem[0] = 0x%0x\n",\
|
|
regs[8], regs[9], regs[10], regs[11], regs[12], regs[13], regs[14], regs[15], \
|
|
regs[16], regs[17], regs[18], regs[19], regs[20], regs[21], regs[22], regs[23], \
|
|
CPU.RAM.mem[0]\
|
|
);
|
|
`define TEST_CHECK(cond) if (cond) begin end else begin \
|
|
$display("Check %s failed", `"cond`"); \
|
|
`PRINT_REGISTERS(CPU.REGS.regs); \
|
|
num_errors += 1; \
|
|
end
|
|
|
|
module mips_pipelined_tb();
|
|
logic [0:0] clk;
|
|
logic [0:0] rst;
|
|
assignment3 CPU (clk, rst);
|
|
|
|
initial clk = 0;
|
|
initial rst = 0;
|
|
always #1 clk = ~clk;
|
|
|
|
integer num_errors = 0;
|
|
initial begin
|
|
rst = 1;
|
|
#2;
|
|
rst = 0;
|
|
#2;
|
|
|
|
$dumpfile("output.vcd");
|
|
$dumpvars(0, clk);
|
|
$dumpvars(1, CPU.REGS);
|
|
$dumpvars(2, CPU.ROM);
|
|
$dumpvars(3, CPU.RAM);
|
|
$dumpvars(4, CPU.PC);
|
|
$dumpvars(5, CPU.CONTROL_UNIT);
|
|
$dumpvars(6, CPU.ALU);
|
|
$display("Beginning Pipelined MIPS tests");
|
|
|
|
#2; // 4x steps to allow pipeline to fill up
|
|
#2;
|
|
#2;
|
|
#2;
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[8] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[9] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[10] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[9] == 32'd7);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.RAM.mem[0] == 32'd7);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[10] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[12] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[10] == 32'd7);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[12] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[13] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[11] == (CPU.REGS.regs[9] + CPU.REGS.regs[10]) );
|
|
`TEST_CHECK(CPU.REGS.regs[11] == 32'd14);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[12] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[13] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[14] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[12] == (CPU.REGS.regs[9] - CPU.REGS.regs[11]));
|
|
`TEST_CHECK(CPU.REGS.regs[12] == -32'sd7);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[13] == (CPU.REGS.regs[9] + 3) );
|
|
`TEST_CHECK(CPU.REGS.regs[13] == 32'd10);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[14] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[15] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[16] == 32'd0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[14] == (CPU.REGS.regs[12] + CPU.REGS.regs[13]));
|
|
`TEST_CHECK(CPU.REGS.regs[14] == 32'd3);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[16] == (CPU.REGS.regs[9] & CPU.REGS.regs[13]));
|
|
`TEST_CHECK(CPU.REGS.regs[16] == 32'd2);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[17] == (CPU.REGS.regs[9] | CPU.REGS.regs[13]));
|
|
`TEST_CHECK(CPU.REGS.regs[17] == 32'd15);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[18] == (CPU.REGS.regs[9] ^ CPU.REGS.regs[13]));
|
|
`TEST_CHECK(CPU.REGS.regs[18] == 32'd13);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[19] == ~(CPU.REGS.regs[9] | CPU.REGS.regs[13]));
|
|
`TEST_CHECK(CPU.REGS.regs[19] == 32'hfffffff0);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[20] == ( $signed(CPU.REGS.regs[12]) < $signed(CPU.REGS.regs[14]) ));
|
|
`TEST_CHECK(CPU.REGS.regs[20] == 32'd1);
|
|
#2;
|
|
`TEST_CHECK(CPU.REGS.regs[21] == ( CPU.REGS.regs[12] < CPU.REGS.regs[14] ));
|
|
`TEST_CHECK(CPU.REGS.regs[21] == 32'd0);
|
|
|
|
// TODO: Verify program never branches
|
|
#2;
|
|
#2;
|
|
#2;
|
|
#2;
|
|
|
|
// TODO: Verify final program register state
|
|
|
|
|
|
if (num_errors == 0) begin $display("\x1b[38;5;10mAll pipelined MIPS tests passing\x1b[m");
|
|
end else begin $display("\x1b[38;5;9m%0d pipelined MIPS test(s) failing\x1b[m", num_errors); end
|
|
|
|
$dumpflush;
|
|
$finish;
|
|
end
|
|
endmodule |