OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [test.S] - Blame information for rev 26

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dgisselq
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;
3
; Filename:     test.S
4
;
5
; Project:      Zip CPU -- a small, lightweight, RISC CPU soft core
6
;
7
; Purpose:      A disorganized test, just showing some initial operation of
8
;               the CPU.  As a disorganized test, it doesn't prove anything
9
;               beyond the generic operation of the CPU.
10
;
11 13 dgisselq
; Status:       As of August, 2015, this file assembles, builds, and passes
12
;               all of its tests in the Verilator simulator.
13 2 dgisselq
;
14 19 dgisselq
;       Okay, as of 15 August, there are now some tests that don't pass.
15
;       In particular, the #include test used to pass but didn't pass today.
16
;       Likewise the PUSH() macro test hasn't passed yet.  Finally, be aware
17
;       that this implementation is specific to where it loads on a board.
18
;       I tried loading it on my Basys development board, where I had placed
19
;       RAM in a different location and ... things didn't work out so well.
20
;       So grep the __here__ line and adjust it for where you intend to load
21
;       this file.
22
;
23
;       In general, as I'm building the CPU, I'm modifying this file to place
24
;       more and more capability tests within the file.  If the Lord is
25
;       willing, this will become the proof that the CPU completely works.
26
;
27
;
28 2 dgisselq
; Creator:      Dan Gisselquist, Ph.D.
29
;               Gisselquist Tecnology, LLC
30
;
31
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
32
;
33
; Copyright (C) 2015, Gisselquist Technology, LLC
34
;
35
; This program is free software (firmware): you can redistribute it and/or
36
; modify it under the terms of  the GNU General Public License as published
37
; by the Free Software Foundation, either version 3 of the License, or (at
38
; your option) any later version.
39
;
40
; This program is distributed in the hope that it will be useful, but WITHOUT
41
; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
42
; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
43
; for more details.
44
;
45
; License:      GPL, v3, as defined and found on www.gnu.org,
46
;               http://www.gnu.org/licenses/gpl.html
47
;
48
;
49
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
50
;
51 26 dgisselq
#include "sys.i"
52 13 dgisselq
        sys.bus         equ     0xc0000000
53
        sys.breaken     equ     0x080
54
        sys.step        equ     0x040
55
        sys.gie         equ     0x020
56
        sys.sleep       equ     0x010
57
        sys.ccv         equ     0x008
58
        sys.ccn         equ     0x004
59
        sys.ccc         equ     0x002
60
        sys.ccz         equ     0x001
61 26 dgisselq
        sys.cctrap      equ     0x200
62 13 dgisselq
        sys.bu.pic      equ     0x000
63
        sys.bus.wdt     equ     0x001
64
        sys.bus.cache   equ     0x002
65
        sys.bus.ctrpic  equ     0x003
66
        sys.bus.tma     equ     0x004
67
        sys.bus.tmb     equ     0x005
68
        sys.bus.tmc     equ     0x006
69
        sys.bus.jiffies equ     0x007
70
        sys.bus.mtask   equ     0x008
71
        sys.bus.mpstl   equ     0x009
72
        sys.bus.mastl   equ     0x00a
73
        sys.bus.mstl    equ     0x00b
74
        sys.bus.utask   equ     0x00c
75
        sys.bus.upstl   equ     0x00d
76
        sys.bus.uastl   equ     0x00e
77
        sys.bus.ustl    equ     0x00f
78
#define DO_TEST_ASSEMBLER
79 26 dgisselq
#define BREAK_TEST
80
#define OVERFLOW_TEST
81
#define CARRY_TEST
82
#define LOOP_TEST
83
#define SHIFT_TEST
84
#define TRAP_TEST
85
#define MPY_TEST
86
// #define      PUSH_TEST
87 2 dgisselq
test:
88 13 dgisselq
#ifdef  DO_TEST_ASSEMBLER
89
; We start out by testing our assembler.  We give it some instructions, which
90
; are then manually checked  by disassembling/dumping the result and making
91
; certain they match.  This is not an automated test, but it is an important
92
; one.
93
        noop
94
        bra     continue_test_with_testable_instructions
95
        break
96
        wait
97 26 dgisselq
        break
