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

Subversion Repositories zipcpu

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

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 69 dgisselq
;               Gisselquist Technology, LLC
30 2 dgisselq
;
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 103 dgisselq
#define LJMP_TEST
80 105 dgisselq
#define EARLY_BRANCH_TEST
81 26 dgisselq
#define BREAK_TEST
82
#define OVERFLOW_TEST
83
#define CARRY_TEST
84
#define LOOP_TEST
85
#define SHIFT_TEST
86
#define TRAP_TEST
87
#define MPY_TEST
88 34 dgisselq
#define PUSH_TEST
89 46 dgisselq
#define PIPELINE_STACK_TEST
90
#define MEM_PIPELINE_TEST
91 60 dgisselq
#define CONDITIONAL_EXECUTION_TEST
92 55 dgisselq
#define NOWAIT_PIPELINE_TEST    // Were wait states btwn regs removed properly?
93 69 dgisselq
#define BCMEM_TEST      // Do memory and conditions work well together?
94 2 dgisselq
test:
95 13 dgisselq
#ifdef  DO_TEST_ASSEMBLER
96
; We start out by testing our assembler.  We give it some instructions, which
97
; are then manually checked  by disassembling/dumping the result and making
98
; certain they match.  This is not an automated test, but it is an important
99
; one.
100
        noop
101
        bra     continue_test_with_testable_instructions
102
        break
103
        wait
104 26 dgisselq
        break
105 13 dgisselq
        busy
106
        rtu
107
continue_test_with_testable_instructions:
108
        ; Now, let's place the assembler into a known state
109 2 dgisselq
        clr     r0
110 13 dgisselq
        clr     r1
111
        clr     r2
112
        clr     r3
113
        clr     r4
114
        clr     r5
115
        clr     r6
116
        clr     r7
117 36 dgisselq
        clr     r8
118 13 dgisselq
        clr     r9
119
        clr     r10
120
        clr     r11
121
        clr     r12
122
        clr     r13
123
        ; Don't clear the CC register
124
        ; Don't clear the SP register
125
        ; And repeat for the user registers
126
        mov     R0,uR0
127
        mov     R0,uR1
128
        mov     R0,uR2
129
        mov     R0,uR3
130
        mov     R0,uR4
131
        mov     R0,uR5
132
        mov     R0,uR6
133
        mov     R0,uR7
134
        mov     R0,uR8
135
        mov     R0,uR9
136
        mov     R0,uR10
137
        mov     R0,uR11
138
        mov     R0,uR12
139
        mov     R0,uR13
140
        mov     R0,uCC
141
        ; Don't clear the user PC register
142
        ; Now, let's try loading some constants into registers
143 19 dgisselq
        ; Specifically, we're testing the LDI, LDIHI, and LDILO instructions
144 13 dgisselq
dead_beef       equ     0xdeadbeef
145
        ldi     0x0dead,r5
146
        ldi     0x0beef,r6
147
        ldi     0xdeadbeef,r7
148
        ldihi   0xdead, r8
149
        ldilo   0xbeef, r8
150
        ldi     dead_beef,r9
151
        cmp     r5,r6
152
        bz      test_failure
153
        cmp     r7,r8
154
        bnz     test_failure
155
        ldi     $deadbeefh,r7   ; Try loading with the $[HEX]h mneumonic
156
        cmp     r7,r8
157
        bnz     test_failure
158
        cmp     r7,r9
159
        bnz     test_failure
160
        bra     skip_dead_beef
161
dead_beef.base:
162
        word    0
163
        fill    5,dead_beef
164
        word    0
165
dead_beef.zero          equ     0
166
dead_beef.values        equ     1
167
skip_dead_beef:
168
        lod     dead_beef.base(pc),r10  ; Should load a zero here
169
        cmp     r10,r11                 ; r11 should still be zero from init abv
170
        bnz     test_failure
171
        mov     dead_beef.base(pc),r10  ; Now, let's get the address
172
        lod     dead_beef.values(r10),r10       ; r10 now equals 0xdeadbeef
173
        cmp     r10,r9
174
        bnz     test_failure
175 34 dgisselq
 
176
; Test whether or not our operator precedence rules work
177
        ldi     5+3*8,r0
178
        ldi     3*8+5,r1
179
        cmp     r0,r1
180
        bnz     test_failure
181
        ldi     (5+3)*8,r0
182
        ldi     8*(3+5),r1
183
        cmp     r0,r1
184
        bnz     test_failure
185
 
186 13 dgisselq
; Test whether or not we can properly decode OCTAL values
187
        clr     r0      ; Re-clear our register set first
