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