summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex AUVOLAT <alex.auvolat@ens.fr>2013-11-04 22:05:57 +0100
committerAlex AUVOLAT <alex.auvolat@ens.fr>2013-11-04 22:05:57 +0100
commitcebd07b64f1f537c5ecf00ec21ff4b7c4032f0a3 (patch)
tree9d2048313fe3ad4c92865c8f0236bed24e64449b
parentf253f98136def21b5e50c5922246e2ddfe315442 (diff)
downloadSystDigit-Projet-cebd07b64f1f537c5ecf00ec21ff4b7c4032f0a3.tar.gz
SystDigit-Projet-cebd07b64f1f537c5ecf00ec21ff4b7c4032f0a3.zip
Added stub C simulator (defined dumb-down syntax for netlists).
-rw-r--r--.gitignore2
-rw-r--r--csim/Makefile5
-rw-r--r--csim/load.c104
-rw-r--r--csim/main.c97
-rw-r--r--csim/sim.c23
-rw-r--r--csim/sim.h116
-rw-r--r--sched/_tags (renamed from tp1/_tags)0
-rw-r--r--sched/graph.ml (renamed from tp1/graph.ml)0
l---------sched/graph_test.byte1
-rw-r--r--sched/graph_test.ml (renamed from tp1/graph_test.ml)0
l---------sched/main.byte1
-rw-r--r--sched/main.ml50
-rw-r--r--sched/netlist.ml (renamed from tp1/netlist.ml)0
-rw-r--r--sched/netlist_ast.ml (renamed from tp1/netlist_ast.ml)0
-rw-r--r--sched/netlist_lexer.mll (renamed from tp1/netlist_lexer.mll)0
-rw-r--r--sched/netlist_parser.mly (renamed from tp1/netlist_parser.mly)0
-rw-r--r--sched/netlist_printer.ml180
-rwxr-xr-xsched/netlist_simulator.byte (renamed from tp1/netlist_simulator.byte)bin190274 -> 190274 bytes
-rw-r--r--sched/scheduler.ml (renamed from tp1/scheduler.ml)0
-rw-r--r--sched/test/clock_div.dumb11
-rw-r--r--sched/test/clock_div.mj (renamed from tp1/test/clock_div.mj)0
-rw-r--r--sched/test/clock_div.net (renamed from tp1/test/clock_div.net)0
-rw-r--r--sched/test/clock_div_sch.net9
-rw-r--r--sched/test/cm2.dumb9
-rw-r--r--sched/test/cm2.mj (renamed from tp1/test/cm2.mj)0
-rw-r--r--sched/test/cm2.net (renamed from tp1/test/cm2.net)0
-rw-r--r--sched/test/cm2_sch.net9
-rw-r--r--sched/test/fulladder.dumb20
-rw-r--r--sched/test/fulladder.mj (renamed from tp1/test/fulladder.mj)0
-rw-r--r--sched/test/fulladder.net (renamed from tp1/test/fulladder.net)0
-rw-r--r--sched/test/fulladder_sch.net12
-rw-r--r--sched/test/nadder.dumb27
-rw-r--r--sched/test/nadder.mj (renamed from tp1/test/nadder.mj)0
-rw-r--r--sched/test/nadder.net (renamed from tp1/test/nadder.net)0
-rw-r--r--sched/test/nadder_sch.net17
-rw-r--r--sched/test/ram.dumb55
-rw-r--r--sched/test/ram.mj (renamed from tp1/test/ram.mj)0
-rw-r--r--sched/test/ram.net (renamed from tp1/test/ram.net)0
-rw-r--r--sched/test/ram_sch.net32
-rw-r--r--tp1/netlist_printer.ml82
-rw-r--r--tp1/scheduler_test.ml41
41 files changed, 780 insertions, 123 deletions
diff --git a/.gitignore b/.gitignore
index a9d6766..c90ad14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@ tp1/*test.byte
tp1/test/*_sch.net
camlsim/*.byte
*.swp
+csim/csim
+*.o
diff --git a/csim/Makefile b/csim/Makefile
new file mode 100644
index 0000000..32d100d
--- /dev/null
+++ b/csim/Makefile
@@ -0,0 +1,5 @@
+main: main.o load.o sim.o
+ gcc -o csim $^
+
+%.o: %.c
+ gcc -c $< -o $@ -g
diff --git a/csim/load.c b/csim/load.c
new file mode 100644
index 0000000..397af5a
--- /dev/null
+++ b/csim/load.c
@@ -0,0 +1,104 @@
+/*
+ Système Digital
+ 2013-2014
+ Alex AUVOLAT
+
+ load.c Code for loading dumbed-down netlist files
+ (no parsing of .net files !!)
+*/
+
+#include <stdlib.h>
+
+#include "sim.h"
+
+void read_arg(FILE *stream, t_arg *dest) {
+ if (fscanf(stream, "$%Ld ", &(dest->val)) > 0) {
+ dest->source_var = -1;
+ } else {
+ fscanf(stream, "%d ", &(dest->source_var));
+ }
+}
+
+t_program *load_dumb_netlist (FILE *stream) {
+ int i;
+
+ // let us suppose that the input to be read is well-formed.
+ t_program *p = malloc(sizeof(t_program));
+
+ // Read variable list, with sizes and identifiers
+ fscanf(stream, "%d ", &(p->n_vars));
+ p->vars = malloc(p->n_vars * sizeof(t_variable));
+
+ for (i = 0; i < p->n_vars; i++) {
+ fscanf(stream, "%d ", &(p->vars[i].size));
+ p->vars[i].mask = (0xFFFFFFFFFFFFFFFF >> (64 - p->vars[i].size));
+
+ p->vars[i].name = malloc(42); // let's bet that the name of a variable will never be longer than 42 chars
+ fscanf(stream, "%s\n", p->vars[i].name);
+ }
+
+ // read input list
+ fscanf(stream, "%d ", &(p->n_inputs));
+ p->inputs = malloc(p->n_inputs * sizeof(t_id));
+ for (i = 0; i < p->n_inputs; i++) {
+ fscanf(stream, "%d ", &(p->inputs[i]));
+ }
+ // read output list
+ fscanf(stream, "%d ", &(p->n_outputs));
+ p->outputs = malloc(p->n_outputs * sizeof(t_id));
+ for (i = 0; i < p->n_outputs; i++) {
+ fscanf(stream, "%d ", &(p->outputs[i]));
+ }
+
+ // read equation list
+ fscanf(stream, "%d ", &(p->n_eqs));
+ p->eqs = malloc(p->n_eqs * sizeof(t_equation));
+ for (i = 0; i < p->n_eqs; i++) {
+ fscanf(stream, "%d ", &(p->eqs[i].dest_var));
+ fscanf(stream, "%d ", &(p->eqs[i].type));
+ switch (p->eqs[i].type) {
+ case C_ARG:
+ read_arg(stream, &(p->eqs[i].Arg.a));
+ break;
+ case C_REG:
+ fscanf(stream, "%d ", &(p->eqs[i].Reg.var));
+ break;
+ case C_NOT:
+ read_arg(stream, &(p->eqs[i].Not.a));
+ break;
+ case C_BINOP:
+ fscanf(stream, "%d ", &(p->eqs[i].Binop.op));
+ read_arg(stream, &(p->eqs[i].Binop.a));
+ read_arg(stream, &(p->eqs[i].Binop.b));
+ break;
+ case C_MUX:
+ read_arg(stream, &(p->eqs[i].Mux.a));
+ read_arg(stream, &(p->eqs[i].Mux.b));
+ read_arg(stream, &(p->eqs[i].Mux.c));
+ break;
+ case C_ROM:
+ fscanf(stream, "%d %d ", &(p->eqs[i].Rom.addr_size), &(p->eqs[i].Rom.word_size));
+ read_arg(stream, &(p->eqs[i].Rom.read_addr));
+ break;
+ case C_RAM:
+ fscanf(stream, "%d %d ", &(p->eqs[i].Ram.addr_size), &(p->eqs[i].Ram.word_size));
+ read_arg(stream, &(p->eqs[i].Ram.read_addr));
+ read_arg(stream, &(p->eqs[i].Ram.write_enable));
+ read_arg(stream, &(p->eqs[i].Ram.write_enable));
+ read_arg(stream, &(p->eqs[i].Ram.data));
+ break;
+ case C_CONCAT:
+ read_arg(stream, &(p->eqs[i].Mux.a));
+ read_arg(stream, &(p->eqs[i].Mux.b));
+ break;
+ case C_SLICE:
+ fscanf(stream, "%d %d ", &(p->eqs[i].Slice.begin), &(p->eqs[i].Slice.end));
+ read_arg(stream, &(p->eqs[i].Slice.source));
+ break;
+ case C_SELECT:
+ fscanf(stream, "%d ", &(p->eqs[i].Select.i));
+ read_arg(stream, &(p->eqs[i].Select.source));
+ break;
+ }
+ }
+}
diff --git a/csim/main.c b/csim/main.c
new file mode 100644
index 0000000..ce3f5b6
--- /dev/null
+++ b/csim/main.c
@@ -0,0 +1,97 @@
+/*
+ Système Digital
+ 2013-2014
+ Alex AUVOLAT
+
+ main.c Main file for the C simulator
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "sim.h"
+
+void usage() {
+ printf ("\nUsage:\n\tcsim [options] <netlist_file>\n\n");
+ printf("Available options:\n");
+ printf("\n -rom <file>\n\tLoad a filename as a ROM file for the machine\n");
+ printf("\n -n <steps>\n\tOnly run #steps steps of simulation (-1 = 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");
+ exit(1);
+}
+
+// Arguments to be parsed
+int steps = 42;
+char *romfile = NULL;
+char *filename = NULL;
+char *infile = NULL;
+char *outfile = NULL;
+
+int main(int argc, char **argv) {
+ int i;
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-rom")) {
+ if (++i == argc) usage();
+ romfile = argv[i];
+ } else if (!strcmp(argv[i], "-n")) {
+ if (++i == argc) usage();
+ steps = atoi(argv[i]);
+ } else if (!strcmp(argv[i], "-in")) {
+ if (++i == argc) usage();
+ infile = argv[i];
+ } else if (!strcmp(argv[i], "-out")) {
+ if (++i == argc) usage();
+ outfile = argv[i];
+ } else {
+ filename = argv[i];
+ }
+ }
+
+ if (filename == NULL) usage();
+
+ // Load program
+ FILE *p_in;
+ p_in = fopen(filename, "r");
+ if (!p_in) {
+ fprintf(stderr, "Error: could not open file %s for input.\n", filename);
+ return 1;
+ }
+ t_program* program = load_dumb_netlist(p_in);
+ fclose(p_in);
+
+ // Setup input and outputs
+ FILE *input = stdin, *output = stdout;
+ if (infile != NULL) {
+ input = fopen(infile, "r");
+ if (!infile) {
+ fprintf(stderr, "Error: could not open file %s for input.\n", infile);
+ return 1;
+ }
+ }
+ if (outfile != NULL) {
+ output = fopen(outfile, "w");
+ if (!output) {
+ fprintf(stderr, "Error: could not open file %s for output.\n", outfile);
+ return 1;
+ }
+ }
+
+ // Run
+ t_machine *machine = init_machine(program);
+ while (i < steps || steps == -1) {
+ read_inputs(machine, input);
+ machine_step(machine);
+ write_outputs(machine, output);
+ }
+
+ // Cleanup
+ if (input != stdin) fclose(input);
+ if (output != stdout) fclose(output);
+
+ // No need to free memory, the OS deletes everything anyways when the process ends.
+
+ return 0;
+}
+
diff --git a/csim/sim.c b/csim/sim.c
new file mode 100644
index 0000000..27827d5
--- /dev/null
+++ b/csim/sim.c
@@ -0,0 +1,23 @@
+/*
+ Système Digital
+ 2013-2014
+ Alex AUVOLAT
+
+ sim.c The code that actually runs the machine
+*/
+
+#include "sim.h"
+
+t_machine *init_machine (t_program *p) {
+}
+
+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/csim/sim.h b/csim/sim.h
new file mode 100644
index 0000000..75f3502
--- /dev/null
+++ b/csim/sim.h
@@ -0,0 +1,116 @@
+#ifndef DEF_SIM_H
+#define DEF_SIM_H
+
+// TODO implement ROM
+
+#include <stdio.h>
+
+// Gate types
+#define C_ARG 0
+#define C_REG 1
+#define C_NOT 2
+#define C_BINOP 3
+#define C_MUX 4
+#define C_ROM 5
+#define C_RAM 6
+#define C_CONCAT 7
+#define C_SLICE 8
+#define C_SELECT 9
+
+// Binary operators
+#define OP_OR 0
+#define OP_XOR 1
+#define OP_AND 2
+#define OP_NAND 3
+
+// Data structures
+typedef unsigned long long int t_value;
+typedef int t_id;
+
+typedef struct { // a variable in the simulator
+ t_value mask;
+ int size;
+ char *name;
+} t_variable;
+
+typedef struct {
+ t_value val;
+ t_id source_var; // if source_var == -1 then it's a direct value, else it's that variable
+} t_arg;
+
+typedef struct {
+ int type;
+ t_id dest_var;
+ union {
+ struct {
+ t_arg a;
+ } Arg;
+ struct {
+ t_id var;
+ } Reg;
+ struct {
+ t_arg a;
+ } Not;
+ struct {
+ int op;
+ t_arg a, b;
+ } Binop;
+ struct {
+ t_arg a, b, c;
+ } Mux;
+ struct {
+ int addr_size, word_size;
+ t_arg read_addr;
+ } Rom;
+ struct {
+ int addr_size, word_size;
+ t_arg read_addr, write_enable, write_addr, data;
+ } Ram;
+ struct {
+ t_arg a, b;
+ } Concat;
+ struct {
+ int begin, end;
+ t_arg source;
+ } Slice;
+ struct {
+ int i;
+ t_arg source;
+ } Select;
+ };
+} t_equation;
+
+
+typedef struct {
+ int n_vars, n_inputs, n_outputs;
+ t_variable *vars;
+ t_id *inputs, *outputs;
+
+ int n_eqs;
+ t_equation *eqs;
+} t_program;
+
+// machine = execution instance
+
+typedef union {
+ t_value r_val;
+ t_value *mem_val;
+} t_mem_reg_data;
+
+typedef struct {
+ t_program *prog;
+ t_value *var_values;
+ t_mem_reg_data *mem_data;
+} t_machine;
+
+
+// The functions for doing stuff with these data structures
+
+t_program *load_dumb_netlist(FILE *stream);
+t_machine *init_machine(t_program *p);
+void read_inputs(t_machine *m, FILE *stream);
+void machine_step(t_machine *m);
+void write_outputs(t_machine *m, FILE *stream);
+
+
+#endif
diff --git a/tp1/_tags b/sched/_tags
index 503ce62..503ce62 100644
--- a/tp1/_tags
+++ b/sched/_tags
diff --git a/tp1/graph.ml b/sched/graph.ml
index 54128ff..54128ff 100644
--- a/tp1/graph.ml
+++ b/sched/graph.ml
diff --git a/sched/graph_test.byte b/sched/graph_test.byte
new file mode 120000
index 0000000..1ec2e64
--- /dev/null
+++ b/sched/graph_test.byte
@@ -0,0 +1 @@
+/home/katchup/Core/ENS/Info/SystDigit-Projet/tp1/_build/graph_test.byte \ No newline at end of file
diff --git a/tp1/graph_test.ml b/sched/graph_test.ml
index ac31677..ac31677 100644
--- a/tp1/graph_test.ml
+++ b/sched/graph_test.ml
diff --git a/sched/main.byte b/sched/main.byte
new file mode 120000
index 0000000..0571503
--- /dev/null
+++ b/sched/main.byte
@@ -0,0 +1 @@
+/home/katchup/Core/ENS/Info/SystDigit-Projet/sched/_build/main.byte \ No newline at end of file
diff --git a/sched/main.ml b/sched/main.ml
new file mode 100644
index 0000000..988d1ec
--- /dev/null
+++ b/sched/main.ml
@@ -0,0 +1,50 @@
+let simulate = ref false
+let number_steps = ref (-1)
+let sim_path = ref "./netlist_simulator.byte"
+let dumb_down = ref false
+
+let compile filename =
+ try
+ let p = Netlist.read_file filename in
+ let out_name = (Filename.chop_suffix filename ".net") ^ "_sch.net" in
+ let dumb_out_name = (Filename.chop_suffix filename ".net") ^ ".dumb" in
+ let q = ref p in
+
+ begin try
+ q := Scheduler.schedule p
+ with
+ | Scheduler.Combinational_cycle ->
+ Format.eprintf "The netlist has a combinatory cycle.@.";
+ exit 2;
+ end;
+
+ let out = open_out out_name in
+ Netlist_printer.print_program out !q;
+ close_out out;
+ let dumb_out = open_out dumb_out_name in
+ Netlist_printer.print_dumb_program dumb_out !q;
+ close_out dumb_out;
+
+ if !simulate then (
+ let simulator =
+ if !number_steps = -1 then
+ !sim_path
+ else
+ !sim_path ^ " -n " ^ (string_of_int !number_steps)
+ in
+ ignore (Unix.system (simulator^" "^(if !dumb_down then dumb_out_name else out_name)))
+ )
+ with
+ | Netlist.Parse_error s -> Format.eprintf "An error accurred: %s@." s; exit 2
+
+let main () =
+ Arg.parse
+ ["-s", Arg.Set simulate, "Launch the simulator";
+ "-sim", Arg.Set_string sim_path, "Path to the circuit simulator";
+ "-d", Arg.Set dumb_down, "Pass the dumbed-down netlist to the simulator (for the C simulator)";
+ "-n", Arg.Set_int number_steps, "Number of steps to simulate"]
+ compile
+ ""
+;;
+
+main ()
diff --git a/tp1/netlist.ml b/sched/netlist.ml
index b1d7932..b1d7932 100644
--- a/tp1/netlist.ml
+++ b/sched/netlist.ml
diff --git a/tp1/netlist_ast.ml b/sched/netlist_ast.ml
index ae16888..ae16888 100644
--- a/tp1/netlist_ast.ml
+++ b/sched/netlist_ast.ml
diff --git a/tp1/netlist_lexer.mll b/sched/netlist_lexer.mll
index 78b0410..78b0410 100644
--- a/tp1/netlist_lexer.mll
+++ b/sched/netlist_lexer.mll
diff --git a/tp1/netlist_parser.mly b/sched/netlist_parser.mly
index 0908703..0908703 100644
--- a/tp1/netlist_parser.mly
+++ b/sched/netlist_parser.mly
diff --git a/sched/netlist_printer.ml b/sched/netlist_printer.ml
new file mode 100644
index 0000000..fbd432a
--- /dev/null
+++ b/sched/netlist_printer.ml
@@ -0,0 +1,180 @@
+open Netlist_ast
+open Format
+
+(* GENERAL PRINTER *)
+
+let rec print_env print lp sep rp ff env =
+ let first = ref true in
+ fprintf ff "%s" lp;
+ Env.iter
+ (fun x ty ->
+ if !first then
+ (first := false; fprintf ff "%a" print (x, ty))
+ else
+ fprintf ff "%s%a" sep print (x, ty)) env;
+ fprintf ff "%s" rp
+
+let rec print_list print lp sep rp ff = function
+ | [] -> ()
+ | x :: l ->
+ fprintf ff "%s%a" lp print x;
+ List.iter (fprintf ff "%s %a" sep print) l;
+ fprintf ff "%s" rp
+
+let print_ty ff ty = match ty with
+ | TBit -> ()
+ | TBitArray n -> fprintf ff " : %d" n
+
+let print_bool ff b =
+ if b then
+ fprintf ff "1"
+ else
+ fprintf ff "0"
+
+let print_value ff v = match v with
+ | VBit b -> print_bool ff b
+ | VBitArray a -> Array.iter (print_bool ff) a
+
+let print_arg ff arg = match arg with
+ | Aconst v -> print_value ff v
+ | Avar id -> fprintf ff "%s" id
+
+let print_op ff op = match op with
+ | And -> fprintf ff "AND"
+ | Nand -> fprintf ff "NAND"
+ | Or -> fprintf ff "OR"
+ | Xor -> fprintf ff "XOR"
+
+let print_exp ff e = match e with
+ | Earg a -> print_arg ff a
+ | Ereg x -> fprintf ff "REG %s" x
+ | Enot x -> fprintf ff "NOT %a" print_arg x
+ | Ebinop(op, x, y) -> fprintf ff "%a %a %a" print_op op print_arg x print_arg y
+ | Emux (c, x, y) -> fprintf ff "MUX %a %a %a " print_arg c print_arg x print_arg y
+ | Erom (addr, word, ra) -> fprintf ff "ROM %d %d %a" addr word print_arg ra
+ | Eram (addr, word, ra, we, wa, data) ->
+ fprintf ff "RAM %d %d %a %a %a %a" addr word
+ print_arg ra print_arg we
+ print_arg wa print_arg data
+ | Eselect (idx, x) -> fprintf ff "SELECT %d %a" idx print_arg x
+ | Econcat (x, y) -> fprintf ff "CONCAT %a %a" print_arg x print_arg y
+ | Eslice (min, max, x) -> fprintf ff "SLICE %d %d %a" min max print_arg x
+
+let print_eq ff (x, e) =
+ fprintf ff "%s = %a@." x print_exp e
+
+let print_var ff (x, ty) =
+ fprintf ff "@[%s%a@]" x print_ty ty
+
+let print_vars ff env =
+ fprintf ff "@[<v 2>VAR@,%a@]@.IN@,"
+ (print_env print_var "" ", " "") env
+
+let print_idents ff ids =
+ let print_ident ff s = fprintf ff "%s" s in
+ print_list print_ident """,""" ff ids
+
+let print_program oc p =
+ let ff = formatter_of_out_channel oc in
+ fprintf ff "INPUT %a@." print_idents p.p_inputs;
+ fprintf ff "OUTPUT %a@." print_idents p.p_outputs;
+ print_vars ff p.p_vars;
+ List.iter (print_eq ff) p.p_eqs;
+ (* flush *)
+ fprintf ff "@."
+
+
+(* PRINTER FOR DUMBED-DOWN NETLIST (variables are identified by numbers) *)
+
+(* constants *)
+let c_arg = 0
+let c_reg = 1
+let c_not = 2
+let c_binop = 3
+let c_mux = 4
+let c_rom = 5
+let c_ram = 6
+let c_concat = 7
+let c_slice = 8
+let c_select = 9
+
+let binop_i = function
+ | Or -> 0
+ | Xor -> 1
+ | And -> 2
+ | Nand -> 3
+
+let print_dumb_program oc p =
+ let ff = formatter_of_out_channel oc in
+ (* associate numbers to variables *)
+ let n_vars = Env.fold (fun _ _ n -> n+1) p.p_vars 0 in
+ let n = ref 0 in
+ let var_id = Hashtbl.create n_vars in
+ fprintf ff "%d\n" n_vars;
+ Env.iter
+ (fun k v ->
+ Hashtbl.add var_id k !n;
+ fprintf ff "%d %s\n"
+ (match v with
+ | TBit -> 1
+ | TBitArray(n) -> n)
+ k;
+ n := !n + 1)
+ p.p_vars;
+ (* write input vars *)
+ fprintf ff "%d" (List.length p.p_inputs);
+ List.iter (fun k -> fprintf ff " %d" (Hashtbl.find var_id k)) p.p_inputs;
+ fprintf ff "\n";
+ (* write output vars *)
+ fprintf ff "%d" (List.length p.p_outputs);
+ List.iter (fun k -> fprintf ff " %d" (Hashtbl.find var_id k)) p.p_outputs;
+ fprintf ff "\n";
+ (* write equations *)
+ fprintf ff "%d\n" (List.length p.p_eqs);
+ (* write equations *)
+ let print_arg = function
+ | Avar(k) -> fprintf ff " %d" (Hashtbl.find var_id k)
+ | Aconst(n) -> fprintf ff " $";
+ begin match n with
+ | VBit(x) -> fprintf ff "%d" (if x then 1 else 0)
+ | VBitArray(a) ->
+ let k = ref 0 in
+ for i = 0 to Array.length a - 1 do
+ k := 2 * !k + (if a.(i) then 1 else 0)
+ done;
+ fprintf ff "%d" !k
+ end
+ in
+ List.iter
+ (fun (k, eqn) ->
+ fprintf ff "%d " (Hashtbl.find var_id k);
+ begin match eqn with
+ | Earg(a) -> fprintf ff "%d" c_arg;
+ print_arg a
+ | Ereg(i) -> fprintf ff "%d %d" c_reg (Hashtbl.find var_id i)
+ | Enot(a) -> fprintf ff "%d" c_not;
+ print_arg a
+ | Ebinop(o, a, b) -> fprintf ff "%d %d" c_binop (binop_i o);
+ print_arg a;
+ print_arg b
+ | Emux(a, b, c) -> fprintf ff "%d" c_mux;
+ print_arg a; print_arg b; print_arg c
+ | Erom(u, v, a) -> fprintf ff "%d %d %d" c_rom u v;
+ print_arg a
+ | Eram (u, v, a, b, c, d) -> fprintf ff "%d %d %d" c_ram u v;
+ print_arg a; print_arg b; print_arg c; print_arg d
+ | Econcat(a, b) -> fprintf ff "%d" c_concat;
+ print_arg a; print_arg b
+ | Eslice(u, v, a) -> fprintf ff "%d %d %d" c_slice u v;
+ print_arg a
+ | Eselect(i, a) -> fprintf ff "%d %d" c_select i;
+ print_arg a
+ end;
+ fprintf ff "\n")
+ p.p_eqs;
+ (* flush *)
+ fprintf ff "@."
+
+
+
+
diff --git a/tp1/netlist_simulator.byte b/sched/netlist_simulator.byte
index 155d39a..155d39a 100755
--- a/tp1/netlist_simulator.byte
+++ b/sched/netlist_simulator.byte
Binary files differ
diff --git a/tp1/scheduler.ml b/sched/scheduler.ml
index 130164b..130164b 100644
--- a/tp1/scheduler.ml
+++ b/sched/scheduler.ml
diff --git a/sched/test/clock_div.dumb b/sched/test/clock_div.dumb
new file mode 100644
index 0000000..bcb07d0
--- /dev/null
+++ b/sched/test/clock_div.dumb
@@ -0,0 +1,11 @@
+3
+1 _l_2
+1 c
+1 o
+0
+1 2
+3
+0 1 2
+2 1 1
+1 2 0
+
diff --git a/tp1/test/clock_div.mj b/sched/test/clock_div.mj
index ad1e919..ad1e919 100644
--- a/tp1/test/clock_div.mj
+++ b/sched/test/clock_div.mj
diff --git a/tp1/test/clock_div.net b/sched/test/clock_div.net
index 9a17fc7..9a17fc7 100644
--- a/tp1/test/clock_div.net
+++ b/sched/test/clock_div.net
diff --git a/sched/test/clock_div_sch.net b/sched/test/clock_div_sch.net
new file mode 100644
index 0000000..0ae5cd9
--- /dev/null
+++ b/sched/test/clock_div_sch.net
@@ -0,0 +1,9 @@
+INPUT
+OUTPUT o
+VAR
+ _l_2, c, o
+IN
+_l_2 = REG o
+o = REG c
+c = NOT _l_2
+
diff --git a/sched/test/cm2.dumb b/sched/test/cm2.dumb
new file mode 100644
index 0000000..632c6ea
--- /dev/null
+++ b/sched/test/cm2.dumb
@@ -0,0 +1,9 @@
+4
+1 _l_1
+1 r
+1 s
+1 x
+1 3
+2 2 1
+3
+
diff --git a/tp1/test/cm2.mj b/sched/test/cm2.mj
index 8863bf1..8863bf1 100644
--- a/tp1/test/cm2.mj
+++ b/sched/test/cm2.mj
diff --git a/tp1/test/cm2.net b/sched/test/cm2.net
index e296b96..e296b96 100644
--- a/tp1/test/cm2.net
+++ b/sched/test/cm2.net
diff --git a/sched/test/cm2_sch.net b/sched/test/cm2_sch.net
new file mode 100644
index 0000000..e9900d5
--- /dev/null
+++ b/sched/test/cm2_sch.net
@@ -0,0 +1,9 @@
+INPUT x
+OUTPUT s, r
+VAR
+ _l_1, r, s, x
+IN
+s = REG _l_1
+_l_1 = XOR x s
+r = AND x s
+
diff --git a/sched/test/fulladder.dumb b/sched/test/fulladder.dumb
new file mode 100644
index 0000000..480d04d
--- /dev/null
+++ b/sched/test/fulladder.dumb
@@ -0,0 +1,20 @@
+9
+1 _l_1
+1 _l_3
+1 _l_4
+1 _l_5
+1 a
+1 b
+1 c
+1 r
+1 s
+3 4 5 6
+2 8 7
+6
+2 3 1 4 5
+3 3 2 2 6
+1 3 2 4 5
+0 3 1 4 5
+8 3 1 0 6
+7 3 0 1 3
+
diff --git a/tp1/test/fulladder.mj b/sched/test/fulladder.mj
index c4b6b0e..c4b6b0e 100644
--- a/tp1/test/fulladder.mj
+++ b/sched/test/fulladder.mj
diff --git a/tp1/test/fulladder.net b/sched/test/fulladder.net
index b2271c2..b2271c2 100644
--- a/tp1/test/fulladder.net
+++ b/sched/test/fulladder.net
diff --git a/sched/test/fulladder_sch.net b/sched/test/fulladder_sch.net
new file mode 100644
index 0000000..96fc154
--- /dev/null
+++ b/sched/test/fulladder_sch.net
@@ -0,0 +1,12 @@
+INPUT a, b, c
+OUTPUT s, r
+VAR
+ _l_1, _l_3, _l_4, _l_5, a, b, c, r, s
+IN
+_l_4 = XOR a b
+_l_5 = AND _l_4 c
+_l_3 = AND a b
+_l_1 = XOR a b
+s = XOR _l_1 c
+r = OR _l_3 _l_5
+
diff --git a/sched/test/nadder.dumb b/sched/test/nadder.dumb
new file mode 100644
index 0000000..469984d
--- /dev/null
+++ b/sched/test/nadder.dumb
@@ -0,0 +1,27 @@
+12
+1 _l_10_50
+1 _l_11_49
+1 _l_16_22
+1 _l_17_21
+1 _l_7_52
+1 _l_9_51
+1 a
+1 b
+1 c
+1 c_n1_27
+1 o
+1 s_n_26
+2 6 7
+2 10 8
+10
+3 9 0 7
+2 9 0 6
+9 0 $0
+0 3 1 2 3
+1 3 2 0 9
+5 3 2 2 3
+4 3 1 2 3
+11 3 1 4 9
+8 3 0 5 1
+10 0 11
+
diff --git a/tp1/test/nadder.mj b/sched/test/nadder.mj
index 0c95386..0c95386 100644
--- a/tp1/test/nadder.mj
+++ b/sched/test/nadder.mj
diff --git a/tp1/test/nadder.net b/sched/test/nadder.net
index bf87051..bf87051 100644
--- a/tp1/test/nadder.net
+++ b/sched/test/nadder.net
diff --git a/sched/test/nadder_sch.net b/sched/test/nadder_sch.net
new file mode 100644
index 0000000..5602eb4
--- /dev/null
+++ b/sched/test/nadder_sch.net
@@ -0,0 +1,17 @@
+INPUT a, b
+OUTPUT o, c
+VAR
+ _l_10_50, _l_11_49, _l_16_22, _l_17_21, _l_7_52, _l_9_51, a, b, c,
+ c_n1_27, o, s_n_26
+IN
+_l_17_21 = SELECT 0 b
+_l_16_22 = SELECT 0 a
+c_n1_27 = 0
+_l_10_50 = XOR _l_16_22 _l_17_21
+_l_11_49 = AND _l_10_50 c_n1_27
+_l_9_51 = AND _l_16_22 _l_17_21
+_l_7_52 = XOR _l_16_22 _l_17_21
+s_n_26 = XOR _l_7_52 c_n1_27
+c = OR _l_9_51 _l_11_49
+o = s_n_26
+
diff --git a/sched/test/ram.dumb b/sched/test/ram.dumb
new file mode 100644
index 0000000..74cf168
--- /dev/null
+++ b/sched/test/ram.dumb
@@ -0,0 +1,55 @@
+27
+1 _l_10_22
+1 _l_10_35
+1 _l_10_48
+1 _l_10_61
+1 _l_11_21
+1 _l_11_34
+1 _l_11_47
+1 _l_11_60
+3 _l_12_20
+2 _l_12_33
+1 _l_12_46
+3 _l_13_19
+2 _l_13_32
+1 _l_13_45
+3 _l_14_18
+2 _l_14_31
+1 _l_14_44
+4 _l_16
+1 _l_9_23
+1 _l_9_36
+1 _l_9_49
+1 _l_9_62
+4 c
+4 o
+2 ra
+2 wa
+1 we
+4 24 26 25 22
+1 23
+23
+11 8 1 3 22
+12 8 1 2 11
+13 8 1 1 12
+3 9 0 13
+23 6 2 4 24 26 25 17
+8 8 1 3 23
+9 8 1 2 8
+10 8 1 1 9
+21 9 0 10
+7 3 2 21 3
+16 0 7
+2 9 0 12
+20 9 0 9
+6 3 2 20 2
+15 7 6 16
+1 9 0 11
+19 9 0 8
+5 3 2 19 1
+14 7 5 15
+0 9 0 22
+18 9 0 23
+4 3 2 18 0
+17 7 4 14
+
diff --git a/tp1/test/ram.mj b/sched/test/ram.mj
index 7c4d1ed..7c4d1ed 100644
--- a/tp1/test/ram.mj
+++ b/sched/test/ram.mj
diff --git a/tp1/test/ram.net b/sched/test/ram.net
index ee4570a..ee4570a 100644
--- a/tp1/test/ram.net
+++ b/sched/test/ram.net
diff --git a/sched/test/ram_sch.net b/sched/test/ram_sch.net
new file mode 100644
index 0000000..56dda0e
--- /dev/null
+++ b/sched/test/ram_sch.net
@@ -0,0 +1,32 @@
+INPUT ra, we, wa, c
+OUTPUT o
+VAR
+ _l_10_22, _l_10_35, _l_10_48, _l_10_61, _l_11_21, _l_11_34, _l_11_47,
+ _l_11_60, _l_12_20 : 3, _l_12_33 : 2, _l_12_46 : 1, _l_13_19 : 3, _l_13_32 : 2,
+ _l_13_45 : 1, _l_14_18 : 3, _l_14_31 : 2, _l_14_44 : 1, _l_16 : 4,
+ _l_9_23, _l_9_36, _l_9_49, _l_9_62, c : 4, o : 4, ra : 2, wa : 2, we
+IN
+_l_13_19 = SLICE 1 3 c
+_l_13_32 = SLICE 1 2 _l_13_19
+_l_13_45 = SLICE 1 1 _l_13_32
+_l_10_61 = SELECT 0 _l_13_45
+o = RAM 2 4 ra we wa _l_16
+_l_12_20 = SLICE 1 3 o
+_l_12_33 = SLICE 1 2 _l_12_20
+_l_12_46 = SLICE 1 1 _l_12_33
+_l_9_62 = SELECT 0 _l_12_46
+_l_11_60 = AND _l_9_62 _l_10_61
+_l_14_44 = _l_11_60
+_l_10_48 = SELECT 0 _l_13_32
+_l_9_49 = SELECT 0 _l_12_33
+_l_11_47 = AND _l_9_49 _l_10_48
+_l_14_31 = CONCAT _l_11_47 _l_14_44
+_l_10_35 = SELECT 0 _l_13_19
+_l_9_36 = SELECT 0 _l_12_20
+_l_11_34 = AND _l_9_36 _l_10_35
+_l_14_18 = CONCAT _l_11_34 _l_14_31
+_l_10_22 = SELECT 0 c
+_l_9_23 = SELECT 0 o
+_l_11_21 = AND _l_9_23 _l_10_22
+_l_16 = CONCAT _l_11_21 _l_14_18
+
diff --git a/tp1/netlist_printer.ml b/tp1/netlist_printer.ml
deleted file mode 100644
index d513137..0000000
--- a/tp1/netlist_printer.ml
+++ /dev/null
@@ -1,82 +0,0 @@
-open Netlist_ast
-open Format
-
-let rec print_env print lp sep rp ff env =
- let first = ref true in
- fprintf ff "%s" lp;
- Env.iter
- (fun x ty ->
- if !first then
- (first := false; fprintf ff "%a" print (x, ty))
- else
- fprintf ff "%s%a" sep print (x, ty)) env;
- fprintf ff "%s" rp
-
-let rec print_list print lp sep rp ff = function
- | [] -> ()
- | x :: l ->
- fprintf ff "%s%a" lp print x;
- List.iter (fprintf ff "%s %a" sep print) l;
- fprintf ff "%s" rp
-
-let print_ty ff ty = match ty with
- | TBit -> ()
- | TBitArray n -> fprintf ff " : %d" n
-
-let print_bool ff b =
- if b then
- fprintf ff "1"
- else
- fprintf ff "0"
-
-let print_value ff v = match v with
- | VBit b -> print_bool ff b
- | VBitArray a -> Array.iter (print_bool ff) a
-
-let print_arg ff arg = match arg with
- | Aconst v -> print_value ff v
- | Avar id -> fprintf ff "%s" id
-
-let print_op ff op = match op with
- | And -> fprintf ff "AND"
- | Nand -> fprintf ff "NAND"
- | Or -> fprintf ff "OR"
- | Xor -> fprintf ff "XOR"
-
-let print_exp ff e = match e with
- | Earg a -> print_arg ff a
- | Ereg x -> fprintf ff "REG %s" x
- | Enot x -> fprintf ff "NOT %a" print_arg x
- | Ebinop(op, x, y) -> fprintf ff "%a %a %a" print_op op print_arg x print_arg y
- | Emux (c, x, y) -> fprintf ff "MUX %a %a %a " print_arg c print_arg x print_arg y
- | Erom (addr, word, ra) -> fprintf ff "ROM %d %d %a" addr word print_arg ra
- | Eram (addr, word, ra, we, wa, data) ->
- fprintf ff "RAM %d %d %a %a %a %a" addr word
- print_arg ra print_arg we
- print_arg wa print_arg data
- | Eselect (idx, x) -> fprintf ff "SELECT %d %a" idx print_arg x
- | Econcat (x, y) -> fprintf ff "CONCAT %a %a" print_arg x print_arg y
- | Eslice (min, max, x) -> fprintf ff "SLICE %d %d %a" min max print_arg x
-
-let print_eq ff (x, e) =
- fprintf ff "%s = %a@." x print_exp e
-
-let print_var ff (x, ty) =
- fprintf ff "@[%s%a@]" x print_ty ty
-
-let print_vars ff env =
- fprintf ff "@[<v 2>VAR@,%a@]@.IN@,"
- (print_env print_var "" ", " "") env
-
-let print_idents ff ids =
- let print_ident ff s = fprintf ff "%s" s in
- print_list print_ident """,""" ff ids
-
-let print_program oc p =
- let ff = formatter_of_out_channel oc in
- fprintf ff "INPUT %a@." print_idents p.p_inputs;
- fprintf ff "OUTPUT %a@." print_idents p.p_outputs;
- print_vars ff p.p_vars;
- List.iter (print_eq ff) p.p_eqs;
- (* flush *)
- fprintf ff "@."
diff --git a/tp1/scheduler_test.ml b/tp1/scheduler_test.ml
deleted file mode 100644
index 20c20f5..0000000
--- a/tp1/scheduler_test.ml
+++ /dev/null
@@ -1,41 +0,0 @@
-let print_only = ref false
-let number_steps = ref (-1)
-
-let compile filename =
- try
- let p = Netlist.read_file filename in
- let out_name = (Filename.chop_suffix filename ".net") ^ "_sch.net" in
- let out = open_out out_name in
- let close_all () =
- close_out out
- in
- begin try
- let p = Scheduler.schedule p in
- Netlist_printer.print_program out p;
- with
- | Scheduler.Combinational_cycle ->
- Format.eprintf "The netlist has a combinatory cycle.@.";
- close_all (); exit 2
- end;
- close_all ();
- if not !print_only then (
- let simulator =
- if !number_steps = -1 then
- "./netlist_simulator.byte"
- else
- "./netlist_simulator.byte -n "^(string_of_int !number_steps)
- in
- ignore (Unix.system (simulator^" "^out_name))
- )
- with
- | Netlist.Parse_error s -> Format.eprintf "An error accurred: %s@." s; exit 2
-
-let main () =
- Arg.parse
- ["-print", Arg.Set print_only, "Only print the result of scheduling";
- "-n", Arg.Set_int number_steps, "Number of steps to simulate"]
- compile
- ""
-;;
-
-main ()