188
        clr     r1
189
        clr     r2
190
        clr     r3
191
        clr     r4
192
        clr     r5
193
        clr     r6
194
        clr     r7
195 36 dgisselq
        clr     r8
196 13 dgisselq
        clr     r9
197
        clr     r10
198
        clr     r11
199
        clr     r12
200
        clr     r13
201
        ;
202
        ldi     $024o,r0
203
        ldi     $20,r1
204
        cmp     r0,r1
205
        bnz     test_failure
206
        ldi     $024,r0
207
        cmp     r0,r1
208
        bnz     test_failure
209
        clr     r0
210
        clr     r1
211 2 dgisselq
        mov     $1+r0,r2
212
        mov     $2+r0,r3
213
        mov     $22h+r0,r4
214
        mov     $377h+r0,ur5
215
        noop
216
        nop
217
        add     r2,r0
218
        add     $32,r0
219
        add     $-33,r0
220 13 dgisselq
        bnz     test_failure
221 36 dgisselq
        not     r0
222 13 dgisselq
        bge     test_failure
223
junk_address:
224 2 dgisselq
        clrf    r0
225 13 dgisselq
        bnz     test_failure
226 2 dgisselq
        ldi     $5,r1
227
        cmp     $0+r0,r1
228
        not.lt  r0
229
        not.ge  r1
230 13 dgisselq
        mov     junk_address(pc),r2     ; Test pc-relative addressing
231
        mov     junk_address(pc),r3
232
        cmp     r2,r3
233
        bnz     test_failure
234
        lod     junk_address(pc),r5     ; Test loads with pc-relative addressing
235
        lod     junk_address(pc),r6
236
        cmp     r5,r6
237
        bnz     test_failure
238 26 dgisselq
#endif
239
 
240
#ifdef  NOONE // Testing comments after ifdef
241
#else   ; After else
242
#endif /* and after endif */
243
 
244 103 dgisselq
#ifdef  LJMP_TEST
245 105 dgisselq
        // A long jump is a 32-bit instruction followed by a 32-bit address.
246
        // The CPU is supposed to jump to this address.  At issue in this test,
247
        // which can only really be verified by watching it in person currently,
248
        // is how fast this branch can take place.  Currently, it takes four
249
        // clocks--not that bad.
250
        //
251
        // Although really long jumps, we also test some of our early branching
252
        // forms here as well:
253
        //      1. Add to PC
254
        //      2. LOD (PC),PC (the long jump itself)
255
        //      3. LDI x,PC     // An early branch target not tested elsewhere
256
        //
257 103 dgisselq
        CLR     R0
258
        CLR     R1
259
        LJMP
260
        .dat    __here__+0x0100000+4
261
        ADD     1,R0
262
        ADD     1,R0
263
        ADD     1,R0
264
        ADD     1,R0
265
        ADD     1,R0
266
        ADD     1,R0
267
        CMP     3,R0
268
        BNZ     test_failure
269
        LOD.Z   __here__+2(PC),PC
270
        BRA     test_failure
271
        .dat    __here__+0x0100000+2
272
        ADD     1,R0
273
        ADD     1,R0
274
        ADD     1,R0
275
        CMP     5,R0
276
        BNZ     test_failure
277
// And our last early branching test
278
        LDI     0x0100000+__here__+4,PC
279
        ADD     1,R0
280
        ADD     1,R0
281
        ADD     1,R0
282
        SUB     1,R0
283
        CMP     4,R0
284
        BNZ     test_failure
285
#endif
286 105 dgisselq
#ifdef  EARLY_BRANCH_TEST
287
        // Unlike the previous test, this test is going to see whether or not
288
        // early branching messes with the pipeline.
289
        BRA     eb_a
290
        BUSY
291
eb_a:
292
        BRA     eb_b
293
        NOP
294
        BUSY
295
eb_b:
296
        BRA     eb_c
297
        NOP
298
        NOP
299
        BUSY
300
eb_c:
301
        BRA     eb_d
302
        NOP
303
        NOP
304
        NOP
305
        BUSY
306
eb_d:
307
        BRA     eb_e
308
        NOP
309
        NOP
310
        NOP
311
        NOP
312
        BUSY
313
eb_e:
314
        NOOP
315
        // Only problem is, I don't expect it to mess with the pipeline unless
316
        // the pipeline is full.  Therefore we are interested in something which
317
        // is not an early branch, conflicting with early branches.  So let's
318
        // try loading our pipeline in all kinds of different configurations,
