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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
open Base
include Cyclesim_intf
module Port_list = Cyclesim0.Port_list
module Private = struct
include Cyclesim0.Private
module Traced_nodes = Cyclesim_compile.Traced_nodes
end
module Traced = Cyclesim0.Traced
module Node = Cyclesim0.Node
module Reg = Cyclesim0.Reg
module Memory = Cyclesim0.Memory
type t_port_list = Cyclesim0.t_port_list
type ('i, 'o) t = ('i, 'o) Cyclesim0.t [@@deriving sexp_of]
let in_ports = Cyclesim0.in_ports
let inputs = Cyclesim0.inputs
let traced t = Cyclesim0.traced t
let lookup_node = Cyclesim0.lookup_node
let lookup_reg = Cyclesim0.lookup_reg
let lookup_mem = Cyclesim0.lookup_mem
module Config = Cyclesim0.Config
let circuit (sim : _ t) = sim.circuit
let cycle_check (sim : _ t) = sim.cycle_check ()
let cycle_before_clock_edge (sim : _ t) = sim.cycle_before_clock_edge ()
let cycle_at_clock_edge (sim : _ t) = sim.cycle_at_clock_edge ()
let cycle_after_clock_edge (sim : _ t) = sim.cycle_after_clock_edge ()
let reset (sim : _ t) = sim.reset ()
let cycle sim =
cycle_check sim;
cycle_before_clock_edge sim;
cycle_at_clock_edge sim;
cycle_after_clock_edge sim
;;
let in_port (sim : _ Cyclesim0.t) name =
try List.Assoc.find_exn sim.in_ports name ~equal:String.equal with
| _ -> raise_s [%message "Couldn't find input port" name]
;;
let lookup_node_by_name (sim : _ Cyclesim0.t) name =
let map = Lazy.force sim.node_by_name in
let%bind.Option name = Map.find map name in
lookup_node sim name
;;
let lookup_reg_by_name (sim : _ Cyclesim0.t) name =
let map = Lazy.force sim.reg_by_name in
let%bind.Option name = Map.find map name in
lookup_reg sim name
;;
let lookup_mem_by_name (sim : _ Cyclesim0.t) name =
let map = Lazy.force sim.memory_by_name in
let%bind.Option name = Map.find map name in
lookup_mem sim name
;;
let lookup_node_or_reg (sim : _ Cyclesim0.t) traced =
match lookup_node sim traced with
| None -> lookup_reg sim traced |> Option.map ~f:Reg.to_node
| Some t -> Some t
;;
let lookup_node_or_reg_by_name (sim : _ Cyclesim0.t) name =
match lookup_node_by_name sim name with
| None -> lookup_reg_by_name sim name |> Option.map ~f:Reg.to_node
| Some t -> Some t
;;
let out_port_after_clock_edge (sim : _ Cyclesim0.t) name =
try List.Assoc.find_exn sim.out_ports_after_clock_edge name ~equal:String.equal with
| _ -> raise_s [%message "Couldn't find output port" name]
;;
let out_port_before_clock_edge (sim : _ Cyclesim0.t) name =
try List.Assoc.find_exn sim.out_ports_before_clock_edge name ~equal:String.equal with
| _ -> raise_s [%message "Couldn't find output port" name]
;;
let out_port ?(clock_edge = Side.After) t name =
match clock_edge with
| Before -> out_port_before_clock_edge t name
| After -> out_port_after_clock_edge t name
;;
let out_ports ?(clock_edge = Side.After) (t : _ t) =
match clock_edge with
| Before -> t.out_ports_before_clock_edge
| After -> t.out_ports_after_clock_edge
;;
let outputs ?(clock_edge = Side.After) (t : _ t) =
match clock_edge with
| Before -> t.outputs_before_clock_edge
| After -> t.outputs_after_clock_edge
;;
module Combine_error = Cyclesim_combine.Combine_error
let combine = Cyclesim_combine.combine
let create ?(implementation = `V2) =
match implementation with
| `V1 -> Cyclesim_compile.create
| `V2 -> Cyclesim2.create
;;
module With_interface (I : Interface.S) (O : Interface.S) = struct
type nonrec t = (Bits.t ref I.t, Bits.t ref O.t) t [@@deriving sexp_of]
module C = Circuit.With_interface (I) (O)
let coerce sim =
let find_port (ports : Cyclesim0.Port_list.t) (name, width) =
match List.Assoc.find ports name ~equal:String.equal with
| Some x -> x
| None -> ref (Bits.zero width)
in
let to_input ports = I.map I.port_names_and_widths ~f:(find_port ports) in
let to_output ports = O.map O.port_names_and_widths ~f:(find_port ports) in
Private.coerce sim ~to_input ~to_output
;;
let create ?implementation ?config ?circuit_config create_fn =
let circuit_config =
match circuit_config with
| None -> Circuit.Config.default_for_simulations
| Some config -> config
in
let circuit = C.create_exn ~config:circuit_config ~name:"simulator" create_fn in
let sim = create ?implementation ?config circuit in
coerce sim
;;
end