98 13 dgisselq
        busy
99
        rtu
100
continue_test_with_testable_instructions:
101
        ; Now, let's place the assembler into a known state
102 2 dgisselq
        clr     r0
103 13 dgisselq
        clr     r1
104
        clr     r2
105
        clr     r3
106
        clr     r4
107
        clr     r5
108
        clr     r6
109
        clr     r7
110
        clr     r9
111
        clr     r10
112
        clr     r11
113
        clr     r12
114
        clr     r13
115
        ; Don't clear the CC register
116
        ; Don't clear the SP register
117
        ; And repeat for the user registers
118
        mov     R0,uR0
119
        mov     R0,uR1
120
        mov     R0,uR2
121
        mov     R0,uR3
122
        mov     R0,uR4
123
        mov     R0,uR5
124
        mov     R0,uR6
125
        mov     R0,uR7
126
        mov     R0,uR8
127
        mov     R0,uR9
128
        mov     R0,uR10
129
        mov     R0,uR11
130
        mov     R0,uR12
131
        mov     R0,uR13
132
        mov     R0,uCC
133
        ; Don't clear the user PC register
134
        ; Now, let's try loading some constants into registers
135 19 dgisselq
        ; Specifically, we're testing the LDI, LDIHI, and LDILO instructions
136 13 dgisselq
dead_beef       equ     0xdeadbeef
137
        ldi     0x0dead,r5
138
        ldi     0x0beef,r6
139
        ldi     0xdeadbeef,r7
140
        ldihi   0xdead, r8
141
        ldilo   0xbeef, r8
142
        ldi     dead_beef,r9
143
        cmp     r5,r6
144
        bz      test_failure
145
        cmp     r7,r8
146
        bnz     test_failure
147
        ldi     $deadbeefh,r7   ; Try loading with the $[HEX]h mneumonic
148
        cmp     r7,r8
149
        bnz     test_failure
150
        cmp     r7,r9
151
        bnz     test_failure
152
        bra     skip_dead_beef
153
dead_beef.base:
154
        word    0
155
        fill    5,dead_beef
156
        word    0
157
dead_beef.zero          equ     0
158
dead_beef.values        equ     1
159
skip_dead_beef:
160
        lod     dead_beef.base(pc),r10  ; Should load a zero here
161
        cmp     r10,r11                 ; r11 should still be zero from init abv
162
        bnz     test_failure
163
        mov     dead_beef.base(pc),r10  ; Now, let's get the address
164
        lod     dead_beef.values(r10),r10       ; r10 now equals 0xdeadbeef
165
        cmp     r10,r9
166
        bnz     test_failure
167
 
168
; Test whether or not we can properly decode OCTAL values
169
        clr     r0      ; Re-clear our register set first
170
        clr     r1
171
        clr     r2
172
        clr     r3
173
        clr     r4
174
        clr     r5
175
        clr     r6
176
        clr     r7
177
        clr     r9
178
        clr     r10
179
        clr     r11
180
        clr     r12
181
        clr     r13
182
        ;
183
        ldi     $024o,r0
184
        ldi     $20,r1
185
        cmp     r0,r1
186
        bnz     test_failure
187
        ldi     $024,r0
188
        cmp     r0,r1
189
        bnz     test_failure
190
        clr     r0
191
        clr     r1
192 2 dgisselq
        mov     $1+r0,r2
193
        mov     $2+r0,r3
194
        mov     $22h+r0,r4
195
        mov     $377h+r0,ur5
196
        noop
197
        nop
198
        add     r2,r0
199
        add     $32,r0
200
        add     $-33,r0
201 13 dgisselq
        bnz     test_failure
202 2 dgisselq
        not.z   r0
203 13 dgisselq
        bge     test_failure
204
junk_address:
205 2 dgisselq
        clrf    r0
206 13 dgisselq
        bnz     test_failure
207 2 dgisselq
        ldi     $5,r1
208
        cmp     $0+r0,r1
209
        not.lt  r0
210
        not.ge  r1
211 13 dgisselq
        mov     junk_address(pc),r2     ; Test pc-relative addressing
212
        mov     junk_address(pc),r3
213
        cmp     r2,r3
214
        bnz     test_failure
