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
open! Import
module Collision_mode = struct
module T = struct
type t =
| Read_before_write
| Write_before_read
[@@deriving sexp_of, compare]
end
include T
include Comparable.Make (T)
end
module Write_port = struct
type t = Signal.write_port =
{ write_clock : Signal.t
; write_address : Signal.t
; write_enable : Signal.t
; write_data : Signal.t
}
let sexp_of_t t =
let open Signal in
[%message
""
(t.write_clock : Signal.t)
(t.write_address : Signal.t)
(t.write_enable : Signal.t)
(t.write_data : Signal.t)]
;;
end
module Read_port = struct
type t = Signal.read_port =
{ read_clock : Signal.t
; read_address : Signal.t
; read_enable : Signal.t
}
[@@deriving sexp_of]
let sexp_of_t t =
let open Signal in
[%message
"" (t.read_clock : Signal.t) (t.read_address : Signal.t) (t.read_enable : Signal.t)]
;;
end
let if_write_before_read_mode ~collision_mode (r : Read_port.t array) =
match (collision_mode : Collision_mode.t) with
| Write_before_read ->
Array.map r ~f:(fun r ->
Signal.reg
(Reg_spec.create () ~clock:r.read_clock)
~enable:r.read_enable
r.read_address)
| Read_before_write -> Array.map r ~f:(fun r -> r.read_address)
;;
let if_read_before_write_mode
~collision_mode
(r : Read_port.t array)
(q : Signal.t array)
=
match (collision_mode : Collision_mode.t) with
| Write_before_read -> q
| Read_before_write ->
Array.map2_exn r q ~f:(fun r q ->
Signal.reg (Reg_spec.create () ~clock:r.read_clock) ~enable:r.read_enable q)
;;
let create ~collision_mode ~size ~write_ports ~read_ports =
Signal.multiport_memory
size
~write_ports
~read_addresses:(if_write_before_read_mode ~collision_mode read_ports)
|> if_read_before_write_mode ~collision_mode read_ports
;;