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
(** Definition of clock, reset and clear signals for sequential logic (ie registers). *)
open! Core0
module type Signal = Reg_spec_intf.Signal
module type S = Reg_spec_intf.S
module Make (Signal : Signal) = struct
type signal = Signal.t [@@deriving sexp_of]
type t =
{ clock : signal
; clock_edge : Edge.t
; reset : signal option
; reset_level : Level.t
; clear : signal option
}
[@@deriving fields ~getters, sexp_of]
let reset_exn t = reset t |> Option.value_exn
let clear_exn t = clear t |> Option.value_exn
let assert_non_empty typ_ t =
if Signal.is_empty t
then raise_s [%message "[Reg_spec] signal must not be empty" typ_ (t : signal)]
;;
let assert_non_empty_or_option typ_ t = Option.iter t ~f:(assert_non_empty typ_)
let validate { clock; clock_edge = _; reset; reset_level = _; clear } =
assert_non_empty "clock" clock;
assert_non_empty_or_option "reset" reset;
assert_non_empty_or_option "clear" clear
;;
let create
?(clock_edge = Edge.Rising)
?reset
?(reset_level = Level.High)
?clear
()
~clock
=
let t = { clock; clock_edge; reset; reset_level; clear } in
validate t;
t
;;
let override ?clock ?clock_edge ?reset ?reset_level ?clear (spec : t) =
let t =
{ clock =
(match clock with
| None -> spec.clock
| Some clock -> clock)
; clock_edge = Option.value clock_edge ~default:spec.clock_edge
; reset =
(match reset with
| None -> spec.reset
| Some reset -> Some reset)
; reset_level = Option.value reset_level ~default:spec.reset_level
; clear =
(match clear with
| None -> spec.clear
| Some clear -> Some clear)
}
in
validate t;
t
;;
end