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

Subversion Repositories ion

[/] [ion/] [trunk/] [tools/] [slite/] [src/] [slite.c] - Diff between revs 44 and 53

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

Rev 44 Rev 53
Line 196... Line 196...
   int delay_slot;              /**< !=0 if prev. instruction was a branch */
   int delay_slot;              /**< !=0 if prev. instruction was a branch */
 
 
   int r[32];
   int r[32];
   int opcode;
   int opcode;
   int pc, pc_next, epc;
   int pc, pc_next, epc;
 
   uint32_t op_addr;            /**< address of opcode being simulated */
   unsigned int hi;
   unsigned int hi;
   unsigned int lo;
   unsigned int lo;
   int status;
   int status;
   unsigned cp0_cause;
   unsigned cp0_cause;
   int userMode;
   int userMode;
Line 262... Line 263...
void reset_cpu(t_state *s);
void reset_cpu(t_state *s);
 
 
/* Hardware simulation */
/* Hardware simulation */
int mem_read(t_state *s, int size, unsigned int address, int log);
int mem_read(t_state *s, int size, unsigned int address, int log);
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log);
void start_load(t_state *s, int rt, int data);
void start_load(t_state *s, uint32_t addr, int rt, int data);
 
 
 
 
/*---- Local functions -------------------------------------------------------*/
/*---- Local functions -------------------------------------------------------*/
 
 
/** Log to file a memory read operation (not including target reg change) */
/** Log to file a memory read operation (not including target reg change) */
void log_read(t_state *s, int full_address, int word_value, int size, int log){
void log_read(t_state *s, int full_address, int word_value, int size, int log){
   if(s->t.log!=NULL && log!=0){
   if(s->t.log!=NULL && log!=0){
      if(size==4){ size=0x04; }
 
      else if(size==2){ size=0x02; }
 
      else { size=0x01; }
 
      fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD\n",
      fprintf(s->t.log, "(%08X) [%08X] <**>=%08X RD\n",
              s->pc, full_address, /*size,*/ word_value);
              s->op_addr, full_address, word_value);
   }
   }
}
}
 
 
/** Read memory, optionally logging */
/** Read memory, optionally logging */
int mem_read(t_state *s, int size, unsigned int address, int log){
int mem_read(t_state *s, int size, unsigned int address, int log){
Line 287... Line 285...
 
 
    s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
    s->irqStatus |= IRQ_UART_WRITE_AVAILABLE;
    switch(address){
    switch(address){
    case UART_READ:
    case UART_READ:
        word_value = 0x00000001;
        word_value = 0x00000001;
        log_read(s, full_address, word_value, size, log);
        //log_read(s, full_address, word_value, size, log);
        return word_value;
        return word_value;
        /* FIXME Take input from text file */
        /* FIXME Take input from text file */
        /*
        /*
        if(kbhit()){
        if(kbhit()){
            HWMemory[0] = getch();
            HWMemory[0] = getch();
Line 309... Line 307...
          s->irqStatus |= IRQ_UART_READ_AVAILABLE;
          s->irqStatus |= IRQ_UART_READ_AVAILABLE;
       return s->irqStatus;
       return s->irqStatus;
       */
       */
       /* FIXME Optionally simulate UART TX delay */
       /* FIXME Optionally simulate UART TX delay */
       word_value = 0x00000003; /* Ready to TX and RX */
       word_value = 0x00000003; /* Ready to TX and RX */
       log_read(s, full_address, word_value, size, log);
       //log_read(s, full_address, word_value, size, log);
       return word_value;
       return word_value;
    case MMU_PROCESS_ID:
    case MMU_PROCESS_ID:
       return s->processId;
       return s->processId;
    case MMU_FAULT_ADDR:
    case MMU_FAULT_ADDR:
       return s->faultAddr;
       return s->faultAddr;
Line 378... Line 376...
    default:
    default:
        /* FIXME this is a bug, should quit */
        /* FIXME this is a bug, should quit */
        printf("ERROR");
        printf("ERROR");
    }
    }
 
 
    log_read(s, full_address, word_value, size, log);
    //log_read(s, full_address, value, size, log);
    return(value);
    return(value);
}
}
 
 
/** Write memory */
/** Write memory */
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log){
void mem_write(t_state *s, int size, unsigned address, unsigned value, int log){
Line 428... Line 426...
            printf("BUG: mem write size invalid (%08x)\n", s->pc);
            printf("BUG: mem write size invalid (%08x)\n", s->pc);
            exit(2);
            exit(2);
        }
        }
 
 
        fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR\n",
        fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR\n",
                s->pc, address, mask, dvalue);
                s->op_addr, address, mask, dvalue);
    }
    }
 
 
    switch(address){
    switch(address){
    case UART_WRITE:
    case UART_WRITE:
        putch(value);
        putch(value);
Line 466... Line 464...
    }
    }
    if(!ptr){
    if(!ptr){
        /* address out of mapped blocks: log and return zero */
        /* address out of mapped blocks: log and return zero */
        if(s->t.log!=NULL && log!=0){
        if(s->t.log!=NULL && log!=0){
            fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR UNMAPPED\n",
            fprintf(s->t.log, "(%08X) [%08X] |%02X|=%08X WR UNMAPPED\n",
                s->pc, address, mask, dvalue);
                s->op_addr, address, mask, dvalue);
        }
        }
        return;
        return;
    }
    }
 
 
    switch(size){
    switch(size){
Line 564... Line 562...
    *hi = rh;
    *hi = rh;
    *lo = rl;
    *lo = rl;
}
}
 
 
/** Load data from memory (used to simulate load delay slots) */
/** Load data from memory (used to simulate load delay slots) */
void start_load(t_state *s, int rt, int data){
void start_load(t_state *s, uint32_t addr, int rt, int data){
    /* load delay slot not simulated */
    /* load delay slot not simulated */
 
    log_read(s, addr, data, 1, 1);
    s->r[rt] = data;
    s->r[rt] = data;
}
}
 
 
/** Execute one cycle of the CPU (including any interlock stall cycles) */
/** Execute one cycle of the CPU (including any interlock stall cycles) */
void cycle(t_state *s, int show_mode){
void cycle(t_state *s, int show_mode){
Line 580... Line 579...
    int imm_shift, branch=0, lbranch=2, skip2=0;
    int imm_shift, branch=0, lbranch=2, skip2=0;
    int *r=s->r;
    int *r=s->r;
    unsigned int *u=(unsigned int*)s->r;
    unsigned int *u=(unsigned int*)s->r;
    unsigned int ptr, epc, rSave;
    unsigned int ptr, epc, rSave;
 
 
    if(!show_mode){
 
        /* if we're NOT showing output to console, log state of CPU to file */
 
        log_cycle(s);
 
    }
 
 
 
    opcode = mem_read(s, 4, s->pc, 0);
    opcode = mem_read(s, 4, s->pc, 0);
    op = (opcode >> 26) & 0x3f;
    op = (opcode >> 26) & 0x3f;
    rs = (opcode >> 21) & 0x1f;
    rs = (opcode >> 21) & 0x1f;
    rt = (opcode >> 16) & 0x1f;
    rt = (opcode >> 16) & 0x1f;
    rd = (opcode >> 11) & 0x1f;
    rd = (opcode >> 11) & 0x1f;
Line 633... Line 627...
       and of the program and quit. */
       and of the program and quit. */
    if(s->pc == s->pc_next+4){
    if(s->pc == s->pc_next+4){
        printf("\n\nEndless loop at 0x%08x\n\n", s->pc-4);
        printf("\n\nEndless loop at 0x%08x\n\n", s->pc-4);
        s->wakeup = 1;
        s->wakeup = 1;
    }
    }
 
    s->op_addr = s->pc;
    s->pc = s->pc_next;
    s->pc = s->pc_next;
    s->pc_next = s->pc_next + 4;
    s->pc_next = s->pc_next + 4;
    if(s->skip){
    if(s->skip){
        s->skip = 0;
        s->skip = 0;
        return;
        return;
Line 749... Line 744...
    case 0x15:/*BNEL*/  lbranch=r[rs]!=r[rt];    break;
    case 0x15:/*BNEL*/  lbranch=r[rs]!=r[rt];    break;
    case 0x16:/*BLEZL*/ lbranch=r[rs]<=0;        break;
    case 0x16:/*BLEZL*/ lbranch=r[rs]<=0;        break;
    case 0x17:/*BGTZL*/ lbranch=r[rs]>0;         break;
    case 0x17:/*BGTZL*/ lbranch=r[rs]>0;         break;
//      case 0x1c:/*MAD*/  break;   /*IV*/
//      case 0x1c:/*MAD*/  break;   /*IV*/
    case 0x20:/*LB*/    //r[rt]=(signed char)mem_read(s,1,ptr,1);  break;
    case 0x20:/*LB*/    //r[rt]=(signed char)mem_read(s,1,ptr,1);  break;
                        start_load(s, rt,(signed char)mem_read(s,1,ptr,1));
                        start_load(s, ptr, rt,(signed char)mem_read(s,1,ptr,1));
                        break;
                        break;
 
 
    case 0x21:/*LH*/    //r[rt]=(signed short)mem_read(s,2,ptr,1); break;
    case 0x21:/*LH*/    //r[rt]=(signed short)mem_read(s,2,ptr,1); break;
                        start_load(s, rt, (signed short)mem_read(s,2,ptr,1));
                        start_load(s, ptr, rt, (signed short)mem_read(s,2,ptr,1));
                        break;
                        break;
    case 0x22:/*LWL*/   //target=8*(ptr&3);
    case 0x22:/*LWL*/   //target=8*(ptr&3);
                        //r[rt]=(r[rt]&~(0xffffffff<<target))|
                        //r[rt]=(r[rt]&~(0xffffffff<<target))|
                        //      (mem_read(s,4,ptr&~3)<<target); break;
                        //      (mem_read(s,4,ptr&~3)<<target); break;
                        break;
                        break;
    case 0x23:/*LW*/    //r[rt]=mem_read(s,4,ptr,1);   break;
    case 0x23:/*LW*/    //r[rt]=mem_read(s,4,ptr,1);   break;
                        start_load(s, rt, mem_read(s,4,ptr,1));
                        start_load(s, ptr, rt, mem_read(s,4,ptr,1));
                        break;
                        break;
    case 0x24:/*LBU*/   //r[rt]=(unsigned char)mem_read(s,1,ptr,1); break;
    case 0x24:/*LBU*/   //r[rt]=(unsigned char)mem_read(s,1,ptr,1); break;
                        start_load(s, rt, (unsigned char)mem_read(s,1,ptr,1));
                        start_load(s, ptr, rt, (unsigned char)mem_read(s,1,ptr,1));
                        break;
                        break;
    case 0x25:/*LHU*/   //r[rt]= (unsigned short)mem_read(s,2,ptr,1);
    case 0x25:/*LHU*/   //r[rt]= (unsigned short)mem_read(s,2,ptr,1);
                        start_load(s, rt, (unsigned short)mem_read(s,2,ptr,1));
                        start_load(s, ptr, rt, (unsigned short)mem_read(s,2,ptr,1));
                        break;
                        break;
    case 0x26:/*LWR*/   //target=32-8*(ptr&3);
    case 0x26:/*LWR*/   //target=32-8*(ptr&3);
                        //r[rt]=(r[rt]&~((unsigned int)0xffffffff>>target))|
                        //r[rt]=(r[rt]&~((unsigned int)0xffffffff>>target))|
                        //((unsigned int)mem_read(s,4,ptr&~3)>>target);
                        //((unsigned int)mem_read(s,4,ptr&~3)>>target);
                        break;
                        break;
Line 782... Line 777...
                        //mem_write(s,1,ptr+3,r[rt]); break;
                        //mem_write(s,1,ptr+3,r[rt]); break;
    case 0x2b:/*SW*/    mem_write(s,4,ptr,r[rt],1);  break;
    case 0x2b:/*SW*/    mem_write(s,4,ptr,r[rt],1);  break;
    case 0x2e:/*SWR*/   break; //FIXME
    case 0x2e:/*SWR*/   break; //FIXME
    case 0x2f:/*CACHE*/ break;
    case 0x2f:/*CACHE*/ break;
    case 0x30:/*LL*/    //r[rt]=mem_read(s,4,ptr);   break;
    case 0x30:/*LL*/    //r[rt]=mem_read(s,4,ptr);   break;
                        start_load(s, rt, mem_read(s,4,ptr,1));
                        start_load(s, ptr, rt, mem_read(s,4,ptr,1));
                        break;
                        break;
//      case 0x31:/*LWC1*/ break;
//      case 0x31:/*LWC1*/ break;
//      case 0x32:/*LWC2*/ break;
//      case 0x32:/*LWC2*/ break;
//      case 0x33:/*LWC3*/ break;
//      case 0x33:/*LWC3*/ break;
//      case 0x35:/*LDC1*/ break;
//      case 0x35:/*LDC1*/ break;
Line 803... Line 798...
    default:
    default:
        /* FIXME should trap unimplemented opcodes */
        /* FIXME should trap unimplemented opcodes */
        printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
        printf("ERROR2 address=0x%x opcode=0x%x\n", s->pc, opcode);
        s->wakeup=1;
        s->wakeup=1;
    }
    }
 
 
 
    /* adjust next PC if this was a ajump instruction */
    s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
    s->pc_next += (branch || lbranch == 1) ? imm_shift : 0;
    s->pc_next &= ~3;
    s->pc_next &= ~3;
    s->skip = (lbranch == 0) | skip2;
    s->skip = (lbranch == 0) | skip2;
 
 
    /* If there was trouble (failed assertions), log it */
    /* If there was trouble (failed assertions), log it */
Line 832... Line 829...
        s->exceptionId = 0;
        s->exceptionId = 0;
        s->userMode = 0;
        s->userMode = 0;
        //s->wakeup = 1;
        //s->wakeup = 1;
    }
    }
 
 
 
    /* if we're NOT showing output to console, log state of CPU to file */
 
    if(!show_mode){
 
        log_cycle(s);
 
    }
 
 
 
 
 
 
    /* if this instruction was any kind of branch that actually jumped, then
    /* if this instruction was any kind of branch that actually jumped, then
       the next instruction will be in a delay slot. Remember it. */
       the next instruction will be in a delay slot. Remember it. */
    delay_slot = ((lbranch==1) || branch || delay_slot);
    delay_slot = ((lbranch==1) || branch || delay_slot);
    s->delay_slot = delay_slot;
    s->delay_slot = delay_slot;
}
}
Line 1077... Line 1081...
 
 
/** Logs last cycle's activity (changes in state and/or loads/stores) */
/** Logs last cycle's activity (changes in state and/or loads/stores) */
void log_cycle(t_state *s){
void log_cycle(t_state *s){
    static unsigned int last_pc = 0;
    static unsigned int last_pc = 0;
    int i;
    int i;
 
    uint32_t log_pc;
 
 
    /* store PC in trace buffer only if there was a jump */
    /* store PC in trace buffer only if there was a jump */
    if(s->pc != (last_pc+4)){
    if(s->pc != (last_pc+4)){
        s->t.buf[s->t.next] = s->pc;
        s->t.buf[s->t.next] = s->pc;
        s->t.next = (s->t.next + 1) % TRACE_BUFFER_SIZE;
        s->t.next = (s->t.next + 1) % TRACE_BUFFER_SIZE;
    }
    }
    last_pc = s->pc;
    last_pc = s->pc;
 
 
    /* if file logging is enabled, dump a trace log to file */
    /* if file logging is enabled, dump a trace log to file */
    if(s->t.log!=NULL){
    if(s->t.log!=NULL){
 
        log_pc = s->op_addr;
 
 
        for(i=0;i<32;i++){
        for(i=0;i<32;i++){
            if(s->t.pr[i] != s->r[i]){
            if(s->t.pr[i] != s->r[i]){
                fprintf(s->t.log, "(%08X) [%02X]=%08X\n", s->pc, i, s->r[i]);
                fprintf(s->t.log, "(%08X) [%02X]=%08X\n", log_pc, i, s->r[i]);
            }
            }
            s->t.pr[i] = s->r[i];
            s->t.pr[i] = s->r[i];
        }
        }
        if(s->lo != s->t.lo){
        if(s->lo != s->t.lo){
            fprintf(s->t.log, "(%08X) [LO]=%08X\n", s->pc, s->lo);
            fprintf(s->t.log, "(%08X) [LO]=%08X\n", log_pc, s->lo);
        }
        }
        s->t.lo = s->lo;
        s->t.lo = s->lo;
 
 
        if(s->hi != s->t.hi){
        if(s->hi != s->t.hi){
            fprintf(s->t.log, "(%08X) [HI]=%08X\n", s->pc, s->hi);
            fprintf(s->t.log, "(%08X) [HI]=%08X\n", log_pc, s->hi);
        }
        }
        s->t.hi = s->hi;
        s->t.hi = s->hi;
 
 
 
        /* */
 
        /* FIXME epc may change by direct write too, handle case */
        if(s->epc != s->t.epc){
        if(s->epc != s->t.epc){
            fprintf(s->t.log, "(%08X) [EP]=%08X\n", s->pc, s->epc);
            fprintf(s->t.log, "(%08X) [EP]=%08X\n", log_pc, s->epc);
        }
        }
        s->t.epc = s->epc;
        s->t.epc = s->epc;
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

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