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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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