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

Subversion Repositories zipcpu

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

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

powered by: WebSVN 2.1.0

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