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

Subversion Repositories zipcpu

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

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 19 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
        sys.bu.pic      equ     0x000
62
        sys.bus.wdt     equ     0x001
63
        sys.bus.cache   equ     0x002
64
        sys.bus.ctrpic  equ     0x003
65
        sys.bus.tma     equ     0x004
66
        sys.bus.tmb     equ     0x005
67
        sys.bus.tmc     equ     0x006
68
        sys.bus.jiffies equ     0x007
69
        sys.bus.mtask   equ     0x008
70
        sys.bus.mpstl   equ     0x009
71
        sys.bus.mastl   equ     0x00a
72
        sys.bus.mstl    equ     0x00b
73
        sys.bus.utask   equ     0x00c
74
        sys.bus.upstl   equ     0x00d
75
        sys.bus.uastl   equ     0x00e
76
        sys.bus.ustl    equ     0x00f
77
#define DO_TEST_ASSEMBLER
78 2 dgisselq
test:
79 13 dgisselq
#ifdef  DO_TEST_ASSEMBLER
80
; We start out by testing our assembler.  We give it some instructions, which
81
; are then manually checked  by disassembling/dumping the result and making
82
; certain they match.  This is not an automated test, but it is an important
83
; one.
84
        noop
85
        bra     continue_test_with_testable_instructions
86
        break
87
        wait
88
        busy
89
        rtu
90
continue_test_with_testable_instructions:
91
        ; Now, let's place the assembler into a known state
92 2 dgisselq
        clr     r0
93 13 dgisselq
        clr     r1
94
        clr     r2
95
        clr     r3
96
        clr     r4
97
        clr     r5
98
        clr     r6
99
        clr     r7
100
        clr     r9
101
        clr     r10
102
        clr     r11
103
        clr     r12
104
        clr     r13
105
        ; Don't clear the CC register
106
        ; Don't clear the SP register
107
        ; And repeat for the user registers
108
        mov     R0,uR0
109
        mov     R0,uR1
110
        mov     R0,uR2
111
        mov     R0,uR3
112
        mov     R0,uR4
113
        mov     R0,uR5
114
        mov     R0,uR6
115
        mov     R0,uR7
116
        mov     R0,uR8
117
        mov     R0,uR9
118
        mov     R0,uR10
119
        mov     R0,uR11
120
        mov     R0,uR12
121
        mov     R0,uR13
122
        mov     R0,uCC
123
        ; Don't clear the user PC register
124
        ; Now, let's try loading some constants into registers
125 19 dgisselq
        ; Specifically, we're testing the LDI, LDIHI, and LDILO instructions
126 13 dgisselq
dead_beef       equ     0xdeadbeef
127
        ldi     0x0dead,r5
128
        ldi     0x0beef,r6
129
        ldi     0xdeadbeef,r7
130
        ldihi   0xdead, r8
131
        ldilo   0xbeef, r8
132
        ldi     dead_beef,r9
133
        cmp     r5,r6
134
        bz      test_failure
135
        cmp     r7,r8
136
        bnz     test_failure
137
        ldi     $deadbeefh,r7   ; Try loading with the $[HEX]h mneumonic
138
        cmp     r7,r8
139
        bnz     test_failure
140
        cmp     r7,r9
141
        bnz     test_failure
142
        bra     skip_dead_beef
143
dead_beef.base:
144
        word    0
145
        fill    5,dead_beef
146
        word    0
147
dead_beef.zero          equ     0
148
dead_beef.values        equ     1
149
skip_dead_beef:
150
        lod     dead_beef.base(pc),r10  ; Should load a zero here
151
        cmp     r10,r11                 ; r11 should still be zero from init abv
152
        bnz     test_failure
153
        mov     dead_beef.base(pc),r10  ; Now, let's get the address
154
        lod     dead_beef.values(r10),r10       ; r10 now equals 0xdeadbeef
155
        cmp     r10,r9
156
        bnz     test_failure
157
 
158
; Test whether or not we can properly decode OCTAL values
159
        clr     r0      ; Re-clear our register set first
160
        clr     r1
161
        clr     r2
162
        clr     r3
163
        clr     r4
164
        clr     r5
165
        clr     r6
166
        clr     r7
167
        clr     r9
168
        clr     r10
169
        clr     r11
170
        clr     r12
171
        clr     r13
172
        ;
173
        ldi     $024o,r0
174
        ldi     $20,r1
175
        cmp     r0,r1
176
        bnz     test_failure
177
        ldi     $024,r0
178
        cmp     r0,r1
179
        bnz     test_failure
180
        clr     r0
181
        clr     r1
182 2 dgisselq
        mov     $1+r0,r2
183
        mov     $2+r0,r3
184
        mov     $22h+r0,r4
185
        mov     $377h+r0,ur5
186
        noop
187
        nop
188
        add     r2,r0
189
        add     $32,r0
