Source file master_statemachine.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
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
open Base
open Hardcaml
module Make
(Master_to_slave : Lite_ports.Master_to_slave)
(Slave_to_master : Lite_ports.Slave_to_master)
(Internal_bus : Internal_bus.S) =
struct
open Signal
module State = struct
type t =
| Idle
| Write
| Read
[@@deriving compare ~localize, enumerate, sexp_of, variants]
end
module I = struct
type 'a t =
{ clock : 'a
; clear : 'a
; int_master : 'a Internal_bus.Master_to_slave.t
; axi_slave : 'a Slave_to_master.t
}
[@@deriving hardcaml ~rtlmangle:false]
end
module O = struct
type 'a t =
{ int_slave : 'a Internal_bus.Slave_to_master.t
; axi_master : 'a Master_to_slave.t
}
[@@deriving hardcaml ~rtlmangle:false]
end
let create _scope (i : _ I.t) =
let reg_spec = Reg_spec.create ~clock:i.clock ~clear:i.clear () in
let sm = Always.State_machine.create (module State) reg_spec ~enable:vdd in
ignore @@ (sm.current -- "STATE");
let int_slave = Internal_bus.Slave_to_master.Of_always.reg reg_spec in
let axi_master = Master_to_slave.Of_always.reg reg_spec in
let open Always in
compile
[ when_ i.axi_slave.arready [ axi_master.arvalid <--. 0 ]
; when_ i.axi_slave.awready [ axi_master.awvalid <--. 0 ]
; when_ i.axi_slave.wready [ axi_master.wvalid <--. 0 ]
; sm.switch
[ ( Idle
, [
when_
i.int_master.read_valid
[ axi_master.arvalid <--. 1
; axi_master.araddr
<-- uresize
i.int_master.address
~width:Master_to_slave.port_widths.araddr
; axi_master.rready <--. 1
; sm.set_next Read
]
; when_
i.int_master.write_valid
[ axi_master.awvalid <--. 1
; axi_master.wvalid <--. 1
; axi_master.wstrb
<-- ones (Internal_bus.Master_to_slave.port_widths.write_data / 8)
; axi_master.awaddr
<-- uresize
i.int_master.address
~width:Master_to_slave.port_widths.awaddr
; axi_master.wdata <-- i.int_master.write_data
; axi_master.bready <--. 1
; sm.set_next Write
]
] )
; ( Read
, [ when_
i.axi_slave.rvalid
[ int_slave.read_data <-- i.axi_slave.rdata
; int_slave.read_ready <--. 1
; Master_to_slave.(Of_always.assign axi_master (Of_signal.zero ()))
]
; when_
(int_slave.read_ready.value &: i.int_master.read_valid)
[ Internal_bus.Slave_to_master.(
Of_always.assign int_slave (Of_signal.zero ()))
; sm.set_next Idle
]
] )
; ( Write
, [ when_
i.axi_slave.bvalid
[ int_slave.write_ready <--. 1
; Master_to_slave.(Of_always.assign axi_master (Of_signal.zero ()))
]
; when_
(int_slave.write_ready.value &: i.int_master.write_valid)
[ Internal_bus.Slave_to_master.(
Of_always.assign int_slave (Of_signal.zero ()))
; sm.set_next Idle
]
] )
]
];
{ O.axi_master = Master_to_slave.Of_always.value axi_master
; int_slave = Internal_bus.Slave_to_master.Of_always.value int_slave
}
;;
let hierarchical ?(name = "master_statemachine") scope =
let module H = Hierarchy.In_scope (I) (O) in
H.hierarchical ~scope ~name create
;;
end