URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
[/] [zipcpu/] [trunk/] [sw/] [zasm/] [test.S] - Rev 13
Go to most recent revision | Compare with Previous | Blame | View Log
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Filename: test.S;; Project: Zip CPU -- a small, lightweight, RISC CPU soft core;; Purpose: A disorganized test, just showing some initial operation of; the CPU. As a disorganized test, it doesn't prove anything; beyond the generic operation of the CPU.;; Status: As of August, 2015, this file assembles, builds, and passes; all of its tests in the Verilator simulator.;; Creator: Dan Gisselquist, Ph.D.; Gisselquist Tecnology, LLC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Copyright (C) 2015, Gisselquist Technology, LLC;; This program is free software (firmware): you can redistribute it and/or; modify it under the terms of the GNU General Public License as published; by the Free Software Foundation, either version 3 of the License, or (at; your option) any later version.;; This program is distributed in the hope that it will be useful, but WITHOUT; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License; for more details.;; License: GPL, v3, as defined and found on www.gnu.org,; http://www.gnu.org/licenses/gpl.html;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sys.bus equ 0xc0000000sys.breaken equ 0x080sys.step equ 0x040sys.gie equ 0x020sys.sleep equ 0x010sys.ccv equ 0x008sys.ccn equ 0x004sys.ccc equ 0x002sys.ccz equ 0x001sys.bu.pic equ 0x000sys.bus.wdt equ 0x001sys.bus.cache equ 0x002sys.bus.ctrpic equ 0x003sys.bus.tma equ 0x004sys.bus.tmb equ 0x005sys.bus.tmc equ 0x006sys.bus.jiffies equ 0x007sys.bus.mtask equ 0x008sys.bus.mpstl equ 0x009sys.bus.mastl equ 0x00asys.bus.mstl equ 0x00bsys.bus.utask equ 0x00csys.bus.upstl equ 0x00dsys.bus.uastl equ 0x00esys.bus.ustl equ 0x00f#define DO_TEST_ASSEMBLERtest:#ifdef DO_TEST_ASSEMBLER; We start out by testing our assembler. We give it some instructions, which; are then manually checked by disassembling/dumping the result and making; certain they match. This is not an automated test, but it is an important; one.noopbra continue_test_with_testable_instructionsbreakwaitbusyrtucontinue_test_with_testable_instructions:; Now, let's place the assembler into a known stateclr r0clr r1clr r2clr r3clr r4clr r5clr r6clr r7clr r9clr r10clr r11clr r12clr r13; Don't clear the CC register; Don't clear the SP register; And repeat for the user registersmov R0,uR0mov R0,uR1mov R0,uR2mov R0,uR3mov R0,uR4mov R0,uR5mov R0,uR6mov R0,uR7mov R0,uR8mov R0,uR9mov R0,uR10mov R0,uR11mov R0,uR12mov R0,uR13mov R0,uCC; Don't clear the user PC register; Now, let's try loading some constants into registersdead_beef equ 0xdeadbeefldi 0x0dead,r5ldi 0x0beef,r6ldi 0xdeadbeef,r7ldihi 0xdead, r8ldilo 0xbeef, r8ldi dead_beef,r9cmp r5,r6bz test_failurecmp r7,r8bnz test_failureldi $deadbeefh,r7 ; Try loading with the $[HEX]h mneumoniccmp r7,r8bnz test_failurecmp r7,r9bnz test_failurebra skip_dead_beefdead_beef.base:word 0fill 5,dead_beefword 0dead_beef.zero equ 0dead_beef.values equ 1skip_dead_beef:lod dead_beef.base(pc),r10 ; Should load a zero herecmp r10,r11 ; r11 should still be zero from init abvbnz test_failuremov dead_beef.base(pc),r10 ; Now, let's get the addresslod dead_beef.values(r10),r10 ; r10 now equals 0xdeadbeefcmp r10,r9bnz test_failure; Test whether or not we can properly decode OCTAL valuesclr r0 ; Re-clear our register set firstclr r1clr r2clr r3clr r4clr r5clr r6clr r7clr r9clr r10clr r11clr r12clr r13;ldi $024o,r0ldi $20,r1cmp r0,r1bnz test_failureldi $024,r0cmp r0,r1bnz test_failureclr r0clr r1mov $1+r0,r2mov $2+r0,r3mov $22h+r0,r4mov $377h+r0,ur5noopnopadd r2,r0add $32,r0add $-33,r0bnz test_failurenot.z r0bge test_failurejunk_address:clrf r0bnz test_failureldi $5,r1cmp $0+r0,r1not.lt r0not.ge r1mov junk_address(pc),r2 ; Test pc-relative addressingmov junk_address(pc),r3cmp r2,r3bnz test_failurelod junk_address(pc),r5 ; Test loads with pc-relative addressinglod junk_address(pc),r6cmp r5,r6bnz test_failure; Now, let's test whether or not our LSR and carry flags workldi -1,r0 ; First test: shifting all the way should yield zerolsr 32,r0cmp 0,r0bnz test_failureldi -1,r0 ; Second test: anything greater than zero should setlsr 0,r0 ; the carry flagbc test_failurelsr 1,r0tst sys.ccc,ccbz test_failurelsr 31,r0tst sys.ccc,ccbz test_failurelsr 1,r0bc test_failure; Now repeat the above tests, looking to see whether or not ASR worksldi -1,r0asr 32,r0cmp -1,r0bnz test_failureldi -1,r0asr 0,r0bc test_failurecmp -1,r0bnz test_failureasr 1,r0tst sys.ccc,r14bz test_failureasr 30,r0tst sys.ccc,r14bz test_failure#endif#ifdef NOONE // Testing comments after ifdef#else ; After else#endif /* and after endif */testbench:// Let's build a software test bench.ldi $c0000000h,r12 ; Set R12 to point to our peripheral addressmov r12,ur12mov test_start(pc),upcldi 0x8000ffff,r0 ; Clear interrupts, turn all vectors offsto r0,(r12)rtumov ucc,r0tst -256,r0bnz test_failurehalt// Go into an infinite loop if the trap fails// Permanent loop instruction -- a busy halt if you willtest_failure:busy; Now for a series of tests. If the test fails, call the trap; interrupt with the test number that failed. Upon completion,; call the trap with #0.; Test LDI to PC; Some data registerstest_data:.dat __here__+0x0100000+5test_start:ldi $0x0100,r11lod test_data+pc,pcclr r11noopcmp $0,r11trap.z r11add $1,r0add $1,r0// Let's test whether overflow worksldi $0x0200,r11ldi $-1,r0lsr $1,r0add $1,r0bv first_overflow_passestrap r11first_overflow_passes:// Overflow set from subtractionldi $0x0300,r11ldi $1,r0rol $31,r0 ; rol $31,r0sub $1,r0bv subtraction_overflow_passestrap r11subtraction_overflow_passes:// Overflow set from LSRldi $0x0400,r11ldi $1,r0rol $31,r0 ; rol $31,r0lsr $1,r0bv lsr_overflow_passestrap r11lsr_overflow_passes:// Overflow set from LSLldi $0x0500,r11ldi $1,r0rol $30,r0lsl $1,r0bv lsl_overflow_passestrap r11lsl_overflow_passes:// Overflow set from LSL, negative to positiveldi $0x0600,r11ldi $1,r0rol $31,r0lsl $1,r0bv second_lsl_overflow_passestrap r11second_lsl_overflow_passes:// Test carryldi $0x0700,r11ldi $-1,r0add $1,r0tst $2,cctrap.z r11// and carry from subtractionldi $0x0800,r11sub $1,r0tst $2,cctrap.z r11// Let's try a loop: for i=0; i<5; i++)// We'll use R0=i, Immediates for 5ldi $0x0800,r11clr r0for_loop:noopadd $1,r0cmp $5,r0blt for_loop//// Let's try a reverse loop. Such loops are usually cheaper to// implement, and this one is no different: 2 loop instructions// (minus setup instructions) vs 3 from before.// R0 = 5; (from before)// do {// } while (R0 > 0);ldi $0x0900,r11bgt_loop:noopsub $1,r0bgt bgt_loop// How about the same thing with a >= comparison?// R1 = 5; // Need to do this explicitly// do {// } while(R1 >= 0);ldi $20,r0ldi $5,r1bge_loop:noopsub $1,r1bge bge_loop// Let's try the reverse loop again, only this time we'll store our// loop variable in memory.// R0 = 5; (from before)// do {// } while (R0 > 0);ldi $0x0a00,r11bra mem_loop_testloop_var:.dat 0mem_loop_test:mov loop_var(pc),r1ldi $5,r0clr r2sto r0,(r1)mem_loop:add $1,r2add $14,r0lod (r1),r0sub $1,r0sto r0,(r1)bgt mem_loopcmp $5,r2trap.ne r11// Return success / Test the trap interruptclr r11trap r11noopnoopbusy// And, in case we miss a halt ...halt
Go to most recent revision | Compare with Previous | Blame | View Log
