summaryrefslogtreecommitdiff
path: root/sched/netlist_dumb.ml
diff options
context:
space:
mode:
Diffstat (limited to 'sched/netlist_dumb.ml')
-rw-r--r--sched/netlist_dumb.ml372
1 files changed, 186 insertions, 186 deletions
diff --git a/sched/netlist_dumb.ml b/sched/netlist_dumb.ml
index 01c187b..646787e 100644
--- a/sched/netlist_dumb.ml
+++ b/sched/netlist_dumb.ml
@@ -1,5 +1,5 @@
(* PRINTER FOR DUMBED-DOWN NETLIST
- (the format used by the C simulator)
+ (the format used by the C simulator)
*)
open Netlist_ast
@@ -8,165 +8,165 @@ open Format
(* Alternative program AST format, better corresponding to the dumb syntax *)
type var_def = {
- name : string;
- size : int }
+ name : string;
+ size : int }
type var_id = int
type const_val = bool array
(* keep type binop from netlist_ast *)
type reg_var = { reg_dest : var_id; source : var_id }
type ram_var = { ram_id : int;
- addr_size : int; word_size : int;
- write_enable : var_id;
- write_addr : var_id; data : var_id }
+ addr_size : int; word_size : int;
+ write_enable : var_id;
+ write_addr : var_id; data : var_id }
type dumb_exp =
- | Dcopy of var_id (* copy a variable - these cannot be eliminated totally *)
- | Dnot of var_id
- | Dbinop of binop * var_id * var_id
- | Dmux of var_id * var_id * var_id
- | Drom of int * int * var_id
- | Dconcat of var_id * var_id
- | Dslice of int * int * var_id
- | Dselect of int * var_id
- | Dreadram of int * var_id
+ | Dcopy of var_id (* copy a variable - these cannot be eliminated totally *)
+ | Dnot of var_id
+ | Dbinop of binop * var_id * var_id
+ | Dmux of var_id * var_id * var_id
+ | Drom of int * int * var_id
+ | Dconcat of var_id * var_id
+ | Dslice of int * int * var_id
+ | Dselect of int * var_id
+ | Dreadram of int * var_id
type dumb_equation = var_id * dumb_exp
type dumb_program = {
- d_vars : var_def list;
- d_inputs : var_id list;
- d_outputs : var_id list;
- d_regs : reg_var list;
- d_rams : ram_var list;
- d_eqs : dumb_equation list }
+ d_vars : var_def list;
+ d_inputs : var_id list;
+ d_outputs : var_id list;
+ d_regs : reg_var list;
+ d_rams : ram_var list;
+ d_eqs : dumb_equation list }
-(* Convert a program to a dumb program *)
+(* Convert a program to a dumb program *)
let mkbinstr a =
- let r = String.make (Array.length a) '0' in
- for i = 0 to Array.length a - 1 do
- if a.(i) then r.[i] <- '1'
- done;
- r
+ let r = String.make (Array.length a) '0' in
+ for i = 0 to Array.length a - 1 do
+ if a.(i) then r.[i] <- '1'
+ done;
+ r
let const_info a =
- "$" ^ (mkbinstr a), Array.length a, a
+ "$" ^ (mkbinstr a), Array.length a, a
let make_program_dumb p =
- (*
- 1. Identify constants and create new variables for them,
- put them on the variable list
- 2. Create map from variable identifier to variable ID,
- add them to variable list
- 3. Extract regs and rams into separate list
- 4. Reformat equation list (replace constants by the
- coresponding constant variables)
- 5. Done.
- *)
- let next_id = ref 0 in
- let vars = ref [] in
- let var_map = Hashtbl.create (Env.cardinal p.p_vars) in
-
- (* Extract constants *)
- List.iter
- (fun (_, eq) ->
- let add = function
- | Aconst(k) ->
- let id, sz, v = const_info k in
- if not (Hashtbl.mem var_map id) then begin
- vars := { name= id; size= sz }::(!vars);
- Hashtbl.add var_map id (!next_id);
- next_id := !next_id + 1
- end
- | _ -> ()
- in match eq with
- | Earg(a) -> add a
- | Enot(a) -> add a
- | Ebinop(_, a, b) -> add a; add b
- | Emux(a, b, c) -> add a; add b; add c
- | Erom(_, _, a) -> add a
- | Eram(_, _, a, b, c, d) -> add a; add b; add c; add d
- | Econcat(a, b) -> add a; add b
- | Eslice(_, _, a) -> add a
- | Eselect(_, a) ->add a
- | _ -> ())
- p.p_eqs;
-
- (* Make ids for variables *)
- let add_var n =
- if not (Hashtbl.mem var_map n) then begin
- vars := { name = n; size = Env.find n p.p_vars }::(!vars);
- Hashtbl.add var_map n (!next_id);
- next_id := !next_id + 1
- end
- in
- List.iter add_var p.p_inputs;
- List.iter (fun (n, _) -> add_var n) p.p_eqs;
- Env.iter (fun n _ -> add_var n) p.p_vars;
-
- let var_id = Hashtbl.find var_map in
- let arg_id = function
- | Avar(x) -> var_id x
- | Aconst(x) ->
- let n, _, _ = const_info x in var_id n
- in
-
- (* Extract registers *)
- let regs, eq2 = List.fold_left
- (fun (regs, eqs) (n, eq) ->
- match eq with
- | Ereg(x) ->
- {
- reg_dest = var_id n;
- source = var_id x;
- }::regs, eqs
- | _ -> regs, (n, eq)::eqs)
- ([],[])
- p.p_eqs in
- (* Extract rams, replace arguments by variable id's *)
- let ram_id = ref 0 in
- let rams, eq3 = List.fold_left
- (fun (rams, eqs) (n, eq) ->
- let ram2 = ref None in
- let eq2 = match eq with
- | Eram(asz, wsz, ra, we, wa, d) ->
- ram_id := !ram_id + 1;
- ram2 := Some({
- ram_id = !ram_id - 1;
- addr_size = asz;
- word_size = wsz;
- write_enable = arg_id we;
- write_addr = arg_id wa;
- data = arg_id d;
- });
- Dreadram(!ram_id - 1, arg_id ra)
- | Earg(a) -> Dcopy(arg_id a)
- | Enot(a) -> Dnot(arg_id a)
- | Ebinop(o, a, b) -> Dbinop(o, arg_id a, arg_id b)
- | Emux(a, b, c) -> Dmux(arg_id a, arg_id b, arg_id c)
- | Erom(u, v, a) -> Drom(u, v, arg_id a)
- | Econcat(a, b) -> Dconcat(arg_id a, arg_id b)
- | Eslice(u, v, a) -> Dslice(u, v, arg_id a)
- | Eselect(i, a) -> Dselect(i, arg_id a)
- | _ -> failwith "This should not happen."
- in
- (match !ram2 with | None -> rams | Some k -> k::rams),
- (var_id n, eq2)::eqs
- )
- ([],[])
- eq2 in
-
- (* Replace arguments by variable id's *)
- {
- d_vars = List.rev (!vars);
- d_inputs = List.map var_id p.p_inputs;
- d_outputs = List.map var_id p.p_outputs;
- d_regs = regs;
- d_rams = List.rev rams;
- d_eqs = eq3;
- }
-
+ (*
+ 1. Identify constants and create new variables for them,
+ put them on the variable list
+ 2. Create map from variable identifier to variable ID,
+ add them to variable list
+ 3. Extract regs and rams into separate list
+ 4. Reformat equation list (replace constants by the
+ coresponding constant variables)
+ 5. Done.
+ *)
+ let next_id = ref 0 in
+ let vars = ref [] in
+ let var_map = Hashtbl.create (Env.cardinal p.p_vars) in
+
+ (* Extract constants *)
+ List.iter
+ (fun (_, eq) ->
+ let add = function
+ | Aconst(k) ->
+ let id, sz, v = const_info k in
+ if not (Hashtbl.mem var_map id) then begin
+ vars := { name= id; size= sz }::(!vars);
+ Hashtbl.add var_map id (!next_id);
+ next_id := !next_id + 1
+ end
+ | _ -> ()
+ in match eq with
+ | Earg(a) -> add a
+ | Enot(a) -> add a
+ | Ebinop(_, a, b) -> add a; add b
+ | Emux(a, b, c) -> add a; add b; add c
+ | Erom(_, _, a) -> add a
+ | Eram(_, _, a, b, c, d) -> add a; add b; add c; add d
+ | Econcat(a, b) -> add a; add b
+ | Eslice(_, _, a) -> add a
+ | Eselect(_, a) ->add a
+ | _ -> ())
+ p.p_eqs;
+
+ (* Make ids for variables *)
+ let add_var n =
+ if not (Hashtbl.mem var_map n) then begin
+ vars := { name = n; size = Env.find n p.p_vars }::(!vars);
+ Hashtbl.add var_map n (!next_id);
+ next_id := !next_id + 1
+ end
+ in
+ List.iter add_var p.p_inputs;
+ List.iter (fun (n, _) -> add_var n) p.p_eqs;
+ Env.iter (fun n _ -> add_var n) p.p_vars;
+
+ let var_id = Hashtbl.find var_map in
+ let arg_id = function
+ | Avar(x) -> var_id x
+ | Aconst(x) ->
+ let n, _, _ = const_info x in var_id n
+ in
+
+ (* Extract registers *)
+ let regs, eq2 = List.fold_left
+ (fun (regs, eqs) (n, eq) ->
+ match eq with
+ | Ereg(x) ->
+ {
+ reg_dest = var_id n;
+ source = var_id x;
+ }::regs, eqs
+ | _ -> regs, (n, eq)::eqs)
+ ([],[])
+ p.p_eqs in
+ (* Extract rams, replace arguments by variable id's *)
+ let ram_id = ref 0 in
+ let rams, eq3 = List.fold_left
+ (fun (rams, eqs) (n, eq) ->
+ let ram2 = ref None in
+ let eq2 = match eq with
+ | Eram(asz, wsz, ra, we, wa, d) ->
+ ram_id := !ram_id + 1;
+ ram2 := Some({
+ ram_id = !ram_id - 1;
+ addr_size = asz;
+ word_size = wsz;
+ write_enable = arg_id we;
+ write_addr = arg_id wa;
+ data = arg_id d;
+ });
+ Dreadram(!ram_id - 1, arg_id ra)
+ | Earg(a) -> Dcopy(arg_id a)
+ | Enot(a) -> Dnot(arg_id a)
+ | Ebinop(o, a, b) -> Dbinop(o, arg_id a, arg_id b)
+ | Emux(a, b, c) -> Dmux(arg_id a, arg_id b, arg_id c)
+ | Erom(u, v, a) -> Drom(u, v, arg_id a)
+ | Econcat(a, b) -> Dconcat(arg_id a, arg_id b)
+ | Eslice(u, v, a) -> Dslice(u, v, arg_id a)
+ | Eselect(i, a) -> Dselect(i, arg_id a)
+ | _ -> failwith "This should not happen."
+ in
+ (match !ram2 with | None -> rams | Some k -> k::rams),
+ (var_id n, eq2)::eqs
+ )
+ ([],[])
+ eq2 in
+
+ (* Replace arguments by variable id's *)
+ {
+ d_vars = List.rev (!vars);
+ d_inputs = List.map var_id p.p_inputs;
+ d_outputs = List.map var_id p.p_outputs;
+ d_regs = regs;
+ d_rams = List.rev rams;
+ d_eqs = eq3;
+ }
+
(* Printer code *)
@@ -182,53 +182,53 @@ let c_select = 7
let c_readram = 8
let binop_id = function
- | Or -> 0
- | Xor -> 1
- | And -> 2
- | Nand -> 3
+ | Or -> 0
+ | Xor -> 1
+ | And -> 2
+ | Nand -> 3
let print_dumb_program oc p =
- let ff = formatter_of_out_channel oc in
- (* print variable list *)
- fprintf ff "%d\n" (List.length p.d_vars);
- List.iter
- (fun v ->
- fprintf ff "%d %s\n" v.size v.name)
- p.d_vars;
- (* print input list *)
- fprintf ff "%d" (List.length p.d_inputs);
- List.iter (fun k -> fprintf ff " %d" k) p.d_inputs;
- fprintf ff "\n";
- (* print output list *)
- fprintf ff "%d" (List.length p.d_outputs);
- List.iter (fun k -> fprintf ff " %d" k) p.d_outputs;
- fprintf ff "\n";
- (* print register list *)
- fprintf ff "%d\n" (List.length p.d_regs);
- List.iter (fun (r: reg_var) ->
- fprintf ff "%d %d\n" r.reg_dest r.source) p.d_regs;
- (* print ram list *)
- fprintf ff "%d\n" (List.length p.d_rams);
- List.iter (fun r -> fprintf ff "%d %d %d %d %d\n"
- r.addr_size r.word_size r.write_enable
- r.write_addr r.data) p.d_rams;
- (* print equation list *)
- fprintf ff "%d\n" (List.length p.d_eqs);
- List.iter (fun (n, e) ->
- fprintf ff "%d " n; match e with
- | Dcopy(x) -> fprintf ff "%d %d\n" c_copy x
- | Dnot(x) -> fprintf ff "%d %d\n" c_not x
- | Dbinop(o, a, b) -> fprintf ff "%d %d %d %d\n" c_binop (binop_id o) a b
- | Dmux(a, b, c) -> fprintf ff "%d %d %d %d\n" c_mux a b c
- | Drom(u, v, a) -> fprintf ff "%d %d %d %d\n" c_rom u v a
- | Dconcat(a, b) -> fprintf ff "%d %d %d\n" c_concat a b
- | Dslice(u, v, a) -> fprintf ff "%d %d %d %d\n" c_slice u v a
- | Dselect(i, a) -> fprintf ff "%d %d %d\n" c_select i a
- | Dreadram(i, k) -> fprintf ff "%d %d %d\n" c_readram i k)
- p.d_eqs;
- (*flush*)
- fprintf ff "@."
+ let ff = formatter_of_out_channel oc in
+ (* print variable list *)
+ fprintf ff "%d\n" (List.length p.d_vars);
+ List.iter
+ (fun v ->
+ fprintf ff "%d %s\n" v.size v.name)
+ p.d_vars;
+ (* print input list *)
+ fprintf ff "%d" (List.length p.d_inputs);
+ List.iter (fun k -> fprintf ff " %d" k) p.d_inputs;
+ fprintf ff "\n";
+ (* print output list *)
+ fprintf ff "%d" (List.length p.d_outputs);
+ List.iter (fun k -> fprintf ff " %d" k) p.d_outputs;
+ fprintf ff "\n";
+ (* print register list *)
+ fprintf ff "%d\n" (List.length p.d_regs);
+ List.iter (fun (r: reg_var) ->
+ fprintf ff "%d %d\n" r.reg_dest r.source) p.d_regs;
+ (* print ram list *)
+ fprintf ff "%d\n" (List.length p.d_rams);
+ List.iter (fun r -> fprintf ff "%d %d %d %d %d\n"
+ r.addr_size r.word_size r.write_enable
+ r.write_addr r.data) p.d_rams;
+ (* print equation list *)
+ fprintf ff "%d\n" (List.length p.d_eqs);
+ List.iter (fun (n, e) ->
+ fprintf ff "%d " n; match e with
+ | Dcopy(x) -> fprintf ff "%d %d\n" c_copy x
+ | Dnot(x) -> fprintf ff "%d %d\n" c_not x
+ | Dbinop(o, a, b) -> fprintf ff "%d %d %d %d\n" c_binop (binop_id o) a b
+ | Dmux(a, b, c) -> fprintf ff "%d %d %d %d\n" c_mux a b c
+ | Drom(u, v, a) -> fprintf ff "%d %d %d %d\n" c_rom u v a
+ | Dconcat(a, b) -> fprintf ff "%d %d %d\n" c_concat a b
+ | Dslice(u, v, a) -> fprintf ff "%d %d %d %d\n" c_slice u v a
+ | Dselect(i, a) -> fprintf ff "%d %d %d\n" c_select i a
+ | Dreadram(i, k) -> fprintf ff "%d %d %d\n" c_readram i k)
+ p.d_eqs;
+ (*flush*)
+ fprintf ff "@."
let print_program oc p =
- print_dumb_program oc (make_program_dumb p)
+ print_dumb_program oc (make_program_dumb p)