190
        add     $-33,r0
191 13 dgisselq
        bnz     test_failure
192 2 dgisselq
        not.z   r0
193 13 dgisselq
        bge     test_failure
194
junk_address:
195 2 dgisselq
        clrf    r0
196 13 dgisselq
        bnz     test_failure
197 2 dgisselq
        ldi     $5,r1
198
        cmp     $0+r0,r1
199
        not.lt  r0
200
        not.ge  r1
201 13 dgisselq
        mov     junk_address(pc),r2     ; Test pc-relative addressing
202
        mov     junk_address(pc),r3
203
        cmp     r2,r3
204
        bnz     test_failure
205
        lod     junk_address(pc),r5     ; Test loads with pc-relative addressing
206
        lod     junk_address(pc),r6
207
        cmp     r5,r6
208
        bnz     test_failure
209
; Now, let's test whether or not our LSR and carry flags work
210
        ldi     -1,r0   ; First test: shifting all the way should yield zero
211
        lsr     32,r0
212
        cmp     0,r0
213
        bnz     test_failure
214
        ldi     -1,r0   ; Second test: anything greater than zero should set
215
        lsr     0,r0    ; the carry flag
216
        bc      test_failure
217
        lsr     1,r0
218
        tst     sys.ccc,cc
219
        bz      test_failure
220
        lsr     31,r0
221
        tst     sys.ccc,cc
222
        bz      test_failure
223
        lsr     1,r0
224
        bc      test_failure
225
; Now repeat the above tests, looking to see whether or not ASR works
226
        ldi     -1,r0
227
        asr     32,r0
228
        cmp     -1,r0
229
        bnz     test_failure
230
        ldi     -1,r0
231
        asr     0,r0
232
        bc      test_failure
233
        cmp     -1,r0
234
        bnz     test_failure
235
        asr     1,r0
236
        tst     sys.ccc,r14
237
        bz      test_failure
238
        asr     30,r0
239
        tst     sys.ccc,r14
240
        bz      test_failure
241
#endif
242 2 dgisselq
 
243 13 dgisselq
#ifdef  NOONE // Testing comments after ifdef
244
#else   ; After else
245
#endif /* and after endif */
246 2 dgisselq
testbench:
247
        // Let's build a software test bench.
248 13 dgisselq
        ldi     $c0000000h,r12  ; Set R12 to point to our peripheral address
249 2 dgisselq
        mov     r12,ur12
250 13 dgisselq
        mov     test_start(pc),upc
251
        ldi     0x8000ffff,r0   ; Clear interrupts, turn all vectors off
252
        sto     r0,(r12)
253 2 dgisselq
        rtu
254 13 dgisselq
        mov     ucc,r0
255
        tst     -256,r0
256
        bnz     test_failure
257 2 dgisselq
        halt
258 13 dgisselq
// Go into an infinite loop if the trap fails
259
// Permanent loop instruction -- a busy halt if you will
260
test_failure:
261 2 dgisselq
        busy
262
 
263
; Now for a series of tests.  If the test fails, call the trap
264
; interrupt with the test number that failed.  Upon completion,
265
; call the trap with #0.
266
 
267
; Test LDI to PC
268
; Some data registers
269 13 dgisselq
test_data:
270
        .dat    __here__+0x0100000+5
271 2 dgisselq
test_start:
272 13 dgisselq
        ldi     $0x0100,r11
273
        lod     test_data+pc,pc
274 2 dgisselq
        clr     r11
275
        noop
276
        cmp     $0,r11
277 13 dgisselq
        trap.z  r11
278 2 dgisselq
        add     $1,r0
279
        add     $1,r0
280
 
281
// Let's test whether overflow works
282 13 dgisselq
        ldi     $0x0200,r11
283 2 dgisselq
        ldi     $-1,r0
284
        lsr     $1,r0
285
        add     $1,r0
286 13 dgisselq
        bv      first_overflow_passes
287
        trap    r11
288
first_overflow_passes:
289 2 dgisselq
// Overflow set from subtraction
290 13 dgisselq
        ldi     $0x0300,r11
291 2 dgisselq
        ldi     $1,r0
292 13 dgisselq
        rol     $31,r0                  ; rol $31,r0
293 2 dgisselq
        sub     $1,r0
294 13 dgisselq
        bv      subtraction_overflow_passes
295
        trap    r11
296
subtraction_overflow_passes:
297 2 dgisselq
// Overflow set from LSR
298 13 dgisselq
        ldi     $0x0400,r11
299 2 dgisselq
        ldi     $1,r0
300 13 dgisselq
        rol     $31,r0                  ; rol $31,r0
301 2 dgisselq
        lsr     $1,r0
302 13 dgisselq
        bv      lsr_overflow_passes
303
        trap    r11
304
lsr_overflow_passes:
305 2 dgisselq
// Overflow set from LSL
306 13 dgisselq
        ldi     $0x0500,r11
