Fixed printing annoyance. Added variable dumping to a wavefile. Updated delay to 2 units (as there is 1 unit of clk being high and 1 unit low).

Removed register initialisation code from testbench.
Fixed typo when wanting to check T0 (R8) but was checking R0.
Added explicit if-else begin-end blocks to logging and a simulation exit when the testbench is done.
This commit is contained in:
riley committed 2026-10-16 11:41:33 +11:00
1 parent 92a0cb17da
commit 559ff01d69
1 file changed
+41 -26
+41 -26
View File
@@ -1,76 +1,88 @@
`include "assignment2.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",\
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] \
);
`define TEST_CHECK(cond) if (cond) begin end else begin \
$display("Check %s failed\n", `"cond`"); \
$display("Check %s failed", `"cond`"); \
`PRINT_REGISTERS(CPU.REGS.regs); \
num_errors += 1; \
end
module mips_tb(input logic [0:0] clk);
module mips_tb();
logic [0:0] clk;
assignment2 #(5) CPU (clk);
initial clk = 0;
always #1 clk = ~clk;
integer num_errors = 0;
initial begin
$dumpfile("output.vcd");
$dumpvars(0, clk);
$dumpvars(1, CPU.REGS);
$dumpvars(2, CPU.ROM);
$dumpvars(3, CPU.PC);
$dumpvars(4, CPU.pc_addr);
$dumpvars(5, CPU.CONTROL_UNIT);
$dumpvars(5, CPU.instruction);
$dumpvars(5, CPU.ALU);
// Zero out lower registers
$display("Beginning MIPS tests");
assign num_errors = 0;
for (integer N = 1; N < 32; ++N)
CPU.REGS.regs[N] = 32'd0;
// Check R-type / initialise
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[8] == 32'd0);
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[9] == (CPU.REGS.regs[8] + 32'd7));
// Check load-store
#1;
#2;
`TEST_CHECK(CPU.RAM.mem[0] == CPU.REGS.regs[9]);
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[10] == CPU.RAM.mem[0]);
// Check arithmetic
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[11] == (CPU.REGS.regs[9] + CPU.REGS.regs[10]));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[12] == (CPU.REGS.regs[9] - CPU.REGS.regs[11]));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[13] == (CPU.REGS.regs[9] + 3));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[14] == (CPU.REGS.regs[12] + CPU.REGS.regs[13]));
// Check logic instructions
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[16] == (CPU.REGS.regs[9] & CPU.REGS.regs[13]));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[17] == (CPU.REGS.regs[9] | CPU.REGS.regs[13]));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[18] == (CPU.REGS.regs[9] ^ CPU.REGS.regs[13]));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[19] == ( ~(CPU.REGS.regs[9] | CPU.REGS.regs[13]) ));
// Check SLT instructions
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[20] == $signed(CPU.REGS.regs[12]) < $signed(CPU.REGS.regs[14]));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[21] == $unsigned(CPU.REGS.regs[12]) < $unsigned(CPU.REGS.regs[14]));
// Check loop branching
for (integer N = 1; N < 11; ++N) begin
#1;
`TEST_CHECK(CPU.REGS.regs[0] == 32'(N));
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[8] == 32'(N));
#2;
`TEST_CHECK(CPU.REGS.regs[22] == $unsigned(CPU.REGS.regs[8]) < $unsigned(CPU.REGS.regs[13]));
end
// Final state check
#1;
#2;
`TEST_CHECK(CPU.REGS.regs[8] == 32'd10);
`TEST_CHECK(CPU.REGS.regs[9] == 32'd7);
`TEST_CHECK(CPU.REGS.regs[10] == 32'd7);
@@ -89,7 +101,10 @@ module mips_tb(input logic [0:0] clk);
`TEST_CHECK(CPU.REGS.regs[22] == 32'd0);
`TEST_CHECK(CPU.REGS.regs[23] == 32'd0);
if (num_errors == 0) $display("\x1b[38;5;10mAll MIPS tests passing\x1b[m");
else $display("\x1b[38;5;9m%0d MIPS test(s) failing\x1b[m", num_errors);
if (num_errors == 0) begin $display("\x1b[38;5;10mAll MIPS tests passing\x1b[m");
end else begin $display("\x1b[38;5;9m%0d MIPS test(s) failing\x1b[m", num_errors); end
$dumpflush;
$finish;
end
endmodule