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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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