Skip to content

Commit 5bbe407

Browse files
committed
feat: add periph mem access support
1 parent 1bc6f1f commit 5bbe407

File tree

2 files changed

+83
-62
lines changed

2 files changed

+83
-62
lines changed

rtl/tc_l2/src/main/scala/axi4/AXI4Bridge.scala

Lines changed: 70 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,11 @@ class AXI4Bridge() extends Module with AXI4Config {
271271
instTransLen := instTransLen + 1.U
272272
}
273273

274-
protected val memTransLen = RegInit(0.U(8.W))
275-
protected val memTransLenReset = WireDefault(this.reset.asBool() || (wtTrans && wtStateIdle) || (memRdTrans && rdStateIdle))
276-
protected val memAxiLen = Wire(UInt(8.W))
277-
protected val memTransLenIncrEna = WireDefault(
278-
(memTransLen =/= memAxiLen) && (wtHdShk || (rdHdShk && (io.axi.r.bits.id === memAxiId)))
279-
)
274+
protected val memTransLen = RegInit(0.U(8.W))
275+
protected val memTransLenReset = WireDefault(this.reset.asBool() || (wtTrans && wtStateIdle) || (memRdTrans && rdStateIdle))
276+
protected val memAxiLen = Wire(UInt(8.W))
277+
protected val memTransLenIncrEna = WireDefault((memTransLen =/= memAxiLen) && (wtHdShk || (rdHdShk && (io.axi.r.bits.id === memAxiId))))
278+
280279
when(memTransLenReset) {
281280
memTransLen := 0.U
282281
}.elsewhen(memTransLenIncrEna) {
@@ -289,16 +288,17 @@ class AXI4Bridge() extends Module with AXI4Config {
289288
protected val MASK_INST_WIDTH = AxiInstDataWidth * 2
290289
protected val AXI_INST_SIZE = if (SoCEna) 2.U else 3.U // because the flash only support 4 bytes access
291290

292-
protected val ALIGNED_MEM_WIDTH = log2Ceil(AxiDataWidth / 8)
293-
protected val OFFSET_MEM_WIDTH = log2Ceil(AxiDataWidth)
294-
protected val MASK_MEM_WIDTH = AxiDataWidth * 2
295-
296-
protected val TRANS_LEN = 1 // eval: 1
297-
protected val BLOCK_TRANS = false.B
291+
protected val ALIGNED_MEM_WIDTH = log2Ceil(AxiDataWidth / 8)
292+
protected val OFFSET_MEM_WIDTH = log2Ceil(AxiDataWidth)
293+
protected val MASK_MEM_WIDTH = AxiDataWidth * 2
294+
protected val ALIGNED_PERIPH_MEM_WIDTH = log2Ceil(AxiPerifDataWidth / 8)
295+
protected val OFFSET_PERIPH_MEM_WIDTH = log2Ceil(AxiPerifDataWidth)
296+
protected val MASK_PERIPH_MEM_WIDTH = AxiPerifDataWidth * 2
297+
protected val TRANS_LEN = 1
298298

299299
// ================================inst data=======================
300300
// no-aligned visit
301-
protected val instTransAligned = WireDefault(BLOCK_TRANS || io.inst.addr(ALIGNED_INST_WIDTH - 1, 0) === 0.U)
301+
protected val instTransAligned = WireDefault(io.inst.addr(ALIGNED_INST_WIDTH - 1, 0) === 0.U)
302302
protected val instSizeByte = WireDefault(io.inst.size === AXI4Bridge.SIZE_B)
303303
protected val instSizeHalf = WireDefault(io.inst.size === AXI4Bridge.SIZE_H)
304304
protected val instSizeWord = WireDefault(io.inst.size === AXI4Bridge.SIZE_W)
@@ -328,7 +328,7 @@ class AXI4Bridge() extends Module with AXI4Config {
328328
protected val instMask = Wire(UInt(MASK_INST_WIDTH.W))
329329

330330
instAlignedOffsetLow := Cat(OFFSET_INST_WIDTH.U - Fill(ALIGNED_INST_WIDTH, "b0".U(1.W)), io.inst.addr(ALIGNED_INST_WIDTH - 1, 0)) << 3
331-
instAlignedOffsetHig := BusWidth.U - instAlignedOffsetLow
331+
instAlignedOffsetHig := AxiInstDataWidth.U - instAlignedOffsetLow
332332
instMask := (
333333
(Fill(MASK_INST_WIDTH, instSizeByte) & Cat(Fill(8, "b0".U(1.W)), "hff".U(8.W)))
334334
| (Fill(MASK_INST_WIDTH, instSizeHalf) & Cat(Fill(16, "b0".U(1.W)), "hffff".U(16.W)))
@@ -358,13 +358,12 @@ class AXI4Bridge() extends Module with AXI4Config {
358358
io.inst.resp := instResp
359359

360360
// ================================mem data=======================
361-
protected val memTransAligned = WireDefault(BLOCK_TRANS || io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0) === 0.U)
361+
protected val memTransAligned = Wire(Bool())
362362
protected val memSizeByte = WireDefault(io.mem.size === AXI4Bridge.SIZE_B)
363363
protected val memSizeHalf = WireDefault(io.mem.size === AXI4Bridge.SIZE_H)
364364
protected val memSizeWord = WireDefault(io.mem.size === AXI4Bridge.SIZE_W)
365365
protected val memSizeDouble = WireDefault(io.mem.size === AXI4Bridge.SIZE_D)
366-
367-
protected val memAddrOpA = WireDefault(UInt(4.W), Cat(0.U, io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0)))
366+
protected val memAddrOpA = Wire(UInt(4.W))
368367
protected val memAddrOpB = WireDefault(
369368
UInt(4.W),
370369
(Fill(4, memSizeByte) & "b0000".U(4.W))
@@ -373,53 +372,74 @@ class AXI4Bridge() extends Module with AXI4Config {
373372
| (Fill(4, memSizeDouble) & "b0111".U(4.W))
374373
)
375374

376-
protected val memAddrEnd = WireDefault(UInt(4.W), memAddrOpA + memAddrOpB)
377-
protected val memOverstep = WireDefault(memAddrEnd(3, ALIGNED_MEM_WIDTH) =/= 0.U)
375+
protected val memAddrEnd = WireDefault(UInt(4.W), memAddrOpA + memAddrOpB)
376+
protected val memOverstep = Wire(Bool())
377+
protected val memAxiSize = Wire(UInt(3.W))
378+
protected val memAxiAddr = Wire(UInt(AxiAddrWidth.W))
379+
protected val memAlignedOffsetLow = Wire(UInt(OFFSET_MEM_WIDTH.W))
380+
protected val memAlignedOffsetHig = Wire(UInt(OFFSET_MEM_WIDTH.W))
381+
protected val memMask = Wire(UInt(MASK_MEM_WIDTH.W))
382+
protected val memMaskLow = Wire(UInt(AxiDataWidth.W))
383+
protected val memMaskHig = Wire(UInt(AxiDataWidth.W))
384+
protected val memStrb = Wire(UInt((AxiDataWidth / 8).W))
385+
protected val memStrbLow = Wire(UInt((AxiDataWidth / 8).W))
386+
protected val memStrbHig = Wire(UInt((AxiDataWidth / 8).W))
378387

379388
memAxiLen := Mux(memTransAligned.asBool(), (TRANS_LEN - 1).U, Cat(Fill(7, "b0".U(1.W)), memOverstep))
389+
memStrb := (
390+
(Fill(8, memSizeByte) & "b1".U(8.W))
391+
| ((Fill(8, memSizeHalf) & "b11".U(8.W)))
392+
| ((Fill(8, memSizeWord) & "b1111".U(8.W)))
393+
| ((Fill(8, memSizeDouble) & "b1111_1111".U(8.W)))
394+
)
380395

381396
// flash only support 4 bytes rd(0x3000_0000~0x3fff_ffff)
382397
// periph suport 4 bytes w/r(0x1000_0000~0x1000_1fff)
383398
// chiplink suport 4 bytes w/r(0x4000_0000~0x7fff_ffff)
384-
protected val memAxiSize = Wire(UInt(3.W))
385399
when(
386400
(io.mem.addr >= UartBaseAddr && io.mem.addr <= UartBoundAddr) ||
387401
(io.mem.addr >= SpiBaseAddr && io.mem.addr <= SpiBoundAddr) ||
388402
(io.mem.addr >= ChiplinkBaseAddr && io.mem.addr <= ChiplinkBoundAddr)
389403
) {
390-
memAxiSize := 2.U
404+
memTransAligned := io.mem.addr(ALIGNED_PERIPH_MEM_WIDTH - 1, 0) === 0.U
405+
memAddrOpA := Cat(0.U, io.mem.addr(ALIGNED_PERIPH_MEM_WIDTH - 1, 0))
406+
memOverstep := memAddrEnd(3, ALIGNED_PERIPH_MEM_WIDTH) =/= 0.U
407+
memAxiSize := 2.U
408+
memAxiAddr := Cat(io.mem.addr(AxiAddrWidth - 1, ALIGNED_PERIPH_MEM_WIDTH), Fill(ALIGNED_PERIPH_MEM_WIDTH, "b0".U(1.W)))
409+
memAlignedOffsetLow := Cat(OFFSET_PERIPH_MEM_WIDTH.U - Fill(ALIGNED_PERIPH_MEM_WIDTH, "b0".U(1.W)), io.mem.addr(ALIGNED_PERIPH_MEM_WIDTH - 1, 0)) << 3
410+
memAlignedOffsetHig := AxiPerifDataWidth.U - memAlignedOffsetLow
411+
memMask := (
412+
(Fill(MASK_PERIPH_MEM_WIDTH, memSizeByte) & Cat(Fill(8, "b0".U(1.W)), "hff".U(8.W)))
413+
| (Fill(MASK_PERIPH_MEM_WIDTH, memSizeHalf) & Cat(Fill(16, "b0".U(1.W)), "hffff".U(16.W)))
414+
| (Fill(MASK_PERIPH_MEM_WIDTH, memSizeWord) & Cat(Fill(32, "b0".U(1.W)), "hffffffff".U(32.W)))
415+
| (Fill(MASK_PERIPH_MEM_WIDTH, memSizeDouble) & Cat(Fill(64, "b0".U(1.W)), "hffffffff_ffffffff".U(64.W)))
416+
) << memAlignedOffsetLow
417+
418+
memMaskLow := memMask(AxiPerifDataWidth - 1, 0)
419+
memMaskHig := memMask(MASK_PERIPH_MEM_WIDTH - 1, AxiPerifDataWidth)
420+
memStrbLow := memStrb << io.mem.addr(ALIGNED_PERIPH_MEM_WIDTH - 1, 0)
421+
memStrbHig := memStrb >> (AxiPerifDataWidth / 8).U - io.mem.addr(ALIGNED_PERIPH_MEM_WIDTH - 1, 0)
391422
}.otherwise {
392-
memAxiSize := 3.U
423+
memTransAligned := io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0) === 0.U
424+
memAddrOpA := Cat(0.U, io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0))
425+
memOverstep := memAddrEnd(3, ALIGNED_MEM_WIDTH) =/= 0.U
426+
memAxiSize := 3.U
427+
memAxiAddr := Cat(io.mem.addr(AxiAddrWidth - 1, ALIGNED_MEM_WIDTH), Fill(ALIGNED_MEM_WIDTH, "b0".U(1.W)))
428+
memAlignedOffsetLow := Cat(OFFSET_MEM_WIDTH.U - Fill(ALIGNED_MEM_WIDTH, "b0".U(1.W)), io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0)) << 3
429+
memAlignedOffsetHig := AxiDataWidth.U - memAlignedOffsetLow
430+
memMask := (
431+
(Fill(MASK_MEM_WIDTH, memSizeByte) & Cat(Fill(8, "b0".U(1.W)), "hff".U(8.W)))
432+
| (Fill(MASK_MEM_WIDTH, memSizeHalf) & Cat(Fill(16, "b0".U(1.W)), "hffff".U(16.W)))
433+
| (Fill(MASK_MEM_WIDTH, memSizeWord) & Cat(Fill(32, "b0".U(1.W)), "hffffffff".U(32.W)))
434+
| (Fill(MASK_MEM_WIDTH, memSizeDouble) & Cat(Fill(64, "b0".U(1.W)), "hffffffff_ffffffff".U(64.W)))
435+
) << memAlignedOffsetLow
436+
437+
memMaskLow := memMask(AxiDataWidth - 1, 0)
438+
memMaskHig := memMask(MASK_MEM_WIDTH - 1, AxiDataWidth)
439+
memStrbLow := memStrb << io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0)
440+
memStrbHig := memStrb >> ((AxiDataWidth / 8).U - io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0))
393441
}
394442

