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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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