GUI: Made the internals/pipline view into a graph and moved the code in a separate file

This commit is contained in:
(Tim) Efthimis Kritikos 2024-03-05 00:49:40 +00:00
parent 031f0d75bf
commit 0e56ea803d
6 changed files with 178 additions and 65 deletions

View File

@ -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

74
gui.c
View File

@ -26,6 +26,7 @@
#include "gui.h"
#include <locale.h>
#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))

158
gui_internals.c Normal file
View File

@ -0,0 +1,158 @@
#include <ncurses.h>
#include "simdata.h"
#include "cpu.h"
#include <stdlib.h>
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;
}

1
gui_internals.h Normal file
View File

@ -0,0 +1 @@
int update_internals(WINDOW *win,struct simdata_t *simdata);

View File

@ -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;
}

View File

@ -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{