aboutsummaryrefslogtreecommitdiffstats
path: root/atk16_fpga/alu_tb.v
blob: 559e23bc8a85ea5d32b5791544f6435f5d746ecf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
`default_nettype none
`define DUMPSTR(x) `"x.vcd`"

`define PLUS  3'd0
`define MINUS 3'd1
`define AND   3'd2
`define OR    3'd3
`define XOR   3'd4
`define SHL   3'd5
`define SHR   3'd6
`define SAR   3'd7

`define TESTCASE(ma, msel, mb, mexpected, mflags) \
    sel      = `msel; \
    a        = ma; \
    b        = mb; \
    #5 if (result != $unsigned(mexpected) || flags !== mflags) begin \
        failed = 1; \
        $write("\033[0;31m[FAIL]\033[0m "); \
        $display("%d msel %0d = %0d, flags %04b", a, b, result, flags); \
        $display("_             expected result %0d", $unsigned(mexpected)); \
        $display("_             expected flags  %04b", mflags); \
    end \
    else begin \
        $write("\033[0;32m[PASS]\033[0m "); \
        $display("%d msel %0d = %0d, flags %04b", a, b, result, flags); \
    end

`timescale 10 ns / 100 ps
module alu_tb();

    reg  [2:0]  sel;
    reg  [15:0] a, b;
    wire [15:0] result;
    wire [3:0]  flags;

    alu dut (
        .sel(sel),
        .a(a),
        .b(b),
        .result(result),
        .flags(flags)
    );

    reg failed;
    initial begin
        failed = 0;
        $dumpfile(`DUMPSTR(`VCD_OUTPUT));
        $dumpvars(0, alu_tb);

        `TESTCASE(16'd10, PLUS, 16'd20, 16'd30, 4'b0000)
        `TESTCASE(-16'd1, PLUS, 16'd1, 16'd0, 4'b1001)
        `TESTCASE(16'h7fff, PLUS, 16'h7fff, 16'hfffe, 4'b0110)
        `TESTCASE(16'd30, MINUS, 16'd30, 16'd0, 4'b0001)
        `TESTCASE(16'd30, MINUS, 16'd40, -16'd10, 4'b1010)
        `TESTCASE(16'h7fff, MINUS, 16'h7fff, 16'd0, 4'b0001)
        `TESTCASE(16'h8000, MINUS, 16'h1, 16'h7fff, 4'b0100)
        `TESTCASE(16'b110, AND, 16'b101, 16'b100, 4'b0000)
        `TESTCASE(16'b110, OR, 16'b101, 16'b111, 4'b0000)
        `TESTCASE(16'b110, XOR, 16'b101, 16'b011, 4'b0000)
        `TESTCASE(16'b110, SHL, 16'd3, 16'b110000, 4'b0000)
        `TESTCASE(16'b1100_0000_0000_0000, SHR, 16'd3, 16'b0001_1000_0000_0000, 4'b0000)
        `TESTCASE(16'b1100_0000_0000_0000, SAR, 16'd3, 16'b1111_1000_0000_0000, 4'b0010)

        #5
        if (failed) begin
            $display("🛑 \033[0;31mTest suite failed\033[0m");
            $fatal(1);
        end else
            $display("✅ \033[0;32mTest suite passed\033[0m");
        $finish;
    end
endmodule