319
        // just to see which if the conditional branch always annihilates the
320
        // early branch as desired.
321
        //
322
        CLR     R0
323
        BZ      ebz_a
324
        BUSY
325
ebz_a:
326
        BZ      ebz_b
327
        NOP
328
        BUSY
329
ebz_b:
330
        BZ      ebz_c
331
        NOP
332
        NOP
333
        BUSY
334
        // Let's repeat that last test, just in case the cache reloaded itself
335
        // in the middle and we didn't get our proper test.
336
ebz_c:
337
        BZ      ebz_d
338
        NOP
339
        NOP
340
        BUSY
341
ebz_d:
342
        BZ      ebz_e
343
        NOP
344
        NOP
345
        NOP
346
        BUSY
347
ebz_e:
348
        BZ      ebz_f
349
        NOP
350
        NOP
351
        NOP
352
        NOP
353
        BUSY
354
ebz_f:
355
        NOOP
356
#endif
357 103 dgisselq
 
358 26 dgisselq
#ifdef  BREAK_TEST
359
breaktest:
360
        bra     breaksupervisor
361
breakuser:
362
        clr     r0
363
        mov     1+r0,r1
364
        mov     1+r1,r2
365
        mov     1+r2,r3
366
        break           ; At address 0x0100097
367
        mov     1+r4,r5
368
        mov     1+r5,r6
369
        clr     cc
370
        busy
371
breaksupervisor:
372 13 dgisselq
        ldi     -1,r0
373 26 dgisselq
        mov     breakuser(pc),upc
374
        rtu     ; Should just keep returning immediately
375
        mov     upc,r0
376
        rtu
377
        rtu
378
        mov     upc,r1
379
        cmp     r0,r1
380 13 dgisselq
        bnz     test_failure
381 26 dgisselq
#endif
382
 
383
#ifdef  TRAP_TEST
384
traptest:
385
        bra     traptest_supervisor
386
        busy
387
traptest_user:
388
        trap    0
389
        busy
390
traptest_supervisor:
391
        mov     traptest_user(pc),upc
392
        rtu
393 69 dgisselq
        mov     ucc,r0
394 26 dgisselq
        tst     sys.cctrap,r0
395 69 dgisselq
        tst.nz  sys.gie,r0
396 13 dgisselq
        bz      test_failure
397
#endif
398 2 dgisselq
 
399
testbench:
400
        // Let's build a software test bench.
401 13 dgisselq
        ldi     $c0000000h,r12  ; Set R12 to point to our peripheral address
402 2 dgisselq
        mov     r12,ur12
403 13 dgisselq
        mov     test_start(pc),upc
404 34 dgisselq
        mov     stack(pc),usp
405 13 dgisselq
        ldi     0x8000ffff,r0   ; Clear interrupts, turn all vectors off
406
        sto     r0,(r12)
407 2 dgisselq
        rtu
408 13 dgisselq
        mov     ucc,r0
409 69 dgisselq
        CMP     sys.cctrap+sys.gie,r0
410 13 dgisselq
        bnz     test_failure
411 2 dgisselq
        halt
412 13 dgisselq
// Go into an infinite loop if the trap fails
413
// Permanent loop instruction -- a busy halt if you will
414
test_failure:
415 2 dgisselq
        busy
416
 
417
; Now for a series of tests.  If the test fails, call the trap
418
; interrupt with the test number that failed.  Upon completion,
419
; call the trap with #0.
420
 
421
; Test LDI to PC
422
; Some data registers
423 13 dgisselq
test_data:
424
        .dat    __here__+0x0100000+5
425 2 dgisselq
test_start:
426 26 dgisselq
        ldi     $0x01000,r11
427 36 dgisselq
        ldi     -1,r10
428 13 dgisselq
        lod     test_data+pc,pc
429 36 dgisselq
        clr     r10
430 2 dgisselq
        noop
431 36 dgisselq
        cmp     $0,r10
432 13 dgisselq
        trap.z  r11
433 2 dgisselq
        add     $1,r0
434
        add     $1,r0
435
 
436 26 dgisselq
#ifdef  OVERFLOW_TEST
437 2 dgisselq
// Let's test whether overflow works
438 26 dgisselq
        ldi     $0x02000,r11
439 2 dgisselq
        ldi     $-1,r0
440
        lsr     $1,r0
441
        add     $1,r0
442 13 dgisselq
        bv      first_overflow_passes
443
        trap    r11
444
first_overflow_passes:
445 2 dgisselq
// Overflow set from subtraction
446 26 dgisselq
        ldi     $0x03000,r11