215
        lod     junk_address(pc),r5     ; Test loads with pc-relative addressing
216
        lod     junk_address(pc),r6
217
        cmp     r5,r6
218
        bnz     test_failure
219 26 dgisselq
#endif
220
 
221
#ifdef  NOONE // Testing comments after ifdef
222
#else   ; After else
223
#endif /* and after endif */
224
 
225
#ifdef  BREAK_TEST
226
breaktest:
227
        bra     breaksupervisor
228
breakuser:
229
        clr     r0
230
        mov     1+r0,r1
231
        mov     1+r1,r2
232
        mov     1+r2,r3
233
        break           ; At address 0x0100097
234
        mov     1+r4,r5
235
        mov     1+r5,r6
236
        clr     cc
237
        busy
238
breaksupervisor:
239 13 dgisselq
        ldi     -1,r0
240 26 dgisselq
        mov     breakuser(pc),upc
241
        rtu     ; Should just keep returning immediately
242
        mov     upc,r0
243
        rtu
244
        rtu
245
        mov     upc,r1
246
        cmp     r0,r1
247 13 dgisselq
        bnz     test_failure
248 26 dgisselq
#endif
249
 
250
#ifdef  TRAP_TEST
251
traptest:
252
        bra     traptest_supervisor
253
        busy
254
traptest_user:
255
        trap    0
256
        busy
257
traptest_supervisor:
258
        mov     traptest_user(pc),upc
259
        rtu
260
        mov     cc,r0
261
        tst     sys.cctrap,r0
262 13 dgisselq
        bz      test_failure
263
#endif
264 2 dgisselq
 
265
testbench:
266
        // Let's build a software test bench.
267 13 dgisselq
        ldi     $c0000000h,r12  ; Set R12 to point to our peripheral address
268 2 dgisselq
        mov     r12,ur12
269 13 dgisselq
        mov     test_start(pc),upc
270
        ldi     0x8000ffff,r0   ; Clear interrupts, turn all vectors off
271
        sto     r0,(r12)
272 2 dgisselq
        rtu
273 13 dgisselq
        mov     ucc,r0
274 26 dgisselq
        cmp     sys.cctrap,r0
275 13 dgisselq
        bnz     test_failure
276 2 dgisselq
        halt
277 13 dgisselq
// Go into an infinite loop if the trap fails
278
// Permanent loop instruction -- a busy halt if you will
279
test_failure:
280 2 dgisselq
        busy
281
 
282
; Now for a series of tests.  If the test fails, call the trap
283
; interrupt with the test number that failed.  Upon completion,
284
; call the trap with #0.
285
 
286
; Test LDI to PC
287
; Some data registers
288 13 dgisselq
test_data:
289
        .dat    __here__+0x0100000+5
290 2 dgisselq
test_start:
291 26 dgisselq
        ldi     $0x01000,r11
292 13 dgisselq
        lod     test_data+pc,pc
293 2 dgisselq
        clr     r11
294
        noop
295
        cmp     $0,r11
296 13 dgisselq
        trap.z  r11
297 2 dgisselq
        add     $1,r0
298
        add     $1,r0
299
 
300 26 dgisselq
#ifdef  OVERFLOW_TEST
301 2 dgisselq
// Let's test whether overflow works
302 26 dgisselq
        ldi     $0x02000,r11
303 2 dgisselq
        ldi     $-1,r0
304
        lsr     $1,r0
305
        add     $1,r0
306 13 dgisselq
        bv      first_overflow_passes
307
        trap    r11
308
first_overflow_passes:
309 2 dgisselq
// Overflow set from subtraction
310 26 dgisselq
        ldi     $0x03000,r11
311 2 dgisselq
        ldi     $1,r0
312 13 dgisselq
        rol     $31,r0                  ; rol $31,r0
313 2 dgisselq
        sub     $1,r0
314 13 dgisselq
        bv      subtraction_overflow_passes
315
        trap    r11
316
subtraction_overflow_passes:
317 2 dgisselq
// Overflow set from LSR
318 26 dgisselq
        ldi     $0x04000,r11
319 2 dgisselq
        ldi     $1,r0
320 13 dgisselq
        rol     $31,r0                  ; rol $31,r0
