Beispiel #1
0
void cpu_state_print()
{//print the state of cpu and contents in memory
     printf("Registers:\n");
     for(int i=0;i<NUM_OF_REGS-1;++i)
     {
		 printf("R%d=%d(%d) ",i,regs[i],reg_valid_bits[i]);
     }
     printf("X=0x%08x(%d) PC=0x%08x\n",regs[NUM_OF_REGS-1],reg_valid_bits[8],PC);
     static const char * name[] ={"Fetch","D/RF","EXE","MEM","WB"};
     printf("content of each stage:\n");
     for(int i=0;i<NUM_OF_STAGES;++i)
     {
		 printf("%s:\t",name[i]);
		 if(stage_context[i].ins==-1)
		 {
			   printf("NOP\n");
		 }
		 else
		 {
			   printf("%s",ins_buffer[stage_context[i].ins]);
			   printf("PC=0x%x\n",stage_context[i].pc);
		 }
     }
     printf("Memory contexts from 0-99:");
     for(int i=0;i<100;)
     {
		 if(i%16==0)
		 {
			   printf("\n0x%-5x:",i);
		 }
		 int j=0;
		 while(i+j<100 && j<16)
		 {
			   u32_t con;
			   mem_fetch(i+j,&con);
			   printf("%08x ",con);
			   ++j;
		 }
		 i+=j;
     }
     puts("");
}
Beispiel #2
0
static int exec_4()
{//Mem stage
	  if(stage_context[3].ins<0) goto end;//nop
	  assert(stage_context[3].decoded != NULL);
	  if(stage_context[3].decoded->type == 6)
	  {//Load.
		//Note:there is no forwarding.Thus the result should be written back in WB
            //decoded->result should contain the address.
		if(mem_fetch(stage_context[3].decoded->result,&stage_context[3].decoded->result)<0)
		{
			  fprintf(stderr,"invalid access to memory address %u",stage_context[3].decoded->result);
			  exit(1);
		}
	  }
	  else if(stage_context[3].decoded->type==10 )
	  {//Store
		    mem_write(stage_context[3].decoded->result,stage_context[3].decoded->src1);
	  }
end:
	  stage_context[4] = stage_context[3];
	  return 0;
}
Beispiel #3
0
word_t
mem_sval_fetch(struct vm *vm, sval_t sval, unsigned int offset)
{
	return mem_fetch(vm, mem_sval_to_vaddr(vm, sval, offset));
}
Beispiel #4
0
int lsa_sim ( void )
{
    unsigned int ra;
    unsigned int rb;
    unsigned int rc;

    unsigned int rega;
    unsigned int regb;

    unsigned int simcount;

    reset_lsa();

    simcount=0;

    while(1)
    {
//if(simcount++>30) break;
        if(state==STATE_HALTED) break;
//printf("[0x%04X] 0x%04X\n",read_register(0),read_register(3]);
        switch(state)
        {
            case STATE_HALTED: break;
            case STATE_FETCH:
                rega=read_register(0);
                inst=mem_fetch(rega);
                rega++;
                write_register(0,rega);
                rd=0;
                wr=0;
                switch(inst&0xF000)
                {
                    case 0x0000: // lpc load pc relative
                        rd=1;
                        add=read_register(0)+(inst&0xFF);
                        break;
                    case 0x1000: // lsp load sp relative
                        rd=1;
                        add=read_register(2)+(inst&0xFF);
                        break;
                    case 0x2000: // spc store pc relative
                        wr=1;
                        add=read_register(0)+(inst&0xFF);
                        data=read_register((inst>>8)&0xF);
                        break;
                    case 0x3000: // ssp store sp relative
                        wr=1;
                        add=read_register(2)+(inst&0xFF);
                        data=read_register((inst>>8)&0xF);
                        break;
                    case 0x4000: // ldw/stw load/store
                        switch(inst&0xF)
                        {
                            case 0x0: // ldw rd,[rs]
                                rd=1;
                                add=read_register((inst>>4)&0xF);
                                break;
                            case 0x1: // ldw rd,[rs++]
                                rd=1;
                                rega=read_register((inst>>4)&0xF);
                                add=rega;
                                rega++;
                                write_register((inst>>4)&0xF,rega);
                                break;
                            case 0x2: // ldw rd,[++rs]
                                rd=1;
                                rega=read_register((inst>>4)&0xF);
                                rega++;
                                add=rega;
                                write_register((inst>>4)&0xF,rega);
                                break;
                            case 0x3: // ldw rd,[rs--]
                                rd=1;
                                rega=read_register((inst>>4)&0xF);
                                add=rega;
                                rega--;
                                write_register((inst>>4)&0xF,rega);
                                break;
                            case 0x4: // ldw rd,[--rs]
                                rd=1;
                                rega=read_register((inst>>4)&0xF);
                                rega--;
                                add=rega;
                                write_register((inst>>4)&0xF,rega);
                                break;

                            case 0x6: // mov rd,rs
                                rega=read_register((inst>>4)&0xF);
                                write_register((inst>>8)&0xF,rega);
                                break;

                            case 0x8: // stw [rd],rs
                                wr=1;
                                add=read_register((inst>>8)&0xF);
                                data=read_register((inst>>4)&0xF);
                                break;
                            case 0x9: // stw [rd++],rs
                                wr=1;
                                rega=read_register((inst>>8)&0xF);
                                add=rega;
                                rega++;
                                write_register((inst>>8)&0xF,rega);
                                data=read_register((inst>>4)&0xF);
                                break;
                            case 0xA: // stw [++rd],rs
                                wr=1;
                                rega=read_register((inst>>8)&0xF);
                                rega++;
                                add=rega;
                                write_register((inst>>8)&0xF,rega);
                                data=read_register((inst>>4)&0xF);
                                break;
                            case 0xB: // stw [rd--],rs
                                wr=1;
                                rega=read_register((inst>>8)&0xF);
                                add=rega;
                                rega--;
                                write_register((inst>>8)&0xF,rega);
                                data=read_register((inst>>4)&0xF);
                                break;
                            case 0xC: // stw [--rd],rs
                                wr=1;
                                rega=read_register((inst>>8)&0xF);
                                rega--;
                                add=rega;
                                write_register((inst>>8)&0xF,rega);
                                data=read_register((inst>>4)&0xF);
                                break;

                            case 0xE: // swap rd,rs
                                rega=read_register((inst>>4)&0xF);
                                regb=read_register((inst>>8)&0xF);
                                write_register((inst>>4)&0xF,regb);
                                write_register((inst>>8)&0xF,rega);
                                break;
                        }
                        break;
                    case 0x5000: // move to/from high register
                        if(inst&0x80)
                        {
                            rega=read_register((inst>>8)&0xF);
                            write_register((inst>>0)&0x7F,rega);
                        }
                        else
                        {
                            rega=read_register((inst>>0)&0x7F);
                            write_register((inst>>8)&0xF,rega);
                        }
                        break;
                    case 0x6000: // alu operation
                        switch(inst&0xF)
                        {
                            case 0x6:
                                opa=0;
                                opb=read_register((inst>>4)&0xF);
                                break;
                            case 0x8:
                            case 0x9:
                                opa=read_register((inst>>4)&0xF);
                                opb=1;
                                break;
                            default:
                                opa=read_register((inst>>8)&0xF);
                                opb=read_register((inst>>4)&0xF);
                                break;
                        }
                        switch(inst&0xF)
                        {
                            case 0x0: res = opa + opb;      break;  //add
                            case 0x1: res = opa - opb;      break;  //sub
                            case 0x2: res = opa & opb;      break;  //and
                            case 0x3: res = opa & (~opb);   break;  //dna
                            case 0x4: res = opa | opb;      break;  //or
                            case 0x5: res = opa ^ opb;      break;  //xor
                            case 0x6: res = opa - opb;      break;  //neg
                            case 0x7: res =     ~ opb;      break;  //not
                            case 0x8: res = opa + opb;      break;  //inc
                            case 0x9: res = opa - opb;      break;  //dec
                            case 0xA: res = opa - opb;      break;  //cmp
                            case 0xB: res = opa & opb;      break;  //tst
                        }
                        rega=read_register(1); //dont use rega until after the switch
                        if((res&0xFFFF)==0) rega|=ZBIT; else rega&=(~ZBIT);
                        if(res&0x8000)      rega|=NBIT; else rega&=(~NBIT);
                        switch(inst&0xF)
                        {
                            case 0x0:
                            case 0x8:
                                //add
                                if(res&0x10000) rega|=CBIT; else rega&=(~CBIT);
                                if
                                (
                                    ((opa&0x8000) == (opb&0x8000))
                                    &&
                                    ((res&0x8000) != (opb&0x8000))
                                )    rega|=VBIT;
                                else rega&=(~VBIT);
                                break;
                            case 0x1:
                            case 0x6:
                            case 0x9:
                            case 0xA:
                                //sub
                                if(res&0x10000) rega&=(~CBIT); else rega|=CBIT;
                                if
                                (
                                    ((opa&0x8000) != (opb&0x8000))
                                    &&
                                    ((res&0x8000) == (opb&0x8000))
                                )    rega|=VBIT;
                                else rega&=(~VBIT);
                                break;
                            default:
                                rega&=(~CBIT);
                                rega&=(~VBIT);
                                break;
                        }
                        write_register(1,rega); //can use rega now
                        switch(inst&0xF)
                        {
                            case 0x0:  //add
                            case 0x1:  //sub
                            case 0x2:  //and
                            case 0x3:  //dna
                            case 0x4:  //or
                            case 0x5:  //xor
                            case 0x6:  //neg
                            case 0x7:  //not
                            case 0x8:  //inc
                            case 0x9:  //dec
                                write_register((inst>>8)&0xF,res);
                                break;
                            case 0xA:  //cmp
                            case 0xB:  //tst
                                //these set flags but do not store
                                break;
                        }
                        break;
                    case 0x7000: // shift
                        opa=read_register((inst>>8)&0xF);
                        switch(inst&0xF)
                        {
                            case 0x0: // register based
                            case 0x1:
                            case 0x2:
                            case 0x3:
                            case 0x4:
                            case 0x5:
                            case 0x6:
                                opb=read_register((inst>>4)&0xF)&0xF;
                                break;
                            case 0x8: // immediate
                            case 0x9:
                            case 0xA:
                            case 0xB:
                            case 0xC:
                            case 0xD:
                            case 0xE:
                                opb=(inst>>4)&0xF;
                                break;
                        }
                        res=opa;
                        if(opb)
                        {
                            switch(inst&0x7)
                            {
                                case 0x0: // lsr
                                    res=opa>>opb;
                                    break;
                                case 0x1: // asr
                                    res=opa>>opb;
                                    if(opa&0x8000) res|=(~0)<<(15-opb);
                                    break;
                                case 0x2: // lsl
                                    res=opa<<opb;
                                    break;
                                case 0x3: // ror
                                    res=opa>>opb;
                                    res|=opa<<(16-opb);
                                    break;
                                case 0x4: // rol
                                    res=opa<<opb;
                                    res|=opa>>(16-opb);
                                    break;
                                case 0x5: // rrc
                                    rega=read_register(1);
                                    res=opa>>opb;
                                    res|=opa<<(17-opb);
                                    if(rega&CBIT)
                                    {
                                        res|=0x8000>>(opb-1);
                                    }
                                    else
                                    {
                                        res&=~(0x8000>>(opb-1));
                                    }
                                    if(opa&(0x0001<<(opb-1))) rega|=CBIT;
                                    else                      rega&=~(CBIT);
                                    write_register(1,rega);
                                    break;
                                case 0x6: // rlc
                                    rega=read_register(1);
                                    res=opa<<opb;
                                    res|=opa>>(17-opb);
                                    if(rega&CBIT)
                                    {
                                        res|=1<<(opb-1);
                                    }
                                    else
                                    {
                                        res&=~(1<<(opb-1));
                                    }
                                    if(opa&(0x8000>>(opb-1))) rega|=CBIT;
                                    else                      rega&=~(CBIT);
                                    write_register(1,rega);
                                    break;
                            }