Skip to content

Commit 236afeb

Browse files
committed
Merge branch 'tc-l3' into dev
2 parents 9de3bb8 + 4446534 commit 236afeb

File tree

3 files changed

+517
-28
lines changed

3 files changed

+517
-28
lines changed
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
package treecorel3
2+
3+
import chisel._
4+
import chisel.uitl._
5+
6+
trait HasAxiParameters {
7+
implicit val p: Parameters
8+
val axiExternal = p(AxiKey)
9+
val axiXDataBits = axiExternal.dataBits
10+
val axiWStrobeBits = axiXDataBits / 8
11+
val axiXAddrBits = axiExternal.addrBits
12+
val axiWIdBits = axiExternal.idBits
13+
val axiRIdBits = axiExternal.idBits
14+
val axiXIdBits = max(axiWIdBits, axiRIdBits)
15+
val axiXUserBits = 1
16+
val axiAWUserBits = axiXUserBits
17+
val axiWUserBits = axiXUserBits
18+
val axiBUserBits = axiXUserBits
19+
val axiARUserBits = axiXUserBits
20+
val axiRUserBits = axiXUserBits
21+
val axiXLenBits = 8
22+
val axiXSizeBits = 3
23+
val axiXBurstBits = 2
24+
val axiXCacheBits = 4
25+
val axiXProtBits = 3
26+
val axiXQosBits = 4
27+
val axiXRegionBits = 4
28+
val axiXRespBits = 2
29+
30+
def bytesToXSize(bytes: UInt) = MuxLookup(
31+
bytes,
32+
UInt("b111"),
33+
Array(UInt(1) -> UInt(0), UInt(2) -> UInt(1), UInt(4) -> UInt(2), UInt(8) -> UInt(3), UInt(16) -> UInt(4), UInt(32) -> UInt(5), UInt(64) -> UInt(6), UInt(128) -> UInt(7))
34+
)
35+
}
36+
37+
abstract class AxiModule(implicit val p: Parameters) extends Module with HasAxiParameters
38+
abstract class AxiBundle(implicit val p: Parameters) extends Bundle with HasAxiParameters
39+
40+
abstract class AxiChannel(implicit p: Parameters) extends AxiBundle()(p)
41+
abstract class AxiMasterToSlaveChannel(implicit p: Parameters) extends AxiChannel()(p)
42+
abstract class AxiSlaveToMasterChannel(implicit p: Parameters) extends AxiChannel()(p)
43+
44+
trait HasAxiMetadata extends HasAxiParameters {
45+
val addr = UInt(width = axiXAddrBits)
46+
val len = UInt(width = axiXLenBits)
47+
val size = UInt(width = axiXSizeBits)
48+
val burst = UInt(width = axiXBurstBits)
49+
val lock = Bool()
50+
val cache = UInt(width = axiXCacheBits)
51+
val prot = UInt(width = axiXProtBits)
52+
val qos = UInt(width = axiXQosBits)
53+
val region = UInt(width = axiXRegionBits)
54+
}
55+
56+
trait HasAxiData extends HasAxiParameters {
57+
val data = UInt(width = axiXDataBits)
58+
val last = Bool()
59+
}
60+
61+
class AxiReadIO(implicit val p: Parameters) extends Bundle {
62+
val ar = Decoupled(new AxiReadAddressChannel)
63+
val r = Decoupled(new AxiReadDataChannel).flip
64+
}
65+
66+
class AxiWriteIO(implicit val p: Parameters) extends Bundle {
67+
val aw = Decoupled(new AxiWriteAddressChannel)
68+
val w = Decoupled(new AxiWriteDataChannel)
69+
val b = Decoupled(new AxiWriteResponseChannel).flip
70+
}
71+
72+
class AxiIO(implicit val p: Parameters) extends Bundle {
73+
val aw = Decoupled(new AxiWriteAddressChannel)
74+
val w = Decoupled(new AxiWriteDataChannel)
75+
val b = Decoupled(new AxiWriteResponseChannel).flip
76+
val ar = Decoupled(new AxiReadAddressChannel)
77+
val r = Decoupled(new AxiReadDataChannel).flip
78+
}
79+
80+
class AxiAddressChannel(implicit p: Parameters) extends AxiMasterToSlaveChannel()(p) with HasAxiMetadata
81+
82+
class AxiResponseChannel(implicit p: Parameters) extends AxiSlaveToMasterChannel()(p) {
83+
val resp = UInt(width = axiXRespBits)
84+
}
85+
86+
class AxiWriteAddressChannel(implicit p: Parameters) extends AxiAddressChannel()(p) {
87+
val id = UInt(width = axiWIdBits)
88+
val user = UInt(width = axiAWUserBits)
89+
}
90+
91+
class AxiWriteDataChannel(implicit p: Parameters) extends AxiMasterToSlaveChannel()(p) with HasAxiData {
92+
val id = UInt(width = axiWIdBits)
93+
val strb = UInt(width = axiWStrobeBits)
94+
val user = UInt(width = axiWUserBits)
95+
}
96+
97+
class AxiWriteResponseChannel(implicit p: Parameters) extends AxiResponseChannel()(p) {
98+
val id = UInt(width = axiWIdBits)
99+
val user = UInt(width = axiBUserBits)
100+
}
101+
102+
class AxiReadAddressChannel(implicit p: Parameters) extends AxiAddressChannel()(p) {
103+
val id = UInt(width = axiRIdBits)
104+
val user = UInt(width = axiARUserBits)
105+
}
106+
107+
class AxiReadDataChannel(implicit p: Parameters) extends AxiResponseChannel()(p) with HasAxiData {
108+
val id = UInt(width = axiRIdBits)
109+
val user = UInt(width = axiRUserBits)
110+
}
111+
112+
object AxiConstants {
113+
def BURST_FIXED = UInt("b00")
114+
def BURST_INCR = UInt("b01")
115+
def BURST_WRAP = UInt("b10")
116+
117+
def RESP_OKAY = UInt("b00")
118+
def RESP_EXOKAY = UInt("b01")
119+
def RESP_SLVERR = UInt("b10")
120+
def RESP_DECERR = UInt("b11")
121+
122+
def CACHE_DEVICE_NOBUF = UInt("b0000")
123+
def CACHE_DEVICE_BUF = UInt("b0001")
124+
def CACHE_NORMAL_NOCACHE_NOBUF = UInt("b0010")
125+
def CACHE_NORMAL_NOCACHE_BUF = UInt("b0011")
126+
127+
def AXPROT(instruction: Bool, nonsecure: Bool, privileged: Bool): UInt =
128+
Cat(instruction, nonsecure, privileged)
129+
130+
def AXPROT(instruction: Boolean, nonsecure: Boolean, privileged: Boolean): UInt =
131+
AXPROT(Bool(instruction), Bool(nonsecure), Bool(privileged))
132+
}
133+
134+
import AxiConstants._
135+
136+
object AxiWriteAddressChannel {
137+
def apply(id: UInt, addr: UInt, size: UInt, len: UInt = UInt(0), burst: UInt = BURST_INCR)(implicit p: Parameters) = {
138+
val aw = Wire(new AxiWriteAddressChannel)
139+
aw.id := id
140+
aw.addr := addr
141+
aw.len := len
142+
aw.size := size
143+
aw.burst := burst
144+
aw.lock := Bool(false)
145+
aw.cache := CACHE_DEVICE_NOBUF
146+
aw.prot := AXPROT(false, false, false)
147+
aw.qos := UInt("b0000")
148+
aw.region := UInt("b0000")
149+
aw.user := UInt(0)
150+
aw
151+
}
152+
}
153+
154+
object AxiReadAddressChannel {
155+
def apply(id: UInt, addr: UInt, size: UInt, len: UInt = UInt(0), burst: UInt = BURST_INCR)(implicit p: Parameters) = {
156+
val ar = Wire(new AxiReadAddressChannel)
157+
ar.id := id
158+
ar.addr := addr
159+
ar.len := len
160+
ar.size := size
161+
ar.burst := burst
162+
ar.lock := Bool(false)
163+
ar.cache := CACHE_DEVICE_NOBUF
164+
ar.prot := AXPROT(false, false, false)
165+
ar.qos := UInt(0)
166+
ar.region := UInt(0)
167+
ar.user := UInt(0)
168+
ar
169+
}
170+
}
171+
172+
object AxiWriteDataChannel {
173+
def apply(data: UInt, strb: Option[UInt] = None, last: Bool = Bool(true), id: UInt = UInt(0))(implicit p: Parameters): AxiWriteDataChannel = {
174+
val w = Wire(new AxiWriteDataChannel)
175+
w.strb := strb.getOrElse(Fill(w.axiWStrobeBits, UInt(1, 1)))
176+
w.data := data
177+
w.last := last
178+
w.id := id
179+
w.user := UInt(0)
180+
w
181+
}
182+
}
183+
184+
object AxiReadDataChannel {
185+
def apply(
186+
id: UInt,
187+
data: UInt,
188+
last: Bool = Bool(true),
189+
resp: UInt = UInt(0)
190+
)(
191+
implicit p: Parameters
192+
) = {
193+
val r = Wire(new AxiReadDataChannel)
194+
r.id := id
195+
r.data := data
196+
r.last := last
197+
r.resp := resp
198+
r.user := UInt(0)
199+
r
200+
}
201+
}
202+
203+
object AxiWriteResponseChannel {
204+
def apply(id: UInt, resp: UInt = UInt(0))(implicit p: Parameters) = {
205+
val b = Wire(new AxiWriteResponseChannel)
206+
b.id := id
207+
b.resp := resp
208+
b.user := UInt(0)
209+
b
210+
}
211+
}
212+
213+
class AxiArbiterIO(arbN: Int)(implicit p: Parameters) extends Bundle {
214+
val master = Vec(arbN, new AxiIO).flip
215+
val slave = new AxiIO
216+
override def cloneType =
217+
new AxiArbiterIO(arbN).asInstanceOf[this.type]
218+
}
219+
220+
/** Arbitrate among arbN masters requesting to a single slave */
221+
class AxiArbiter(val arbN: Int)(implicit p: Parameters) extends AxiModule {
222+
val io = new AxiArbiterIO(arbN)
223+
224+
if (arbN > 1) {
225+
val arbIdBits = log2Up(arbN)
226+
227+
val ar_arb = Module(new RRArbiter(new AxiReadAddressChannel, arbN))
228+
val aw_arb = Module(new RRArbiter(new AxiWriteAddressChannel, arbN))
229+
230+
val slave_r_arb_id = io.slave.r.bits.id(arbIdBits - 1, 0)
231+
val slave_b_arb_id = io.slave.b.bits.id(arbIdBits - 1, 0)
232+
233+
val w_chosen = Reg(UInt(width = arbIdBits))
234+
val w_done = Reg(init = Bool(true))
235+
236+
when(aw_arb.io.out.fire()) {
237+
w_chosen := aw_arb.io.chosen
238+
w_done := Bool(false)
239+
}
240+
241+
when(io.slave.w.fire() && io.slave.w.bits.last) {
242+
w_done := Bool(true)
243+
}
244+
245+
for (i <- 0 until arbN) {
246+
val m_ar = io.master(i).ar
247+
val m_aw = io.master(i).aw
248+
val m_r = io.master(i).r
249+
val m_b = io.master(i).b
250+
val a_ar = ar_arb.io.in(i)
251+
val a_aw = aw_arb.io.in(i)
252+
val m_w = io.master(i).w
253+
254+
a_ar <> m_ar
255+
a_ar.bits.id := Cat(m_ar.bits.id, UInt(i, arbIdBits))
256+
257+
a_aw <> m_aw
258+
a_aw.bits.id := Cat(m_aw.bits.id, UInt(i, arbIdBits))
259+
260+
m_r.valid := io.slave.r.valid && slave_r_arb_id === UInt(i)
261+
m_r.bits := io.slave.r.bits
262+
m_r.bits.id := io.slave.r.bits.id >> UInt(arbIdBits)
263+
264+
m_b.valid := io.slave.b.valid && slave_b_arb_id === UInt(i)
265+
m_b.bits := io.slave.b.bits
266+
m_b.bits.id := io.slave.b.bits.id >> UInt(arbIdBits)
267+
268+
m_w.ready := io.slave.w.ready && w_chosen === UInt(i) && !w_done
269+
}
270+
271+
io.slave.r.ready := io.master(slave_r_arb_id).r.ready
272+
io.slave.b.ready := io.master(slave_b_arb_id).b.ready
273+
274+
io.slave.w.bits := io.master(w_chosen).w.bits
275+
io.slave.w.valid := io.master(w_chosen).w.valid && !w_done
276+
277+
io.slave.ar <> ar_arb.io.out
278+
279+
io.slave.aw.bits <> aw_arb.io.out.bits
280+
io.slave.aw.valid := aw_arb.io.out.valid && w_done
281+
aw_arb.io.out.ready := io.slave.aw.ready && w_done
282+
283+
} else {
284+
io.slave <> io.master.head
285+
}
286+
}

0 commit comments

Comments
 (0)