321 2 dgisselq
        lsr     $1,r0
322 13 dgisselq
        bv      lsr_overflow_passes
323
        trap    r11
324
lsr_overflow_passes:
325 2 dgisselq
// Overflow set from LSL
326 26 dgisselq
        ldi     $0x05000,r11
327 2 dgisselq
        ldi     $1,r0
328 13 dgisselq
        rol     $30,r0
329 2 dgisselq
        lsl     $1,r0
330 13 dgisselq
        bv      lsl_overflow_passes
331
        trap    r11
332
lsl_overflow_passes:
333 2 dgisselq
// Overflow set from LSL, negative to positive
334 26 dgisselq
        ldi     $0x06000,r11
335 2 dgisselq
        ldi     $1,r0
336 13 dgisselq
        rol     $31,r0
337 2 dgisselq
        lsl     $1,r0
338 13 dgisselq
        bv      second_lsl_overflow_passes
339
        trap    r11
340 26 dgisselq
#endif // OVERFLOW_TEST
341
#ifdef  CARRY_TEST
342 13 dgisselq
second_lsl_overflow_passes:
343 2 dgisselq
// Test carry
344 26 dgisselq
        ldi     $0x07000,r11
345 2 dgisselq
        ldi     $-1,r0
346
        add     $1,r0
347
        tst     $2,cc
348 13 dgisselq
        trap.z  r11
349 2 dgisselq
// and carry from subtraction
350 26 dgisselq
        ldi     $0x08000,r11
351
        clr     r0
352 2 dgisselq
        sub     $1,r0
353
        tst     $2,cc
354 13 dgisselq
        trap.z  r11
355 26 dgisselq
#endif
356 2 dgisselq
 
357 26 dgisselq
#ifdef  LOOP_TEST
358
 
359 2 dgisselq
// Let's try a loop: for i=0; i<5; i++)
360
//      We'll use R0=i, Immediates for 5
361 26 dgisselq
        ldi     $0x09000,r11
362 13 dgisselq
        clr     r0
363 2 dgisselq
for_loop:
364
        noop
365
        add     $1,r0
366
        cmp     $5,r0
367
        blt     for_loop
368
//
369
// Let's try a reverse loop.  Such loops are usually cheaper to
370
// implement, and this one is no different: 2 loop instructions
371
// (minus setup instructions) vs 3 from before.
372
// R0 = 5; (from before)
373
// do {
374
// } while (R0 > 0);
375 26 dgisselq
        ldi     $0x0a000,r11
376 2 dgisselq
bgt_loop:
377
        noop
378
        sub     $1,r0
379
        bgt     bgt_loop
380
 
381
// How about the same thing with a >= comparison?
382
// R1 = 5; // Need to do this explicitly
383
// do {
384
// } while(R1 >= 0);
385 13 dgisselq
        ldi     $20,r0
386 2 dgisselq
        ldi     $5,r1
387
bge_loop:
388
        noop
389
        sub     $1,r1
390
        bge     bge_loop
391
 
392
// Let's try the reverse loop again, only this time we'll store our
393
// loop variable in memory.
394
// R0 = 5; (from before)
395
// do {
396
// } while (R0 > 0);
397 26 dgisselq
        ldi     $0x0b000,r11
398 13 dgisselq
        bra     mem_loop_test
399 2 dgisselq
loop_var:
400
        .dat    0
401 13 dgisselq
mem_loop_test:
402
        mov     loop_var(pc),r1
403
        ldi     $5,r0
404
        clr     r2
405
        sto     r0,(r1)
406 2 dgisselq
mem_loop:
407
        add     $1,r2
408
        add     $14,r0
409
        lod     (r1),r0
410
        sub     $1,r0
411 13 dgisselq
        sto     r0,(r1)
412
        bgt     mem_loop
413 2 dgisselq
        cmp     $5,r2
414 13 dgisselq
        trap.ne r11
415 26 dgisselq
#endif
416 2 dgisselq
 
417 26 dgisselq
#ifdef  SHIFT_TEST
418
; Now, let's test whether or not our LSR and carry flags work
419
        ldi     $0x0c000,r11
420
        ldi     -1,r0   ; First test: shifting all the way should yield zero
