GUI,CPU: Added some quick content to the Pipeline tab and made the CPU Pipelined!

This commit is contained in:
(Tim) Efthimis Kritikos 2024-02-20 21:56:48 +00:00
parent 9abad9d9ed
commit 0b9be7aaa6
3 changed files with 260 additions and 70 deletions

165
cpu.c
View File

@ -2,17 +2,26 @@
#include "cpu.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
struct fetch_data_t *malloc_fetch_data(){
return NULL;
struct fetch_data_t *ret=malloc(sizeof(struct fetch_data_t));
ret->wait_for_exec=0;
return ret;
}
void free_fetch_data(__attribute__((unused)) struct fetch_data_t *tofree){
void free_fetch_data(struct fetch_data_t *tofree){
free(tofree);
}
int fetch(struct simdata_t *simdata){
free_instr_list(&simdata->cpu_gui_hints->fetching_list);
if(simdata->fetch_data->wait_for_exec!=0){
simdata->decode_data->valid=0;
simdata->fetch_data->wait_for_exec--;
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->valid=1;
simdata->decode_data->address=simdata->registers->PC;
add_to_instr_list(&simdata->cpu_gui_hints->fetching_list,simdata->registers->PC);
simdata->registers->PC+=4;
@ -23,7 +32,10 @@ int fetch(struct simdata_t *simdata){
struct decode_data_t *malloc_decode_data(){
return malloc(sizeof(struct decode_data_t));
struct decode_data_t *ret=malloc(sizeof(struct decode_data_t));
if(ret)
ret->valid=0;
return ret;
}
void free_decode_data(struct decode_data_t *tofree){
free(tofree);
@ -31,6 +43,10 @@ void free_decode_data(struct decode_data_t *tofree){
int decode(struct simdata_t *simdata){
uint16_t opcode,op1,op2,imm;
free_instr_list(&simdata->cpu_gui_hints->decoding_list);
if(simdata->decode_data->valid==0){
simdata->exec_data->valid=0;
return 0;
}
switch((simdata->decode_data->in_bytecode&0xE0000000)>>29){
case 0:
opcode=(simdata->decode_data->in_bytecode&0x1F000000)>>24;
@ -59,6 +75,7 @@ int decode(struct simdata_t *simdata){
simdata->exec_data->out_op->OP_ADDR=IMMEDIATE;
simdata->exec_data->out_op->data=simdata->decode_data->in_bytecode&0x00FFFFFF;
simdata->exec_data->EXEC_ACTION=(opcode&0x10)?CALL:JUMP;
simdata->fetch_data->wait_for_exec=1;
break;
case 0x0F:/* load SP */
simdata->exec_data->EXEC_ACTION=MOVE;
@ -69,6 +86,7 @@ int decode(struct simdata_t *simdata){
break;
case 0x10:
simdata->exec_data->EXEC_ACTION=RET;
simdata->fetch_data->wait_for_exec=1;
break;
default:
return 1;
@ -216,6 +234,7 @@ int decode(struct simdata_t *simdata){
default:
return 1;
}
simdata->exec_data->valid=1;
simdata->exec_data->address=simdata->decode_data->address;
add_to_instr_list(&simdata->cpu_gui_hints->decoding_list,simdata->decode_data->address);
return 0;
@ -247,6 +266,7 @@ struct exec_data_t *malloc_exec_data(){
free(ret);
return 0;
}
ret->valid=0;
return ret;
}
void free_exec_data(struct exec_data_t *tofree){
@ -257,6 +277,8 @@ void free_exec_data(struct exec_data_t *tofree){
}
int exec(struct simdata_t *simdata){
free_instr_list(&simdata->cpu_gui_hints->executing_list);
if(simdata->exec_data->valid==0)
return 0;
int condition=0;
switch(simdata->exec_data->EXEC_ACTION){
case CALL:
@ -449,31 +471,44 @@ int cpu_cycle_clock(struct simdata_t *simdata){
free_instr_list(&simdata->cpu_gui_hints->fetching_list);
free_instr_list(&simdata->cpu_gui_hints->decoding_list);
free_instr_list(&simdata->cpu_gui_hints->executing_list);
switch(state){
case 0:
switch(fetch(simdata)){
case 0: break;
default: return 3;
}
break;
case 1:
switch(decode(simdata)){
case 0: break;
default: return 2;
}
break;
case 2:
switch(exec(simdata)){
case 0: break;
case 2: return 4;
default: return 1;
}
break;
switch(exec(simdata)){
case 0: break;
case 2: return 4;
default: return 1;
}
if(state==2)
state=0;
else
state++;
switch(decode(simdata)){
case 0: break;
default: return 2;
}
switch(fetch(simdata)){
case 0: break;
default: return 3;
}
// switch(state){
// case 0:
// switch(fetch(simdata)){
// case 0: break;
// default: return 3;
// }
// break;
// case 1:
// switch(decode(simdata)){
// case 0: break;
// default: return 2;
// }
// break;
// case 2:
// switch(exec(simdata)){
// case 0: break;
// case 2: return 4;
// default: return 1;
// }
// break;
// }
// if(state==2)
// state=0;
// else
// state++;
simdata->current_clock++;
return 0;
}
@ -498,3 +533,77 @@ void cpu_simdata_free(struct simdata_t *simdata){
free_exec_data(simdata->exec_data);
free(simdata->registers);
}
char* EXEC_ACTION_t_to_string(enum EXEC_ACTION_t in){
char* ret;
switch(in){
case EXEC_ALU: ret="EXEC_ALU"; break;
case MOVE: ret="MOVE"; break;
case JUMP: ret="JUMP"; break;
case CALL: ret="CALL"; break;
case NOP: ret="NOP"; break;
case HALT: ret="HALT"; break;
case RET: ret="RET"; break;
case PUSH: ret="PUSH"; break;
case POP: ret="POP"; break;
default: ret="";
}
char *real_ret=malloc(9);
*real_ret=0;
strncpy(real_ret,ret,9);
return real_ret;
}
char* ALU_OP_t_to_string(enum ALU_OP_t in){
char* ret;
switch(in){
case ALU_ADD: ret="LU_ADD"; break;
case ALU_SUB: ret="LU_SUB"; break;
case ALU_SL: ret="LU_SL"; break;
case ALU_SR: ret="LU_SR"; break;
case ALU_CMP: ret="LU_CMP"; break;
case ALU_FDIV: ret="LU_FDIV"; break;
case ALU_FMUL: ret="LU_FMUL"; break;
case ALU_FADD: ret="LU_FADD"; break;
case ALU_FSUB: ret="LU_FSUB"; break;
case ALU_FSIN: ret="LU_FSIN"; break;
case ALU_FCOS: ret="LU_FCOS"; break;
case ALU_DEC: ret="LU_DEC"; break;
case ALU_INC: ret="LU_INC"; break;
default: ret="";
}
char *real_ret=malloc(8);
*real_ret=0;
strncpy(real_ret,ret,8);
return real_ret;
}
char* COND_t_to_string(enum COND_t in){
char* ret;
switch(in){
case COND_NONE: ret="COND_NONE"; break;
case COND_ZERO: ret="COND_ZERO"; break;
case COND_NZERO: ret="COND_NZERO"; break;
case COND_CARRY: ret="COND_CARRY"; break;
case COND_NCARRY: ret="COND_NCARRY"; break;
default: ret="";
}
char *real_ret=malloc(12);
*real_ret=0;
strncpy(real_ret,ret,12);
return real_ret;
}
char* OP_ADDR_t_to_string(enum OP_ADDR_t in){
char* ret;
switch(in){
case IMMEDIATE: ret="IMMEDIATE"; break;
case REGISTER: ret="REGISTER"; break;
case REGISTERL: ret="REGISTERL"; break;
case REGISTERH: ret="REGISTERH"; break;
case REGISTER_IND: ret="REGISTER_IND"; break;
default: ret="";
}
char *real_ret=malloc(13);
*real_ret=0;
strncpy(real_ret,ret,13);
return real_ret;
}

9
cpu.h
View File

@ -2,11 +2,12 @@
#include "simdata.h"
struct fetch_data_t{
uint8_t wait_for_exec;
};
struct decode_data_t{
uint32_t in_bytecode;
uint32_t address; // used only for the gui hints (for now)
uint8_t valid;
};
@ -70,9 +71,13 @@ struct exec_data_t {
struct exec_op_t *in_op2;
struct exec_op_t *out_op;
uint32_t address; // used only for the gui hints (for now)
uint8_t valid;
};
char* EXEC_ACTION_t_to_string(enum EXEC_ACTION_t in);
char* ALU_OP_t_to_string(enum ALU_OP_t in);
char* COND_t_to_string(enum COND_t in);
char* OP_ADDR_t_to_string(enum OP_ADDR_t in);
void cpu_simdata_free(struct simdata_t *simdata);
int cpu_simdata_malloc(struct simdata_t *simdata);

156
gui.c
View File

@ -35,12 +35,18 @@ int terminal_height;
struct gui_settings_t *gui_settings;
WINDOW *tabs;
WINDOW *general_memdump;
WINDOW *general_stack;
WINDOW *general_disas;
WINDOW *general_registers;
WINDOW *general_terminal_output;
WINDOW *memory_memdump;
WINDOW *pipeline_pipeline;
WINDOW *pipeline_disas;
WINDOW *debug_simdata;
int monochrome;
@ -55,7 +61,7 @@ int get_terminal_size(){
}
char *tab_name[]={"Overview","Memory","Internal","Debug"};
char *tab_name[]={"Overview","Memory","Pipeline","Debug"};
unsigned int CURRENT_TAB=1;
@ -78,6 +84,11 @@ int gui_ncurses_refresh(){
}else if(CURRENT_TAB==2){
if(wrefresh(memory_memdump)==ERR)
return 1;
}else if(CURRENT_TAB==3){
if(wrefresh(pipeline_disas)==ERR)
return 1;
if(wrefresh(pipeline_pipeline)==ERR)
return 1;
}else if(CURRENT_TAB==4){
if(wrefresh(debug_simdata)==ERR)
return 1;
@ -211,8 +222,11 @@ int start_gui(){
debug_simdata=newwin(terminal_height-1-border*2,terminal_width-border*2,1+border,border);
pipeline_pipeline=newwin(terminal_height-1-border*2,terminal_width-border*3-GENERAL_DISAS_WIDTH,1+border,border);
pipeline_disas=newwin(terminal_height-1-border*2,GENERAL_DISAS_WIDTH,1+border,border+terminal_width-border*3-GENERAL_DISAS_WIDTH);
gui_settings=malloc(sizeof(struct gui_settings_t));
gui_settings->cycles_per_frame=40;
gui_settings->cycles_per_frame=100;
if(gui_ncurses_refresh())
return 1;
@ -277,14 +291,14 @@ int select_instruction_color(struct simdata_t *simdata, WINDOW* window,uint32_t
return 1;
}
int update_general_disas(struct simdata_t *simdata){
werase(general_disas);
int update_disas(WINDOW *win,struct simdata_t *simdata){
werase(win);
int width,height;
getmaxyx(general_disas,height,width);
box(general_disas, 0 , 0);
mvwprintw(general_disas,0,width/2-7,"[ DISASSEMBLY ]");
getmaxyx(win,height,width);
box(win, 0 , 0);
mvwprintw(win,0,width/2-7,"[ DISASSEMBLY ]");
if(simdata->registers==NULL||simdata->RAM==NULL){
mvwprintw(general_disas,1,1,"Data not initialised");
mvwprintw(win,1,1,"Data not initialised");
return 0;
}
int offset_arrow;
@ -298,59 +312,59 @@ int update_general_disas(struct simdata_t *simdata){
else
offset_arrow=3;
if(width<18){
mvwprintw(general_disas,1,1,"too small window");
mvwprintw(win,1,1,"too small window");
}else{
uint32_t ADDRESS=(simdata->registers->PC-(usable_height/2-2)*4)&0x00FFFFFF;
for (int i=2;i<usable_height;i++){
int overall_offset=offset_arrow-2;
mvwaddch(general_disas,i,11+overall_offset,ACS_VLINE);
mvwaddch(win,i,11+overall_offset,ACS_VLINE);
if(ADDRESS==simdata->registers->PC)
wattron(general_disas,A_BOLD);
mvwprintw(general_disas,i,4+overall_offset,"%06X",ADDRESS);
wattron(win,A_BOLD);
mvwprintw(win,i,4+overall_offset,"%06X",ADDRESS);
char* disas=disassemble(*(uint32_t*)(simdata->RAM+ADDRESS));
int space_left=width-14-2+(overall_offset?0:1);
if(space_left<25)
disas[space_left+1]=0;
select_instruction_color(simdata,general_disas,ADDRESS,1);
mvwprintw(general_disas,i,13+overall_offset,"%s",disas);
select_instruction_color(simdata,general_disas,ADDRESS,0);
select_instruction_color(simdata,win,ADDRESS,1);
mvwprintw(win,i,13+overall_offset,"%s",disas);
select_instruction_color(simdata,win,ADDRESS,0);
if(ADDRESS==simdata->registers->PC)
wattroff(general_disas,A_BOLD);
wattroff(win,A_BOLD);
ADDRESS=(ADDRESS+4)&0xFFFFFF;
free(disas);
}
mvwaddch(general_disas,usable_height/2,offset_arrow,ACS_RARROW);
mvwaddch(general_disas,usable_height/2,offset_arrow-1,ACS_ULCORNER);
mvwaddch(general_disas,usable_height/2+1,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,usable_height/2+2,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,usable_height/2+3,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,usable_height/2+4,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,usable_height/2+5,offset_arrow-1,ACS_VLINE);
mvwaddch(general_disas,usable_height/2+6,offset_arrow-1,'P');
mvwaddch(win,usable_height/2,offset_arrow,ACS_RARROW);
mvwaddch(win,usable_height/2,offset_arrow-1,ACS_ULCORNER);
mvwaddch(win,usable_height/2+1,offset_arrow-1,ACS_VLINE);
mvwaddch(win,usable_height/2+2,offset_arrow-1,ACS_VLINE);
mvwaddch(win,usable_height/2+3,offset_arrow-1,ACS_VLINE);
mvwaddch(win,usable_height/2+4,offset_arrow-1,ACS_VLINE);
mvwaddch(win,usable_height/2+5,offset_arrow-1,ACS_VLINE);
mvwaddch(win,usable_height/2+6,offset_arrow-1,'P');
if(offset_arrow==2)
mvwaddch(general_disas,usable_height/2+7,offset_arrow-1,'C');
mvwaddch(win,usable_height/2+7,offset_arrow-1,'C');
else
mvwaddch(general_disas,usable_height/2+6,offset_arrow,'C');
mvwaddch(win,usable_height/2+6,offset_arrow,'C');
if(have_legend){
wattron(general_disas,COLOR_PAIR(12));
mvwprintw(general_disas,height-2,2," ");
wattroff(general_disas,COLOR_PAIR(12));
mvwprintw(general_disas,height-2,4,"=Fetch");
wattron(win,COLOR_PAIR(12));
mvwprintw(win,height-2,2," ");
wattroff(win,COLOR_PAIR(12));
mvwprintw(win,height-2,4,"=Fetch");
wattron(general_disas,COLOR_PAIR(13));
mvwprintw(general_disas,height-2,11," ");
wattroff(general_disas,COLOR_PAIR(13));
mvwprintw(general_disas,height-2,13,"=Decode");
wattron(win,COLOR_PAIR(13));
mvwprintw(win,height-2,11," ");
wattroff(win,COLOR_PAIR(13));
mvwprintw(win,height-2,13,"=Decode");
wattron(general_disas,COLOR_PAIR(14));
mvwprintw(general_disas,height-2,21," ");
wattroff(general_disas,COLOR_PAIR(14));
mvwprintw(general_disas,height-2,23,"=Exec");
wattron(win,COLOR_PAIR(14));
mvwprintw(win,height-2,21," ");
wattroff(win,COLOR_PAIR(14));
mvwprintw(win,height-2,23,"=Exec");
}
}
@ -753,7 +767,7 @@ int update_debug_simdata(struct simdata_t *simdata){
getmaxyx(debug_simdata,height,width);
box(debug_simdata, 0 , 0);
mvwprintw(debug_simdata,0,width/2-5,"[ SIMDATA ]");
if(simdata->registers==NULL||simdata->RAM==NULL){
if(simdata->registers==NULL){
mvwprintw(debug_simdata,1,1,"Data not initialised");
return 0;
}
@ -782,6 +796,63 @@ int update_debug_simdata(struct simdata_t *simdata){
else
return 0;
}
int update_pipeline(WINDOW *win,struct simdata_t *simdata){
int width,height;
werase(win);
getmaxyx(win,height,width);
box(win, 0 , 0);
mvwprintw(win,0,width/2-6,"[ PIPELINE ]");
if(simdata->registers==NULL||simdata->exec_data==NULL){
mvwprintw(win,1,1,"Data not initialised");
return 0;
}
wattron(win,A_BOLD);
mvwprintw(win,1,1,"-------------- fetch --------------");
wattroff(win,A_BOLD);
mvwprintw(win,2,1," wait_for_exec=%d",simdata->fetch_data->wait_for_exec);
wattron(win,A_BOLD);
mvwprintw(win,5,1,"-------------- decode -------------");
wattroff(win,A_BOLD);
mvwprintw(win,6,1," valid=%d in_bytecode=%08X address=%06X",simdata->decode_data->valid,simdata->decode_data->in_bytecode,simdata->decode_data->address);
wattron(win,A_BOLD);
mvwprintw(win,9,1,"-------------- execute -------------");
wattroff(win,A_BOLD);
char *tofree;
mvwprintw(win,10,1," valid=%d EXEC_ACTION=%s",simdata->exec_data->valid, (tofree=EXEC_ACTION_t_to_string(simdata->exec_data->EXEC_ACTION)) );
free(tofree);
mvwprintw(win,10,35,"ALU_OP=%s", (tofree=ALU_OP_t_to_string(simdata->exec_data->ALU_OP)) );
free(tofree);
mvwprintw(win,10,52,"COND=%s", (tofree=COND_t_to_string(simdata->exec_data->COND)) );
free(tofree);
mvwprintw(win,10,70,"address=%06X", simdata->exec_data->address);
int y=12;
struct exec_op_t *cur;
for(int i=0;i<3;i++){
mvwprintw(win,y,2,"------ [ %s ] -----",i==0?"OPERAND 1":(1==1?"OPERAND 2":"OUTPUT OPERAND"));
y++;
switch(i){
case 0:cur=simdata->exec_data->in_op1;break;
case 1:cur=simdata->exec_data->in_op2;break;
case 2:cur=simdata->exec_data->out_op;break;
}
mvwprintw(win,y,2,"OP_ADDR=%s", (tofree=OP_ADDR_t_to_string(cur->OP_ADDR)) );
free(tofree);
mvwprintw(win,y,24,"data=%06X", cur->data );
y+=2;
}
if(height==3)
return 0;
else
return 0;
}
int clear_back_window=1;
int update_gui(struct simdata_t *simdata){
@ -798,7 +869,7 @@ int update_gui(struct simdata_t *simdata){
return 1;
if(update_general_stack(simdata))
return 1;
if(update_general_disas(simdata))
if(update_disas(general_disas,simdata))
return 1;
if(update_general_registers(simdata))
return 1;
@ -807,6 +878,11 @@ int update_gui(struct simdata_t *simdata){
}else if(CURRENT_TAB==2){
if(update_memory_memdump(simdata))
return 1;
}else if(CURRENT_TAB==3){
if(update_disas(pipeline_disas,simdata))
return 1;
if(update_pipeline(pipeline_pipeline,simdata))
return 1;
}else if(CURRENT_TAB==4){
if(update_debug_simdata(simdata))
return 1;