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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [bench/] [asm/] [cputest.c] - Diff between revs 172 and 202

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 172 Rev 202
Line 31... Line 31...
//
//
//
//
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
//
//
//
 
#ifndef NULL
#define NULL    (void *)0
#define NULL    (void *)0
 
#endif
 
 
volatile        int     *const UARTTX = (volatile int *)0x010b,
volatile        int     *const UARTTX = (volatile int *)0x010b,
        * const UART_CTRL = (int *)0x0107;
        * const UART_CTRL = (int *)0x0107;
// #define      ZIPSYS
// #define      ZIPSYS
#ifdef  ZIPSYS
#ifdef  ZIPSYS
#define HAVE_COUNTER
#define HAVE_COUNTER
Line 58... Line 61...
 
 
unsigned        zip_ucc(void);
unsigned        zip_ucc(void);
void            zip_save_context(int *);
void            zip_save_context(int *);
void            zip_halt(void);
void            zip_halt(void);
 
 
 
 
 
void    txchr(char v);
 
void    txstr(const char *str);
 
void    txhex(int num);
 
void    tx4hex(int num);
 
 
 
 
asm("\t.section\t.start\n"
asm("\t.section\t.start\n"
        "\t.global\t_start\n"
        "\t.global\t_start\n"
        "\t.type\t_start,@function\n"
        "\t.type\t_start,@function\n"
"_start:\n"
"_start:\n"
#ifdef  HAVE_SCOPE
#ifdef  HAVE_SCOPE
Line 108... Line 118...
#endif
#endif
#endif
#endif
 
 
 
 
extern  int     run_test(void *pc, void *stack);
extern  int     run_test(void *pc, void *stack);
asm("\t.global\trun_test\n"
asm("\t.text\n\t.global\trun_test\n"
        "\t.type\trun_test,@function\n"
        "\t.type\trun_test,@function\n"
"run_test:\n"
"run_test:\n"
        "\tCLR\tR3\n"
        "\tCLR\tR3\n"
        "\tMOV\ttest_return(PC),uR0\n"
        "\tMOV\ttest_return(PC),uR0\n"
        "\tMOV\tR3,uR1\n"
        "\tMOV\tR3,uR1\n"
Line 123... Line 133...
        "\tMOV\tR3,uR6\n"
        "\tMOV\tR3,uR6\n"
        "\tMOV\tR3,uR7\n"
        "\tMOV\tR3,uR7\n"
        "\tMOV\tR3,uR8\n"
        "\tMOV\tR3,uR8\n"
        "\tMOV\tR3,uR9\n"
        "\tMOV\tR3,uR9\n"
        "\tMOV\tR3,uR10\n"
        "\tMOV\tR3,uR10\n"
        "\tMOV\tR1,uR11\n"
        "\tMOV\tR3,uR11\n"
        "\tMOV\tR1,uR12\n"
        "\tMOV\tR3,uR12\n"
        "\tMOV\tR2,uSP\n"
        "\tMOV\tR2,uSP\n"       // uSP = stack
        "\tMOV\t0x20+R3,uCC\n"
        "\tMOV\t0x20+R3,uCC\n"  // Clear uCC of all but the GIE bit
        "\tMOV\tR1,uPC\n"
        "\tMOV\tR1,uPC\n"       // uPC = pc
        "\tRTU\n"
        "\tRTU\n"
"test_return:\n"
"test_return:\n"
        "\tMOV\tuR1,R1\n"
        "\tMOV\tuR1,R1\n"
        "\tAND\t0xffffffdf,CC\n"
        "\tAND\t0xffffffdf,CC\n"
        // Works with 5 NOOPS, works with 3 NOOPS, works with 1 NOOP
        // Works with 5 NOOPS, works with 3 NOOPS, works with 1 NOOP
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
 
extern  int     idle_test(void);
 
asm("\t.text\n\t.global\tidle_test\n"
 
        "\t.type\tidle_test,@function\n"
 
"idle_test:\n"
 
        "\tCLR\tR1\n"
 
        "\tMOV\tidle_loop(PC),uR0\n"
 
        "\tMOV\tR1,uR1\n"
 
        "\tMOV\tR1,uR2\n"
 
        "\tMOV\tR1,uR3\n"
 
        "\tMOV\tR1,uR4\n"
 
        "\tMOV\tR1,uR5\n"
 
        "\tMOV\tR1,uR6\n"
 
        "\tMOV\tR1,uR7\n"
 
        "\tMOV\tR1,uR8\n"
 
        "\tMOV\tR1,uR9\n"
 
        "\tMOV\tR1,uR10\n"
 
        "\tMOV\tR1,uR11\n"
 
        "\tMOV\tR1,uR12\n"
 
        "\tMOV\tR1,uSP\n"
 
        "\tMOV\t0x20+R1,uCC\n"
 
        "\tMOV\tidle_loop(PC),uPC\n"
 
        "\tWAIT\n"
 
        "\tMOV uPC,R1\n"
 
        "\tCMP idle_loop(PC),R1\n"
 
        "\tLDI   0,R1\n"
 
        "\tLDI.NZ 1,R1\n"
 
        "\nRETN\n"
 
"idle_loop:\n"
 
        "\tWAIT\n"
 
        "\tBRA idle_loop\n");
 
 
void    break_one(void);
void    break_one(void);
asm("\t.global\tbreak_one\n"
asm("\t.text\n\t.global\tbreak_one\n"
        "\t.type\tbreak_one,@function\n"
        "\t.type\tbreak_one,@function\n"
"break_one:\n"
"break_one:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tBREAK\n"
        "\tBREAK\n"
        "\tLDI\t1,R1\n" // Test fails
        "\tLDI\t1,R1\n" // Test fails
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
void    break_two(void);
void    break_two(void);
        // Can we stop a break before we hit it?
        // Can we stop a break before we hit it?
asm("\t.global\tbreak_two\n"
asm("\t.text\n\t.global\tbreak_two\n"
        "\t.type\tbreak_two,@function\n"
        "\t.type\tbreak_two,@function\n"
"break_two:\n"
"break_two:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tJMP\tR0\n"
        "\tJMP\tR0\n"
        "\tBREAK\n");
        "\tBREAK\n");
 
 
void    early_branch_test(void);
void    early_branch_test(void);
asm("\t.global\tearly_branch_test\n"
asm("\t.text\n\t.global\tearly_branch_test\n"
        "\t.type\tearly_branch_test,@function\n"
        "\t.type\tearly_branch_test,@function\n"
"early_branch_test:\n"
"early_branch_test:\n"
        "\tLDI\t1,R1\n"
        "\tLDI\t1,R1\n"
        "\tBRA\t_eb_a\n"
        "\tBRA\t_eb_a\n"
        "\tBREAK\n"
        "\tBREAK\n"
Line 200... Line 241...
"_eb_f:\n"
"_eb_f:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
void    trap_test_and(void);
void    trap_test_and(void);
asm("\t.global\ttrap_test_and\n"
asm("\t.text\n\t.global\ttrap_test_and\n"
        "\t.type\ttrap_test_and,@function\n"
        "\t.type\ttrap_test_and,@function\n"
"trap_test_and:\n"
"trap_test_and:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tAND\t0xffffffdf,CC\n"
        "\tAND\t0xffffffdf,CC\n"
        "\tLDI\t1,R1\n" // Test fails
        "\tLDI\t1,R1\n" // Test fails
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
void    trap_test_clr(void);
void    trap_test_clr(void);
asm("\t.global\ttrap_test_clr\n"
asm("\t.text\n\t.global\ttrap_test_clr\n"
        "\t.type\ttrap_test_clr,@function\n"
        "\t.type\ttrap_test_clr,@function\n"
"trap_test_clr:\n"
"trap_test_clr:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tCLR\tCC\n"
        "\tCLR\tCC\n"
        "\tLDI\t1,R1\n" // Test fails
        "\tLDI\t1,R1\n" // Test fails
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
void    overflow_test(void);
void    overflow_test(void);
asm("\t.global\toverflow_test\n"
asm("\t.text\n\t.global\toverflow_test\n"
        "\t.type\toverflow_test,@function\n"
        "\t.type\toverflow_test,@function\n"
"overflow_test:\n"
"overflow_test:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R3\n"         // Clear our scorecard
        "\tLDI\t0,R3\n"         // Clear our scorecard
// First test: does adding one to the maximum integer cause an overflow?
// First test: does adding one to the maximum integer cause an overflow?
Line 252... Line 293...
// And return the results
// And return the results
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
 
 
void    carry_test(void);
void    carry_test(void);
asm("\t.global\tcarry_test\n"
asm("\t.text\n\t.global\tcarry_test\n"
        "\t.type\tcarry_test,@function\n"
        "\t.type\tcarry_test,@function\n"
"carry_test:\n"
"carry_test:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R3\n"
        "\tLDI\t0,R3\n"
// First, in adding
// First, in adding
Line 281... Line 322...
        "\tXOR\t31,R3\n"
        "\tXOR\t31,R3\n"
        "\tOR\tR3,R1\n"
        "\tOR\tR3,R1\n"
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
void    loop_test(void);
void    loop_test(void);
asm("\t.global\tloop_test\n"
asm("\t.text\n\t.global\tloop_test\n"
        "\t.type\tloop_test,@function\n"
        "\t.type\tloop_test,@function\n"
"loop_test:\n"
"loop_test:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
// Let's try a loop: for(i=0; i<5; i++)
// Let's try a loop: for(i=0; i<5; i++)
        "\tLDI\t0,R2\n"
        "\tLDI\t0,R2\n"
Line 339... Line 380...
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
// Test whether or not LSL, LSR, and ASR instructions work, together with their
// Test whether or not LSL, LSR, and ASR instructions work, together with their
// carry flags
// carry flags
void    shift_test(void);
void    shift_test(void);
asm("\t.global\tshift_test\n"
asm("\t.text\n\t.global\tshift_test\n"
        "\t.type\tshift_test,@function\n"
        "\t.type\tshift_test,@function\n"
"shift_test:\n"
"shift_test:\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R1\n"
        "\tLDI\t0,R3\n"
        "\tLDI\t0,R3\n"
        "\tLDI\t0,R4\n"
        "\tLDI\t0,R4\n"
Line 406... Line 447...
        "\tOR\tR4,R3\n"
        "\tOR\tR4,R3\n"
        "\tOR\tR3,R1\n"
        "\tOR\tR3,R1\n"
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
int     sw_brev(int v);
int     sw_brev(int v);
asm("\t.global\tsw_brev\n"
asm("\t.text\n\t.global\tsw_brev\n"
        "\t.type\tsw_brev,@function\n"
        "\t.type\tsw_brev,@function\n"
"sw_brev:\n"
"sw_brev:\n"
        "\tSUB\t2,SP\n"
        "\tSUB\t2,SP\n"
        "\tSTO\tR2,(SP)\n"
        "\tSTO\tR2,(SP)\n"
        "\tSTO\tR3,1(SP)\n"
        "\tSTO\tR3,1(SP)\n"
Line 429... Line 470...
        "\tLOD\t1(SP),R3\n"
        "\tLOD\t1(SP),R3\n"
        "\tADD\t2,SP\n"
        "\tADD\t2,SP\n"
        "\tJMP\tR0");
        "\tJMP\tR0");
 
 
void    pipeline_stack_test(void);
void    pipeline_stack_test(void);
asm("\t.global\tpipeline_stack_test\n"
asm("\t.text\n\t.global\tpipeline_stack_test\n"
        "\t.type\tpipeline_stack_test,@function\n"
        "\t.type\tpipeline_stack_test,@function\n"
"pipeline_stack_test:\n"
"pipeline_stack_test:\n"
        "\tSUB\t1,SP\n"
        "\tSUB\t1,SP\n"
        "\tSTO\tR0,(SP)\n"
        "\tSTO\tR0,(SP)\n"
        "\tLDI\t0,R0\n"
        "\tLDI\t0,R0\n"
Line 471... Line 512...
        "\tADD\t1,SP\n"
        "\tADD\t1,SP\n"
        "\tJMP\tR0\n"
        "\tJMP\tR0\n"
        );
        );
 
 
void    pipeline_stack_test_component(void);
void    pipeline_stack_test_component(void);
asm("\t.global\tpipeline_stack_test_component\n"
asm("\t.text\n\t.global\tpipeline_stack_test_component\n"
        "\t.type\tpipeline_stack_test_component,@function\n"
        "\t.type\tpipeline_stack_test_component,@function\n"
"pipeline_stack_test_component:\n"
"pipeline_stack_test_component:\n"
        "\tSUB\t13,SP\n"
        "\tSUB\t13,SP\n"
        "\tSTO\tR0,(SP)\n"
        "\tSTO\tR0,(SP)\n"
        "\tSTO\tR1,1(SP)\n"
        "\tSTO\tR1,1(SP)\n"
Line 519... Line 560...
        "\tADD\t13,SP\n"
        "\tADD\t13,SP\n"
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
//mpy_test
//mpy_test
void    mpy_test(void);
void    mpy_test(void);
asm("\t.global\tmpy_test\n"
asm("\t.text\n\t.global\tmpy_test\n"
        "\t.type\tmpy_test,@function\n"
        "\t.type\tmpy_test,@function\n"
"mpy_test:\n"
"mpy_test:\n"
        "\tCLR\tR1\n"
        "\tCLR\tR1\n"
        // First test: let's count multiples of 137
        // First test: let's count multiples of 137
        "\tLDI\t137,R2\n"       // What we're doing multiples of
        "\tLDI\t137,R2\n"       // What we're doing multiples of
Line 551... Line 592...
        "\tOR\t1,R1\n"
        "\tOR\t1,R1\n"
"end_mpy_137_test_loop:\n"
"end_mpy_137_test_loop:\n"
        // Second test ... whatever that might be
        // Second test ... whatever that might be
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
 
unsigned        soft_mpyuhi(unsigned, unsigned);
 
int             soft_mpyshi(int,int);
 
 
 
unsigned        hard_mpyuhi(unsigned, unsigned);
 
asm("\t.text\n\t.global\thard_mpyuhi\n"
 
        "\t.type\thard_mpyuhi,@function\n"
 
"hard_mpyuhi:\n"
 
        "\tNOOP\n"
 
        "\tNOOP\n"
 
        "\tMPYUHI\tR2,R1\n"
 
        "\tRETN\n");
 
 
 
int     hard_mpyshi(int, int);
 
asm("\t.text\n\t.global\thard_mpyshi\n"
 
        "\t.type\thard_mpyshi,@function\n"
 
"hard_mpyshi:\n"
 
        "\tMPYSHI\tR2,R1\n"
 
        "\tRETN\n");
 
 
 
void    debugmpy(char *str, int a, int b, int s, int r) {
 
#ifdef  HAVE_SCOPE
 
        // Trigger the scope, if it hasn't been triggered yet
 
        // but ... dont reset it if it has been.
 
        *SCOPE = TRIGGER_SCOPE_NOW;
 
#endif
 
        txstr("\r\n"); txstr(str); txhex(a);
 
        txstr(" x "); txhex(b);
 
        txstr(" = "); txhex(s);
 
        txstr("(Soft) = "); txhex(r);
 
        txstr("(Hard)\r\n");
 
}
 
 
 
int     mpyhi_test(void) {
 
        int     a = 0xf97e27ab, b = 0;
 
 
 
        while(b<0x6fffffff) {
 
                int     r, sr;
 
 
 
                sr = soft_mpyuhi(a, b);
 
                r = hard_mpyuhi(a,b);
 
                if (r != sr) {
 
                        debugmpy("MPYUHI: ", a,b,sr,r);
 
                        return 1;
 
                }
 
 
 
                sr = soft_mpyshi(a, b);
 
                r = hard_mpyshi(a,b);
 
                if (r != sr) {
 
                        debugmpy("MPYSHI: ", a,b,sr,r);
 
                        return 2;
 
                }
 
 
 
                sr = soft_mpyshi(-a, b);
 
                r = hard_mpyshi(-a,b);
 
                if (r != sr) {
 
                        debugmpy("MPYSHI-NEG: ", -a,b,sr,r);
 
                        return 3;
 
                }
 
 
 
                b += 0x197e2*7;
 
        }
 
 
 
        return 0;
 
}
 
 
 
unsigned        soft_mpyuhi(unsigned a, unsigned b) {
 
        unsigned        alo, ahi, blo, bhi;
 
        unsigned        rhi, rlhi, rllo;
 
 
 
        alo = (a     & 0x0ffff);
 
        ahi = (a>>16)& 0x0ffff;
 
        blo = (b     & 0x0ffff);
 
        bhi = (b>>16)& 0x0ffff;
 
 
 
        rhi = 0;
 
        rlhi = 0;
 
        rllo = 0;
 
 
 
        for(int i=0; i<16; i++) {
 
                if (b&(1<<i)) {
 
                        unsigned slo, shi, sup;
 
                        slo = (alo << i);
 
                        shi = (ahi << i);
 
                        shi |= (slo>>16) & 0x0ffff;
 
                        slo &= 0x0ffff;
 
                        sup = (shi>>16)&0x0ffff;
 
                        shi &= 0x0ffff;
 
 
 
                        rhi  += sup;
 
                        rlhi += shi;
 
                        rllo += slo;
 
 
 
                        rlhi += (rllo >> 16)&0x0ffff;
 
                        rllo &= 0x0ffff;
 
 
 
                        rhi  += (rlhi >> 16)&0x0ffff;
 
                        rlhi &= 0x0ffff;
 
                }
 
        }
 
 
 
        for(int i=16; i<32; i++) {
 
                if (b&(1<<i)) {
 
                        unsigned slo, shi, sup;
 
                        slo = (alo << (i-16));
 
                        shi = (ahi << (i-16));
 
                        shi |= (slo>>16) & 0x0ffff;
 
                        slo &= 0x0ffff;
 
                        sup = (shi>>16)&0x0ffff;
 
                        shi &= 0x0ffff;
 
 
 
                        rhi  += sup << 16;
 
                        rhi  += shi;
 
                        rlhi += slo;
 
 
 
                        rhi  += (rlhi >> 16)&0x0ffff;
 
                        rlhi &= 0x0ffff;
 
                }
 
        }
 
 
 
        return rhi;
 
}
 
 
 
int     soft_mpyshi(int a, int b) {
 
        unsigned        sgn, r, p;
 
 
 
        sgn = ((a^b)>>31)&0x01;
 
 
 
        if (a<0) a = -a;
 
        if (b<0) b = -b;
 
 
 
        p = a * b;
 
 
 
        // This will only fail if the lower 32-bits of of a*b are 0,
 
        // at which point our following negation won't capture the carry it
 
        // needs.
 
        r = soft_mpyuhi(a, b);
 
 
 
        r = (sgn)?(r^-1):r;
 
        if ((sgn)&&(p==0))
 
                r += 1;
 
        return r;
 
}
 
 
//brev_test
//brev_test
//pipeline_test -- used to be called pipeline memory race conditions
//pipeline_test -- used to be called pipeline memory race conditions
void    pipeline_test(void);
void    pipeline_test(void);
asm("\t.global\tpipeline_test\n"
asm("\t.text\n\t.global\tpipeline_test\n"
        "\t.type\tpipeline_test,@function\n"
        "\t.type\tpipeline_test,@function\n"
"pipeline_test:\n"
"pipeline_test:\n"
        "\tSUB\t2,SP\n"
        "\tSUB\t2,SP\n"
        // Test setup
        // Test setup
        "\tLDI\t275,R2\n"
        "\tLDI\t275,R2\n"
Line 604... Line 788...
        "\tADD\t2,SP\n"
        "\tADD\t2,SP\n"
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
//mempipe_test
//mempipe_test
void    mempipe_test(void);
void    mempipe_test(void);
asm("\t.global\tmempipe_test\n"
asm("\t.text\n\t.global\tmempipe_test\n"
        "\t.type\tmempipe_test,@function\n"
        "\t.type\tmempipe_test,@function\n"
"mempipe_test:\n"
"mempipe_test:\n"
        "\tSUB\t4,SP\n"
        "\tSUB\t4,SP\n"
        "\tSTO\tR0,(SP)\n"
        "\tSTO\tR0,(SP)\n"
        "\tLDI\t0x1000,R11\n"
        "\tLDI\t0x1000,R11\n"
Line 641... Line 825...
        "\tADD\t4,SP\n"
        "\tADD\t4,SP\n"
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
//cexec_test
//cexec_test
void    cexec_test(void);
void    cexec_test(void);
asm("\t.global\tcexec_test\n"
asm("\t.text\n\t.global\tcexec_test\n"
        "\t.type\tcexec_test,@function\n"
        "\t.type\tcexec_test,@function\n"
"cexec_test:\n"
"cexec_test:\n"
        "\tSUB\t1,SP\n"
        "\tSUB\t1,SP\n"
        "\tSTO\tR0,(SP)\n"
        "\tSTO\tR0,(SP)\n"
        //
        //
Line 665... Line 849...
// are written to the register file.  This set of code is designed to test
// are written to the register file.  This set of code is designed to test
// whether this bypass logic works.
// whether this bypass logic works.
//
//
//nowaitpipe_test
//nowaitpipe_test
void    nowaitpipe_test(void);
void    nowaitpipe_test(void);
asm("\t.global\tnowaitpipe_test\n"
asm("\t.text\n\t.global\tnowaitpipe_test\n"
        "\t.type\tnowaitpipe_test,@function\n"
        "\t.type\tnowaitpipe_test,@function\n"
"nowaitpipe_test:\n"
"nowaitpipe_test:\n"
        "\tSUB\t2,SP\n"
        "\tSUB\t2,SP\n"
        //
        //
        // Let's start with ALU-ALU testing
        // Let's start with ALU-ALU testing
Line 740... Line 924...
        "\tADD\t2,SP\n"
        "\tADD\t2,SP\n"
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
//bcmem_test
//bcmem_test
void    bcmem_test(void);
void    bcmem_test(void);
asm("\t.global\tbcmem_test\n"
asm("\t.text\n.global\tbcmem_test\n"
        "\t.type\tbcmem_test,@function\n"
        "\t.type\tbcmem_test,@function\n"
"bcmem_test:\n"
"bcmem_test:\n"
        "\tSUB\t1,SP\n"
        "\tSUB\t1,SP\n"
        "\tCLR\tR1\n"
        "\tCLR\tR1\n"
        "\tCLR\tR2\n"
        "\tCLR\tR2\n"
Line 771... Line 955...
        "\tOR.NZ\t4,R1\n"
        "\tOR.NZ\t4,R1\n"
//
//
        "\tADD\t1,SP\n"
        "\tADD\t1,SP\n"
        "\tJMP\tR0\n");
        "\tJMP\tR0\n");
 
 
 
// The illegal instruction test.  Specifically, illegal instructions cannot be
 
// allowed to execute.  The PC must, upon completion, point to the illegal
 
// instruction that caused the exception.
 
//
 
// To create our illegal instruction, we assume that the only the three
 
// operations without arguments are NOOP, BREAK, LOCK, and so we envision a
 
// fourth instruction to create.
 
void    ill_test(void);
 
asm("\t.text\n.global\till_test\n"
 
        "\t.type\till_test,@function\n"
 
"ill_test:\n"
 
        "\t.word\t0x7ff00000\n"
 
        "\tJMP\tR0\n");
 
 
//
//
// The CC register has some ... unique requirements associated with it.
// The CC register has some ... unique requirements associated with it.
// Particularly, flags are unavailable until after an ALU operation completes,
// Particularly, flags are unavailable until after an ALU operation completes,
// and they can't really be bypassed for the CC register.  After writeback,
// and they can't really be bypassed for the CC register.  After writeback,
// the "new" CC register isn't really available for another clock.  Trying to
// the "new" CC register isn't really available for another clock.  Trying to
Line 785... Line 983...
//
//
// Here, let's see if our pipeline can successfully navigate any of these
// Here, let's see if our pipeline can successfully navigate any of these
// issues.
// issues.
//
//
void    ccreg_test(void);
void    ccreg_test(void);
asm("\t.global\tccreg_test\n"
asm("\t.text\n.global\tccreg_test\n"
        "\t.type\tccreg_test,@function\n"
        "\t.type\tccreg_test,@function\n"
"ccreg_test:\n"
"ccreg_test:\n"
        // First test: If we try to change the fixed bits, will they change
        // First test: If we try to change the fixed bits, will they change
        // because the pipeline tries to bypass the write-back stage
        // because the pipeline tries to bypass the write-back stage
        "\tCLR\tR1\n"   // We'll start with an "answer" of success
        "\tCLR\tR1\n"   // We'll start with an "answer" of success
Line 845... Line 1043...
        *PIC = 0x80000000|(msk<<16);
        *PIC = 0x80000000|(msk<<16);
        asm("WAIT\n");
        asm("WAIT\n");
        *PIC = 0; // Turn interrupts back off, lest they confuse the test
        *PIC = 0; // Turn interrupts back off, lest they confuse the test
}
}
 
 
asm("\nidle_task:\n\tWAIT\n\tBRA\tidle_task\n");
asm("\n\t.text\nidle_task:\n\tWAIT\n\tBRA\tidle_task\n");
 
 
__attribute__((noinline))
__attribute__((noinline))
void    txchr(char v) {
void    txchr(char v) {
 
        if (zip_cc() & CC_GIE) {
 
                while(*UARTTX & 0x100)
 
                        ;
 
        } else
        wait(INT_UARTTX);
        wait(INT_UARTTX);
        *UARTTX = v;
        *UARTTX = v;
}
}
 
 
__attribute__((noinline))
__attribute__((noinline))
Line 874... Line 1076...
                txchr(ch);
                txchr(ch);
        }
        }
}
}
 
 
__attribute__((noinline))
__attribute__((noinline))
 
void    tx4hex(int num) {
 
        if (num & 0xffff0000){
 
                txhex(num);
 
                return;
 
        } for(int ds=12; ds>=0; ds-=4) {
 
                int     ch;
 
                ch = (num >> ds)&0x0f;
 
                if (ch >= 10)
 
                        ch = 'A'+ch-10;
 
                else
 
                        ch += '0';
 
                txchr(ch);
 
        }
 
}
 
 
 
__attribute__((noinline))
void    txreg(const char *name, int val) {
void    txreg(const char *name, int val) {
        txstr(name);    // 4 characters
        txstr(name);    // 4 characters
        txstr("0x");    // 2 characters
        txstr("0x");    // 2 characters
        txhex(val);     // 8 characters
        txhex(val);     // 8 characters
        txstr("    ");  // 4 characters
        txstr("    ");  // 4 characters
Line 893... Line 1111...
        int     context[16], stop_time;
        int     context[16], stop_time;
 
 
        // Trigger the scope, if it hasn't already triggered.  Otherwise,
        // Trigger the scope, if it hasn't already triggered.  Otherwise,
        // if it has triggered, don't clear it.
        // if it has triggered, don't clear it.
#ifdef  HAVE_SCOPE
#ifdef  HAVE_SCOPE
        *SCOPE = 0x8f000004;
        *SCOPE = TRIGGER_SCOPE_NOW;
#endif
#endif
 
 
        MARKSTOP;
        MARKSTOP;
        save_context(context);
        save_context(context);
        *listno++ = context[1];
        *listno++ = context[1];
Line 933... Line 1151...
        txreg("uSP : ", context[13]);
        txreg("uSP : ", context[13]);
        txreg("uCC : ", context[14]);
        txreg("uCC : ", context[14]);
        txreg("uPC : ", context[15]);
        txreg("uPC : ", context[15]);
        txstr("\r\n\r\n");
        txstr("\r\n\r\n");
 
 
        asm("\tBUSY");
        // While previous versions of cputest.c called zip_busy(), here we
 
        // reject that notion for the simple reason that zip_busy may not
 
        // necessarily halt any Verilator simulation.  Instead, we try to 
 
        // halt the CPU.
 
        while(1)
 
                zip_halt();
}
}
 
 
void    testid(const char *str) {
void    testid(const char *str) {
        const int       WIDTH=32;
        const int       WIDTH=32;
        txstr(str);
        txstr(str);
Line 964... Line 1187...
        *TIMER = 0x7fffffff;
        *TIMER = 0x7fffffff;
#endif
#endif
#ifdef  HAVE_COUNTER
#ifdef  HAVE_COUNTER
        *COUNTER = 0;
        *COUNTER = 0;
#endif
#endif
 
#ifdef  HAVE_SCOPE
// #define      STACKTEST       asm("CMP\t16108,SP\n\tHALT.NZ\n")
        *SCOPE = PREPARE_SCOPE;
#define STACKTEST
#endif
        STACKTEST;
 
 
 
        // *UART_CTRL = 8333; // 9600 Baud, 8-bit chars, no parity, one stop bit
        // *UART_CTRL = 8333; // 9600 Baud, 8-bit chars, no parity, one stop bit
        *UART_CTRL = 25; // 9600 Baud, 8-bit chars, no parity, one stop bit
        *UART_CTRL = 25; // 9600 Baud, 8-bit chars, no parity, one stop bit
        //
        //
        STACKTEST;
 
 
 
        txstr("\r\n");
        txstr("\r\n");
        txstr("Running CPU self-test\n");
        txstr("Running CPU self-test\r\n");
        txstr("-----------------------------------\r\n");
        txstr("-----------------------------------\r\n");
 
 
        int     tnum = 0;
        int     tnum = 0;
        STACKTEST;
 
 
 
        // Test break instruction in user mode
        // Test break instruction in user mode
        // Make sure the break works as designed
        // Make sure the break works as designed
        testid("Break test #1"); MARKSTART;
        testid("Break test #1"); MARKSTART;
        STACKTEST;
 
 
 
        if ((run_test(break_one, user_stack_ptr))||(zip_ucc()&0x1f50))
        if ((run_test(break_one, user_stack_ptr))||(zip_ucc()&0x1f50))
                test_fails(start_time, &testlist[tnum]);
                test_fails(start_time, &testlist[tnum]);
        STACKTEST;
 
 
 
        save_context(context);
        save_context(context);
        if ((context[15] != (int)break_one+1)||(0==(zip_ucc()&0x80)))
        if ((context[15] != (int)break_one+1)||(0==(zip_ucc()&0x80)))
                test_fails(start_time, &testlist[tnum]);
                test_fails(start_time, &testlist[tnum]);
        txstr("Pass\r\n"); testlist[tnum++] = 0; // 0
        txstr("Pass\r\n"); testlist[tnum++] = 0; // 0
 
 
        STACKTEST;
 
 
 
        // Test break instruction in user mode
        // Test break instruction in user mode
        // Make sure that a decision on the clock prior won't still cause a 
        // Make sure that a decision on the clock prior won't still cause a 
        // break condition
        // break condition
        testid("Break test #2"); MARKSTART;
        testid("Break test #2"); MARKSTART;
        if ((run_test(break_two, user_stack_ptr))||(zip_ucc()&0x1d90))
        if ((run_test(break_two, user_stack_ptr))||(zip_ucc()&0x1d90))
Line 1053... Line 1269...
        testid("Shift test"); MARKSTART;
        testid("Shift test"); MARKSTART;
        if ((run_test(shift_test, user_stack_ptr))||(zip_ucc()&0x01d90))
        if ((run_test(shift_test, user_stack_ptr))||(zip_ucc()&0x01d90))
                test_fails(start_time, &testlist[tnum]);
                test_fails(start_time, &testlist[tnum]);
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #8
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #8
 
 
        // MPY_TEST
 
        testid("Multiply test"); MARKSTART;
 
        if ((run_test(mpy_test, user_stack_ptr))||(zip_ucc()&0x01d90))
 
                test_fails(start_time, &testlist[tnum]);
 
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #9
 
 
 
        // BREV_TEST
        // BREV_TEST
        //testid("BREV/stack test"); MARKSTART;
        //testid("BREV/stack test"); MARKSTART;
        //if ((run_test(brev_test, user_stack_ptr))||(zip_ucc()&0x01d90))
        //if ((run_test(brev_test, user_stack_ptr))||(zip_ucc()&0x01d90))
                //test_fails(start_time);
                //test_fails(start_time);
        //txstr("Pass\r\n");
        //txstr("Pass\r\n");
Line 1096... Line 1306...
        if ((run_test(bcmem_test, user_stack_ptr))||(zip_ucc()&0x01d90))
        if ((run_test(bcmem_test, user_stack_ptr))||(zip_ucc()&0x01d90))
                test_fails(start_time, &testlist[tnum]);
                test_fails(start_time, &testlist[tnum]);
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #14
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #14
 
 
        // Illegal Instruction test
        // Illegal Instruction test
        testid("Illegal Instruction test"); MARKSTART;
        testid("Ill Instruction test, NULL PC"); MARKSTART;
        if ((run_test(NULL, user_stack_ptr))||((zip_ucc()^0x100)&0x01d90))
        if ((run_test(NULL, user_stack_ptr))||((zip_ucc()^0x100)&0x01d90))
                test_fails(start_time, &testlist[tnum]);
                test_fails(start_time, &testlist[tnum]);
        txstr("Pass\r\n"); testlist[tnum++] = 0;
        txstr("Pass\r\n"); testlist[tnum++] = 0;
 
 
 
        // Illegal Instruction test
 
        testid("Ill Instruction test, two"); MARKSTART;
 
        if ((run_test(ill_test, user_stack_ptr))||((zip_ucc()^0x100)&0x01d90))
 
                test_fails(start_time, &testlist[tnum]);
 
        save_context(context);
 
        if (context[15] != (int)&ill_test)
 
                test_fails(start_time, &testlist[tnum]);
 
        txstr("Pass\r\n"); testlist[tnum++] = 0;
 
 
        // Pipeline memory race condition test
        // Pipeline memory race condition test
        // DIVIDE test
        // DIVIDE test
 
 
        // CC Register test
        // CC Register test
        testid("CC Register test"); MARKSTART;
        testid("CC Register test"); MARKSTART;
Line 1116... Line 1335...
        testid("Multi-Arg test"); MARKSTART;
        testid("Multi-Arg test"); MARKSTART;
        if ((run_test(multiarg_test, user_stack_ptr))||(zip_ucc()&0x01d90))
        if ((run_test(multiarg_test, user_stack_ptr))||(zip_ucc()&0x01d90))
                test_fails(start_time, &testlist[tnum]);
                test_fails(start_time, &testlist[tnum]);
        txstr("Pass\r\n"); testlist[tnum++] = 0;
        txstr("Pass\r\n"); testlist[tnum++] = 0;
 
 
 
        // MPY_TEST
 
        testid("Multiply test"); MARKSTART;
 
        if ((run_test(mpy_test, user_stack_ptr))||(zip_ucc()&0x01d90))
 
                test_fails(start_time, &testlist[tnum]);
 
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #9
 
 
 
        // MPYxHI_TEST
 
        testid("Multiply HI-word test"); MARKSTART;
 
        if ((run_test(mpyhi_test, user_stack_ptr))||(zip_ucc()&0x01d90))
 
                test_fails(start_time, &testlist[tnum]);
 
        txstr("Pass\r\n"); testlist[tnum++] = 0; // #9
        txstr("\r\n");
        txstr("\r\n");
        txstr("-----------------------------------\r\n");
        txstr("-----------------------------------\r\n");
        txstr("All tests passed.  Halting CPU.\n");
        txstr("All tests passed.  Halting CPU.\r\n");
        zip_halt();
        zip_halt();
}
}
 
 
// To build this:
// To build this:
//      zip-gcc -O3 -Wall -Wextra -nostdlib -fno-builtin -T xula.ld -Wl,-Map,cputest.map cputest.cpp -o cputest
//      zip-gcc -O3 -Wall -Wextra -nostdlib -fno-builtin -T xula.ld -Wl,-Map,cputest.map cputest.cpp -o cputest

powered by: WebSVN 2.1.0

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