CPU: Added support for requiring multiple clock cycles for different instruction in the execution unit and updated the gui/internals tab accordingly

This commit is contained in:
(Tim) Efthimis Kritikos 2024-03-06 02:37:55 +00:00
parent 8dc7a27cdb
commit c59791e7e2
3 changed files with 381 additions and 197 deletions

166
cpu.c
View File

@ -8,18 +8,33 @@
struct fetch_data_t *malloc_fetch_data(){ struct fetch_data_t *malloc_fetch_data(){
struct fetch_data_t *ret=malloc(sizeof(struct fetch_data_t)); struct fetch_data_t *ret=malloc(sizeof(struct fetch_data_t));
ret->wait_for_exec=0; ret->wait_for_exec=0;
ret->exec_done=1;
ret->decode_done=1;
ret->fetch_wait=0;
return ret; return ret;
} }
void free_fetch_data(struct fetch_data_t *tofree){ void free_fetch_data(struct fetch_data_t *tofree){
free(tofree); free(tofree);
} }
int fetch(struct simdata_t *simdata){ int fetch(struct simdata_t *simdata){
free_instr_list(&simdata->cpu_gui_hints->fetching_list); free_instr_list(&simdata->cpu_gui_hints->fetching_list);
if(simdata->fetch_data->wait_for_exec!=0){ if(simdata->fetch_data->wait_for_exec!=0){
simdata->fetch_data->fetch_wait=1;
simdata->decode_data->valid=0; simdata->decode_data->valid=0;
simdata->fetch_data->wait_for_exec--; simdata->fetch_data->wait_for_exec=0;
return 0; return 0;
} }
if(simdata->fetch_data->fetch_wait){
if(simdata->fetch_data->exec_done){
simdata->fetch_data->fetch_wait=0;
}else
return 0;
}
if(!simdata->fetch_data->decode_done)
return 0;
simdata->decode_data->in_bytecode=(uint32_t)(simdata->RAM[simdata->registers->PC])<<24|(uint32_t)(simdata->RAM[simdata->registers->PC+1])<<16|(uint32_t)(simdata->RAM[simdata->registers->PC+2])<<8|(uint32_t)(simdata->RAM[simdata->registers->PC+3]); simdata->decode_data->in_bytecode=(uint32_t)(simdata->RAM[simdata->registers->PC])<<24|(uint32_t)(simdata->RAM[simdata->registers->PC+1])<<16|(uint32_t)(simdata->RAM[simdata->registers->PC+2])<<8|(uint32_t)(simdata->RAM[simdata->registers->PC+3]);
simdata->decode_data->valid=1; simdata->decode_data->valid=1;
simdata->decode_data->address=simdata->registers->PC; simdata->decode_data->address=simdata->registers->PC;
@ -35,6 +50,7 @@ struct decode_data_t *malloc_decode_data(){
struct decode_data_t *ret=malloc(sizeof(struct decode_data_t)); struct decode_data_t *ret=malloc(sizeof(struct decode_data_t));
if(ret) if(ret)
ret->valid=0; ret->valid=0;
ret->exec_done=1;
return ret; return ret;
} }
void free_decode_data(struct decode_data_t *tofree){ void free_decode_data(struct decode_data_t *tofree){
@ -43,8 +59,13 @@ void free_decode_data(struct decode_data_t *tofree){
int decode(struct simdata_t *simdata){ int decode(struct simdata_t *simdata){
uint16_t opcode,op1,op2,imm; uint16_t opcode,op1,op2,imm;
free_instr_list(&simdata->cpu_gui_hints->decoding_list); free_instr_list(&simdata->cpu_gui_hints->decoding_list);
if(simdata->decode_data->exec_done==0){
simdata->fetch_data->decode_done=0;
return 0;
}
if(simdata->decode_data->valid==0){ if(simdata->decode_data->valid==0){
simdata->exec_data->valid=0; simdata->exec_data->valid=0;
simdata->fetch_data->decode_done=1;
return 0; return 0;
} }
switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){ switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){
@ -234,6 +255,7 @@ int decode(struct simdata_t *simdata){
default: default:
return 1; return 1;
} }
simdata->fetch_data->decode_done=1;
simdata->exec_data->valid=1; simdata->exec_data->valid=1;
simdata->exec_data->address=simdata->decode_data->address; simdata->exec_data->address=simdata->decode_data->address;
add_to_instr_list(&simdata->cpu_gui_hints->decoding_list,simdata->decode_data->address); add_to_instr_list(&simdata->cpu_gui_hints->decoding_list,simdata->decode_data->address);
@ -267,6 +289,7 @@ struct exec_data_t *malloc_exec_data(){
return 0; return 0;
} }
ret->valid=0; ret->valid=0;
ret->cycles_left=0;
return ret; return ret;
} }
void free_exec_data(struct exec_data_t *tofree){ void free_exec_data(struct exec_data_t *tofree){
@ -275,8 +298,41 @@ void free_exec_data(struct exec_data_t *tofree){
free(tofree->out_op); free(tofree->out_op);
free(tofree); free(tofree);
} }
#define RR_SIMPL_INDX 0
#define RR_COMPLX_INDX 1
#define RR_FCOMPLX_INDX 2
#define MEM_ACCS_INDX 3
#define IMM_LOAD_INDX 4
#define BRNCH_MISS_INDX 5
#define BRNCH_TAKN_INDX 6
#define BRNCH_UNCO_INDX 7
#define CALL_RET_INDX 8
#define RR_FTRI_INDX 9
#define RR_MOVE_INDX 10
int delay_values[]={
1, // register-register (integer) add,sub,inc,dec,shift left/right float add,sub
4, // register-register integer multiply, divide
4, // register-register float multiply, divide
2, // push / pop / read mem / write mem
1, // immediate to register
1, // branch not taken
3, // branch taken
3, // branch unconditional
4, // call/ret
4, // float sin/cos
1 // register-register move
};
int exec(struct simdata_t *simdata){ int exec(struct simdata_t *simdata){
free_instr_list(&simdata->cpu_gui_hints->executing_list); free_instr_list(&simdata->cpu_gui_hints->executing_list);
if(simdata->exec_data->valid==1){
simdata->fetch_data->exec_done=0;
simdata->decode_data->exec_done=0;
}
if(simdata->exec_data->cycles_left==0){
if(simdata->exec_data->valid==0) if(simdata->exec_data->valid==0)
return 0; return 0;
int condition=0; int condition=0;
@ -290,6 +346,17 @@ int exec(struct simdata_t *simdata){
case COND_CARRY: condition=simdata->registers->FLAGS&2; break; case COND_CARRY: condition=simdata->registers->FLAGS&2; break;
case COND_NCARRY: condition=!(simdata->registers->FLAGS&2); break; case COND_NCARRY: condition=!(simdata->registers->FLAGS&2); break;
} }
switch(simdata->exec_data->COND){
case COND_NONE:
simdata->exec_data->cycles_left=delay_values[BRNCH_UNCO_INDX];
break;
default:
if(condition)
simdata->exec_data->cycles_left=delay_values[BRNCH_TAKN_INDX];
else
simdata->exec_data->cycles_left=delay_values[BRNCH_MISS_INDX];
break;
}
if(condition){ if(condition){
if(simdata->exec_data->EXEC_ACTION==CALL){ if(simdata->exec_data->EXEC_ACTION==CALL){
*(uint32_t*)(simdata->RAM+simdata->registers->SP)=simdata->registers->PC; *(uint32_t*)(simdata->RAM+simdata->registers->SP)=simdata->registers->PC;
@ -302,6 +369,7 @@ int exec(struct simdata_t *simdata){
} }
break; break;
case RET: case RET:
simdata->exec_data->cycles_left=delay_values[CALL_RET_INDX];
simdata->registers->SP-=4; simdata->registers->SP-=4;
simdata->registers->PC=simdata->RAM[simdata->registers->SP]; simdata->registers->PC=simdata->RAM[simdata->registers->SP];
break; break;
@ -317,6 +385,9 @@ int exec(struct simdata_t *simdata){
simdata->registers->GPR[simdata->exec_data->in_op2->data]; simdata->registers->GPR[simdata->exec_data->in_op2->data];
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
(simdata->registers->GPR[simdata->exec_data->out_op->data] < simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1; (simdata->registers->GPR[simdata->exec_data->out_op->data] < simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
break; break;
case ALU_SUB: case ALU_SUB:
case ALU_CMP: case ALU_CMP:
@ -324,48 +395,81 @@ int exec(struct simdata_t *simdata){
simdata->registers->GPR[simdata->exec_data->in_op1->data]; simdata->registers->GPR[simdata->exec_data->in_op1->data];
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
(simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1; (simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
break; break;
case ALU_SL: case ALU_SL:
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x80000000)?2:0); ((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x80000000)?2:0);
result = simdata->registers->GPR[simdata->exec_data->in_op1->data]<<1; result = simdata->registers->GPR[simdata->exec_data->in_op1->data]<<1;
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
break; break;
case ALU_SR: case ALU_SR:
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00000001)?2:0); ((simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00000001)?2:0);
result = simdata->registers->GPR[simdata->exec_data->in_op1->data]>>1; result = simdata->registers->GPR[simdata->exec_data->in_op1->data]>>1;
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
break; break;
case ALU_FDIV: case ALU_FDIV:
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])/ result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])/
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
simdata->exec_data->cycles_left=delay_values[RR_COMPLX_INDX];
break; break;
case ALU_FMUL: case ALU_FMUL:
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])* result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])*
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data]));
simdata->exec_data->cycles_left=delay_values[RR_COMPLX_INDX];
break; break;
case ALU_FADD: case ALU_FADD:
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])+ result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])+
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
break; break;
case ALU_FSUB: case ALU_FSUB:
result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])- result = ieee754_float_to_uint32(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op2->data])-
uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])); uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]));
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
break; break;
case ALU_FSIN: case ALU_FSIN:
result = ieee754_float_to_uint32(sinf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]))); result = ieee754_float_to_uint32(sinf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])));
simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX];
break; break;
case ALU_FCOS: case ALU_FCOS:
result = ieee754_float_to_uint32(cosf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data]))); result = ieee754_float_to_uint32(cosf(uint32_to_ieee754_float(simdata->registers->GPR[simdata->exec_data->in_op1->data])));
simdata->exec_data->cycles_left=delay_values[RR_FTRI_INDX];
break; break;
case ALU_DEC: case ALU_DEC:
*(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])-1; *(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])-1;
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
(simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1; (simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
simdata->exec_data->cycles_left=delay_values[RR_FCOMPLX_INDX];
break; break;
case ALU_INC: case ALU_INC:
*(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])+1; *(uint32_t*)&result = *(uint32_t*)(&simdata->registers->GPR[simdata->exec_data->in_op1->data])+1;
simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)| simdata->registers->FLAGS=(simdata->registers->FLAGS&0xFFFFFFFD)|
(simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1; (simdata->registers->GPR[simdata->exec_data->out_op->data] > simdata->registers->GPR[simdata->exec_data->in_op1->data])<<1;
simdata->exec_data->cycles_left=delay_values[RR_SIMPL_INDX];
break; break;
default: default:
return 1; return 1;
@ -379,20 +483,28 @@ int exec(struct simdata_t *simdata){
case MOVE: case MOVE:
switch(simdata->exec_data->out_op->OP_ADDR){ switch(simdata->exec_data->out_op->OP_ADDR){
case REGISTERL: case REGISTERL:
if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE) if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0xFFFF0000)|(0x0000FFFF& simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0xFFFF0000)|(0x0000FFFF&
simdata->exec_data->in_op1->data); simdata->exec_data->in_op1->data);
else simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX];
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0xFFFF0000)|(0x0000FFFF& }else{
simdata->registers->GPR[simdata->exec_data->in_op1->data]); //simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0xFFFF0000)|(0x0000FFFF&
// simdata->registers->GPR[simdata->exec_data->in_op1->data]);
//simdata->exec_data->cycles_left=
return 1;
}
break; break;
case REGISTERH: case REGISTERH:
if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE) if(simdata->exec_data->in_op1->OP_ADDR==IMMEDIATE){
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x0000FFFF)|((0x0000FFFF& simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x0000FFFF)|((0x0000FFFF&
simdata->exec_data->in_op1->data)<<16); simdata->exec_data->in_op1->data)<<16);
else simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX];
simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x0000FFFF)|((0x0000FFFF& }else{
simdata->registers->GPR[simdata->exec_data->in_op1->data])<<16); //simdata->registers->GPR[simdata->exec_data->out_op->data]=(simdata->registers->GPR[simdata->exec_data->out_op->data]&0x0000FFFF)|((0x0000FFFF&
// simdata->registers->GPR[simdata->exec_data->in_op1->data])<<16);
//simdata->exec_data->cycles_left=
return 1;
}
break; break;
case REGISTER: /* This is for special registers like the SP which is 24bits long */ case REGISTER: /* This is for special registers like the SP which is 24bits long */
if(simdata->exec_data->out_op->data==0xFF){ if(simdata->exec_data->out_op->data==0xFF){
@ -401,19 +513,24 @@ int exec(struct simdata_t *simdata){
simdata->registers->SP=simdata->exec_data->in_op1->data; simdata->registers->SP=simdata->exec_data->in_op1->data;
else else
return 2; return 2;
simdata->exec_data->cycles_left=delay_values[IMM_LOAD_INDX];
}else if( simdata->exec_data->in_op1->OP_ADDR==REGISTER ){ /*for completeion, not valid ( yet )*/ }else if( simdata->exec_data->in_op1->OP_ADDR==REGISTER ){ /*for completeion, not valid ( yet )*/
if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 ) //if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 )
simdata->registers->SP=simdata->registers->GPR[simdata->exec_data->in_op1->data]; // simdata->registers->SP=simdata->registers->GPR[simdata->exec_data->in_op1->data];
else //else
return 2; // return 2;
return 1;
} }
}else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER_IND){ }else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER_IND){
if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 ) if( (simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000) == 0 ){
simdata->registers->GPR[simdata->exec_data->out_op->data]=*(uint32_t*)(simdata->RAM+simdata->registers->GPR[simdata->exec_data->in_op1->data]); simdata->registers->GPR[simdata->exec_data->out_op->data]=*(uint32_t*)(simdata->RAM+simdata->registers->GPR[simdata->exec_data->in_op1->data]);
else simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX];
}else
return 2; return 2;
}else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){ }else if(simdata->exec_data->in_op1->OP_ADDR==REGISTER){
simdata->registers->GPR[simdata->exec_data->out_op->data]=simdata->registers->GPR[simdata->exec_data->in_op1->data]; simdata->registers->GPR[simdata->exec_data->out_op->data]=simdata->registers->GPR[simdata->exec_data->in_op1->data];
simdata->exec_data->cycles_left=delay_values[RR_MOVE_INDX];
}else }else
return 1; return 1;
break; break;
@ -423,14 +540,20 @@ int exec(struct simdata_t *simdata){
if(simdata->registers->GPR[simdata->exec_data->out_op->data]==0x00FFFFFC) if(simdata->registers->GPR[simdata->exec_data->out_op->data]==0x00FFFFFC)
if(terminal_output(simdata->registers->GPR[simdata->exec_data->in_op1->data],simdata)) if(terminal_output(simdata->registers->GPR[simdata->exec_data->in_op1->data],simdata))
return 1; return 1;
simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX];
}else }else
return 1; return 1;
break; break;
default: default:
return 1; return 1;
} }
case NOP: break; break;
case NOP:
simdata->exec_data->cycles_left=1;
break;
case HALT: case HALT:
simdata->exec_data->cycles_left=1;
simdata->cpu_state=CPU_HALTED; simdata->cpu_state=CPU_HALTED;
break; break;
case PUSH: case PUSH:
@ -439,6 +562,7 @@ int exec(struct simdata_t *simdata){
simdata->RAM[simdata->registers->SP+2]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00FF0000)>>16; simdata->RAM[simdata->registers->SP+2]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0x00FF0000)>>16;
simdata->RAM[simdata->registers->SP+3]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000)>>24; simdata->RAM[simdata->registers->SP+3]=(simdata->registers->GPR[simdata->exec_data->in_op1->data]&0xFF000000)>>24;
simdata->registers->SP+=4; simdata->registers->SP+=4;
simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX];
break; break;
case POP: case POP:
simdata->registers->SP-=4; simdata->registers->SP-=4;
@ -446,8 +570,18 @@ int exec(struct simdata_t *simdata){
simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+1]<<8; simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+1]<<8;
simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+2]<<16; simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+2]<<16;
simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+3]<<24; simdata->registers->GPR[simdata->exec_data->in_op1->data]|=simdata->RAM[simdata->registers->SP+3]<<24;
simdata->exec_data->cycles_left=delay_values[MEM_ACCS_INDX];
break; break;
} }
}
if(simdata->exec_data->cycles_left!=0)
simdata->exec_data->cycles_left--;
else
return 1;//internal error
if(simdata->exec_data->cycles_left==0){
simdata->fetch_data->exec_done=1;
simdata->decode_data->exec_done=1;
}
add_to_instr_list(&simdata->cpu_gui_hints->executing_list,simdata->exec_data->address); add_to_instr_list(&simdata->cpu_gui_hints->executing_list,simdata->exec_data->address);
return 0; return 0;
} }