307 2 dgisselq
        ldi     $1,r0
308 13 dgisselq
        rol     $30,r0
309 2 dgisselq
        lsl     $1,r0
310 13 dgisselq
        bv      lsl_overflow_passes
311
        trap    r11
312
lsl_overflow_passes:
313 2 dgisselq
// Overflow set from LSL, negative to positive
314 13 dgisselq
        ldi     $0x0600,r11
315 2 dgisselq
        ldi     $1,r0
316 13 dgisselq
        rol     $31,r0
317 2 dgisselq
        lsl     $1,r0
318 13 dgisselq
        bv      second_lsl_overflow_passes
319
        trap    r11
320
second_lsl_overflow_passes:
321 2 dgisselq
// Test carry
322 13 dgisselq
        ldi     $0x0700,r11
323 2 dgisselq
        ldi     $-1,r0
324
        add     $1,r0
325
        tst     $2,cc
326 13 dgisselq
        trap.z  r11
327 2 dgisselq
// and carry from subtraction
328 13 dgisselq
        ldi     $0x0800,r11
329 2 dgisselq
        sub     $1,r0
330
        tst     $2,cc
331 13 dgisselq
        trap.z  r11
332 2 dgisselq
 
333
// Let's try a loop: for i=0; i<5; i++)
334
//      We'll use R0=i, Immediates for 5
335 13 dgisselq
        ldi     $0x0800,r11
336
        clr     r0
337 2 dgisselq
for_loop:
338
        noop
339
        add     $1,r0
340
        cmp     $5,r0
341
        blt     for_loop
342
//
343
// Let's try a reverse loop.  Such loops are usually cheaper to
344
// implement, and this one is no different: 2 loop instructions
345
// (minus setup instructions) vs 3 from before.
346
// R0 = 5; (from before)
347
// do {
348
// } while (R0 > 0);
349 13 dgisselq
        ldi     $0x0900,r11
350 2 dgisselq
bgt_loop:
351
        noop
352
        sub     $1,r0
353
        bgt     bgt_loop
354
 
355
// How about the same thing with a >= comparison?
356
// R1 = 5; // Need to do this explicitly
357
// do {
358
// } while(R1 >= 0);
359 13 dgisselq
        ldi     $20,r0
360 2 dgisselq
        ldi     $5,r1
361
bge_loop:
362
        noop
363
        sub     $1,r1
364
        bge     bge_loop
365
 
366
// Let's try the reverse loop again, only this time we'll store our
367
// loop variable in memory.
368
// R0 = 5; (from before)
369
// do {
370
// } while (R0 > 0);
371 13 dgisselq
        ldi     $0x0a00,r11
372
        bra     mem_loop_test
373 2 dgisselq
loop_var:
374
        .dat    0
375 13 dgisselq
mem_loop_test:
376
        mov     loop_var(pc),r1
377
        ldi     $5,r0
378
        clr     r2
379
        sto     r0,(r1)
380 2 dgisselq
mem_loop:
381
        add     $1,r2
382
        add     $14,r0
383
        lod     (r1),r0
384
        sub     $1,r0
385 13 dgisselq
        sto     r0,(r1)
386
        bgt     mem_loop
387 2 dgisselq
        cmp     $5,r2
388 13 dgisselq
        trap.ne r11
389 2 dgisselq
 
390 19 dgisselq
// Let's test whether LSL works
391
        ldi     $0x0b00,r11
392
        ldi     0x035,r2
393
        lsl     8,r2
394
        ldi     0x03500,r1
395
        cmp     r2,r1
396
        trap.ne r11
397
        ldi     0x074,r0
398
        and     0x0ff,r0
399
        or      r0,r2
400
        cmp     0x03574,r2
401
        trap.ne r11
402
 
403 2 dgisselq
// Return success / Test the trap interrupt
404
        clr     r11
405 13 dgisselq
        trap    r11
406 2 dgisselq
        noop
407
        noop
408
 
409
        busy
410
 
411
// And, in case we miss a halt ...
412
        halt
413 16 dgisselq
 
414
// Now, let's test whether or not we can handle a subroutine
415 19 dgisselq
#ifdef  PUSH_TEST
416 16 dgisselq
reverse_bit_order:
417
        PUSH(R1,SP)
418
        PUSH(R2,SP)
419
        LDI     32,R1
420
        CLR     R2
421
        LSL     1,R2
422
        LSR     1,R0
423
        OR.C    1,R2
424
        SUB     1,R1
425
        BNZ     reverse_bit_order_loop
426
        MOV     R2,R0
427
        POP(R2,SP)
428
        POP(R1,SP)
429
        RET
430 19 dgisselq
#endif
431 16 dgisselq
        fill    512,0
432
stack:
433
        word    0

powered by: WebSVN 2.1.0

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