447 2 dgisselq
        ldi     $1,r0
448 13 dgisselq
        rol     $31,r0                  ; rol $31,r0
449 2 dgisselq
        sub     $1,r0
450 13 dgisselq
        bv      subtraction_overflow_passes
451
        trap    r11
452
subtraction_overflow_passes:
453 2 dgisselq
// Overflow set from LSR
454 26 dgisselq
        ldi     $0x04000,r11
455 2 dgisselq
        ldi     $1,r0
456 13 dgisselq
        rol     $31,r0                  ; rol $31,r0
457 2 dgisselq
        lsr     $1,r0
458 13 dgisselq
        bv      lsr_overflow_passes
459
        trap    r11
460
lsr_overflow_passes:
461 2 dgisselq
// Overflow set from LSL
462 26 dgisselq
        ldi     $0x05000,r11
463 2 dgisselq
        ldi     $1,r0
464 13 dgisselq
        rol     $30,r0
465 2 dgisselq
        lsl     $1,r0
466 13 dgisselq
        bv      lsl_overflow_passes
467
        trap    r11
468
lsl_overflow_passes:
469 2 dgisselq
// Overflow set from LSL, negative to positive
470 26 dgisselq
        ldi     $0x06000,r11
471 2 dgisselq
        ldi     $1,r0
472 13 dgisselq
        rol     $31,r0
473 2 dgisselq
        lsl     $1,r0
474 13 dgisselq
        bv      second_lsl_overflow_passes
475
        trap    r11
476 26 dgisselq
#endif // OVERFLOW_TEST
477
#ifdef  CARRY_TEST
478 13 dgisselq
second_lsl_overflow_passes:
479 2 dgisselq
// Test carry
480 26 dgisselq
        ldi     $0x07000,r11
481 2 dgisselq
        ldi     $-1,r0
482
        add     $1,r0
483 55 dgisselq
        tst     sys.ccc,cc
484 13 dgisselq
        trap.z  r11
485 2 dgisselq
// and carry from subtraction
486 26 dgisselq
        ldi     $0x08000,r11
487
        clr     r0
488 2 dgisselq
        sub     $1,r0
489 55 dgisselq
        tst     sys.ccc,cc
490 13 dgisselq
        trap.z  r11
491 55 dgisselq
// Carry from right shift
492
        clr     r0              ; r0 = 0
493
        lsr     1,r0            ; r0 = 0, c = 0
494
        add.c   1,r0            ; r0 = 0
495
        cmp     1,r0            ; r0 ?= 1
496
        trap.z  r11
497
        LDI     1,r0            ; r0 = 1
498
        lsr     1,r0            ; r0 = 0, c = 1
499
        add.c   1,r0            ; r0 = 1
500
        cmp     1,r0
501
        trap.nz r11
502
 
503
        ldi     0x070eca6,r0
504
        ldi     0x0408b85,r1
505
        ldi     0x0387653,r2
506
        lsr     1,r0
507
        xor.c   r1,r0
508
        cmp     r2,r0
509
        trap.nz r11
510 26 dgisselq
#endif
511 2 dgisselq
 
512 26 dgisselq
#ifdef  LOOP_TEST
513
 
514 2 dgisselq
// Let's try a loop: for i=0; i<5; i++)
515
//      We'll use R0=i, Immediates for 5
516 26 dgisselq
        ldi     $0x09000,r11
517 13 dgisselq
        clr     r0
518 2 dgisselq
for_loop:
519
        noop
520
        add     $1,r0
521
        cmp     $5,r0
522
        blt     for_loop
523
//
524
// Let's try a reverse loop.  Such loops are usually cheaper to
525
// implement, and this one is no different: 2 loop instructions
526
// (minus setup instructions) vs 3 from before.
527
// R0 = 5; (from before)
528
// do {
529
// } while (R0 > 0);
530 26 dgisselq
        ldi     $0x0a000,r11
531 2 dgisselq
bgt_loop:
532
        noop
533
        sub     $1,r0
534
        bgt     bgt_loop
535
 
536
// How about the same thing with a >= comparison?
537
// R1 = 5; // Need to do this explicitly
538
// do {
539
// } while(R1 >= 0);
540 13 dgisselq
        ldi     $20,r0
541 2 dgisselq
        ldi     $5,r1
542
bge_loop:
543
        noop
544
        sub     $1,r1
545
        bge     bge_loop
546
 
