diff --git a/Makefile b/Makefile index a1bb9b9..9e7b8f9 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ USE_AALIB=1 all:first -OBJECT_FILES=gui.o gui_display.o main.o simdata.o assembly.o cpu.o +OBJECT_FILES=gui.o gui_display.o gui_internals.o main.o simdata.o assembly.o cpu.o MAIN_ROM=programs/utah_teapot.rom ROMS=test.rom ${MAIN_ROM} programs/cube.rom UTAH_TEAPOT_ASCII_STL=assets/Utah_teapot_ascii.stl diff --git a/gui.c b/gui.c index 4819713..53ce0f8 100644 --- a/gui.c +++ b/gui.c @@ -26,6 +26,7 @@ #include "gui.h" #include #include "gui_display.h" +#include "gui_internals.h" #define GENERAL_STACK_MAX_WIDTH 16 #define GENERAL_DISAS_WIDTH 41 @@ -45,8 +46,8 @@ WINDOW *general_terminal_output; WINDOW *memory_memdump; -WINDOW *pipeline_pipeline; -WINDOW *pipeline_disas; +WINDOW *internals_internals; +WINDOW *internals_disas; WINDOW *debug_simdata; @@ -64,7 +65,7 @@ int get_terminal_size(){ } -char *tab_name[]={"Overview","Memory","Pipeline","Debug","Display"}; +char *tab_name[]={"Overview","Memory","Internals","Debug","Display"}; unsigned int CURRENT_TAB=1; @@ -88,9 +89,9 @@ int gui_ncurses_refresh(){ if(wrefresh(memory_memdump)==ERR) return 1; }else if(CURRENT_TAB==3){ - if(wrefresh(pipeline_disas)==ERR) + if(wrefresh(internals_disas)==ERR) return 1; - if(wrefresh(pipeline_pipeline)==ERR) + if(wrefresh(internals_internals)==ERR) return 1; }else if(CURRENT_TAB==4){ if(wrefresh(debug_simdata)==ERR) @@ -231,8 +232,8 @@ int start_gui(enum FB_DRIVER_t fb_driver){ 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); + internals_internals=newwin(terminal_height-1-border*2,terminal_width-border*3-GENERAL_DISAS_WIDTH,1+border,border); + internals_disas=newwin(terminal_height-1-border*2,GENERAL_DISAS_WIDTH,1+border,border+terminal_width-border*3-GENERAL_DISAS_WIDTH); display_terminal_output=newwin(terminal_height-1,terminal_width,1,0); @@ -649,61 +650,6 @@ int update_debug_simdata(struct simdata_t *simdata){ 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 force_disp_terminal_output_update(struct simdata_t *simdata){ if(update_display_terminal_output(display_terminal_output,simdata)) return 1; @@ -747,9 +693,9 @@ int update_gui(struct simdata_t *simdata){ if(update_memory_memdump(simdata)) return 1; }else if(CURRENT_TAB==3){ - if(update_disas(pipeline_disas,simdata)) + if(update_disas(internals_disas,simdata)) return 1; - if(update_pipeline(pipeline_pipeline,simdata)) + if(update_internals(internals_internals,simdata)) return 1; }else if(CURRENT_TAB==4){ if(update_debug_simdata(simdata)) diff --git a/gui_internals.c b/gui_internals.c new file mode 100644 index 0000000..db86c61 --- /dev/null +++ b/gui_internals.c @@ -0,0 +1,158 @@ +#include +#include "simdata.h" +#include "cpu.h" +#include + +void drawbox(WINDOW *win,int x0, int y0, int x1, int y1){ + mvwhline(win,y0, x0, 0, x1-x0); + mvwhline(win,y1, x0, 0, x1-x0); + mvwvline(win,y0, x0, 0, y1-y0); + mvwvline(win,y0, x1, 0, y1-y0); + mvwaddch(win,y0, x0, ACS_ULCORNER); + mvwaddch(win,y1, x0, ACS_LLCORNER); + mvwaddch(win,y0, x1, ACS_URCORNER); + mvwaddch(win,y1, x1, ACS_LRCORNER); +} + +int update_internals(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,"[ INTERNALS ]"); + + if(simdata->registers==NULL||simdata->exec_data==NULL){ + mvwprintw(win,1,1,"Data not initialised"); + return 0; + } + + int graph_height,graph_width; + switch(simdata->cpu_structure){ + case CPU_STRUCTURE_SIMPLE_PIPELINED: + graph_height=42; + graph_width=59; + break; + default: + graph_height=1; + graph_height=41; + break; + } + int starty,startx,boxwidth; + starty=height/2-graph_height/2; + startx=width/2-graph_width/2; + + switch(simdata->cpu_structure){ + case CPU_STRUCTURE_SIMPLE_PIPELINED: + int fetch_arrow_enter_y; + int decode_arrow_exit_y; + boxwidth=50; + + /* FETCH BOX */ + drawbox(win,startx+boxwidth/2-50/2,starty,startx+boxwidth/2-50/2+50,starty+4); + mvwprintw(win,starty,startx+boxwidth/2-4,"[ FETCH ]"); + starty+=2; + mvwprintw(win,starty,startx+boxwidth/2-15/2,"wait_for_exec=%d",simdata->fetch_data->wait_for_exec); + fetch_arrow_enter_y=starty; + starty+=2; + + /* -------> */ + mvwaddch(win,starty,startx+boxwidth/2,ACS_TTEE); + starty++; + mvwvline(win,starty,startx+boxwidth/2, 0, 2); + starty+=2; + mvwaddch(win,starty,startx+boxwidth/2,'V'); + starty+=1; + + starty+=1; + + /* DECODE BOX */ + drawbox(win,startx+boxwidth/2-50/2,starty,startx+boxwidth/2-50/2+50,starty+6); + mvwprintw(win,starty,startx+boxwidth/2-5,"[ DECODE ]"); + starty+=2; + mvwprintw(win,starty,startx+boxwidth/2-7/2,"valid=%d",simdata->decode_data->valid); + decode_arrow_exit_y=starty; + 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); + starty+=2; + + /* -------> */ + mvwaddch(win,starty,startx+boxwidth/2,ACS_TTEE); + starty++; + mvwvline(win,starty,startx+boxwidth/2, 0, 2); + starty+=2; + mvwaddch(win,starty,startx+boxwidth/2,'V'); + starty+=1; + + starty+=1; + + /* EXECUTE BOX */ + drawbox(win,startx+boxwidth/2-50/2,starty,startx+boxwidth/2-50/2+50,starty+21); + mvwprintw(win,starty,startx+boxwidth/2-8,"[ EXECUTE UNIT ]"); + starty+=2; + 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)) ); + free(tofree); + starty+=2; + + mvwprintw(win,starty,startx+boxwidth/2-41/2,"ALU_OP=%s", (tofree=ALU_OP_t_to_string(simdata->exec_data->ALU_OP)) ); + free(tofree); + starty+=2; + + mvwprintw(win,starty,startx+boxwidth/2-41/2,"COND=%s", (tofree=COND_t_to_string(simdata->exec_data->COND)) ); + free(tofree); + mvwprintw(win,starty,startx+boxwidth/2-41/2+20,"address=%06X", simdata->exec_data->address); + starty+=2; + + // Operand boxes + struct exec_op_t *cur; + for(int i=0;i<3;i++){ + drawbox(win,startx+boxwidth/2-45/2,starty,startx+boxwidth/2-50/2+45,starty+3); + wattron(win,A_REVERSE); + switch(i){ + case 0: + mvwprintw(win,starty,startx+5," Input operand 1 "); + cur=simdata->exec_data->in_op1; + break; + case 1: + mvwprintw(win,starty,startx+5," Input operand 2 "); + cur=simdata->exec_data->in_op2; + break; + case 2: + mvwprintw(win,starty,startx+5," Output operand "); + cur=simdata->exec_data->out_op; + break; + } + wattroff(win,A_REVERSE); + starty+=2; + mvwprintw(win,starty,startx+7,"data=%06X OP_ADDR=%s",cur->data , (tofree=OP_ADDR_t_to_string(cur->OP_ADDR)) ); + free(tofree); + starty+=2; + } + + /* Wait for exec arrow */ + mvwaddch(win,decode_arrow_exit_y,startx+50,ACS_LTEE); + mvwhline(win,decode_arrow_exit_y,startx+51, 0, 3); + mvwaddch(win,decode_arrow_exit_y,startx+54,ACS_LRCORNER); + mvwvline(win,fetch_arrow_enter_y+1,startx+54, 0,decode_arrow_exit_y-fetch_arrow_enter_y-1); + mvwaddch(win,fetch_arrow_enter_y,startx+54,ACS_URCORNER); + mvwhline(win,fetch_arrow_enter_y,startx+53, 0, 1); + mvwaddch(win,fetch_arrow_enter_y,startx+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 ,startx+55,"For"); + mvwprintw(win,fetch_arrow_enter_y+(decode_arrow_exit_y-fetch_arrow_enter_y-1)/2+1,startx+55,"Exec"); + + break; + default: + mvwprintw(win,starty,startx,"No graph available for this cpu structure"); + break; + + } + + if(height==3) + return 0; + else + return 0; +} + diff --git a/gui_internals.h b/gui_internals.h new file mode 100644 index 0000000..0d734f9 --- /dev/null +++ b/gui_internals.h @@ -0,0 +1 @@ +int update_internals(WINDOW *win,struct simdata_t *simdata); diff --git a/simdata.c b/simdata.c index 9faa5a2..2a22314 100644 --- a/simdata.c +++ b/simdata.c @@ -45,6 +45,7 @@ struct simdata_t *init_simdata(){ ret->cpu_gui_hints->executing_list=NULL; ret->terminal_output=malloc(0); ret->terminal_output_size=0; + ret->cpu_structure=CPU_STRUCTURE_SIMPLE_PIPELINED; return ret; } diff --git a/simdata.h b/simdata.h index 0c76494..de35061 100644 --- a/simdata.h +++ b/simdata.h @@ -6,6 +6,11 @@ enum CPU_STATE_t{ CPU_HALTED }; +enum CPU_STRUCTURE_t{ //TODO: I would prefer this would go to cpu.h + CPU_STRUCTURE_SIMPLE_NON_PIPELINED, + CPU_STRUCTURE_SIMPLE_PIPELINED +}; + struct simdata_t{ long unsigned int current_clock; uint8_t *RAM; @@ -21,6 +26,8 @@ struct simdata_t{ uint32_t* terminal_output; uint64_t terminal_output_size; + + enum CPU_STRUCTURE_t cpu_structure; }; struct instr_list_t{