2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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.
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
14 // Copyright (c) 2017 Bluespec, Inc. All Rights Reserved
16 package AXI4_Lite_Types;
18 // ================================================================
19 // BSV library imports
22 import Connectable :: *;
25 // BSV additional libs
27 import Semi_FIFOF :: *;
29 // ****************************************************************
30 // ****************************************************************
31 // Section: RTL-level interfaces
32 // ****************************************************************
33 // ****************************************************************
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.
40 interface AXI4_Lite_Slave_IFC #(numeric type wd_addr,
42 numeric type wd_user);
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
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
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
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
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)
85 typedef enum { AXI4_LITE_OKAY, AXI4_LITE_EXOKAY, AXI4_LITE_SLVERR, AXI4_LITE_DECERR } AXI4_Lite_Resp
86 deriving (Bits, Eq, FShow);
88 // Write Address channel
91 Bit #(wd_addr) awaddr;
92 Bit #(wd_user) awuser;
94 } AXI4_Lite_Wr_Addr #(numeric type wd_addr, numeric type wd_user)
95 deriving (Bits, FShow);
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);
105 // Write Response channel
108 AXI4_Lite_Resp bresp;
109 Bit #(wd_user) buser;
110 } AXI4_Lite_Wr_Resp #(numeric type wd_user)
111 deriving (Bits, FShow);
113 // Read Address channel
116 Bit #(wd_addr) araddr;
117 Bit #(wd_user) aruser;
119 } AXI4_Lite_Rd_Addr #(numeric type wd_addr, numeric type wd_user)
120 deriving (Bits, FShow);
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);
131 // ================================================================
132 // Slave transactor interface
134 interface AXI4_Lite_Slave_Xactor_IFC #(numeric type wd_addr,
135 numeric type wd_data,
136 numeric type wd_user);
140 interface AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user) axi_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;
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
151 // ----------------------------------------------------------------
154 module mkAXI4_Lite_Slave_Xactor (AXI4_Lite_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user));
156 Bool unguarded = True;
157 Bool guarded = False;
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);
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);
167 // ----------------------------------------------------------------
179 interface axi_side = interface AXI4_Lite_Slave_IFC;
181 method Action m_awvalid (Bool awvalid,
182 Bit #(wd_addr) awaddr,
184 Bit #(wd_user) awuser);
185 if (awvalid && f_wr_addr.notFull)
186 f_wr_addr.enq (AXI4_Lite_Wr_Addr {awaddr: awaddr,
191 method Bool m_awready;
192 return f_wr_addr.notFull;
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});
203 method Bool m_wready;
204 return f_wr_data.notFull;
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)
217 method Action m_arvalid (Bool arvalid,
218 Bit #(wd_addr) araddr,
220 Bit #(wd_user) aruser);
221 if (arvalid && f_rd_addr.notFull)
222 f_rd_addr.enq (AXI4_Lite_Rd_Addr {araddr: araddr,
227 method Bool m_arready;
228 return f_rd_addr.notFull;
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)
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);
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
251 // ================================================================