547
// Let's try the reverse loop again, only this time we'll store our
548
// loop variable in memory.
549
// R0 = 5; (from before)
550
// do {
551
// } while (R0 > 0);
552 26 dgisselq
        ldi     $0x0b000,r11
553 13 dgisselq
        bra     mem_loop_test
554 2 dgisselq
loop_var:
555
        .dat    0
556 13 dgisselq
mem_loop_test:
557
        mov     loop_var(pc),r1
558
        ldi     $5,r0
559
        clr     r2
560
        sto     r0,(r1)
561 2 dgisselq
mem_loop:
562
        add     $1,r2
563
        add     $14,r0
564
        lod     (r1),r0
565
        sub     $1,r0
566 13 dgisselq
        sto     r0,(r1)
567
        bgt     mem_loop
568 2 dgisselq
        cmp     $5,r2
569 13 dgisselq
        trap.ne r11
570 26 dgisselq
#endif
571 2 dgisselq
 
572 26 dgisselq
#ifdef  SHIFT_TEST
573
; Now, let's test whether or not our LSR and carry flags work
574
        ldi     $0x0c000,r11
575
        ldi     -1,r0   ; First test: shifting all the way should yield zero
576
        lsr     32,r0
577
        cmp     0,r0
578
        bnz     test_failure
579
        ldi     -1,r0   ; Second test: anything greater than zero should set
580
        lsr     0,r0    ; the carry flag
581
        bc      test_failure
582
        lsr     1,r0
583 103 dgisselq
        tst     sys.ccc,cc
584 26 dgisselq
        bz      test_failure
585
        lsr     31,r0
586
        tst     sys.ccc,cc
587
        bz      test_failure
588
        lsr     1,r0
589
        bc      test_failure
590
; Now repeat the above tests, looking to see whether or not ASR works
591
        ldi     -1,r0
592
        asr     32,r0
593
        cmp     -1,r0
594
        bnz     test_failure
595
        ldi     -1,r0
596
        asr     0,r0
597
        bc      test_failure
598
        cmp     -1,r0
599
        bnz     test_failure
600
        asr     1,r0
601
        tst     sys.ccc,r14
602
        bz      test_failure
603
        asr     30,r0
604
        tst     sys.ccc,r14
605
        bz      test_failure
606
 
607 19 dgisselq
// Let's test whether LSL works
608
        ldi     0x035,r2
609
        lsl     8,r2
610
        ldi     0x03500,r1
611
        cmp     r2,r1
612
        trap.ne r11
613
        ldi     0x074,r0
614
        and     0x0ff,r0
615
        or      r0,r2
616
        cmp     0x03574,r2
617
        trap.ne r11
618 26 dgisselq
#endif
619 19 dgisselq
 
620 26 dgisselq
#ifdef  MPY_TEST
621
 
622
// We have two multiply instructions.  Let's see if those work
623
        ldi     $0x0d000,r11    // Mark our test
624
        ldi     23171,r0        // = sqrt(2)/2 * 32768
625
        mpyu    r0,r0           // Should = 2/4 * 2^30 = 2^29 or thereabouts
626
        ldi     536895241,r2
627
        cmp     r0,r2
628
        trap.ne r11
629
        ldi     0x0ffff,r0
630
        mpyu    r0,r0
631
        ldi     0xfffe0001,r1
632
        cmp     r1,r0
633
        trap.ne r11
634
        ldi     0x08001,r0
635
        ldi     0x07fff,r1
636
        mpys    r0,r1           // FAILS: result is 0x008001 ??? (pipeline prob)
637
        ldi     0x3fff0001,r2
638
        neg     r2
639
        cmp     r2,r1           // @0x010011c
640
        trap.ne r11             //TRAP FAILS TO TRIGGER ????? (R2=0x0c000ffff,R1=0x0008001 -- did mpy even happen?)
641
        mpys    r0,r0           // FAILS: result is 0x40010001
642
        ldi     0x3fff0001,r2
643
        cmp     r2,r0
644
        trap.ne r11             // TRAP FAILS TO TRIGGER AGAIN
645
        ldi     0x08000,r0
646
        mpys    r0,r0           // R0 now equals 0x40000000
647
        ldi     0x40000000,r1
648
        cmp     r0,r1
649
        trap.ne r11
650 69 dgisselq
//
651
// And from our eyeball test ...
652
        LDI     0x01ff01ff,R0
653
        MOV     R0,R7
654
        MOV     8(SP),R6
655
        LSR     7,R0
656
        AND     7,R0
657
        LDI     7,R1
658
        SUB     R0,R1
659
        MOV     R1,R0
