URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/zipcpu/trunk/bench
- from Rev 69 to Rev 74
- ↔ Reverse comparison
Rev 69 → Rev 74
/asm/poptest.s
0,0 → 1,141
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; Filename: poptest.s |
; |
; Project: Zip CPU -- a small, lightweight, RISC CPU soft core |
; |
; Purpose: Testing whether or not the new popcount (POPC) and bit reversal |
; (BREV) operations work by using software to duplicate these |
; instructions and then comparing the software result to the actual |
; harddware result. As of the first half billion values, this works. |
; (I'm still running on the rest ....) |
; |
; Creator: Dan Gisselquist, Ph.D. |
; Gisselquist Technology, 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 |
; |
; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
#define LFSRFILL 0x000001 |
#define LFSRTAPS 0x0408b85 |
master_entry: |
MOV user_entry(PC),uPC |
MOV stack(PC),uSP |
; |
RTU |
; |
HALT |
|
user_entry: |
; LDI LFSRFILL,R6 |
; LDI LFSRTAPS,R7 |
CLR R6 |
LDI 1,R7 |
CLR R8 |
CLR R12 |
|
function_test_loop: |
; Pseudorandom number generator |
; LSR 1,R6 |
; XOR.C R7,R6 |
|
; In order number generator |
ADD R7,R6 |
|
MOV R6,R0 |
ADD 1,R8 |
|
POPC R0,R4 |
BREV R0,R5 |
|
MOV 2+__HERE__(PC),R1 |
BRA sw_pop_count |
CMP R0,R4 |
ADD.NZ 1,R12 |
TRAP.NZ 0 |
|
MOV R6,R0 |
MOV 2+__HERE__(PC),R1 |
BRA sw_reverse_bit_order |
CMP R0,R5 |
ADD.NZ 2,R12 |
TRAP.NZ 0x01000 |
|
; |
; CMP LFSRFILL,R6 |
; TRAP.Z 0 |
; |
CMP 0,R6 |
TRAP.Z 0 |
|
BRA function_test_loop |
|
|
sw_pop_count: |
; On entry, R0 = value of interest |
; R1 = return address |
; On exit, R0 = result |
; R1 = return address |
SUB 2,SP |
STO R1,(SP) ; R1 will be our loop counter |
STO R2,1(SP) ; R2 will be our accumulator and eventual result |
CLR R2 |
sw_pop_count_loop: |
LSR 1,R0 |
ADD.C 1,R2 |
BZ sw_pop_count_exit |
BRA sw_pop_count_loop |
sw_pop_count_exit: |
MOV R2,R0 |
LOD (SP),R1 |
LOD 1(SP),R2 |
ADD 2,SP |
JMP R1 |
|
|
|
sw_reverse_bit_order: |
; On entry, R0 = value of interest |
; R1 = return address |
; On exit, R0 = result |
; R1 = return address |
SUB 2,SP |
STO R1,(SP) ; R1 will be our loop counter |
STO R2,1(SP) ; R2 will be our accumulator and eventual result |
LDI 32,R1 |
CLR R2 |
reverse_bit_order_loop: |
LSL 1,R2 |
LSR 1,R0 |
OR.C 1,R2 |
SUB 1,R1 |
BZ reverse_bit_order_exit |
BRA reverse_bit_order_loop |
reverse_bit_order_exit: |
MOV R2,R0 |
LOD (SP),R1 |
LOD 1(SP),R2 |
ADD 2,SP |
JMP R1 |
|
|
fill 512,0 |
stack: // Must point to a valid word initially |
word 0 |
/asm/zipdhry.S
49,10 → 49,11
// DMIPS: 40.5 100 MHz (sim) 0.41 // 20151212 (H/W DIV) |
// DMIPS: 8.2 100 MHz (sim) 0.08 // 20151104--!pipelined |
// DMIPS: 60.1 100 MHz (sim) 0.60 // 20151215 (New PF) |
// DMIPS: 54.8 100 MHz (sim) 0.55 // 20151219 |
// DMIPS: 60.0 100 MHz (sim) 0.60 // 20151226 (BugFix) |
// On real hardware: |
// DMIPS: 24.7 100 MHz (basys) 0.25 // Initial baseline |
// DMIPS: 30.6 100 MHz (basys) 0.31 // 20151017 |
// DMIPS: 48.4 100 MHz (basys) 0.48 // 20151227 (New pf/ISA) |
// |
// (And, under Verilator, if the cache holds the entire 4kW program: 55.1 DMIPS) |
// |
157,11 → 158,18
#define PIPELINED_STRCMP |
// |
// |
dev.scope.cpu equ 0x0120 |
sys.ctr.mtask equ 0xc0000008 |
// int main(int argc, char **argv) { |
// dhrystone(); |
// } |
// #define LOAD_ADDRESS entry+PC |
#define LOAD_ADDRESS lcl_strcpy+PC |
entry: |
LDI 0x0c000010,R0 |
LDI dev.scope.cpu,R1 |
STO R0,(R1) |
; |
MOV top_of_stack(PC),uSP |
MOV entry(PC),uR12 |
; Store our tick counter in R1 |
180,6 → 188,7
LOD (R1),R0 |
HALT ; Stop the CPU--We're done!!!!!!! |
|
// |
// typedef enum { Ident_1, Ident_2, Ident_3, Ident_4, Ident_5 } test_enum; |
// typedef enum { false, true } bool; |
|
193,53 → 202,7
variant.var_1.int_comp equ 3 |
variant.var_1.str_comp equ 4 |
|
gbl_arr_1: |
fill 50,0 |
gbl_arr_2: |
fill 2500,0 |
gbl_ch: |
word 0 |
gbl_ch_2: |
word 0 |
gbl_bool: |
word 0 |
gbl_int: |
word 0 |
gbl_ptr: |
word 0 |
|
some_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',',' ' |
word 'S','O','M','E',' ','S','T','R','I','N','G' |
word 0 |
|
first_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',' |
word ' ','1','\'','S','T' |
word ' ','S','T','R','I','N','G' |
word 0 |
|
second_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',',' ' |
word '2','\'','N','D',' ','S','T','R','I','N','G' |
word 0 |
|
third_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',',' ' |
word '3','\'','R','D',' ','S','T','R','I','N','G' |
word 0 |
|
// Arr_1_Dim gbl_arr_1; |
// Arr_2_Dim gbl_arr_2; |
// char gbl_ch, gbl_ch_2; |
// bool gbl_bool; |
// int gbl_int; |
// RECP gbl_ptr; |
|
//char *lcl_strcpy(char *d, char *s) { |
// char *cpd = d, ch; |
// |
292,9 → 255,9
CMP.NZ 0,R3 |
STO.NZ R3,1(R0) |
CMP.NZ 0,R4 |
STO.NZ R4,1(R0) |
STO.NZ R4,2(R0) |
CMP.NZ 0,R5 |
STO.NZ R5,1(R0) |
STO.NZ R5,3(R0) |
|
LOD (SP),R2 |
LOD 1(SP),R3 |
301,8 → 264,11
LOD 2(SP),R4 |
LOD 3(SP),R5 |
ADD 4,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 |
HALT.LT |
#endif |
JMP R2 |
NOP |
|
#else |
lcl_strcpy: |
345,6 → 311,10
lcl_strcpy_end_of_loop: |
LOD (SP),R2 |
ADD 1,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 |
BUSY.LT |
#endif |
JMP R2 |
#endif |
|
380,6 → 350,7
LOD 2(R1),R8 |
LOD 3(R1),R9 |
; |
; |
CMP 0,R2 |
CMP.NZ 0,R3 |
CMP.NZ 0,R4 |
432,8 → 403,11
LOD 6(SP),R8 |
LOD 7(SP),R9 |
ADD 8,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 |
BUSY.LT |
#endif |
JMP R2 |
NOP |
|
#else |
lcl_strcmp: |
499,6 → 473,10
LOD (SP),R2 |
LOD 1(SP),R3 |
ADD 2,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 |
BUSY.LT |
#endif |
JMP R2 |
#endif |
|
532,6 → 510,10
LDILO.Z 1,R0 |
LOD (SP),R2 |
ADD 1,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 |
BUSY.LT |
#endif |
JMP R2 |
#endif |
|
562,7 → 544,11
func_2: |
; |
SUB 6,SP |
STO R2,(SP) |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 |
BUSY.LT |
#endif |
STO R2,(SP) ; SP = 0x08daf |
STO R3,1(SP) |
STO R4,2(SP) |
STO R5,3(SP) |
650,8 → 636,11
LOD 4(SP),R6 |
LOD 5(SP),R7 |
ADD 6,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 |
BUSY.LT |
#endif |
JMP R2 |
NOP |
|
//bool func_3(test_enum a) { |
// test_enum lcl_enum; |
671,6 → 660,10
CMP 2,R0 |
CLR R0 ; CLR Doesn't set flags |
LDILO.Z 1,R0 |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R1 |
BUSY.LT |
#endif |
JMP R1 |
#endif |
|
733,7 → 726,7
#else |
CMP 2,R0 |
LDI 3,R1 |
#ifdef SKIP_SHORT_CIRCUITS |
#ifndef SKIP_SHORT_CIRCUITS |
BUSY.NZ |
#endif |
STO.NZ R1,(R3) |
771,7 → 764,8
BRA proc_6_end_of_case |
proc_6_case_not_two: |
#ifndef SKIP_SHORT_CIRCUITS |
BUSY |
NOOP ;;;;;;;; TODO This fails--needs the NOOP |
BUSY ;;;;;;;; TODO so as not to do the BUSY |
#endif |
CMP 4,R2 |
BNZ proc_6_case_not_four |
782,9 → 776,12
proc_6_end_of_case: |
LOD (SP),R2 |
LOD 1(SP),R3 |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R2 ; TODO This fails, even when the address |
BUSY.LT |
#endif |
ADD 2,SP |
JMP R2 |
NOP |
|
// void proc_7(int a, int b, int *c) { |
// int lcl; |
798,6 → 795,10
ADD 2+R0,R1 |
STO R1,(R2) |
|
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R3 |
BUSY.LT |
#endif |
JMP R3 |
#endif |
|
871,6 → 872,10
LOD 1(SP),R5 |
LOD 2(SP),R6 |
ADD 3,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R4 |
BUSY.LT |
#endif |
JMP R4 |
|
// void proc_5(void) { |
955,8 → 960,11
LOD 1(SP),R2 |
LOD 2(SP),R3 |
ADD 3,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R1 |
BUSY.LT |
#endif |
JMP R1 |
NOP |
|
// void proc_2(int *a) { |
// int lcl_int; |
1016,8 → 1024,11
LOD 4(SP),R5 |
LOD 5(SP),R6 |
ADD 6,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R1 |
BUSY.LT |
#endif |
JMP R1 |
NOP |
|
//void proc_1 (RECP a) { |
// RECP nxt = a->ptr_comp; |
1061,18 → 1072,19
MOV R0,R9 |
LOD ptr_comp(R9),R4 |
#ifndef SKIP_SHORT_CIRCUITS |
TST -1,R4 |
TST -1,R4 ; R4 = 0x100e9f |
BUSY.Z |
CMP PC,R9 |
CMP PC,R9 ; R9 = 0x100ec2 |
BUSY.LT |
#endif |
MOV R9,R6 |
LOD gbl_ptr(R12),R7 |
LOD gbl_ptr(R12),R7 ; (0x100a04) -> 0x100ec2 |
; BUSY ; R7 = 0x0100ec2 |
|
#ifndef SKIP_SHORT_CIRCUITS |
LOD variant.var_1.enum_comp(R7), R0 |
CMP 2,R0 |
BUSY.NZ |
CMP 2,R0 ; R0 = 0 |
BUSY.NZ ; TODO Fails here |
#endif |
|
#ifdef NO_LOOP_UNROLLING |
1124,7 → 1136,7
LDI 5,R5 |
STO R5,variant.var_1.int_comp(R9) |
STO R5,variant.var_1.int_comp(R4) |
MOV ptr_comp(R4),R0 |
MOV ptr_comp(R4),R0 ; R4 = 0x8e41, ptr_comp(R4)=R4 |
MOV __HERE__+2(PC),R1 |
BRA proc_3 ; Uses R0 and R1 |
|
1145,7 → 1157,7
BRA proc_6 |
; |
LOD gbl_ptr(R12),R5 |
LOD ptr_comp(R5),R5 |
LOD ptr_comp(R5),R5 |
STO R5,ptr_comp(R4) |
; |
#ifdef NO_INLINE |
1192,8 → 1204,11
LOD 10(SP),R11 |
#endif |
ADD 11,SP |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R1 |
BUSY.LT |
#endif |
JMP R1 // Jumps to wrong address ?? |
NOP |
|
// void dhrystone(void) { |
// int lcl_int_1, lcl_int_2, lcl_int_3, index, number_of_runs = 500; |
1367,7 → 1382,8
dhrystone_while_loop: |
// lcl_int_3 = 5 * lcl_int_1 - lcl_int_2; |
MOV R5,R7 |
MPYS 5,R7 |
LDI 5,R0 |
MPYS R0,R7 |
SUB R6,R7 |
STO R7,lcl_int_3(SP) |
#ifndef SKIP_SHORT_CIRCUITS |
1402,7 → 1418,7
CMP 3,R0 |
BUSY.NZ |
CMP 3,R6 |
BUSY.NZ |
BUSY.NZ |
LOD lcl_int_3(SP),R0 |
CMP 7,R0 |
BUSY.NZ |
1416,6 → 1432,11
BRA proc_8 |
// proc_1(gbl_ptr); |
LOD gbl_ptr(PC),R0 |
#ifndef SKIP_SHORT_CIRCUITS |
LOD variant.var_1.enum_comp(R0), R1 |
CMP 2,R1 ; R0 = 0 |
BUSY.NZ ; TODO Fails here |
#endif |
MOV __HERE__+2(PC),R1 |
BRA proc_1 |
// |
1500,7 → 1521,7
LDI 9,R0 |
#endif |
#endif |
STO R0,lcl_int_1(SP) |
STO R0,lcl_int_1(SP) ;;; TODO FAILS HERE (Watched it fail!) |
// lcl_int_2 = 7 * ( lcl_int_2 - lcl_int_3) - lcl_int_1; |
LOD lcl_int_3(SP),R2 |
SUB R2,R6 |
1510,12 → 1531,12
#ifndef SKIP_SHORT_CIRCUITS |
LOD lcl_int_1(SP),R0 |
CMP 1,R0 |
BUSY.NZ |
CMP 13,R6 |
BUSY.NZ |
LOD lcl_int_3(SP),R0 |
CMP 7,R0 |
BUSY.NZ |
CMP.Z 13,R6 |
LOD.Z lcl_int_3(SP),R0 |
CMP.Z 7,R0 |
BZ dhrystone_triple_test_still_good |
BUSY |
dhrystone_triple_test_still_good: |
#endif |
MOV lcl_int_1(SP),R0 |
MOV __HERE__+2(PC),R1 |
1548,6 → 1569,10
; |
ADD 12+RECSIZE+RECSIZE+30+30+3,SP |
; Return from subroutine |
#ifndef SKIP_SHORT_CIRCUITS |
CMP LOAD_ADDRESS,R0 |
BUSY.LT |
#endif |
JMP R0 |
#else |
LDI 0,CC |
1555,4 → 1580,51
NOP |
BUSY |
#endif |
gbl_arr_1: |
fill 50,0 |
gbl_arr_2: |
fill 2500,0 |
gbl_ch: |
word 0 |
gbl_ch_2: |
word 0 |
gbl_bool: |
word 0 |
gbl_int: |
word 0 |
gbl_ptr: |
word 0 |
|
some_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',',' ' |
word 'S','O','M','E',' ','S','T','R','I','N','G' |
word 0 |
|
first_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',' |
word ' ','1','\'','S','T' |
word ' ','S','T','R','I','N','G' |
word 0 |
|
second_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',',' ' |
word '2','\'','N','D',' ','S','T','R','I','N','G' |
word 0 |
|
third_string: |
word 'D','H','R','Y','S','T','O','N','E',' ' |
word 'P','R','O','G','R','A','M',',',' ' |
word '3','\'','R','D',' ','S','T','R','I','N','G' |
word 0 |
|
// Arr_1_Dim gbl_arr_1; |
// Arr_2_Dim gbl_arr_2; |
// char gbl_ch, gbl_ch_2; |
// bool gbl_bool; |
// int gbl_int; |
// RECP gbl_ptr; |
|
; |
/asm/Makefile
30,8 → 30,8
# |
################################################################################ |
# |
all: zipdhry.z testdiv.z wdt.z halttest.z |
ZDIR := ../../sw/zasm/z2 |
all: zipdhry.z testdiv.z wdt.z halttest.z zipdhry.txt nullpc.txt poptest.txt |
ZDIR := ../../sw/zasm |
ZASM := $(ZDIR)/zasm |
ZDMP := $(ZDIR)/zdump |
LIBS := ../../sw/lib |
46,6 → 46,16
zipdhry.txt: zipdhry.z |
$(ZDMP) zipdhry.z > zipdhry.txt |
|
nullpc.z: nullpc.s |
$(ZASM) $(INCS) $^ -o $@ |
nullpc.txt: nullpc.z |
$(ZDMP) nullpc.z > nullpc.txt |
|
poptest.z: poptest.s |
$(ZASM) $(INCS) $^ -o $@ |
poptest.txt: poptest.z |
$(ZDMP) poptest.z > poptest.txt |
|
wdt.z: wdt.S |
$(ZASM) $(INCS) $^ -o $@ |
|
/asm/nullpc.s
0,0 → 1,89
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
; Filename: nullpc.s |
; |
; Project: Zip CPU -- a small, lightweight, RISC CPU soft core |
; |
; Purpose: A quick test of whether or not the prefetch shuts down and |
; idles properly when given an invalid (NULL) address. This is |
; intended to be run in the simulator (zippy_tb), as I don't know how I |
; would verify operation on a real device. |
; |
; Creator: Dan Gisselquist, Ph.D. |
; Gisselquist Technology, 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 |
; |
; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; |
start: |
CLR R0 |
CLR R1 |
CLR R2 |
CLR R3 |
CLR R4 |
MOV R0,uR0 |
MOV R0,uR1 |
MOV R0,uR2 |
MOV R0,uR3 |
MOV R0,uR4 |
MOV user_start(PC),uPC |
MOV R0,uCC |
RTU |
MOV uCC,R0 |
TST 0x100,R0 |
BNZ user_test_worked |
; We could do a BUSY.Z, but then the simulator wouldn't have |
; picked up our stop condition |
BUSY |
user_test_worked: |
MOV user_dive_test(PC),uPC |
RTU |
MOV uCC,R0 |
TST 0x0800,R0 |
BRA user_dive_worked |
BUSY |
user_dive_worked: |
; Finally, let's test whether or not a null address from supervisor |
; mode halts the CPU as desired. |
JMP R1 |
NOOP |
NOOP |
; HALT = success. However, if we halt here we certainly don't have |
; a success. Hence, signal a test failure by calling a busy instruction |
BUSY |
|
; Let's see if jumping to a null address creates the exception we want |
user_start: |
JMP R1 |
NOOP |
NOOP |
|
; How about divide by zero? |
user_dive_test: |
LDI 25,R0 |
CLR R1 |
CLR R2 |
DIVS R1,R0 |
ADD 1,R2 |
ADD 1,R2 |
ADD 1,R2 |
ADD 1,R2 |
ADD 1,R2 |
BUSY |