diff options
Diffstat (limited to 'rtl/tb_lisp_coproc.sv')
| -rw-r--r-- | rtl/tb_lisp_coproc.sv | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/rtl/tb_lisp_coproc.sv b/rtl/tb_lisp_coproc.sv new file mode 100644 index 0000000..6c39aa4 --- /dev/null +++ b/rtl/tb_lisp_coproc.sv | |||
| @@ -0,0 +1,171 @@ | |||
| 1 | `timescale 1ns/1ps | ||
| 2 | |||
| 3 | module tb_lisp_coproc; | ||
| 4 | |||
| 5 | // Testbench signals | ||
| 6 | reg clk; | ||
| 7 | reg rst; | ||
| 8 | reg cs; | ||
| 9 | reg rw; // 0=Write, 1=Read | ||
| 10 | reg [2:0] addr; | ||
| 11 | reg [7:0] data_in; | ||
| 12 | wire [7:0] data_out; | ||
| 13 | |||
| 14 | // Test variables | ||
| 15 | reg [7:0] read_data; | ||
| 16 | integer i; | ||
| 17 | |||
| 18 | // Instantiate the DUT | ||
| 19 | lisp_coproc dut ( | ||
| 20 | .clk(clk), | ||
| 21 | .rst(rst), | ||
| 22 | .cs(cs), | ||
| 23 | .rw(rw), | ||
| 24 | .addr(addr), | ||
| 25 | .data_in(data_in), | ||
| 26 | .data_out(data_out) | ||
| 27 | ); | ||
| 28 | |||
| 29 | // Clock generation | ||
| 30 | initial begin | ||
| 31 | clk = 0; | ||
| 32 | forever #5 clk = ~clk; | ||
| 33 | end | ||
| 34 | |||
| 35 | // CPU Write Task | ||
| 36 | task cpu_write; | ||
| 37 | input [2:0] addr_in; | ||
| 38 | input [7:0] data_in_in; | ||
| 39 | begin | ||
| 40 | @(posedge clk); | ||
| 41 | cs = 1'b1; | ||
| 42 | rw = 1'b0; // Write | ||
| 43 | addr = addr_in; | ||
| 44 | data_in = data_in_in; | ||
| 45 | @(posedge clk); | ||
| 46 | cs = 1'b0; | ||
| 47 | end | ||
| 48 | endtask | ||
| 49 | |||
| 50 | // CPU Read Task | ||
| 51 | task cpu_read; | ||
| 52 | input [2:0] addr_in; | ||
| 53 | output [7:0] data_out_out; | ||
| 54 | reg [7:0] status; | ||
| 55 | begin | ||
| 56 | // Poll until not busy | ||
| 57 | do begin | ||
| 58 | @(posedge clk); | ||
| 59 | cs = 1'b1; | ||
| 60 | rw = 1'b1; // Read | ||
| 61 | addr = 3'h4; // Status register | ||
| 62 | @(posedge clk); | ||
| 63 | status = data_out; | ||
| 64 | cs = 1'b0; | ||
| 65 | end while (status[0]); // Check BUSY bit | ||
| 66 | |||
| 67 | // Read the requested address | ||
| 68 | @(posedge clk); | ||
| 69 | cs = 1'b1; | ||
| 70 | rw = 1'b1; // Read | ||
| 71 | addr = addr_in; | ||
| 72 | @(posedge clk); | ||
| 73 | data_out_out = data_out; | ||
| 74 | cs = 1'b0; | ||
| 75 | end | ||
| 76 | endtask | ||
| 77 | |||
| 78 | // Test Sequence | ||
| 79 | initial begin | ||
| 80 | // Initialize signals | ||
| 81 | rst = 1'b1; | ||
| 82 | cs = 1'b0; | ||
| 83 | rw = 1'b0; | ||
| 84 | addr = 3'h0; | ||
| 85 | data_in = 8'h00; | ||
| 86 | |||
| 87 | // Apply reset | ||
| 88 | #20; | ||
| 89 | rst = 1'b0; | ||
| 90 | #20; | ||
| 91 | |||
| 92 | // Test 1: Reset Test | ||
| 93 | $display("Test 1: Reset Test"); | ||
| 94 | cpu_read(3'h4, read_data); // Read STATUS | ||
| 95 | $display("STATUS after reset: 0x%02h (expected: 0x00)", read_data); | ||
| 96 | if (read_data != 8'h00) $display("ERROR: Reset test failed"); | ||
| 97 | |||
| 98 | // Test 2: ADD Test | ||
| 99 | $display("\nTest 2: ADD Test"); | ||
| 100 | cpu_write(3'h1, 8'h85); // ARG1 = NUMBER(5) | ||
| 101 | cpu_write(3'h2, 8'h86); // ARG2 = NUMBER(6) | ||
| 102 | cpu_write(3'h0, 8'h06); // OPCODE = ADD | ||
| 103 | |||
| 104 | cpu_read(3'h3, read_data); // Read RESULT | ||
| 105 | $display("ADD Result: 0x%02h (expected: 0x8B, NUMBER(11))", read_data); | ||
| 106 | if (read_data != 8'h8B) $display("ERROR: ADD test failed"); | ||
| 107 | |||
| 108 | cpu_read(3'h4, read_data); // Read STATUS | ||
| 109 | $display("STATUS after ADD: 0x%02h (expected: 0x00, ZERO=0)", read_data); | ||
| 110 | if (read_data != 8'h00) $display("ERROR: ADD status test failed"); | ||
| 111 | |||
| 112 | // Test 3: CONS Test | ||
| 113 | $display("\nTest 3: CONS Test"); | ||
| 114 | cpu_write(3'h1, 8'h41); // ARG1 = ATOM('T') | ||
| 115 | cpu_write(3'h2, 8'h42); // ARG2 = ATOM('B') | ||
| 116 | cpu_write(3'h0, 8'h01); // OPCODE = CONS | ||
| 117 | |||
| 118 | cpu_read(3'h3, read_data); // Read RESULT | ||
| 119 | $display("CONS Result: 0x%02h (expected: 0xC0, CONS(0))", read_data); | ||
| 120 | if (read_data != 8'hC0) $display("ERROR: CONS test failed"); | ||
| 121 | |||
| 122 | // Test CAR and CDR | ||
| 123 | cpu_write(3'h1, read_data); // Use the CONS result as ARG1 | ||
| 124 | cpu_write(3'h0, 8'h02); // OPCODE = CAR | ||
| 125 | |||
| 126 | cpu_read(3'h3, read_data); // Read RESULT | ||
| 127 | $display("CAR Result: 0x%02h (expected: 0x41, ATOM('T'))", read_data); | ||
| 128 | if (read_data != 8'h41) $display("ERROR: CAR test failed"); | ||
| 129 | |||
| 130 | cpu_write(3'h1, 8'hC0); // ARG1 = CONS(0) | ||
| 131 | cpu_write(3'h0, 8'h03); // OPCODE = CDR | ||
| 132 | |||
| 133 | cpu_read(3'h3, read_data); // Read RESULT | ||
| 134 | $display("CDR Result: 0x%02h (expected: 0x42, ATOM('B'))", read_data); | ||
| 135 | if (read_data != 8'h42) $display("ERROR: CDR test failed"); | ||
| 136 | |||
| 137 | // Test 4: Error Test (CAR on a Number) | ||
| 138 | $display("\nTest 4: Error Test (CAR on a Number)"); | ||
| 139 | cpu_write(3'h1, 8'h85); // ARG1 = NUMBER(5) | ||
| 140 | cpu_write(3'h0, 8'h02); // OPCODE = CAR | ||
| 141 | |||
| 142 | cpu_read(3'h4, read_data); // Read STATUS | ||
| 143 | $display("STATUS after CAR on Number: 0x%02h (expected: 0x04, ERR_TYPE=1)", read_data); | ||
| 144 | if (read_data != 8'h04) $display("ERROR: Error test failed"); | ||
| 145 | |||
| 146 | // Test 5: Heap Full Test | ||
| 147 | $display("\nTest 5: Heap Full Test"); | ||
| 148 | // Fill the heap with CONS operations | ||
| 149 | // Since bump_alloc is now 2, we have used 2 cells. | ||
| 150 | // 16 cells total. 14 left. 7 more CONS possible. | ||
| 151 | for (i = 0; i < 7; i = i + 1) begin | ||
| 152 | cpu_write(3'h1, 8'h41); | ||
| 153 | cpu_write(3'h2, 8'h42); | ||
| 154 | cpu_write(3'h0, 8'h01); | ||
| 155 | cpu_read(3'h3, read_data); | ||
| 156 | end | ||
| 157 | |||
| 158 | // One more CONS should cause heap full error | ||
| 159 | cpu_write(3'h1, 8'h41); | ||
| 160 | cpu_write(3'h2, 8'h42); | ||
| 161 | cpu_write(3'h0, 8'h01); | ||
| 162 | |||
| 163 | cpu_read(3'h4, read_data); // Read STATUS | ||
| 164 | $display("STATUS after Heap Full: 0x%02h (expected: 0x02, ERR_HEAP_FULL=1)", read_data); | ||
| 165 | if (read_data != 8'h02) $display("ERROR: Heap Full test failed"); | ||
| 166 | |||
| 167 | $display("\nAll tests completed."); | ||
| 168 | $finish; | ||
| 169 | end | ||
| 170 | |||
| 171 | endmodule | ||