660
        MPYU    5,R0
661
        CMP     20,R0
662
        TRAP.NE R11
663 26 dgisselq
#endif
664 34 dgisselq
 
665
#ifdef  PUSH_TEST
666
        ldi     $0x0e000,r11    // Mark our test
667
        ldi     0x01248cab,r0
668
        ldi     0xd5312480,r1   // Let's see if we can preserve this as well
669
        mov     r1,r7
670 69 dgisselq
        FJSR(reverse_bit_order,R4);     // *SP = 0x010013d
671 34 dgisselq
        cmp     r0,r1
672
        trap.ne r11
673
        cmp     r0,r7
674
        trap.ne r11
675
#endif
676 39 dgisselq
 
677
#ifdef  PIPELINE_STACK_TEST
678
        ldi     $0x0f000,r11    // Mark our test
679
        LDI     1,R0
680
        MOV     1(R0),R1
681
        MOV     1(R1),R2
682
        MOV     1(R2),R3
683
        MOV     1(R3),R4
684
        MOV     1(R4),R5
685
        MOV     1(R5),R6
686 69 dgisselq
        FJSR(pipeline_stack_test,R7)
687 39 dgisselq
        CMP     1,R0
688
        trap.ne R11
689
        CMP     2,R1
690
        trap.ne R11
691
        CMP     3,R2
692
        trap.ne R11
693
        CMP     4,R3
694
        trap.ne R11
695
        CMP     5,R4
696
        trap.ne R11
697
        CMP     6,R5
698
        trap.ne R11
699
        CMP     7,R6
700
        trap.ne R11
701
#endif
702 46 dgisselq
 
703
#ifdef  MEM_PIPELINE_TEST
704 69 dgisselq
        LDI     0x10000,R11
705
        FJSR(mem_pipeline_test,R0)
706 46 dgisselq
#endif  // MEM_PIPELINE_TEST
707
 
708 60 dgisselq
#ifdef  CONDITIONAL_EXECUTION_TEST
709 69 dgisselq
        LDI     0x11000,R11
710
        FJSR(conditional_execution_test,R0)
711 60 dgisselq
#endif  // CONDITIONAL_EXECUTION_TEST
712
 
713 55 dgisselq
#ifdef  NOWAIT_PIPELINE_TEST
714 69 dgisselq
        LDI     0x12000,R11
715
        FJSR(nowait_pipeline_test,R0)
716 55 dgisselq
#endif  // NOWAIT_PIPELINE_TEST
717
 
718 69 dgisselq
#ifdef  BCMEM_TEST
719
        LDI     0x13000,R11
720
        CLR     R0
721
        LDI     -1,R1
722
        STO     R0,bcmemtestloc(PC)
723
        LOD     bcmemtestloc(PC),R1
724
        CMP     R0,R1
725
        TRAP.NZ R11
726
        CMP     0x13000,R11
727
        BZ      bcmemtest_cmploc_1
728
        STO     R11,bcmemtestloc(PC)
729
bcmemtest_cmploc_1:
730
        LOD     bcmemtestloc(PC),R0
731
        CMP     R0,R11
732
        TRAP.Z  R11
733
        CLR     R0
734
        CMP     R0,R11
735
        BZ      bcmemtest_cmploc_2
736
        STO.NZ  R11,bcmemtestloc(PC)
737
bcmemtest_cmploc_2:
738
        NOOP
739
        LOD     bcmemtestloc(PC),R0
740
        CMP     R0,R11
741
        TRAP.NZ R11
742
        BRA     end_bcmemtest
743
bcmemtestloc:
744
        WORD    0
745
end_bcmemtest:
746
#endif
747 2 dgisselq
// Return success / Test the trap interrupt
748
        clr     r11
749 103 dgisselq
        trap    r11     // FAILS HERE FAILS FAILS FAILS !!!!!!!!!!!
750 2 dgisselq
        noop
751
        noop
752
 
753
        busy
754
 
755
// And, in case we miss a halt ...
756
        halt
757 16 dgisselq
 
758
// Now, let's test whether or not we can handle a subroutine
759 19 dgisselq
#ifdef  PUSH_TEST
760 16 dgisselq
reverse_bit_order:
761 69 dgisselq
        SUB     3,SP
762
        STO     R1,(SP)         ; R1 will be our loop counter
763
        STO     R2,1(SP)        ; R2 will be our accumulator and eventual result
764
        STO     R4,2(SP)
765 16 dgisselq
        LDI     32,R1
766
        CLR     R2
