summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--README89
-rw-r--r--cpu/Makefile2
-rw-r--r--monitor/Makefile3
-rw-r--r--monitor/disp.c35
-rwxr-xr-xmonitor/monbin17656 -> 0 bytes
-rw-r--r--monitor/mon.c51
-rw-r--r--monitor/mon.h7
-rw-r--r--sched/Makefile7
-rw-r--r--sched/simplify.ml5
-rw-r--r--tests/Makefile16
-rw-r--r--tests/clock2.mj4
-rw-r--r--tests/clockHMS.mj4
13 files changed, 186 insertions, 39 deletions
diff --git a/.gitignore b/.gitignore
index 2b5941f..eda51f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
*.byte
*.native
csim/csim
+sched/sched
+monitor/mon
*.o
*.ps
*/*.net
diff --git a/README b/README
index 7523ba5..1d1be18 100644
--- a/README
+++ b/README
@@ -2,6 +2,8 @@ Système Digital 2013-2014
Cours J.Vuillemin, TD T.Bourke
Alex AUVOLAT (Info 2013)
+Émile ENGUEHARD (Info 2013)
+Jonathan LAURENT (Info 2013)
Introduction
@@ -14,11 +16,11 @@ sched/
A scheduler for netlists.
Input : a netlist.
Output : a netlist with topologically sorted operators
- plus a dumbed-down version for input to the C circuit simulator
+ plus a dumbed-down version for input to the C circuit simulator
This program is also capable of a few optimisation (usually reduces netlist
- size by 1/4 or 1/3).
+ size by 1/3 or better).
$ cd sched/
- $ ocamlbuild main.byte
+ $ make
csim/
A circuit simulator written in C.
@@ -27,12 +29,36 @@ csim/
dumbed-down netlist, that is output by the scheduler.
$ cd csim/
$ make
+ Command-line arguments are detailed if the simulator is run with no arguments.
-minijazz/
- The MiniJazz compiler (given by the teachers).
+cpu/
+ A CPU circuit designed in `plan_micro.pdf`.
+ The netlist for the CPU is generated by Caml code (and not MiniJazz code),
+ therefore this directory also contains Caml files for generating netlists
+ with Caml code (see `netlist_gen.mli` and `example_cpu.ml` for usage example).
+
+monitor/
+ A C program used to monitor the simulator. The monitor has many functionnalities :
+ - Shows input and output at every step on a nice screen
+ - Ticking (every second or at every step)
+ - Running the simulator manually, at fixed frequency, or at maximum speed
+ - Serial input/output with simulated CPU
+ - 7-bar digit display based on simulator output
+ $ cd monitor/
+ $ make
+ Command-line arguments are in the format :
+ <simulator path> [<arguments for simulator> ...]
tests/
- Various test files.
+ Various test circuits (written in MiniJazz).
+ For file a.mj, type :
+ $ make a.sim
+ to compile and run the simulator on that file, and type :
+ $ make a.mon
+ to compile and run it with the monitor (better !)
+
+minijazz/
+ The MiniJazz compiler (given by the teachers).
*.pdf
Documentation about the project.
@@ -47,12 +73,34 @@ REFERENCES
Chapters 2 to 4
+HOW TO RUN THE CPU
+==================
-INTERNALS
-=========
+Compile the scheduler :
-Convention for binary values
-----------------------------
+ $ cd sched/; make; cd ..
+
+Compile the monitor :
+
+ $ cd monitor/; make; cd ..
+
+Run the CPU with the monitor :
+
+ $ cd cpu/; make
+
+You are now in the main screen of the monitor. The following commands are usefull :
+
+ (empty command) Execute one step of simulator
+ q Exit simulator
+ a Run simulator at max speed
+ f <freq> Run simulator at given frequency (in Hz)
+ t <input#> Send ticks every second on selected input
+
+Other commands are documented in `monitor/mon.c`
+
+
+CONVENTION FOR BINARY VALUES
+============================
/!\ This convention is contrary to the one used in the example file nadder.mj
(Therefore I have modified that file...)
@@ -77,6 +125,9 @@ The right shift is also inverted.
- left shift logical -> rigth shift logical
+SIMULATOR INTERNALS
+===================
+
The dumbed-down netlist format (OLD FORMAT)
-------------------------------------------
@@ -204,6 +255,11 @@ the format :
<variable name>\t<binary representation>\t<decimal representation>
The output contains an empty line at the end of every cycle.
+When the simulator is launched, it sends an output describing the I/O mechanism
+of the simulated circuit :
+<number of inputs> <number of outputs>\n
+[for each input : <input size> <input name>\n]
+
How ROMs are handled
--------------------
@@ -241,19 +297,12 @@ not defined in the ROM file) will be considered zeroes.
-TODO
-----
-
-- More advanced commands for the simulator (cf Jonathan's simulator)
-
NEXT STEPS
----------
-- Define convention for processor input/output
-- Code UI
-- How can we generate netlists with ocaml code ?
-- Code processor
-
+- Finish ALU
+- Code assembler
+- Code basic OS for the CPU
diff --git a/cpu/Makefile b/cpu/Makefile
index a39375b..898b007 100644
--- a/cpu/Makefile
+++ b/cpu/Makefile
@@ -3,7 +3,7 @@
GENERATOR=netlist_ast.ml netlist_gen.ml netlist_gen.mli
AUXILLARY=alu.ml
-SCHED=../sched/main.native
+SCHED=../sched/sched
SIM=../csim/csim
MON=../monitor/mon
diff --git a/monitor/Makefile b/monitor/Makefile
index 15dadc4..92b7a60 100644
--- a/monitor/Makefile
+++ b/monitor/Makefile
@@ -3,3 +3,6 @@ HF=mon.h
mon: $(CF) $(HF)
gcc -o $@ $(CF) -lcurses -O2
+
+clean:
+ rm mon
diff --git a/monitor/disp.c b/monitor/disp.c
index 7eaedc0..96d994d 100644
--- a/monitor/disp.c
+++ b/monitor/disp.c
@@ -74,9 +74,12 @@ void disp_display(t_mon *mon) {
werase(wpstatus);
- wprintw(wpstatus, "Step:\t\t%d\t%s\t%s\n",
+ wprintw(wpstatus, "Step:\t\t%d\t%s",
mon->step,
- (mon->status == MS_AUTO ? "A" : "M"),
+ (mon->status == MS_AUTO ? "A" : (mon->status == MS_RUN ? "M" : "")));
+ if (mon->status == MS_FREQ) wprintw(wpstatus, "%dHz", mon->freq);
+ if (mon->status == MS_AUTO) wprintw(wpstatus, " %dHz", mon->max_freq);
+ wprintw(wpstatus, "\t%s\n",
(mon->ticker_mode == TM_SECOND ? "TS" : (mon->ticker_mode == TM_FAST ? "TF" : "TZ")));
wprintw(wpstatus, "\nInputs:\n");
@@ -98,9 +101,30 @@ void disp_display(t_mon *mon) {
}
if (mon->n_outputs == 0) wprintw(wpstatus, "\t(none)\n");
- wprintw(wpstatus, "\nSerial buffer:\n%s\n", mon->ser_buf);
+ if (mon->ser_in_in != -1) {
+ wprintw(wpstatus, "\nSerial buffer:\n%s\n", mon->ser_buf);
+ }
+
+ wprintw(wpstatus, "\n\n");
+ for (i = 0; i < 8; i++)
+ wprintw(wpstatus, " %s ", (mon->d7[i] != -1 && mon->outputs[mon->d7[i]].v_bin[0] == '1' ? "---" : " "));
+ wprintw(wpstatus, "\n");
+ for (i = 0; i < 8; i++)
+ wprintw(wpstatus, " %c %c",
+ (mon->d7[i] != -1 && mon->outputs[mon->d7[i]].v_bin[1] == '1' ? '|' : ' '),
+ (mon->d7[i] != -1 && mon->outputs[mon->d7[i]].v_bin[2] == '1' ? '|' : ' '));
+ wprintw(wpstatus, "\n");
+ for (i = 0; i < 8; i++)
+ wprintw(wpstatus, " %s ", (mon->d7[i] != -1 && mon->outputs[mon->d7[i]].v_bin[3] == '1' ? "---" : " "));
+ wprintw(wpstatus, "\n");
+ for (i = 0; i < 8; i++)
+ wprintw(wpstatus, " %c %c",
+ (mon->d7[i] != -1 && mon->outputs[mon->d7[i]].v_bin[4] == '1' ? '|' : ' '),
+ (mon->d7[i] != -1 && mon->outputs[mon->d7[i]].v_bin[5] == '1' ? '|' : ' '));
+ wprintw(wpstatus, "\n");
+ for (i = 0; i < 8; i++)
+ wprintw(wpstatus, " %s ", (mon->d7[i] != -1 && mon->outputs[mon->d7[i]].v_bin[6] == '1' ? "---" : " "));
- wmove(wcmdline, 0, cmd_pos + 2);
wrefresh(wpstatus);
if (mon->ser_out_buf != 0) {
@@ -108,6 +132,9 @@ void disp_display(t_mon *mon) {
wrefresh(wpoutput);
mon->ser_out_buf = 0;
}
+
+ wmove(wcmdline, 0, cmd_pos + 2);
+ wrefresh(wcmdline);
}
diff --git a/monitor/mon b/monitor/mon
deleted file mode 100755
index 0c60bde..0000000
--- a/monitor/mon
+++ /dev/null
Binary files differ
diff --git a/monitor/mon.c b/monitor/mon.c
index 41182a8..4a51f6e 100644
--- a/monitor/mon.c
+++ b/monitor/mon.c
@@ -10,6 +10,7 @@
q Quit
a Set automatic mode (send input all the time)
m Set manual mode (send input when user sends empty command)
+ f <freq> Set frequency mode (every second, do 'freq' steps)
i <id> <v> Set input #id to value v (v is a string, transmitted as-is to simulator)
tf Tick fast (send 1 every cycle)
ts Tick for every second
@@ -22,6 +23,7 @@
i3 : output for serial output
s Set no serial input
:<text> Send text to serial
+ d7 x x ... Set outputs to be interpreted as 7-bar digit displayer (up to 8 outputs, use - for no output)
*/
int mon_read_prologue(t_mon *mon) {
@@ -49,6 +51,8 @@ int mon_read_prologue(t_mon *mon) {
}
mon->step = 0;
+ mon->freq = 1;
+ mon->max_freq = 1000;
mon->status = MS_RUN;
mon->clk = time(NULL);
@@ -61,15 +65,39 @@ int mon_read_prologue(t_mon *mon) {
mon->ser_buf[0] = 0;
mon->ser_out_buf = 0;
+ for (i = 0; i < 8; i++) mon->d7[i] = -1;
+
return 0;
}
void mon_loop(t_mon *mon) {
disp_display(mon);
+ time_t prev_time = time(NULL);
+ int steps = 0;
+
while (mon->status != MS_FINISH) {
handle_kbd(mon);
if (mon->status == MS_AUTO) {
mon_step(mon);
+ steps++;
+ if (time(NULL) != prev_time) {
+ mon->max_freq = steps;
+ steps = 0;
+ prev_time = time(NULL);
+ }
+ } else if (mon->status == MS_FREQ) {
+ if (steps < mon->freq) {
+ mon_step(mon);
+ steps++;
+ usleep(1000000 / mon->freq - 1000000 / mon->max_freq);
+ } else {
+ if (prev_time != time(NULL)) {
+ steps = 0;
+ prev_time = time(NULL);
+ } else {
+ usleep(10000);
+ }
+ }
} else {
usleep(10000);
}
@@ -85,6 +113,12 @@ void mon_handle_command(t_mon *mon, const char *c) {
mon->status = MS_AUTO;
} else if (!strcmp(c, "m")) {
mon->status = MS_RUN;
+ } else if (c[0] == 'f') {
+ const char *p = c + 1;
+ mon->freq = 0;
+ while (isspace(*p)) p++;
+ while (isdigit(*p)) mon->freq = 10 * mon->freq + (*(p++) - '0');
+ mon->status = MS_FREQ;
} else if (c[0] == 'i') {
const char *p = c + 1;
int a = 0;
@@ -132,9 +166,26 @@ void mon_handle_command(t_mon *mon, const char *c) {
mon->ser_out = w;
}
}
+
} else if (c[0] == ':') {
strcat(mon->ser_buf, c + 1);
strcat(mon->ser_buf, "\n");
+ } else if (c[0] == 'd' && c[1] == '7') {
+ const char *p = c + 2;
+ int i = 0;
+ for (i = 0; i < 8; i++) {
+ while (isspace(*p)) p++;
+ if (*p == 0) {
+ mon->d7[i] = -1;
+ } else if (*p == '-') {
+ mon->d7[i] = -1;
+ p++;
+ } else {
+ mon->d7[i] = 0;
+ while (isdigit(*p)) mon->d7[i] = 10 * mon->d7[i] + (*(p++) - '0');
+ if (mon->d7[i] >= mon->n_outputs) mon->d7[i] = -1;
+ }
+ }
}
disp_display(mon);
}
diff --git a/monitor/mon.h b/monitor/mon.h
index 39ac37e..7abcf8c 100644
--- a/monitor/mon.h
+++ b/monitor/mon.h
@@ -22,7 +22,8 @@ typedef struct {
typedef enum {
MS_FINISH,
MS_RUN,
- MS_AUTO
+ MS_AUTO,
+ MS_FREQ
} t_status;
typedef enum {
@@ -39,6 +40,8 @@ typedef struct {
t_output *outputs;
int step;
+ int freq;
+ int max_freq;
t_status status;
@@ -49,6 +52,8 @@ typedef struct {
int ser_in_in, ser_in_busy_out, ser_out;
char ser_buf[256];
char ser_out_buf;
+
+ int d7[8];
} t_mon;
void disp_init();
diff --git a/sched/Makefile b/sched/Makefile
index 460b639..4d36b96 100644
--- a/sched/Makefile
+++ b/sched/Makefile
@@ -1,10 +1,11 @@
IN=graph.ml main.ml netlist_ast.ml netlist_dumb.ml netlist_lexer.mll netlist.ml netlist_parser.mly netlist_printer.ml scheduler.ml simplify.ml
-all: main.native
+all: sched
-main.native: $(IN)
+sched: $(IN)
ocamlbuild -libs unix main.native
+ mv main.native sched
clean:
+ rm sched
rm -rf _build
- rm main.native
diff --git a/sched/simplify.ml b/sched/simplify.ml
index 86c4790..ef2f0dc 100644
--- a/sched/simplify.ml
+++ b/sched/simplify.ml
@@ -328,9 +328,8 @@ let topo_sort p =
let rec simplify_with steps p =
let pp, use = List.fold_left
(fun (x, u) (f, n) ->
- print_string n;
let xx, uu = f x in
- print_string (if uu then " *\n" else "\n");
+ print_endline (if uu then n ^ " *" else n);
(xx, u || uu))
(p, false) steps in
if use then simplify_with steps pp else pp
@@ -338,6 +337,8 @@ let rec simplify_with steps p =
let simplify p =
let p = simplify_with [
topo_sort, "topo_sort";
+ ] p in
+ let p = simplify_with [
cascade_slices, "cascade_slices";
pass_concat, "pass_concat";
select_to_id, "select_to_id";
diff --git a/tests/Makefile b/tests/Makefile
index cf2f62f..02f1c9b 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,17 +1,25 @@
.SECONDARY:
MINIJAZZ=../minijazz/mjc.byte
-SCHED=../sched/main.native
+SCHED=../sched/sched
SIM=../csim/csim
+MON=../monitor/mon
-%.sim: %.dumb
+%.mon: _build/%.dumb
+ $(MON) $(SIM) -rom decode7 decode7.rom $<
+
+%.sim: _build/%.dumb
$(SIM) -n 12 $<
-%.dumb %.snet %_opt.dumb %_opt.snet: %.net
+_build/%.dumb _build/%.snet _build/%_opt.dumb _build/%_opt.snet: _build/%.net
$(SCHED) $<
-%.net: %.mj
+_build/%.net: %.mj _build
$(MINIJAZZ) $<
+ mv `basename -s .mj $<`.net _build
+
+_build:
+ mkdir _build
clean:
rm *.net
diff --git a/tests/clock2.mj b/tests/clock2.mj
index 6f28603..73b5e6a 100644
--- a/tests/clock2.mj
+++ b/tests/clock2.mj
@@ -69,11 +69,11 @@ dec7(i:[4]) = (o:[7]) where
o = decode7
end where
-main() = (sec_u:[4],d7_sec_u:[7],sec_d:[4],d7_sec_d:[7],
+main(tick) = (sec_u:[4],d7_sec_u:[7],sec_d:[4],d7_sec_d:[7],
min_u:[4],d7_min_u:[7],min_d:[4],d7_min_d:[7],
hour_u:[4],d7_hour_u:[7],hour_d:[4],d7_hour_d:[7],
next_day) where
- (count_seca, aug_seca) = count_mod_keep<2,2>(1);
+ (count_seca, aug_seca) = count_mod_keep<2,2>(tick);
(count_secb, aug_secb) = count_mod_keep<3,5>(aug_seca);
(count_secc, aug_min) = count_mod_keep<3,6>(aug_secb);
sec_u = count_seca[0] . count_secb;
diff --git a/tests/clockHMS.mj b/tests/clockHMS.mj
index 4575c58..ea10d4f 100644
--- a/tests/clockHMS.mj
+++ b/tests/clockHMS.mj
@@ -62,8 +62,8 @@ count_mod<n, m>(in:[n], op) = (out:[n], reset) where
out = and_each<n>(neq, incr);
end where
-main() = (count_sec:[6],count_min:[6],count_hour:[5],next_day) where
- (count_sec, aug_min) = count_mod<6, 60>(save_sec, 1);
+main(tick) = (count_sec:[6],count_min:[6],count_hour:[5],next_day) where
+ (count_sec, aug_min) = count_mod<6, 60>(save_sec, tick);
save_sec = reg_n<6>(count_sec);
(count_min, aug_hour) = count_mod<6, 60>(save_min, aug_min);