summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2014-01-03 19:05:10 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2014-01-03 19:05:10 +0100
commit1ff268ab13dd299c4cdc1e379df5397bd6a394e3 (patch)
tree014db93062f26cdfe2d2639fd833afd554e94a66
parentc46fe12e47c405fbb03f0c93121402d873bc470e (diff)
downloadSystDigit-Projet-1ff268ab13dd299c4cdc1e379df5397bd6a394e3.tar.gz
SystDigit-Projet-1ff268ab13dd299c4cdc1e379df5397bd6a394e3.zip
Added simulator monitor tool.
-rw-r--r--cpu/Makefile3
-rw-r--r--cpu/alu.ml27
-rw-r--r--cpu/cpu.ml88
-rw-r--r--csim/Makefile2
-rw-r--r--csim/main.c17
-rw-r--r--csim/sim.c11
-rw-r--r--csim/sim.h1
-rw-r--r--monitor/Makefile5
-rw-r--r--monitor/disp.c92
-rw-r--r--monitor/main.c61
-rwxr-xr-xmonitor/monbin0 -> 14209 bytes
-rw-r--r--monitor/mon.c86
-rw-r--r--monitor/mon.h54
-rw-r--r--plan_micro.pdfbin76635 -> 76693 bytes
-rw-r--r--plan_micro.tm3
-rw-r--r--tests/Makefile2
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) $<
diff --git a/cpu/alu.ml b/cpu/alu.ml
index a0115a4..7356fbb 100644
--- a/cpu/alu.ml
+++ b/cpu/alu.ml
@@ -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 *)
diff --git a/cpu/cpu.ml b/cpu/cpu.ml
index f72e404..6a71efd 100644
--- a/cpu/cpu.ml
+++ b/cpu/cpu.ml
@@ -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);
diff --git a/csim/sim.c b/csim/sim.c
index 04cad15..f91ac75 100644
--- a/csim/sim.c
+++ b/csim/sim.c
@@ -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*,
diff --git a/csim/sim.h b/csim/sim.h
index 0265f53..b06399f 100644
--- a/csim/sim.h
+++ b/csim/sim.h
@@ -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
new file mode 100755
index 0000000..9c7d629
--- /dev/null
+++ b/monitor/mon
Binary files differ
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
index bf23aef..f80e45d 100644
--- a/plan_micro.pdf
+++ b/plan_micro.pdf
Binary files differ
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) $<