6
cpu.h
View File

@ -3,11 +3,16 @@
struct fetch_data_t{ struct fetch_data_t{
uint8_t wait_for_exec; uint8_t wait_for_exec;
uint8_t exec_done;
uint8_t decode_done;
int fetch_wait;
}; };
struct decode_data_t{ struct decode_data_t{
uint32_t in_bytecode; uint32_t in_bytecode;
uint32_t address; // used only for the gui hints (for now) uint32_t address; // used only for the gui hints (for now)
uint8_t valid; uint8_t valid;
uint8_t exec_done;
}; };
@ -72,6 +77,7 @@ struct exec_data_t {
struct exec_op_t *out_op; struct exec_op_t *out_op;
uint32_t address; // used only for the gui hints (for now) uint32_t address; // used only for the gui hints (for now)
uint8_t valid; uint8_t valid;
uint8_t cycles_left;
}; };
char* EXEC_ACTION_t_to_string(enum EXEC_ACTION_t in); char* EXEC_ACTION_t_to_string(enum EXEC_ACTION_t in);

View File

@ -31,7 +31,7 @@ int update_internals(WINDOW *win,struct simdata_t *simdata){
switch(simdata->cpu_structure){ switch(simdata->cpu_structure){
case CPU_STRUCTURE_SIMPLE_PIPELINED: case CPU_STRUCTURE_SIMPLE_PIPELINED:
graph_height=42; graph_height=42;
graph_width=59; graph_width=82;
break; break;
default: default:
graph_height=1; graph_height=1;
@ -46,103 +46,147 @@ int update_internals(WINDOW *win,struct simdata_t *simdata){
case CPU_STRUCTURE_SIMPLE_PIPELINED: case CPU_STRUCTURE_SIMPLE_PIPELINED:
int fetch_arrow_enter_y; int fetch_arrow_enter_y;
int decode_arrow_exit_y; int decode_arrow_exit_y;
int exec_arrow_y;
boxwidth=50; boxwidth=50;
/* FETCH BOX */ /* FETCH BOX */
drawbox(win,startx+boxwidth/2-50/2,starty,startx+boxwidth/2-50/2+50,starty+4); drawbox(win,startx+20+boxwidth/2-50/2,starty,startx+20+boxwidth/2-50/2+50,starty+6);
mvwprintw(win,starty,startx+boxwidth/2-4,"[ FETCH ]"); mvwprintw(win,starty,startx+20+boxwidth/2-4,"[ FETCH ]");
starty+=2; starty+=2;
mvwprintw(win,starty,startx+boxwidth/2-15/2,"wait_for_exec=%d",simdata->fetch_data->wait_for_exec); mvwprintw(win,starty,startx+20+boxwidth/2-27/2,"wait_for_exec=%d exec_done=%d",simdata->fetch_data->wait_for_exec,simdata->fetch_data->exec_done);
starty+=2;
mvwprintw(win,starty,startx+20+boxwidth/2-26/2,"fetch_wait=%d decode_done=%d",simdata->fetch_data->fetch_wait,simdata->fetch_data->decode_done);
fetch_arrow_enter_y=starty; fetch_arrow_enter_y=starty;
starty+=2; starty+=2;
/* -------> */ /* -------> */
mvwaddch(win,starty,startx+boxwidth/2,ACS_TTEE); mvwaddch(win,starty,startx+20+boxwidth/2,ACS_TTEE);
starty++; starty++;
mvwvline(win,starty,startx+boxwidth/2, 0, 2); mvwvline(win,starty,startx+20+boxwidth/2, 0, 2);
starty+=2; starty+=2;
mvwaddch(win,starty,startx+boxwidth/2,'V'); mvwaddch(win,starty,startx+20+boxwidth/2,'V');
starty+=1; starty+=1;
starty+=1; starty+=1;
/* DECODE BOX */ /* DECODE BOX */
drawbox(win,startx+boxwidth/2-50/2,starty,startx+boxwidth/2-50/2+50,starty+6); drawbox(win,startx+20+boxwidth/2-50/2,starty,startx+20+boxwidth/2-50/2+50,starty+6);
mvwprintw(win,starty,startx+boxwidth/2-5,"[ DECODE ]"); mvwprintw(win,starty,startx+20+boxwidth/2-5,"[ DECODE ]");
starty+=2; starty+=2;
mvwprintw(win,starty,startx+boxwidth/2-7/2,"valid=%d",simdata->decode_data->valid); mvwprintw(win,starty,startx+20+boxwidth/2-19/2,"valid=%d exec_done=%d",simdata->decode_data->valid,simdata->decode_data->exec_done);
decode_arrow_exit_y=starty; decode_arrow_exit_y=starty;
starty+=2; starty+=2;
mvwprintw(win,starty,startx+boxwidth/2-41/2,"in_bytecode=0x%08X address=0x%06X",simdata->decode_data->in_bytecode,simdata->decode_data->address); mvwprintw(win,starty,startx+20+boxwidth/2-41/2,"in_bytecode=0x%08X address=0x%06X",simdata->decode_data->in_bytecode,simdata->decode_data->address);
starty+=2; starty+=2;
/* -------> */ /* -------> */
mvwaddch(win,starty,startx+boxwidth/2,ACS_TTEE); mvwaddch(win,starty,startx+20+boxwidth/2,ACS_TTEE);
starty++; starty++;
mvwvline(win,starty,startx+boxwidth/2, 0, 2); mvwvline(win,starty,startx+20+boxwidth/2, 0, 2);
starty+=2; starty+=2;
mvwaddch(win,starty,startx+boxwidth/2,'V'); mvwaddch(win,starty,startx+20+boxwidth/2,'V');
starty+=1; starty+=1;
starty+=1; starty+=1;
/* EXECUTE BOX */ /* EXECUTE BOX */
drawbox(win,startx+boxwidth/2-50/2,starty,startx+boxwidth/2-50/2+50,starty+21); drawbox(win,startx+20+boxwidth/2-50/2,starty,startx+20+boxwidth/2-50/2+50,starty+21);
mvwprintw(win,starty,startx+boxwidth/2-8,"[ EXECUTE UNIT ]"); mvwprintw(win,starty,startx+20+boxwidth/2-8,"[ EXECUTE UNIT ]");
starty+=2; starty+=2;
char *tofree; char *tofree;
mvwprintw(win,starty,startx+boxwidth/2-41/2,"valid=%d EXEC_ACTION=%s",simdata->exec_data->valid, (tofree=EXEC_ACTION_t_to_string(simdata->exec_data->EXEC_ACTION)) ); mvwprintw(win,starty,startx+20+boxwidth/2-41/2,"valid=%d EXEC_ACTION=%s",simdata->exec_data->valid, (tofree=EXEC_ACTION_t_to_string(simdata->exec_data->EXEC_ACTION)) );
free(tofree); free(tofree);
starty+=2; starty+=2;
mvwprintw(win,starty,startx+boxwidth/2-41/2,"ALU_OP=%s", (tofree=ALU_OP_t_to_string(simdata->exec_data->ALU_OP)) ); mvwprintw(win,starty,startx+20+boxwidth/2-41/2,"ALU_OP=%s ", (tofree=ALU_OP_t_to_string(simdata->exec_data->ALU_OP)) );
free(tofree); free(tofree);
mvwprintw(win,starty,startx+20+boxwidth/2-41/2+20,"cycles_left=%d ", simdata->exec_data->cycles_left );
starty+=2; starty+=2;
mvwprintw(win,starty,startx+boxwidth/2-41/2,"COND=%s", (tofree=COND_t_to_string(simdata->exec_data->COND)) );
mvwprintw(win,starty,startx+20+boxwidth/2-41/2,"COND=%s", (tofree=COND_t_to_string(simdata->exec_data->COND)) );
free(tofree); free(tofree);
mvwprintw(win,starty,startx+boxwidth/2-41/2+20,"address=%06X", simdata->exec_data->address); mvwprintw(win,starty,startx+20+boxwidth/2-41/2+20,"address=%06X", simdata->exec_data->address);
starty+=2; starty+=2;
// Operand boxes // Operand boxes
struct exec_op_t *cur; struct exec_op_t *cur;
for(int i=0;i<3;i++){ for(int i=0;i<3;i++){
drawbox(win,startx+boxwidth/2-45/2,starty,startx+boxwidth/2-50/2+45,starty+3); drawbox(win,startx+20+boxwidth/2-45/2,starty,startx+20+boxwidth/2-50/2+45,starty+3);
wattron(win,A_REVERSE); wattron(win,A_REVERSE);
switch(i){ switch(i){
case 0: case 0:
mvwprintw(win,starty,startx+5," Input operand 1 "); mvwprintw(win,starty,startx+20+5," Input operand 1 ");
cur=simdata->exec_data->in_op1; cur=simdata->exec_data->in_op1;
break; break;
case 1: case 1:
mvwprintw(win,starty,startx+5," Input operand 2 "); exec_arrow_y=starty;
mvwprintw(win,starty,startx+20+5," Input operand 2 ");
cur=simdata->exec_data->in_op2; cur=simdata->exec_data->in_op2;
break; break;
case 2: case 2:
mvwprintw(win,starty,startx+5," Output operand "); mvwprintw(win,starty,startx+20+5," Output operand ");
cur=simdata->exec_data->out_op; cur=simdata->exec_data->out_op;
break; break;
} }
wattroff(win,A_REVERSE); wattroff(win,A_REVERSE);
starty+=2; starty+=2;
mvwprintw(win,starty,startx+7,"data=%06X OP_ADDR=%s",cur->data , (tofree=OP_ADDR_t_to_string(cur->OP_ADDR)) ); mvwprintw(win,starty,startx+20+7,"data=%06X OP_ADDR=%s",cur->data , (tofree=OP_ADDR_t_to_string(cur->OP_ADDR)) );
free(tofree); free(tofree);
starty+=2; starty+=2;
} }
/* Wait for exec arrow */ /* Wait for exec arrow */
mvwaddch(win,decode_arrow_exit_y,startx+50,ACS_LTEE); mvwaddch(win,decode_arrow_exit_y,startx+20+50,ACS_LTEE);
mvwhline(win,decode_arrow_exit_y,startx+51, 0, 3); mvwhline(win,decode_arrow_exit_y,startx+20+51, 0, 3);
mvwaddch(win,decode_arrow_exit_y,startx+54,ACS_LRCORNER); mvwaddch(win,decode_arrow_exit_y,startx+20+54,ACS_LRCORNER);
mvwvline(win,fetch_arrow_enter_y+1,startx+54, 0,decode_arrow_exit_y-fetch_arrow_enter_y-1); mvwvline(win,fetch_arrow_enter_y+1,startx+20+54, 0,decode_arrow_exit_y-fetch_arrow_enter_y-1);
mvwaddch(win,fetch_arrow_enter_y,startx+54,ACS_URCORNER); mvwaddch(win,fetch_arrow_enter_y,startx+20+54,ACS_URCORNER);
mvwhline(win,fetch_arrow_enter_y,startx+53, 0, 1); mvwhline(win,fetch_arrow_enter_y,startx+20+53, 0, 1);
mvwaddch(win,fetch_arrow_enter_y,startx+52,'<'); mvwaddch(win,fetch_arrow_enter_y,startx+20+52,'<');
mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2-1,startx+55,"Wait"); mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2-1,startx+20+55,"Wait");
mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2 ,startx+55,"For"); mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2 ,startx+20+55,"For");
mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2+1,startx+55,"Exec"); mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2+1,startx+20+55,"Exec");
/* Decode done arrow */
mvwaddch(win,decode_arrow_exit_y,startx+20,ACS_RTEE);
mvwhline(win,decode_arrow_exit_y,startx+17, 0, 3);
mvwaddch(win,decode_arrow_exit_y,startx+16,ACS_LLCORNER);
mvwvline(win,fetch_arrow_enter_y+1,startx+16, 0,decode_arrow_exit_y-fetch_arrow_enter_y-1);
mvwaddch(win,fetch_arrow_enter_y,startx+16,ACS_ULCORNER);
mvwhline(win,fetch_arrow_enter_y,startx+17, 0, 1);
mvwaddch(win,fetch_arrow_enter_y,startx+18,'>');
mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2 ,startx+10,"Decode");
mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2+1,startx+12,"Done");
decode_arrow_exit_y+=2;//a bit of a hack i know
/* Exec done (decode) arrow */
mvwaddch(win,exec_arrow_y,startx+20,ACS_RTEE);
mvwhline(win,exec_arrow_y,startx+17, 0, 3);
mvwaddch(win,exec_arrow_y,startx+16,ACS_LLCORNER);
mvwvline(win,decode_arrow_exit_y+1,startx+16, 0,exec_arrow_y-decode_arrow_exit_y-1);
mvwaddch(win,decode_arrow_exit_y,startx+16,ACS_ULCORNER);
mvwhline(win,decode_arrow_exit_y,startx+17, 0, 1);
mvwaddch(win,decode_arrow_exit_y,startx+18,'>');
mvwprintw(win,decode_arrow_exit_y+(exec_arrow_y-decode_arrow_exit_y-1)/2 ,startx+12,"Exec");
mvwprintw(win,decode_arrow_exit_y+(exec_arrow_y-decode_arrow_exit_y-1)/2+1,startx+12,"Done");
fetch_arrow_enter_y-=2;//a bit of a hack i know
exec_arrow_y+=3;
/* Exec done (fetch) arrow */
mvwaddch(win,exec_arrow_y,startx+20,ACS_RTEE);
mvwhline(win,exec_arrow_y,startx+9, 0, 11);
mvwaddch(win,exec_arrow_y,startx+8,ACS_LLCORNER);
mvwvline(win,fetch_arrow_enter_y+1,startx+8, 0,exec_arrow_y-fetch_arrow_enter_y-1);
mvwaddch(win,fetch_arrow_enter_y,startx+8,ACS_ULCORNER);
mvwhline(win,fetch_arrow_enter_y,startx+9, 0, 9);
mvwaddch(win,fetch_arrow_enter_y,startx+18,'>');
mvwprintw(win,fetch_arrow_enter_y+(exec_arrow_y-fetch_arrow_enter_y-1)/2 ,startx+4,"Exec");
mvwprintw(win,fetch_arrow_enter_y+(exec_arrow_y-fetch_arrow_enter_y-1)/2+1,startx+4,"Done");
break; break;
default: default:
mvwprintw(win,starty,startx,"No graph available for this cpu structure"); mvwprintw(win,starty,startx,"No graph available for this cpu structure");