diff options
author | Alex AUVOLAT <alex.auvolat@ens.fr> | 2013-11-04 22:05:57 +0100 |
---|---|---|
committer | Alex AUVOLAT <alex.auvolat@ens.fr> | 2013-11-04 22:05:57 +0100 |
commit | cebd07b64f1f537c5ecf00ec21ff4b7c4032f0a3 (patch) | |
tree | 9d2048313fe3ad4c92865c8f0236bed24e64449b | |
parent | f253f98136def21b5e50c5922246e2ddfe315442 (diff) | |
download | SystDigit-Projet-cebd07b64f1f537c5ecf00ec21ff4b7c4032f0a3.tar.gz SystDigit-Projet-cebd07b64f1f537c5ecf00ec21ff4b7c4032f0a3.zip |
Added stub C simulator (defined dumb-down syntax for netlists).
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | csim/Makefile | 5 | ||||
-rw-r--r-- | csim/load.c | 104 | ||||
-rw-r--r-- | csim/main.c | 97 | ||||
-rw-r--r-- | csim/sim.c | 23 | ||||
-rw-r--r-- | csim/sim.h | 116 | ||||
-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.byte | 1 | ||||
-rw-r--r-- | sched/graph_test.ml (renamed from tp1/graph_test.ml) | 0 | ||||
l--------- | sched/main.byte | 1 | ||||
-rw-r--r-- | sched/main.ml | 50 | ||||
-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.ml | 180 | ||||
-rwxr-xr-x | sched/netlist_simulator.byte (renamed from tp1/netlist_simulator.byte) | bin | 190274 -> 190274 bytes | |||
-rw-r--r-- | sched/scheduler.ml (renamed from tp1/scheduler.ml) | 0 | ||||
-rw-r--r-- | sched/test/clock_div.dumb | 11 | ||||
-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.net | 9 | ||||
-rw-r--r-- | sched/test/cm2.dumb | 9 | ||||
-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.net | 9 | ||||
-rw-r--r-- | sched/test/fulladder.dumb | 20 | ||||
-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.net | 12 | ||||
-rw-r--r-- | sched/test/nadder.dumb | 27 | ||||
-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.net | 17 | ||||
-rw-r--r-- | sched/test/ram.dumb | 55 | ||||
-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.net | 32 | ||||
-rw-r--r-- | tp1/netlist_printer.ml | 82 | ||||
-rw-r--r-- | tp1/scheduler_test.ml | 41 |
41 files changed, 780 insertions, 123 deletions
@@ -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/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 Binary files differindex 155d39a..155d39a 100755 --- a/tp1/netlist_simulator.byte +++ b/sched/netlist_simulator.byte 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 () |