767 34 dgisselq
reverse_bit_order_loop:
768 16 dgisselq
        LSL     1,R2
769
        LSR     1,R0
770
        OR.C    1,R2
771
        SUB     1,R1
772
        BNZ     reverse_bit_order_loop
773
        MOV     R2,R0
774 69 dgisselq
        LOD     (SP),R1
775
        LOD     1(SP),R2
776
        LOD     2(SP),R4
777
        ADD     3,SP
778
        JMP     R4
779 19 dgisselq
#endif
780 39 dgisselq
 
781 55 dgisselq
; The pipeline stack test examines whether or not a series of memory commands
782
; can be evaluated right after the other without problems.  This depends upon
783
; the calling routine to properly set up registers to be tested.
784
;
785
; This is also an incomplete test, as nothing is done to test how these
786
; pipeline reads/writes are affected by condition codes.
787
;
788 39 dgisselq
#ifdef  PIPELINE_STACK_TEST
789
pipeline_stack_test:
790
        SUB     13,SP
791 69 dgisselq
        STO     R0,(SP)
792
        STO     R1,1(SP)
793
        STO     R2,2(SP)
794
        STO     R3,3(SP)
795
        STO     R4,4(SP)
796
        STO     R5,5(SP)
797
        STO     R6,6(SP)
798
        STO     R7,7(SP)
799
        STO     R8,8(SP)
800
        STO     R9,9(SP)
801
        STO     R10,10(SP)
802
        STO     R11,11(SP)
803
        STO     R12,12(SP)
804 39 dgisselq
        XOR     -1,R0
805
        XOR     -1,R1
806
        XOR     -1,R2
807
        XOR     -1,R3
808
        XOR     -1,R4
809
        XOR     -1,R5
810
        XOR     -1,R6
811
        XOR     -1,R7
812
        XOR     -1,R8
813
        XOR     -1,R9
814
        XOR     -1,R10
815
        XOR     -1,R11
816
        XOR     -1,R12
817 69 dgisselq
        LOD     (SP),R0
818
        LOD     1(SP),R1
819
        LOD     2(SP),R2
820
        LOD     3(SP),R3
821
        LOD     4(SP),R4
822
        LOD     5(SP),R5
823
        LOD     6(SP),R6
824
        LOD     7(SP),R7
825
        LOD     8(SP),R8
826
        LOD     9(SP),R9
827
        LOD     10(SP),R10
828
        LOD     11(SP),R11
829
        LOD     12(SP),R12
830 39 dgisselq
        ADD     13,SP
831 69 dgisselq
        JMP     R7
832 39 dgisselq
#endif // PIPELINE_STACK_TEST
833
 
834 46 dgisselq
#ifdef  MEM_PIPELINE_TEST
835
mem_pipeline_test:
836
        SUB     4,SP
837 69 dgisselq
        STO     R0,(SP)
838
        STO     R1,1(SP)
839 46 dgisselq
        LDI     0x10000,R11
840
        ;
841
        ; Test #1 ... Let's start by writing a value to memory
842
        LDI     -1,R0
843
        CLR     R1
844 69 dgisselq
        STO     R0,2(SP)
845
        LOD     2(SP),R1
846 46 dgisselq
        CMP     R1,R0
847
        MOV.NZ  R11,CC
848
 
849
        ; Test #2, reading and then writing a value from memory
850
        NOP
851
        NOP
852
        CLR     R0
853
        CLR     R1
854 69 dgisselq
        LOD     2(SP),R0        ; This should load back up our -1 value
855
        STO     R0,3(SP)
856 46 dgisselq
        ; Insist that the pipeline clear
857 69 dgisselq
        LOD     2(SP),R0
858 46 dgisselq
        ; Now let's try loading into R1
859
        NOP
860
        NOP
861
        NOP
862
        NOP
863 69 dgisselq
        LOD     3(SP),R1
864 46 dgisselq
        CMP     R1,R0
865
        MOV.NZ  R11,CC
866
 
867 69 dgisselq
        LOD     (SP),R0
868
        LOD     1(SP),R1
869 46 dgisselq
        ADD     4,SP
870 69 dgisselq
        JMP     R0
871 46 dgisselq
#endif
872
 
873 60 dgisselq
#ifdef  CONDITIONAL_EXECUTION_TEST
874
conditional_execution_test:
875 69 dgisselq
        SUB     1,SP
876
        STO     R0,(SP)
877
        ;
878 60 dgisselq
        CLRF    R0
879
        ADD.Z   1,R0
880
        TRAP.NZ R11
881
        CMP.Z   0,R0