395-
protected val memAxiAddr = Cat(io.mem.addr(AxiAddrWidth - 1, ALIGNED_MEM_WIDTH), Fill(ALIGNED_MEM_WIDTH, "b0".U(1.W)))
396-
protected val memAlignedOffsetLow = Wire(UInt(OFFSET_MEM_WIDTH.W))
397-
protected val memAlignedOffsetHig = Wire(UInt(OFFSET_MEM_WIDTH.W))
398-
protected val memMask = Wire(UInt(MASK_MEM_WIDTH.W))
399-
400-
memAlignedOffsetLow := Cat(OFFSET_MEM_WIDTH.U - Fill(ALIGNED_MEM_WIDTH, "b0".U(1.W)), io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0)) << 3
401-
memAlignedOffsetHig := BusWidth.U - memAlignedOffsetLow
402-
memMask := (
403-
(Fill(MASK_MEM_WIDTH, memSizeByte) & Cat(Fill(8, "b0".U(1.W)), "hff".U(8.W)))
404-
| (Fill(MASK_MEM_WIDTH, memSizeHalf) & Cat(Fill(16, "b0".U(1.W)), "hffff".U(16.W)))
405-
| (Fill(MASK_MEM_WIDTH, memSizeWord) & Cat(Fill(32, "b0".U(1.W)), "hffffffff".U(32.W)))
406-
| (Fill(MASK_MEM_WIDTH, memSizeDouble) & Cat(Fill(64, "b0".U(1.W)), "hffffffff_ffffffff".U(64.W)))
407-
) << memAlignedOffsetLow
408-
409-
protected val memMaskLow = memMask(AxiDataWidth - 1, 0)
410-
protected val memMaskHig = memMask(MASK_MEM_WIDTH - 1, AxiDataWidth)
411-
protected val memStrb = Wire(UInt((AxiDataWidth / 8).W))
412-
413-
memStrb := (
414-
(Fill(8, memSizeByte) & "b1".U(8.W))
415-
| ((Fill(8, memSizeHalf) & "b11".U(8.W)))
416-
| ((Fill(8, memSizeWord) & "b1111".U(8.W)))
417-
| ((Fill(8, memSizeDouble) & "b1111_1111".U(8.W)))
418-
)
419-
420-
protected val memStrbLow = WireDefault(UInt((AxiDataWidth / 8).W), memStrb << io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0))
421-
protected val memStrbHig = WireDefault(UInt((AxiDataWidth / 8).W), memStrb >> ((AxiDataWidth / 8).U - io.mem.addr(ALIGNED_MEM_WIDTH - 1, 0)))
422-
423443
protected val memAxiUser = Fill(AxiUserLen, "b0".U(1.W))
424444
protected val memReady = RegInit(false.B)
425445
protected val memReadyNxt = WireDefault(memTransDone)

