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

Subversion Repositories zipcpu

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

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

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

powered by: WebSVN 2.1.0

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