1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20package vta.interface.axi
21
22import chisel3._
23import chisel3.util._
24import vta.util.genericbundle._
25
26case class AXIParams(
27    coherent: Boolean = false,
28    idBits: Int = 1,
29    addrBits: Int = 32,
30    dataBits: Int = 64,
31    lenBits: Int = 8,
32    userBits: Int = 1
33) {
34  require(addrBits > 0)
35  require(dataBits >= 8 && dataBits % 2 == 0)
36
37  val strbBits = dataBits / 8
38  val sizeBits = 3
39  val burstBits = 2
40  val lockBits = 2
41  val cacheBits = 4
42  val protBits = 3
43  val qosBits = 4
44  val regionBits = 4
45  val respBits = 2
46  val sizeConst = log2Ceil(dataBits / 8)
47  val idConst = 0
48  val userConst = if (coherent) 1 else 0
49  val burstConst = 1
50  val lockConst = 0
51  val cacheConst = if (coherent) 15 else 3
52  val protConst = if (coherent) 4 else 0
53  val qosConst = 0
54  val regionConst = 0
55}
56
57abstract class AXIBase(params: AXIParams)
58    extends GenericParameterizedBundle(params)
59
60// AXILite
61
62class AXILiteAddress(params: AXIParams) extends AXIBase(params) {
63  val addr = UInt(params.addrBits.W)
64}
65
66class AXILiteWriteData(params: AXIParams) extends AXIBase(params) {
67  val data = UInt(params.dataBits.W)
68  val strb = UInt(params.strbBits.W)
69}
70
71class AXILiteWriteResponse(params: AXIParams) extends AXIBase(params) {
72  val resp = UInt(params.respBits.W)
73}
74
75class AXILiteReadData(params: AXIParams) extends AXIBase(params) {
76  val data = UInt(params.dataBits.W)
77  val resp = UInt(params.respBits.W)
78}
79
80class AXILiteMaster(params: AXIParams) extends AXIBase(params) {
81  val aw = Decoupled(new AXILiteAddress(params))
82  val w = Decoupled(new AXILiteWriteData(params))
83  val b = Flipped(Decoupled(new AXILiteWriteResponse(params)))
84  val ar = Decoupled(new AXILiteAddress(params))
85  val r = Flipped(Decoupled(new AXILiteReadData(params)))
86
87  def tieoff() {
88    aw.valid := false.B
89    aw.bits.addr := 0.U
90    w.valid := false.B
91    w.bits.data := 0.U
92    w.bits.strb := 0.U
93    b.ready := false.B
94    ar.valid := false.B
95    ar.bits.addr := 0.U
96    r.ready := false.B
97  }
98}
99
100class AXILiteClient(params: AXIParams) extends AXIBase(params) {
101  val aw = Flipped(Decoupled(new AXILiteAddress(params)))
102  val w = Flipped(Decoupled(new AXILiteWriteData(params)))
103  val b = Decoupled(new AXILiteWriteResponse(params))
104  val ar = Flipped(Decoupled(new AXILiteAddress(params)))
105  val r = Decoupled(new AXILiteReadData(params))
106
107  def tieoff() {
108    aw.ready := false.B
109    w.ready := false.B
110    b.valid := false.B
111    b.bits.resp := 0.U
112    ar.ready := false.B
113    r.valid := false.B
114    r.bits.resp := 0.U
115    r.bits.data := 0.U
116  }
117}
118
119// AXI extends AXILite
120
121class AXIAddress(params: AXIParams) extends AXILiteAddress(params) {
122  val id = UInt(params.idBits.W)
123  val user = UInt(params.userBits.W)
124  val len = UInt(params.lenBits.W)
125  val size = UInt(params.sizeBits.W)
126  val burst = UInt(params.burstBits.W)
127  val lock = UInt(params.lockBits.W)
128  val cache = UInt(params.cacheBits.W)
129  val prot = UInt(params.protBits.W)
130  val qos = UInt(params.qosBits.W)
131  val region = UInt(params.regionBits.W)
132}
133
134class AXIWriteData(params: AXIParams) extends AXILiteWriteData(params) {
135  val last = Bool()
136  val id = UInt(params.idBits.W)
137  val user = UInt(params.userBits.W)
138}
139
140class AXIWriteResponse(params: AXIParams) extends AXILiteWriteResponse(params) {
141  val id = UInt(params.idBits.W)
142  val user = UInt(params.userBits.W)
143}
144
145class AXIReadData(params: AXIParams) extends AXILiteReadData(params) {
146  val last = Bool()
147  val id = UInt(params.idBits.W)
148  val user = UInt(params.userBits.W)
149}
150
151class AXIMaster(params: AXIParams) extends AXIBase(params) {
152  val aw = Decoupled(new AXIAddress(params))
153  val w = Decoupled(new AXIWriteData(params))
154  val b = Flipped(Decoupled(new AXIWriteResponse(params)))
155  val ar = Decoupled(new AXIAddress(params))
156  val r = Flipped(Decoupled(new AXIReadData(params)))
157
158  def tieoff() {
159    aw.valid := false.B
160    aw.bits.addr := 0.U
161    aw.bits.id := 0.U
162    aw.bits.user := 0.U
163    aw.bits.len := 0.U
164    aw.bits.size := 0.U
165    aw.bits.burst := 0.U
166    aw.bits.lock := 0.U
167    aw.bits.cache := 0.U
168    aw.bits.prot := 0.U
169    aw.bits.qos := 0.U
170    aw.bits.region := 0.U
171    w.valid := false.B
172    w.bits.data := 0.U
173    w.bits.strb := 0.U
174    w.bits.last := false.B
175    w.bits.id := 0.U
176    w.bits.user := 0.U
177    b.ready := false.B
178    ar.valid := false.B
179    ar.bits.addr := 0.U
180    ar.bits.id := 0.U
181    ar.bits.user := 0.U
182    ar.bits.len := 0.U
183    ar.bits.size := 0.U
184    ar.bits.burst := 0.U
185    ar.bits.lock := 0.U
186    ar.bits.cache := 0.U
187    ar.bits.prot := 0.U
188    ar.bits.qos := 0.U
189    ar.bits.region := 0.U
190    r.ready := false.B
191  }
192
193  def setConst() {
194    aw.bits.user := params.userConst.U
195    aw.bits.burst := params.burstConst.U
196    aw.bits.lock := params.lockConst.U
197    aw.bits.cache := params.cacheConst.U
198    aw.bits.prot := params.protConst.U
199    aw.bits.qos := params.qosConst.U
200    aw.bits.region := params.regionConst.U
201    aw.bits.size := params.sizeConst.U
202    aw.bits.id := params.idConst.U
203    w.bits.id := params.idConst.U
204    w.bits.user := params.userConst.U
205    w.bits.strb := Fill(params.strbBits, true.B)
206    ar.bits.user := params.userConst.U
207    ar.bits.burst := params.burstConst.U
208    ar.bits.lock := params.lockConst.U
209    ar.bits.cache := params.cacheConst.U
210    ar.bits.prot := params.protConst.U
211    ar.bits.qos := params.qosConst.U
212    ar.bits.region := params.regionConst.U
213    ar.bits.size := params.sizeConst.U
214    ar.bits.id := params.idConst.U
215  }
216}
217
218class AXIClient(params: AXIParams) extends AXIBase(params) {
219  val aw = Flipped(Decoupled(new AXIAddress(params)))
220  val w = Flipped(Decoupled(new AXIWriteData(params)))
221  val b = Decoupled(new AXIWriteResponse(params))
222  val ar = Flipped(Decoupled(new AXIAddress(params)))
223  val r = Decoupled(new AXIReadData(params))
224
225  def tieoff() {
226    aw.ready := false.B
227    w.ready := false.B
228    b.valid := false.B
229    b.bits.resp := 0.U
230    b.bits.user := 0.U
231    b.bits.id := 0.U
232    ar.ready := false.B
233    r.valid := false.B
234    r.bits.resp := 0.U
235    r.bits.data := 0.U
236    r.bits.user := 0.U
237    r.bits.last := false.B
238    r.bits.id := 0.U
239  }
240}
241
242// XilinxAXILiteClient and XilinxAXIMaster bundles are needed
243// for wrapper purposes, because the package RTL tool in Xilinx Vivado
244// only allows certain name formats
245
246class XilinxAXILiteClient(params: AXIParams) extends AXIBase(params) {
247  val AWVALID = Input(Bool())
248  val AWREADY = Output(Bool())
249  val AWADDR = Input(UInt(params.addrBits.W))
250  val WVALID = Input(Bool())
251  val WREADY = Output(Bool())
252  val WDATA = Input(UInt(params.dataBits.W))
253  val WSTRB = Input(UInt(params.strbBits.W))
254  val BVALID = Output(Bool())
255  val BREADY = Input(Bool())
256  val BRESP = Output(UInt(params.respBits.W))
257  val ARVALID = Input(Bool())
258  val ARREADY = Output(Bool())
259  val ARADDR = Input(UInt(params.addrBits.W))
260  val RVALID = Output(Bool())
261  val RREADY = Input(Bool())
262  val RDATA = Output(UInt(params.dataBits.W))
263  val RRESP = Output(UInt(params.respBits.W))
264}
265
266class XilinxAXIMaster(params: AXIParams) extends AXIBase(params) {
267  val AWVALID = Output(Bool())
268  val AWREADY = Input(Bool())
269  val AWADDR = Output(UInt(params.addrBits.W))
270  val AWID = Output(UInt(params.idBits.W))
271  val AWUSER = Output(UInt(params.userBits.W))
272  val AWLEN = Output(UInt(params.lenBits.W))
273  val AWSIZE = Output(UInt(params.sizeBits.W))
274  val AWBURST = Output(UInt(params.burstBits.W))
275  val AWLOCK = Output(UInt(params.lockBits.W))
276  val AWCACHE = Output(UInt(params.cacheBits.W))
277  val AWPROT = Output(UInt(params.protBits.W))
278  val AWQOS = Output(UInt(params.qosBits.W))
279  val AWREGION = Output(UInt(params.regionBits.W))
280  val WVALID = Output(Bool())
281  val WREADY = Input(Bool())
282  val WDATA = Output(UInt(params.dataBits.W))
283  val WSTRB = Output(UInt(params.strbBits.W))
284  val WLAST = Output(Bool())
285  val WID = Output(UInt(params.idBits.W))
286  val WUSER = Output(UInt(params.userBits.W))
287  val BVALID = Input(Bool())
288  val BREADY = Output(Bool())
289  val BRESP = Input(UInt(params.respBits.W))
290  val BID = Input(UInt(params.idBits.W))
291  val BUSER = Input(UInt(params.userBits.W))
292  val ARVALID = Output(Bool())
293  val ARREADY = Input(Bool())
294  val ARADDR = Output(UInt(params.addrBits.W))
295  val ARID = Output(UInt(params.idBits.W))
296  val ARUSER = Output(UInt(params.userBits.W))
297  val ARLEN = Output(UInt(params.lenBits.W))
298  val ARSIZE = Output(UInt(params.sizeBits.W))
299  val ARBURST = Output(UInt(params.burstBits.W))
300  val ARLOCK = Output(UInt(params.lockBits.W))
301  val ARCACHE = Output(UInt(params.cacheBits.W))
302  val ARPROT = Output(UInt(params.protBits.W))
303  val ARQOS = Output(UInt(params.qosBits.W))
304  val ARREGION = Output(UInt(params.regionBits.W))
305  val RVALID = Input(Bool())
306  val RREADY = Output(Bool())
307  val RDATA = Input(UInt(params.dataBits.W))
308  val RRESP = Input(UInt(params.respBits.W))
309  val RLAST = Input(Bool())
310  val RID = Input(UInt(params.idBits.W))
311  val RUSER = Input(UInt(params.userBits.W))
312}
313