rtl/tc_l2/src/main/scala/common/AXI4Config.scala

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@ trait AXI4Config extends InstConfig {
99
val AxiReqWt = 1
1010
val AxiReqNop = 2
1111

12-
val AxiDataWidth = 64
13-
val AxiInstDataWidth = if (SoCEna) 32 else 64
14-
val AxiAddrWidth = 32 // FIME: is right? the original val is 64
15-
val AxiProtLen = 3
16-
val AxiIdLen = 4
17-
val AxiUserLen = 1
18-
val AxiSizeLen = 2
19-
val AxiBurstLen = 2
20-
val AxiCacheLen = 4
21-
val AxiQosLen = 4
22-
val AxiRegionLen = 4
23-
val AxiRespLen = 2
12+
val AxiDataWidth = 64
13+
val AxiInstDataWidth = if (SoCEna) 32 else 64
14+
val AxiPerifDataWidth = 32
15+
val AxiAddrWidth = 32 // FIME: is right? the original val is 64
16+
val AxiProtLen = 3
17+
val AxiIdLen = 4
18+
val AxiUserLen = 1
19+
val AxiSizeLen = 2
20+
val AxiBurstLen = 2
21+
val AxiCacheLen = 4
22+
val AxiQosLen = 4
23+
val AxiRegionLen = 4
24+
val AxiRespLen = 2
2425
}

0 commit comments

Comments
 (0)