882
        TRAP.Z  R11
883
 
884 69 dgisselq
        LOD     (SP),R0
885
        ADD     1,SP
886
        JMP     R0
887 60 dgisselq
#endif
888
 
889 55 dgisselq
;
890
; Pipeline stalls have been hideous problems for me.  The CPU has been modified
891
; with special logic to keep stages from stalling.  For the most part, this
892
; means that ALU and memory results may be accessed either before or as they
893
; are written to the register file.  This set of code is designed to test
894
; whether this bypass logic works.
895
#ifdef  NOWAIT_PIPELINE_TEST
896
nowait_pipeline_test:
897
        ; Allocate for us some number of registers
898
        ;
899 60 dgisselq
        SUB     6,SP
900
        ; Leave a spot open on the stack for a local variable,
901
        ; kept in memory.
902 69 dgisselq
        STO     R0,(SP)
903
        STO     R1,1(SP)
904
        STO     R2,2(SP)
905
        STO     R3,3(SP)
906
        STO     R4,4(SP)
907 55 dgisselq
        ;
908
        ; Let's start with ALU-ALU testing
909
        ;       AA: result->input A
910 60 dgisselq
        CLR     R0
911
        ADD     1,R0
912
        CMP     1,R0
913
        TRAP.NZ R11
914
 
915 55 dgisselq
        ;       AA: result->input B
916 60 dgisselq
        CLR     R0
917
        CLR     R1
918
        ADD     1,R0
919
        CMP     R0,R1
920
        TRAP.Z  R11
921
 
922 55 dgisselq
        ;       AA: result->input A on condition
923 60 dgisselq
        CLRF    R0
924
        ADD.Z   5,R0
925
        CMP     5,R0
926
        TRAP.NZ R11
927
 
928 55 dgisselq
        ;       AA: result->input B on condition
929 60 dgisselq
        CLR     R0
930
        CLRF    R1
931
        ADD.Z   5,R0
932
        CMP     R0,R1
933
        TRAP.Z  R11
934
 
935 55 dgisselq
        ;       AA: result->input B plus offset
936 60 dgisselq
        CLR     R0
937
        CLRF    R1
938
        ADD     5,R0
939
        CMP     -5(R0),R1
940
        TRAP.NZ R11
941
 
942 55 dgisselq
        ;       AA: result->input B plus offset on condition
943 60 dgisselq
        CLR     R0
944
        CLRF    R1
945
        ADD.Z   5,R0
946
        CMP     -5(R0),R1
947
        TRAP.NZ R11
948
 
949 55 dgisselq
        ;
950
        ; Then we need to do ALU-Mem input testing
951 60 dgisselq
        ;
952
        CLR     R0
953 69 dgisselq
        STO     R0,5(SP)
954 60 dgisselq
        LDI     8352,R0
955 69 dgisselq
        LOD     5(SP),R0
956 60 dgisselq
        TST     -1,R0
957
        TRAP.NZ R11
958
 
959
        LDI     937,R0          ; Let's try again, this time something that's
960 69 dgisselq
        STO     R0,5(SP)        ; not zero
961 60 dgisselq
        NOOP
962 69 dgisselq
        LOD     5(SP),R0
963 60 dgisselq
        CMP     938,R0          ; Let's not compare with self, let's that
964
        TRAP.GE R11             ; masks a problem--compare with a different
965
        CMP     936,R0          ; number instead.
966
        TRAP.LT R11
967
 
968 55 dgisselq
        ; Mem output->ALU input testing
969 60 dgisselq
        ;       We just did that as partof our last test
970 55 dgisselq
        ; Mem output->MEM input testing
971
        ;
972 60 dgisselq
        LDI     5328,R2
973 69 dgisselq
        LOD     5(SP),R2
974
        STO     R2,5(SP)
975
        LOD     5(SP),R1
976 60 dgisselq
        CMP     937,R1
977
        TRAP.NZ R11
978
        ;
979 69 dgisselq
        LOD     (SP),R0
980
        LOD     1(SP),R1
981
        LOD     2(SP),R2
982
        LOD     3(SP),R3
983
        LOD     4(SP),R4
984 60 dgisselq
        ADD     6,SP
985 69 dgisselq
        JMP     R0
986 55 dgisselq
#endif  // NOWAIT_PIPELINE_TEST
987
 
988 69 dgisselq
 
989 16 dgisselq
        fill    512,0
990 34 dgisselq
stack:  // Must point to a valid word initially
991 16 dgisselq
        word    0

powered by: WebSVN 2.1.0

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