Source file combinational_op.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
open Base
type create_fn = (Bits.Mutable.t list -> Bits.Mutable.t list -> unit[@sexp.opaque])
[@@deriving sexp_of]
type t =
{ name : string
; input_widths : int list
; output_widths : int list
; create_fn : create_fn
}
[@@deriving fields ~getters, sexp_of]
let create ~name ~input_widths ~output_widths ~create_fn () =
if List.is_empty output_widths
then raise_s [%message "[Combinational_op]s require at least one output"];
List.iter input_widths ~f:(fun width ->
if width <= 0
then raise_s [%message "[Combinational_op] input width <=0" (width : int)]);
List.iter output_widths ~f:(fun width ->
if width <= 0
then raise_s [%message "[Combinational_op] output width <=0" (width : int)]);
{ name; input_widths; output_widths; create_fn }
;;
let create_fn_of_bits f src dst =
let bits = f (List.map src ~f:Bits.Mutable.to_bits) in
List.iter2_exn bits dst ~f:(fun bits dst -> Bits.Mutable.copy_bits ~src:bits ~dst)
;;
let instantiate t ~inputs =
if List.length t.input_widths <> List.length inputs
then
raise_s
[%message
"[Combinational_op.instantiate] got mismatched input lengths"
~input_widths:(t.input_widths : int list)
(inputs : Signal.t list)];
let inputs = List.mapi inputs ~f:(fun i input -> "i" ^ Int.to_string i, input) in
let outputs =
List.mapi t.output_widths ~f:(fun i width -> "o" ^ Int.to_string i, width)
in
let instance = Instantiation.create () ~name:t.name ~inputs ~outputs in
List.map outputs ~f:(fun (name, _) -> Map.find_exn instance name)
;;