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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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