Source file datapath_register.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
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
open! Base
open! Hardcaml
module Make (Data : Hardcaml.Interface.S) = struct
module IO = struct
type 'a t =
{ data : 'a Data.t
; valid : 'a
; ready : 'a
}
[@@deriving hardcaml]
end
module I = struct
type 'a t =
{ clock : 'a
; clear : 'a
; i : 'a IO.t [@rtlprefix "i_"]
}
[@@deriving hardcaml]
end
let create_io spec (i : _ IO.t) =
let open Signal in
let reg = reg spec in
let wire0 () = Always.Variable.wire ~default:gnd in
let output_ready = i.ready in
let temp_valid_reg = wire 1 in
let output_valid_reg = wire 1 in
let output_valid_next = wire0 () in
let temp_valid_next = wire0 () in
let store_input_to_output = wire0 () in
let store_input_to_temp = wire0 () in
let store_temp_to_output = wire0 () in
let input_ready_early =
output_ready |: (~:temp_valid_reg &: (~:output_valid_reg |: ~:(i.valid)))
in
let input_ready_reg = reg ~enable:vdd input_ready_early in
output_valid_reg <== reg ~enable:vdd output_valid_next.value;
temp_valid_reg <== reg ~enable:vdd temp_valid_next.value;
Always.(
compile
[
output_valid_next <-- output_valid_reg
; temp_valid_next <-- temp_valid_reg
; store_input_to_output <--. 0
; store_input_to_temp <--. 0
; store_temp_to_output <--. 0
; if_
input_ready_reg
[
if_
(output_ready |: ~:output_valid_reg)
[
output_valid_next <-- i.valid
; store_input_to_output <--. 1
]
[
temp_valid_next <-- i.valid
; store_input_to_temp <--. 1
]
]
@@ elif
output_ready
[
output_valid_next <-- temp_valid_reg
; temp_valid_next <--. 0
; store_temp_to_output <--. 1
]
[]
]);
let temp = Data.map i.data ~f:(reg ~enable:store_input_to_temp.value) in
let output =
Data.map
(Data.Of_signal.mux2 store_input_to_output.value i.data temp)
~f:(reg ~enable:(store_input_to_output.value |: store_temp_to_output.value))
in
{ IO.data = output; valid = output_valid_reg; ready = input_ready_reg }
;;
let create _scope (i : _ I.t) =
let spec = Reg_spec.create () ~clock:i.clock ~clear:i.clear in
create_io spec i.i
;;
let hierarchical ?instance scope i =
let module Scoped = Hierarchy.In_scope (I) (IO) in
Scoped.hierarchical ~scope ~name:"datapath_reg" ?instance create i
;;
end