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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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