2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
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.
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.
30 ------------------------------------------------------------------------
33 // Copyright (c) 2017 Bluespec, Inc. All Rights Reserved
35 package AXI4_Lite_Types;
37 // ================================================================
38 // BSV library imports
41 import Connectable :: *;
44 // BSV additional libs
46 import Semi_FIFOF :: *;
48 // ****************************************************************
49 // ****************************************************************
50 // Section: RTL-level interfaces
51 // ****************************************************************
52 // ****************************************************************
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.
59 interface AXI4_Lite_Slave_IFC #(numeric type wd_addr,
61 numeric type wd_user);
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
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
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
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
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)
104 typedef enum { AXI4_LITE_OKAY, AXI4_LITE_EXOKAY, AXI4_LITE_SLVERR, AXI4_LITE_DECERR } AXI4_Lite_Resp
105 deriving (Bits, Eq, FShow);
107 // Write Address channel
110 Bit #(wd_addr) awaddr;
111 Bit #(wd_user) awuser;
113 } AXI4_Lite_Wr_Addr #(numeric type wd_addr, numeric type wd_user)
114 deriving (Bits, FShow);
116 // Write Data channel
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);
124 // Write Response channel
127 AXI4_Lite_Resp bresp;
128 Bit #(wd_user) buser;
129 } AXI4_Lite_Wr_Resp #(numeric type wd_user)
130 deriving (Bits, FShow);
132 // Read Address channel
135 Bit #(wd_addr) araddr;
136 Bit #(wd_user) aruser;
138 } AXI4_Lite_Rd_Addr #(numeric type wd_addr, numeric type wd_user)
139 deriving (Bits, FShow);
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);
150 // ================================================================
151 // Slave transactor interface
153 interface AXI4_Lite_Slave_Xactor_IFC #(numeric type wd_addr,
154 numeric type wd_data,
155 numeric type wd_user);
159 interface AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user) axi_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;
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
170 // ----------------------------------------------------------------
173 module mkAXI4_Lite_Slave_Xactor (AXI4_Lite_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user));
175 Bool unguarded = True;
176 Bool guarded = False;
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);
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);
186 // ----------------------------------------------------------------
198 interface axi_side = interface AXI4_Lite_Slave_IFC;
200 method Action m_awvalid (Bool awvalid,
201 Bit #(wd_addr) awaddr,
203 Bit #(wd_user) awuser);
204 if (awvalid && f_wr_addr.notFull)
205 f_wr_addr.enq (AXI4_Lite_Wr_Addr {awaddr: awaddr,
210 method Bool m_awready;
211 return f_wr_addr.notFull;
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});
222 method Bool m_wready;
223 return f_wr_data.notFull;
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)
236 method Action m_arvalid (Bool arvalid,
237 Bit #(wd_addr) araddr,
239 Bit #(wd_user) aruser);
240 if (arvalid && f_rd_addr.notFull)
241 f_rd_addr.enq (AXI4_Lite_Rd_Addr {araddr: araddr,
246 method Bool m_arready;
247 return f_rd_addr.notFull;
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)
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);
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
270 // ================================================================