diff options
-rw-r--r-- | cpu/Makefile | 3 | ||||
-rw-r--r-- | cpu/alu.ml | 27 | ||||
-rw-r--r-- | cpu/cpu.ml | 88 | ||||
-rw-r--r-- | csim/Makefile | 2 | ||||
-rw-r--r-- | csim/main.c | 17 | ||||
-rw-r--r-- | csim/sim.c | 11 | ||||
-rw-r--r-- | csim/sim.h | 1 | ||||
-rw-r--r-- | monitor/Makefile | 5 | ||||
-rw-r--r-- | monitor/disp.c | 92 | ||||
-rw-r--r-- | monitor/main.c | 61 | ||||
-rwxr-xr-x | monitor/mon | bin | 0 -> 14209 bytes | |||
-rw-r--r-- | monitor/mon.c | 86 | ||||
-rw-r--r-- | monitor/mon.h | 54 | ||||
-rw-r--r-- | plan_micro.pdf | bin | 76635 -> 76693 bytes | |||
-rw-r--r-- | plan_micro.tm | 3 | ||||
-rw-r--r-- | tests/Makefile | 2 |
16 files changed, 414 insertions, 38 deletions
diff --git a/cpu/Makefile b/cpu/Makefile index 1ab6397..ed59bb5 100644 --- a/cpu/Makefile +++ b/cpu/Makefile @@ -5,9 +5,10 @@ AUXILLARY=alu.ml SCHED=../sched/main.native SIM=../csim/csim +MON=../monitor/mon all: _build/cpu_opt.dumb - $(SIM) -rom ROM0 prog_rom0.rom $< + $(MON) $(SIM) -n 8 -rom ROM0 prog_rom0.rom $< %.sim: _build/%.dumb $(SIM) $< @@ -12,6 +12,18 @@ let rec eq_c n v c = (* v is a value, c is a constant *) else (eq_c 1 (v ** 0) (c mod 2)) ^& (eq_c (n-1) (v % (1, n-1)) (c/2)) +let rec all1 n x = + if n = 1 then + x + else + (x ** 0) ^& (all1 (n-1) (x % (1, n-1))) + +let rec nonnull n a = + if n = 1 then + a + else + (a ** 0) ^| (nonnull (n-1) (a % (1, n-1))) + let rec sign_extend n_a n_dest a = a ++ rep (n_dest - n_a) (a ** (n_a - 1)) @@ -27,23 +39,18 @@ let rec nadder n a b c_in = let s_n1, c_out = nadder (n-1) (a % (1, n-1)) (b % (1, n-1)) c_n1 in s_n ++ s_n1, c_out +let rec npshift_signed n p a b = + a (* TODO *) + let nadder_nocarry n a b = let a, b = nadder n a b (const "0") in ignore b a let rec eq_n n a b = - if n = 1 then - not (a ^^ b) - else - (not ((a ** 0) ^^ (b ** 0))) - ^& (eq_n (n-1) (a % (1, n-1)) (b % (1, n-1))) + all1 n (not (a ^^ b)) let rec ne_n n a b = - if n = 1 then - a ^^ b - else - ((a ** 0) ^^ (b ** 0)) - ^| (ne_n (n-1) (a % (1, n-1)) (b % (1, n-1))) + nonnull n (a ^^ b) let rec lt_n n a b = const "0" (* TODO : less than *) @@ -9,25 +9,62 @@ let one n = let two n = const "01" ++ zeroes (n-2) +let ser_out, set_ser_out = loop 8 +let ser_in_busy, set_ser_in_busy = loop 1 let cpu_ram ra we wa d = (* Ram chip has word size = 8 bits and address size = 16 bits 0x0000 to 0x3FFF is ROM0 - 0x4000 to 0x7FFF is unused, reserved for MMIO + 0x4000 to 0x7FFF is MMIO : + byte 0x4000 is clock ticker (increments by one every tick ; zeroed on read) + byte 0x4100 is serial input (zeroed on read) + byte 0x4102 is serial output 0x8000 to 0xFFFF is RAM *) + let read_data = zeroes 8 in + let ra_hi1 = ra ** 15 in let ra_lo1 = ra % (0, 14) in let ra_hi2 = ra ** 14 in let ra_lo2 = ra % (0, 13) in let read_rom = (not ra_hi1) ^& (not ra_hi2) in + let rd_rom = rom "ROM0" 14 8 ra_lo2 in + let read_data = mux read_rom read_data rd_rom in + + let read_ram = ra_hi1 in let wa_hi1 = wa ** 15 in let wa_lo1 = wa % (0, 14) in let we_ram = we ^& wa_hi1 in - - let rd_rom = rom "ROM0" 14 8 ra_lo2 in let rd_ram = ram 15 8 ra_lo1 we_ram wa_lo1 d in - mux read_ram (mux read_rom (zeroes 8) rd_rom) rd_ram + let read_data = mux read_ram read_data rd_ram in + + let read_tick = eq_c 16 ra 0x4000 in + let next_tick, set_next_tick = loop 8 in + let tick = reg 8 next_tick in + let tick_d = sign_extend 1 8 (get "tick") in + let read_data = + set_next_tick (mux read_tick (nadder_nocarry 8 tick tick_d) tick_d) ^. + mux read_tick read_data tick in + + let write_ser = we ^& (eq_c 16 wa 0x4102) in + let read_data = + set_ser_out (mux write_ser (zeroes 8) d) ^. + read_data in + + let read_ser = eq_c 16 ra 0x4000 in + let next_ser, set_next_ser = loop 8 in + let ser = reg 8 next_ser in + let ser_in = get "ser_in" in + let iser = nonnull 8 ser_in in + let ser = mux iser ser ser_in in + let ser_busy = nonnull 8 ser in + let read_data = + set_ser_in_busy ser_busy ^. + set_next_ser ser ^. + mux read_ser read_data ser in + + read_data + let r0 = zeroes 16 let r1, save_r1 = loop 16 @@ -65,17 +102,6 @@ let save_cpu_regs wr wd = save_r7 (reg 16 next_r7) ^. r0 -(* -let ticker n = - let k, save_k = loop n in - let s = reg n k in - let next = nadder_nocarry n s (one n) in - ignore (save_k next) s - -let tick1 = ticker 1 -let tick2 = ticker 2 -*) - let rl, rh, i, ex, exf, pc = let next_read, save_next_read = loop 1 in let read = not (reg 1 (not next_read)) in @@ -123,10 +149,21 @@ let rl, rh, i, ex, exf, pc = let wr = zeroes 3 in let rwd = zeroes 16 in + (* instruction : se/sne/slt/slte/sleu/sleu *) + let instr_sxxx = exec ^& (eq_c 4 (i_i % (1, 4)) 0b0010) in + let f0 = i_i ** 0 in + let cond_sxxx = alu_comparer 16 f0 i_f v_ra v_rb in + let wr = mux instr_sxxx wr i_r in + let rwd = mux instr_sxxx rwd (mux cond_sxxx (zeroes 16) (one 16)) in + (* instruction : incri *) let instr_incri = exec ^& eq_c 5 i_i 0b00110 in let wr = mux instr_incri wr i_r in let rwd = mux instr_incri rwd (nadder_nocarry 16 v_r (sign_extend 8 16 i_id)) in + (* instruction : shi *) + let instr_shi = exec ^& eq_c 5 i_i 0b00111 in + let wr = mux instr_shi wr i_r in + let rwd = mux instr_shi rwd (npshift_signed 16 8 v_r i_id) in (* instruction : j *) let instr_j = exec ^& eq_c 5 i_i 0b01000 in @@ -147,6 +184,11 @@ let rl, rh, i, ex, exf, pc = let wr = mux instr_jalxx wr (const "011") in let rwd = mux instr_jalxx rwd next_pc in + (* instruction : lra *) + let instr_lra = exec ^& eq_c 5 i_i 0b01100 in + let wr = mux instr_lra wr (const "101") in + let rwd = mux instr_lra rwd (nadder_nocarry 16 pc (sign_extend 11 16 i_jd)) in + (* instruction : lw/lwr/sw/swr *) let instr_lsw = eq_c 4 (i_i % (1, 4)) 0b1000 in let instr_lswr = eq_c 4 (i_i % (1, 4)) 0b1010 in @@ -178,6 +220,15 @@ let rl, rh, i, ex, exf, pc = let d = mux swx_save_hi d (v_r % (8, 15)) in let exec_finished = mux instr_lwx exec_finished swx_save_hi in + (* instruction : lil/lilz/liu/liuz *) + let instr_lixx = eq_c 3 (i_i % (2, 4))0b110 in + let instr_lixz = i ** 0 in + let instr_liux = i ** 1 in + let wr = mux instr_lixx wr i_r in + let rwd = mux instr_lixx rwd + (mux instr_liux + ( (* lil *) i_id ++ (mux instr_lixz (v_r % (8, 15)) (zeroes 8)) ) + ( (* liu *) (mux instr_lixz (v_r % (0, 7)) (zeroes 8)) ++ i_id)) in save_cpu_regs wr rwd ^. save_ram_read (cpu_ram ra we wa d) ^. @@ -187,7 +238,10 @@ let rl, rh, i, ex, exf, pc = let p = program - [] + [ + "tick", 1; + "ser_in", 8; + ] [ "read_ilow", 1, rl; "read_ihi", 1, rh; @@ -203,6 +257,8 @@ let p = "r5_E", 16, r5; "r6_F", 16, r6; "r7_G", 16, r7; + "ser_out", 8, ser_out; + "ser_in_busy", 1, ser_in_busy; ] let () = Netlist_gen.print stdout p diff --git a/csim/Makefile b/csim/Makefile index 6827579..ae4cc4e 100644 --- a/csim/Makefile +++ b/csim/Makefile @@ -1,5 +1,5 @@ csim: main.o load.o sim.o util.o - gcc -o csim $^ + gcc -o $@ $^ %.o: %.c gcc -c $< -o $@ -O2 -g diff --git a/csim/main.c b/csim/main.c index 5689cb4..2a88fbc 100644 --- a/csim/main.c +++ b/csim/main.c @@ -14,18 +14,18 @@ void usage() { - printf ("\nUsage:\n\tcsim [options] <netlist_file>\n\n"); - printf("Available options:\n"); - printf("\n -rom <prefix> <file>\n\tLoad a filename as a ROM file for the machine\n"); - printf("\tA given ROM file is used for all ROM chips with variable name having given prefix\n"); - printf("\n -n <steps>\n\tOnly run #steps steps of simulation (0 = infinity)\n"); - printf("\n -in <in-file>\n\tRead inputs from given file (eg. named pipe). Defaults to STDIN.\n"); - printf("\n -out <out-file>\n\tWrite outputs to given file (eg. named pipe). Defaults to STDOut.\n"); + fprintf(stderr, "\nUsage:\n\tcsim [options] <netlist_file>\n\n"); + fprintf(stderr, "Available options:\n"); + fprintf(stderr, "\n -rom <prefix> <file>\n\tLoad a filename as a ROM file for the machine\n"); + fprintf(stderr, "\tA given ROM file is used for all ROM chips with variable name having given prefix\n"); + fprintf(stderr, "\n -n <steps>\n\tOnly run #steps steps of simulation (0 = infinity)\n"); + fprintf(stderr, "\n -in <in-file>\n\tRead inputs from given file (eg. named pipe). Defaults to STDIN.\n"); + fprintf(stderr, "\n -out <out-file>\n\tWrite outputs to given file (eg. named pipe). Defaults to STDOUT.\n"); exit(1); } // Arguments to be parsed -int steps = 12; +int steps = 0; char *filename = NULL; char *infile = NULL; char *outfile = NULL; @@ -88,6 +88,7 @@ int main(int argc, char **argv) { // Run t_machine *machine = init_machine(program); + machine_banner(machine, output); i = 0; while (i < steps || steps == 0) { read_inputs(machine, input); @@ -52,6 +52,17 @@ t_machine *init_machine (t_program *p) { return m; } +void machine_banner(t_machine *m, FILE *stream) { + int i; + fprintf(stream, "%d %d\n", m->prog->n_inputs, m->prog->n_outputs); + for (i = 0; i < m->prog->n_inputs; i++) { + fprintf(stream, "%d %s\n", + m->prog->vars[m->prog->inputs[i]].size, + m->prog->vars[m->prog->inputs[i]].name); + } + fprintf(stream, "\n"); +} + void read_inputs(t_machine *m, FILE *stream) { /* FORMAT : For each input in the list, *in the order specified*, @@ -124,6 +124,7 @@ void add_rom(const char *prefix, FILE *file); // Implemented in sim.c t_machine *init_machine(t_program *p); +void machine_banner(t_machine *m, FILE *stream); void read_inputs(t_machine *m, FILE *stream); void machine_step(t_machine *m); void write_outputs(t_machine *m, FILE *stream); diff --git a/monitor/Makefile b/monitor/Makefile new file mode 100644 index 0000000..15dadc4 --- /dev/null +++ b/monitor/Makefile @@ -0,0 +1,5 @@ +CF=main.c disp.c mon.c +HF=mon.h + +mon: $(CF) $(HF) + gcc -o $@ $(CF) -lcurses -O2 diff --git a/monitor/disp.c b/monitor/disp.c new file mode 100644 index 0000000..d25c04d --- /dev/null +++ b/monitor/disp.c @@ -0,0 +1,92 @@ +#include <curses.h> +#include "mon.h" + +/* Screen disposition : + + program | program + status | output + window | interp. + ---------------------- + command line +*/ + +#define STATUS_WIN_WIDTH 60 + +static void disp_cmdline(); + +static char command[100]; +static int cmd_pos = 0; + +static WINDOW *wpstatus, *wpoutput, *wcmdline; + +void disp_init() { + initscr(); + cbreak(); + noecho(); + nonl(); + + wpstatus = newwin(LINES - 4, STATUS_WIN_WIDTH, 1, 1); + wpoutput = newwin(LINES - 4, COLS - STATUS_WIN_WIDTH - 3, 1, STATUS_WIN_WIDTH + 2); + wcmdline = newwin(1, COLS - 2, LINES - 2, 1); + + intrflush(wcmdline, FALSE); + keypad(wcmdline, TRUE); + nodelay(wcmdline, TRUE); + + cmd_pos = 0; + command[0] = 0; + disp_cmdline(); +} + +void disp_finish() { + endwin(); +} + +void handle_kbd(t_mon *mon) { + int x; + while ((x = wgetch(wcmdline)) != ERR) { + if (x == '\r') { + mon_handle_command(mon, command); + cmd_pos = 0; + } else if (x == KEY_BACKSPACE) { + if (cmd_pos > 0) cmd_pos--; + } else if (x >= 32 && x <= 127) { + if (cmd_pos < 99) + command[cmd_pos++] = x; + } + command[cmd_pos] = 0; + disp_cmdline(); + } +} + +// DISPLAY + +void disp_cmdline() { + werase(wcmdline); + wprintw(wcmdline, "> %s", command); + wrefresh(wcmdline); +} + +void disp_display(t_mon *mon) { + int i; + + werase(wpstatus); + + wprintw(wpstatus, "Step:\t\t%d\n", mon->step); + wprintw(wpstatus, "\nInputs:\n"); + for (i = 0; i < mon->n_inputs; i++) { + wprintw(wpstatus, "\t%s (%d)\t%s\n", mon->inputs[i].name, mon->inputs[i].size, mon->inputs[i].value); + } + if (mon->n_inputs == 0) wprintw(wpstatus, "\t(none)\n"); + wprintw(wpstatus, "\nOutputs:\n"); + for (i = 0; i < mon->n_outputs; i++) { + wprintw(wpstatus, "\t%s\t%s\t%ld\n", mon->outputs[i].name, mon->outputs[i].v_bin, mon->outputs[i].v_int); + } + if (mon->n_outputs == 0) wprintw(wpstatus, "\t(none)\n"); + + wmove(wcmdline, 0, cmd_pos + 2); + wrefresh(wpstatus); +} + + + diff --git a/monitor/main.c b/monitor/main.c new file mode 100644 index 0000000..27fc1e0 --- /dev/null +++ b/monitor/main.c @@ -0,0 +1,61 @@ +#include <curses.h> +#include <signal.h> + +#include "mon.h" + +#define MON2SIM "/tmp/mon2sim" +#define SIM2MON "/tmp/sim2mon" + +void usage(char* p) { + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s <simulator> [<simulator arguments>...]\n"); + fprintf(stderr, "\n"); +} + +int main(int argc, char *argv[]) { + int err; + + if (argc < 2) { + usage(argv[0]); + return 1; + } + + // Launch simulator + mkfifo(MON2SIM, 0600); + mkfifo(SIM2MON, 0600); + int sim_pid = fork(); + if (sim_pid == 0) { + // child : launch simulator + freopen(MON2SIM, "r", stdin); + freopen(SIM2MON, "w", stdout); + execv(argv[1], argv + 1); + } + + t_mon mon; + mon.to_sim = fopen(MON2SIM, "w"); + mon.from_sim = fopen(SIM2MON, "r"); + if (err = mon_read_prologue(&mon)) { + fprintf(stderr, "\nError while launching simulator (%d).\n", err); + goto finish; + } + + // Setup display + disp_init(); + + // RUN !!! + mon_loop(&mon); + + // clean up + disp_finish(); + +finish: + kill(sim_pid, SIGTERM); + waitpid(sim_pid); + + fclose(mon.to_sim); + fclose(mon.from_sim); + unlink(MON2SIM); + unlink(SIM2MON); + + return 0; +} diff --git a/monitor/mon b/monitor/mon Binary files differnew file mode 100755 index 0000000..9c7d629 --- /dev/null +++ b/monitor/mon diff --git a/monitor/mon.c b/monitor/mon.c new file mode 100644 index 0000000..8ff2851 --- /dev/null +++ b/monitor/mon.c @@ -0,0 +1,86 @@ +#include <stdlib.h> +#include <unistd.h> + +#include "mon.h" + +int mon_read_prologue(t_mon *mon) { + int i; + + if (fscanf(mon->from_sim, " %d %d\n", &mon->n_inputs, &mon->n_outputs) == EOF) + return -1; + + mon->inputs = malloc(mon->n_inputs * sizeof(t_input)); + mon->outputs = malloc(mon->n_outputs * sizeof(t_output)); + + // Read input description + for (i = 0; i < mon->n_inputs; i++) { + mon->inputs[i].value[0] = '0'; + mon->inputs[i].value[1] = 0; + if (fscanf(mon->from_sim, "%d %s\n", &mon->inputs[i].size, mon->inputs[i].name) == EOF) + return -(i+2); + } + + // Zeroify output description + for (i = 0; i < mon->n_outputs; i++) { + mon->outputs[i].name[0] = 0; + mon->outputs[i].v_bin[0] = 0; + mon->outputs[i].v_int = 0; + } + + mon->step = 0; + mon->status = MS_RUN; + + mon->clk = time(NULL); + + return 0; +} + +void mon_loop(t_mon *mon) { + disp_display(mon); + while (mon->status != MS_FINISH) { + handle_kbd(mon); + if (mon->status == MS_AUTO) { + mon_step(mon); + } else { + usleep(10000); + } + } +} + +void mon_handle_command(t_mon *mon, char *c) { + if (c[0] == 0) { // empty command : run step + mon_step(mon); + } else if (!strcmp(c, "q")) { + mon->status = MS_FINISH; + } else if (!strcmp(c, "a")) { + mon->status = MS_AUTO; + } else if (!strcmp(c, "m")) { + mon->status = MS_RUN; + } +} + +void mon_step(t_mon *mon) { + int i = 0; + + // Get ticker + time_t new_clk = time(NULL); + int ticker = new_clk - mon->clk; + mon->clk = new_clk; + + // Send inputs to simulator + for (i = 0; i < mon->n_inputs; i++) { + fprintf(mon->to_sim, "%s\n", mon->inputs[i].value); + } + + // Read outputs from simulator + for (i = 0; i < mon->n_outputs; i++) { + fscanf(mon->from_sim, "%s %s %d\n", + mon->outputs[i].name, + mon->outputs[i].v_bin, + &mon->outputs[i].v_int); + } + + // Display + mon->step++; + disp_display(mon); +} diff --git a/monitor/mon.h b/monitor/mon.h new file mode 100644 index 0000000..e08f01c --- /dev/null +++ b/monitor/mon.h @@ -0,0 +1,54 @@ +#ifndef DEF_MON_H +#define DEF_MON_H + +#include <time.h> +#include <stdio.h> +#include <curses.h> + +typedef unsigned long long int t_value; + +typedef struct { + char name[32]; + char v_bin[32]; + t_value v_int; +} t_output; + +typedef struct { + char name[32]; + int size; + char value[32]; +} t_input; + +typedef enum { + MS_FINISH, + MS_RUN, + MS_AUTO +} t_status; + +typedef struct { + FILE *to_sim, *from_sim; + + int n_inputs, n_outputs; + t_input *inputs; + t_output *outputs; + + int step; + + t_status status; + + time_t clk; +} t_mon; + +void disp_init(); +void disp_display(t_mon *mon); +void disp_finish(); + +void handle_kbd(t_mon *mon); + +int mon_read_prologue(t_mon *mon); // nonzero on error +void mon_step(t_mon *mon); +void mon_loop(t_mon *mon); + +void mon_handle_command(t_mon *mon, char *c); + +#endif diff --git a/plan_micro.pdf b/plan_micro.pdf Binary files differindex bf23aef..f80e45d 100644 --- a/plan_micro.pdf +++ b/plan_micro.pdf diff --git a/plan_micro.tm b/plan_micro.tm index 6b4e436..4431f85 100644 --- a/plan_micro.tm +++ b/plan_micro.tm @@ -138,7 +138,8 @@ signé>>|<row|<cell|>|<cell|>|<cell|3>|<cell|jleru>|<cell|if <math|R<rsub|A>\<leqslant\>R<rsub|B>> then <math|PC\<leftarrow\>R<rsub|>>>|<cell|non - signé>>|<row|<cell|01100>|<cell|>|<cell|>|<cell|<em|nop>>|<cell|>|<cell|>>|<row|<cell|01101>|<cell|>|<cell|>|<cell|<em|nop>>|<cell|>|<cell|>>|<row|<cell|01110>|<cell|>|<cell|>|<cell|<em|nop>>|<cell|>|<cell|>>|<row|<cell|01111>|<cell|>|<cell|>|<cell|<em|nop>>|<cell|>|<cell|>>|<row|<cell|10000>|<cell|K>|<cell|>|<cell|lw>|<cell|<math|R\<leftarrow\>mem<around*|(|R<rprime|'>+d|)>> + signé>>|<row|<cell|01100>|<cell|J>|<cell|>|<cell|lra>|<cell|<math|E\<leftarrow\>PC+d>>|<cell|<math|d> + signé>>|<row|<cell|01101>|<cell|>|<cell|>|<cell|<em|nop>>|<cell|>|<cell|>>|<row|<cell|01110>|<cell|>|<cell|>|<cell|<em|nop>>|<cell|>|<cell|>>|<row|<cell|01111>|<cell|>|<cell|>|<cell|<em|nop>>|<cell|>|<cell|>>|<row|<cell|10000>|<cell|K>|<cell|>|<cell|lw>|<cell|<math|R\<leftarrow\>mem<around*|(|R<rprime|'>+d|)>> (16 bits)>|<cell|>>|<row|<cell|10001>|<cell|K>|<cell|>|<cell|sw>|<cell|<math|mem<around*|(|R<rprime|'>+d|)>\<leftarrow\>R> (16 bits)>|<cell|>>|<row|<cell|10010>|<cell|K>|<cell|>|<cell|lb>|<cell|<math|R<rsub|lo>\<leftarrow\>mem<around*|(|R<rprime|'>+d|)> ; R<rsub|hi>\<leftarrow\>0> (8 bits)>|<cell|>>|<row|<cell|10011>|<cell|K>|<cell|>|<cell|sb>|<cell|<math|mem<around*|(|R<rprime|'>+d|)>\<leftarrow\>R<rsub|lo>> diff --git a/tests/Makefile b/tests/Makefile index 7a0792c..cf2f62f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -5,7 +5,7 @@ SCHED=../sched/main.native SIM=../csim/csim %.sim: %.dumb - $(SIM) $< + $(SIM) -n 12 $< %.dumb %.snet %_opt.dumb %_opt.snet: %.net $(SCHED) $< |