a1bb465cc1ed1ce950739e94cbcabd97265c3eb6
[pinmux.git] / src / bsv_lib / AXI4_Lite_Types.bsv
1 /*
2 Copyright (c) 2013, IIT Madras
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 * Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 * Neither the name of IIT Madras nor the names of its contributors
15 may be used to endorse or promote products derived from this software
16 without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 ------------------------------------------------------------------------
31
32 */
33 // Copyright (c) 2017 Bluespec, Inc. All Rights Reserved
34
35 package AXI4_Lite_Types;
36
37 // ================================================================
38 // BSV library imports
39
40 import FIFOF :: *;
41 import Connectable :: *;
42
43 // ----------------
44 // BSV additional libs
45
46 import Semi_FIFOF :: *;
47
48 // ****************************************************************
49 // ****************************************************************
50 // Section: RTL-level interfaces
51 // ****************************************************************
52 // ****************************************************************
53
54 // ================================================================
55 // These are the signal-level interfaces for an AXI4-Lite master.
56 // The (*..*) attributes ensure that when bsc compiles this to Verilog,
57 // we get exactly the signals specified in the ARM spec.
58
59 interface AXI4_Lite_Slave_IFC #(numeric type wd_addr,
60 numeric type wd_data,
61 numeric type wd_user);
62 // Wr Addr channel
63 (* always_ready, always_enabled *)
64 method Action m_awvalid ((* port="awvalid" *) Bool awvalid, // in
65 (* port="awaddr" *) Bit #(wd_addr) awaddr, // in
66 (* port="awsize" *) Bit #(3) awsize, // in
67 (* port="awuser" *) Bit #(wd_user) awuser); // in
68 (* always_ready, result="awready" *)
69 method Bool m_awready; // out
70
71 // Wr Data channel
72 (* always_ready, always_enabled *)
73 method Action m_wvalid ((* port="wvalid" *) Bool wvalid, // in
74 (* port="wdata" *) Bit #(wd_data) wdata, // in
75 (* port="wstrb" *) Bit #(TDiv #(wd_data,8)) wstrb); // in
76 (* always_ready, result="wready" *)
77 method Bool m_wready; // out
78
79 // Wr Response channel
80 (* always_ready, result="bvalid" *) method Bool m_bvalid; // out
81 (* always_ready, result="bresp" *) method Bit #(2) m_bresp; // out
82 (* always_ready, result="buser" *) method Bit #(wd_user) m_buser; // out
83 (* always_ready, always_enabled *) method Action m_bready ((* port="bready" *) Bool bready); // in
84
85 // Rd Addr channel
86 (* always_ready, always_enabled *)
87 method Action m_arvalid ((* port="arvalid" *) Bool arvalid, // in
88 (* port="araddr" *) Bit #(wd_addr) araddr, // in
89 (* port="arsize" *) Bit #(3) arsize, // in
90 (* port="aruser" *) Bit #(wd_user) aruser); // in
91 (* always_ready, result="arready" *)
92 method Bool m_arready; // out
93
94 // Rd Data channel
95 (* always_ready, result="rvalid" *) method Bool m_rvalid; // out
96 (* always_ready, result="rresp" *) method Bit #(2) m_rresp; // out
97 (* always_ready, result="rdata" *) method Bit #(wd_data) m_rdata; // out
98 (* always_ready, result="ruser" *) method Bit #(wd_user) m_ruser; // out
99 (* always_ready, always_enabled *) method Action m_rready ((* port="rready" *) Bool rready); // in
100 endinterface: AXI4_Lite_Slave_IFC
101 // ================================================================
102 // Higher-level types for payloads (rather than just bits)
103
104 typedef enum { AXI4_LITE_OKAY, AXI4_LITE_EXOKAY, AXI4_LITE_SLVERR, AXI4_LITE_DECERR } AXI4_Lite_Resp
105 deriving (Bits, Eq, FShow);
106
107 // Write Address channel
108
109 typedef struct {
110 Bit #(wd_addr) awaddr;
111 Bit #(wd_user) awuser;
112 Bit#(3) awsize;
113 } AXI4_Lite_Wr_Addr #(numeric type wd_addr, numeric type wd_user)
114 deriving (Bits, FShow);
115
116 // Write Data channel
117
118 typedef struct {
119 Bit #(wd_data) wdata;
120 Bit #(TDiv #(wd_data, 8)) wstrb;
121 } AXI4_Lite_Wr_Data #(numeric type wd_data)
122 deriving (Bits, FShow);
123
124 // Write Response channel
125
126 typedef struct {
127 AXI4_Lite_Resp bresp;
128 Bit #(wd_user) buser;
129 } AXI4_Lite_Wr_Resp #(numeric type wd_user)
130 deriving (Bits, FShow);
131
132 // Read Address channel
133
134 typedef struct {
135 Bit #(wd_addr) araddr;
136 Bit #(wd_user) aruser;
137 Bit#(3) arsize;
138 } AXI4_Lite_Rd_Addr #(numeric type wd_addr, numeric type wd_user)
139 deriving (Bits, FShow);
140
141 // Read Data channel
142
143 typedef struct {
144 AXI4_Lite_Resp rresp;
145 Bit #(wd_data) rdata;
146 Bit #(wd_user) ruser;
147 } AXI4_Lite_Rd_Data #(numeric type wd_data, numeric type wd_user)
148 deriving (Bits, FShow);
149
150 // ================================================================
151 // Slave transactor interface
152
153 interface AXI4_Lite_Slave_Xactor_IFC #(numeric type wd_addr,
154 numeric type wd_data,
155 numeric type wd_user);
156 method Action reset;
157
158 // AXI side
159 interface AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user) axi_side;
160
161 // FIFOF side
162 interface FIFOF_O #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) o_wr_addr;
163 interface FIFOF_O #(AXI4_Lite_Wr_Data #(wd_data)) o_wr_data;
164 interface FIFOF_I #(AXI4_Lite_Wr_Resp #(wd_user)) i_wr_resp;
165
166 interface FIFOF_O #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) o_rd_addr;
167 interface FIFOF_I #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) i_rd_data;
168 endinterface: AXI4_Lite_Slave_Xactor_IFC
169
170 // ----------------------------------------------------------------
171 // Slave transactor
172
173 module mkAXI4_Lite_Slave_Xactor (AXI4_Lite_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user));
174
175 Bool unguarded = True;
176 Bool guarded = False;
177
178 // These FIFOs are guarded on BSV side, unguarded on AXI side
179 FIFOF #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) f_wr_addr <- mkGFIFOF (unguarded, guarded);
180 FIFOF #(AXI4_Lite_Wr_Data #(wd_data)) f_wr_data <- mkGFIFOF (unguarded, guarded);
181 FIFOF #(AXI4_Lite_Wr_Resp #(wd_user)) f_wr_resp <- mkGFIFOF (guarded, unguarded);
182
183 FIFOF #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) f_rd_addr <- mkGFIFOF (unguarded, guarded);
184 FIFOF #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) f_rd_data <- mkGFIFOF (guarded, unguarded);
185
186 // ----------------------------------------------------------------
187 // INTERFACE
188
189 method Action reset;
190 f_wr_addr.clear;
191 f_wr_data.clear;
192 f_wr_resp.clear;
193 f_rd_addr.clear;
194 f_rd_data.clear;
195 endmethod
196
197 // AXI side
198 interface axi_side = interface AXI4_Lite_Slave_IFC;
199 // Wr Addr channel
200 method Action m_awvalid (Bool awvalid,
201 Bit #(wd_addr) awaddr,
202 Bit#(3) awsize,
203 Bit #(wd_user) awuser);
204 if (awvalid && f_wr_addr.notFull)
205 f_wr_addr.enq (AXI4_Lite_Wr_Addr {awaddr: awaddr,
206 awsize:awsize,
207 awuser: awuser});
208 endmethod
209
210 method Bool m_awready;
211 return f_wr_addr.notFull;
212 endmethod
213
214 // Wr Data channel
215 method Action m_wvalid (Bool wvalid,
216 Bit #(wd_data) wdata,
217 Bit #(TDiv #(wd_data, 8)) wstrb);
218 if (wvalid && f_wr_data.notFull)
219 f_wr_data.enq (AXI4_Lite_Wr_Data {wdata: wdata, wstrb: wstrb});
220 endmethod
221
222 method Bool m_wready;
223 return f_wr_data.notFull;
224 endmethod
225
226 // Wr Response channel
227 method Bool m_bvalid = f_wr_resp.notEmpty;
228 method Bit #(2) m_bresp = pack (f_wr_resp.first.bresp);
229 method Bit #(wd_user) m_buser = f_wr_resp.first.buser;
230 method Action m_bready (Bool bready);
231 if (bready && f_wr_resp.notEmpty)
232 f_wr_resp.deq;
233 endmethod
234
235 // Rd Addr channel
236 method Action m_arvalid (Bool arvalid,
237 Bit #(wd_addr) araddr,
238 Bit#(3) arsize,
239 Bit #(wd_user) aruser);
240 if (arvalid && f_rd_addr.notFull)
241 f_rd_addr.enq (AXI4_Lite_Rd_Addr {araddr: araddr,
242 arsize: arsize,
243 aruser: aruser});
244 endmethod
245
246 method Bool m_arready;
247 return f_rd_addr.notFull;
248 endmethod
249
250 // Rd Data channel
251 method Bool m_rvalid = f_rd_data.notEmpty;
252 method Bit #(2) m_rresp = pack (f_rd_data.first.rresp);
253 method Bit #(wd_data) m_rdata = f_rd_data.first.rdata;
254 method Bit #(wd_user) m_ruser = f_rd_data.first.ruser;
255 method Action m_rready (Bool rready);
256 if (rready && f_rd_data.notEmpty)
257 f_rd_data.deq;
258 endmethod
259 endinterface;
260
261 // FIFOF side
262 interface o_wr_addr = to_FIFOF_O (f_wr_addr);
263 interface o_wr_data = to_FIFOF_O (f_wr_data);
264 interface i_wr_resp = to_FIFOF_I (f_wr_resp);
265
266 interface o_rd_addr = to_FIFOF_O (f_rd_addr);
267 interface i_rd_data = to_FIFOF_I (f_rd_data);
268 endmodule: mkAXI4_Lite_Slave_Xactor
269
270 // ================================================================
271
272 endpackage