421
        lsr     32,r0
422
        cmp     0,r0
423
        bnz     test_failure
424
        ldi     -1,r0   ; Second test: anything greater than zero should set
425
        lsr     0,r0    ; the carry flag
426
        bc      test_failure
427
        lsr     1,r0
428
        tst     sys.ccc,cc      ; FAILS HERE!!!  @0x010007c
429
        bz      test_failure
430
        lsr     31,r0
431
        tst     sys.ccc,cc
432
        bz      test_failure
433
        lsr     1,r0
434
        bc      test_failure
435
; Now repeat the above tests, looking to see whether or not ASR works
436
        ldi     -1,r0
437
        asr     32,r0
438
        cmp     -1,r0
439
        bnz     test_failure
440
        ldi     -1,r0
441
        asr     0,r0
442
        bc      test_failure
443
        cmp     -1,r0
444
        bnz     test_failure
445
        asr     1,r0
446
        tst     sys.ccc,r14
447
        bz      test_failure
448
        asr     30,r0
449
        tst     sys.ccc,r14
450
        bz      test_failure
451
 
452 19 dgisselq
// Let's test whether LSL works
453
        ldi     0x035,r2
454
        lsl     8,r2
455
        ldi     0x03500,r1
456
        cmp     r2,r1
457
        trap.ne r11
458
        ldi     0x074,r0
459
        and     0x0ff,r0
460
        or      r0,r2
461
        cmp     0x03574,r2
462
        trap.ne r11
463 26 dgisselq
#endif
464 19 dgisselq
 
465 26 dgisselq
#ifdef  MPY_TEST
466
 
467
// We have two multiply instructions.  Let's see if those work
468
        ldi     $0x0d000,r11    // Mark our test
469
        ldi     23171,r0        // = sqrt(2)/2 * 32768
470
        mpyu    r0,r0           // Should = 2/4 * 2^30 = 2^29 or thereabouts
471
        ldi     536895241,r2
472
        cmp     r0,r2
473
        trap.ne r11
474
        ldi     0x0ffff,r0
475
        mpyu    r0,r0
476
        ldi     0xfffe0001,r1
477
        cmp     r1,r0
478
        trap.ne r11
479
        ldi     0x08001,r0
480
        ldi     0x07fff,r1
481
        mpys    r0,r1           // FAILS: result is 0x008001 ??? (pipeline prob)
482
        ldi     0x3fff0001,r2
483
        neg     r2
484
        cmp     r2,r1           // @0x010011c
485
        trap.ne r11             //TRAP FAILS TO TRIGGER ????? (R2=0x0c000ffff,R1=0x0008001 -- did mpy even happen?)
486
        mpys    r0,r0           // FAILS: result is 0x40010001
487
        ldi     0x3fff0001,r2
488
        cmp     r2,r0
489
        trap.ne r11             // TRAP FAILS TO TRIGGER AGAIN
490
        ldi     0x08000,r0
491
        mpys    r0,r0           // R0 now equals 0x40000000
492
        ldi     0x40000000,r1
493
        cmp     r0,r1
494
        trap.ne r11
495
#endif
496
 
497 2 dgisselq
// Return success / Test the trap interrupt
498
        clr     r11
499 13 dgisselq
        trap    r11
500 2 dgisselq
        noop
501
        noop
502
 
503
        busy
504
 
505
// And, in case we miss a halt ...
506
        halt
507 16 dgisselq
 
508
// Now, let's test whether or not we can handle a subroutine
509 19 dgisselq
#ifdef  PUSH_TEST
510 16 dgisselq
reverse_bit_order:
511
        PUSH(R1,SP)
512
        PUSH(R2,SP)
513
        LDI     32,R1
514
        CLR     R2
515
        LSL     1,R2
516
        LSR     1,R0
517
        OR.C    1,R2
518
        SUB     1,R1
519
        BNZ     reverse_bit_order_loop
520
        MOV     R2,R0
521
        POP(R2,SP)
522
        POP(R1,SP)
523
        RET
524 19 dgisselq
#endif
525 16 dgisselq
        fill    512,0
526
stack:
527
        word    0

powered by: WebSVN 2.1.0

© copyright 1999-2022 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.