diff options
Diffstat (limited to 'sched')
-rw-r--r-- | sched/netlist_dumb.ml | 193 |
1 files changed, 179 insertions, 14 deletions
diff --git a/sched/netlist_dumb.ml b/sched/netlist_dumb.ml index 7736d94..1e2a57f 100644 --- a/sched/netlist_dumb.ml +++ b/sched/netlist_dumb.ml @@ -14,7 +14,6 @@ type var_id = int type const_val = bool array (* keep type binop from netlist_ast *) -type const_var = { dest : var_id; value : const_val } type reg_var = { dest : var_id; source : var_id } type ram_var = { dest : var_id; addr_size : int; word_size : int; @@ -50,19 +49,191 @@ let mkbinstr a = done; r +let const_info = function + | VBit(a) -> "$" ^ (mkbinstr [|a|]), 1, [|a|] + | VBitArray(a) -> "$" ^ (mkbinstr a), Array.length a, a + let make_program_dumb p = - let vars = ref [] in - let var_map = Hashtbl.create (Env.cardinal p.p_vars) in - () (* TODO *) (* - 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 + 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) + 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 *) + Env.iter + (fun k v -> + let sz = match v with + | TBit -> 1 + | TBitArray(n) -> n + in + vars := { name = k; size = sz }::(!vars); + Hashtbl.add var_map k (!next_id); + next_id := !next_id + 1) + 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) -> + { + dest = var_id n; + source = var_id x; + }::regs, eqs + | _ -> regs, (n, eq)::eqs) + ([],[]) + p.p_eqs in + (* Extract rams *) + let rams, eq3 = List.fold_left + (fun (rams, eqs) (n, eq) -> + match eq with + | Eram(asz, wsz, ra, we, wa, d) -> + { + dest = var_id n; + addr_size = asz; + word_size = wsz; + read_addr = arg_id ra; + write_enable = arg_id we; + write_addr = arg_id wa; + data = arg_id d; + }::rams, eqs + | _ -> rams, (n, eq)::eqs) + ([],[]) + eq2 in + + (* Replace arguments by variable id's *) + let eqs = List.map + (fun (n, eq) -> + (var_id n, match eq with + | 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.")) + eq3 in + + { + 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 = rams; + d_eqs = eqs; + } +(* Printer code *) + +(* Identifiers *) +let c_copy = 0 +let c_not = 1 +let c_binop = 2 +let c_mux = 3 +let c_rom = 4 +let c_concat = 5 +let c_slice = 6 +let c_select = 7 + +let binop_id = function + | 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.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 %d %d\n" + r.dest r.addr_size r.word_size r.read_addr 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) + p.d_eqs; + (*flush*) + fprintf ff "@." + +let print_program oc p = + print_dumb_program oc (make_program_dumb p) + + +(* OLD PRINTER CODE *) + + +(* (* constants *) let c_arg = 0 @@ -76,12 +247,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_program oc p = let ff = formatter_of_out_channel oc in (* associate numbers to variables *) @@ -151,6 +316,6 @@ let print_program oc p = (* flush *) fprintf ff "@." - +*) |