From 19851a7c9eaf9f06cbfbe0232730448465402040 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 19:38:45 -0700 Subject: [PATCH 1/9] apb: SRAM reports errors on illegal access --- src/main/scala/amba/apb/SRAM.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/amba/apb/SRAM.scala b/src/main/scala/amba/apb/SRAM.scala index 57babb9c..e74fb9a2 100644 --- a/src/main/scala/amba/apb/SRAM.scala +++ b/src/main/scala/amba/apb/SRAM.scala @@ -32,17 +32,18 @@ class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4 if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail) val mask = bigBits(address.mask >> log2Ceil(beatBytes)) val paddr = Cat((mask zip (in.paddr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse) + val legal = address.contains(in.paddr) // Use single-ported memory with byte-write enable val mem = SeqMem(1 << mask.filter(b=>b).size, Vec(beatBytes, Bits(width = 8))) val read = in.psel && !in.penable && !in.pwrite - when (in.psel && !in.penable && in.pwrite) { + when (in.psel && !in.penable && in.pwrite && legal) { mem.write(paddr, Vec.tabulate(beatBytes) { i => in.pwdata(8*(i+1)-1, 8*i) }, in.pstrb.toBools) } in.pready := Bool(true) - in.pslverr := Bool(false) + in.pslverr := RegNext(!legal) in.prdata := mem.readAndHold(paddr, read).asUInt } } From f1fb3be603e11e527b6137e6e0d811f4edd7de01 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 19:39:03 -0700 Subject: [PATCH 2/9] ahb: SRAM reports errors on illegal access --- src/main/scala/amba/ahb/SRAM.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/scala/amba/ahb/SRAM.scala b/src/main/scala/amba/ahb/SRAM.scala index 74e546dc..560cc016 100644 --- a/src/main/scala/amba/ahb/SRAM.scala +++ b/src/main/scala/amba/ahb/SRAM.scala @@ -38,6 +38,7 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4 val a_mask = MaskGen(in.haddr, in.hsize, beatBytes) val a_address = Cat((mask zip (in.haddr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse) val a_write = in.hwrite + val a_legal = address.contains(in.haddr) // The data phase signals val d_wdata = Vec.tabulate(beatBytes) { i => in.hwdata(8*(i+1)-1, 8*i) } @@ -67,6 +68,7 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4 val read = a_request && !a_write // In case we choose to stall, we need to hold the read data val d_rdata = mem.readAndHold(a_address, read) + val d_legal = RegEnable(a_legal, in.hreadyout) // Whenever the port is not needed for reading, execute pending writes when (!read && p_valid) { p_valid := Bool(false) @@ -75,7 +77,7 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4 // Record the request for later? p_latch_d := a_request && a_write - when (a_request && a_write) { + when (a_request && a_write && a_legal) { p_valid := Bool(true) p_address := a_address p_mask := a_mask @@ -96,7 +98,7 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4 // Finally, the outputs in.hreadyout := (if(fuzzHreadyout) { !d_request || LFSR16(Bool(true))(0) } else { Bool(true) }) - in.hresp := AHBParameters.RESP_OKAY + in.hresp := Mux(d_legal || !in.hreadyout, AHBParameters.RESP_OKAY, AHBParameters.RESP_ERROR) in.hrdata := Mux(in.hreadyout, muxdata.asUInt, UInt(0)) } } From e8cb6dafd359572c4a52d75292f37c3b87c3b4e5 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 21:04:05 -0700 Subject: [PATCH 3/9] tilelink: SRAM reports errors on illegal access --- src/main/scala/tilelink/SRAM.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/tilelink/SRAM.scala b/src/main/scala/tilelink/SRAM.scala index 310845b6..38d2184e 100644 --- a/src/main/scala/tilelink/SRAM.scala +++ b/src/main/scala/tilelink/SRAM.scala @@ -43,6 +43,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, val edge = node.edgesIn(0) val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2) + val a_legal = address.contains(in.a.bits.address) val memAddress = Cat(addrBits.reverse) val mem = SeqMem(1 << addrBits.size, Vec(beatBytes, Bits(width = 8))) @@ -52,6 +53,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, val d_source = Reg(UInt()) val d_addr = Reg(UInt()) val d_data = Wire(UInt()) + val d_legal = Reg(Bool()) // Flow control when (in.d.fire()) { d_full := Bool(false) } @@ -59,7 +61,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, in.d.valid := d_full in.a.ready := in.d.ready || !d_full - in.d.bits := edge.AccessAck(d_addr, UInt(0), d_source, d_size) + in.d.bits := edge.AccessAck(d_addr, UInt(0), d_source, d_size, !d_legal) // avoid data-bus Mux in.d.bits.data := d_data in.d.bits.opcode := Mux(d_read, TLMessages.AccessAckData, TLMessages.AccessAck) @@ -73,10 +75,11 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, d_size := in.a.bits.size d_source := in.a.bits.source d_addr := edge.addr_lo(in.a.bits) + d_legal := a_legal } // exactly this pattern is required to get a RWM memory - when (in.a.fire() && !read) { + when (in.a.fire() && !read && a_legal) { mem.write(memAddress, wdata, in.a.bits.mask.toBools) } val ren = in.a.fire() && read From b2cc4b99ed57556ff0c5d024ef1fbc7f71018061 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 21:13:07 -0700 Subject: [PATCH 4/9] tilelink: TestSRAM reports errors on illegal access --- src/main/scala/devices/tilelink/TestRAM.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/tilelink/TestRAM.scala b/src/main/scala/devices/tilelink/TestRAM.scala index 38a18260..d6d27edb 100644 --- a/src/main/scala/devices/tilelink/TestRAM.scala +++ b/src/main/scala/devices/tilelink/TestRAM.scala @@ -49,12 +49,13 @@ class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int in.d.valid := in.a.valid val hasData = edge.hasData(in.a.bits) + val legal = address.contains(in.a.bits.address) val wdata = Vec.tabulate(beatBytes) { i => in.a.bits.data(8*(i+1)-1, 8*i) } - in.d.bits := edge.AccessAck(in.a.bits, UInt(0)) + in.d.bits := edge.AccessAck(in.a.bits, UInt(0), !legal) in.d.bits.data := Cat(mem(memAddress).reverse) in.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData) - when (in.a.fire() && hasData) { mem.write(memAddress, wdata, in.a.bits.mask.toBools) } + when (in.a.fire() && hasData && legal) { mem.write(memAddress, wdata, in.a.bits.mask.toBools) } // Tie off unused channels in.b.valid := Bool(false) From df44b23956007162db32719446c3ca1f598354cb Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 21:07:08 -0700 Subject: [PATCH 5/9] axi4: SRAM can emulate incompletely populated memory --- src/main/scala/amba/axi4/SRAM.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/amba/axi4/SRAM.scala b/src/main/scala/amba/axi4/SRAM.scala index 72e580c1..680c0098 100644 --- a/src/main/scala/amba/axi4/SRAM.scala +++ b/src/main/scala/amba/axi4/SRAM.scala @@ -7,11 +7,11 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule +class AXI4RAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, errors: Seq[AddressSet] = Nil)(implicit p: Parameters) extends LazyModule { val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters( Seq(AXI4SlaveParameters( - address = List(address), + address = List(address) ++ errors, regionType = RegionType.UNCACHED, executable = executable, supportsRead = TransferSizes(1, beatBytes), From 28fbf1af8e84ba4d8825fe82d05cf4fea93afe87 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 21:07:58 -0700 Subject: [PATCH 6/9] ahb: SRAM can emulate incompletely populated memory --- src/main/scala/amba/ahb/SRAM.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/amba/ahb/SRAM.scala b/src/main/scala/amba/ahb/SRAM.scala index 560cc016..ff8b93fa 100644 --- a/src/main/scala/amba/ahb/SRAM.scala +++ b/src/main/scala/amba/ahb/SRAM.scala @@ -7,11 +7,11 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, fuzzHreadyout: Boolean = false)(implicit p: Parameters) extends LazyModule +class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, fuzzHreadyout: Boolean = false, errors: Seq[AddressSet] = Nil)(implicit p: Parameters) extends LazyModule { val node = AHBSlaveNode(Seq(AHBSlavePortParameters( Seq(AHBSlaveParameters( - address = List(address), + address = List(address) ++ errors, regionType = RegionType.UNCACHED, executable = executable, supportsRead = TransferSizes(1, beatBytes * AHBParameters.maxTransfer), From 9310a33e77285bafe5f58a9777691566dc7e14f9 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 21:08:07 -0700 Subject: [PATCH 7/9] apb: SRAM can emulate incompletely populated memory --- src/main/scala/amba/apb/SRAM.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/amba/apb/SRAM.scala b/src/main/scala/amba/apb/SRAM.scala index e74fb9a2..59e26dc5 100644 --- a/src/main/scala/amba/apb/SRAM.scala +++ b/src/main/scala/amba/apb/SRAM.scala @@ -7,11 +7,11 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule +class APBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, errors: Seq[AddressSet] = Nil)(implicit p: Parameters) extends LazyModule { val node = APBSlaveNode(Seq(APBSlavePortParameters( Seq(APBSlaveParameters( - address = List(address), + address = List(address) ++ errors, regionType = RegionType.UNCACHED, executable = executable, supportsRead = true, From 702143eb33234e4bc1278f71699c48a7803880e8 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 21:08:14 -0700 Subject: [PATCH 8/9] tilelink: SRAM can emulate incompletely populated memory --- src/main/scala/tilelink/SRAM.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/tilelink/SRAM.scala b/src/main/scala/tilelink/SRAM.scala index 38d2184e..774b337d 100644 --- a/src/main/scala/tilelink/SRAM.scala +++ b/src/main/scala/tilelink/SRAM.scala @@ -8,14 +8,14 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.util._ -class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, name: Option[String] = None)(implicit p: Parameters) extends LazyModule +class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, name: Option[String] = None, errors: Seq[AddressSet] = Nil)(implicit p: Parameters) extends LazyModule { private val resources = name.map(new SimpleDevice(_, Seq("sifive,sram0")).reg("mem")).getOrElse(new MemoryDevice().reg) val node = TLManagerNode(Seq(TLManagerPortParameters( Seq(TLManagerParameters( - address = List(address), + address = List(address) ++ errors, resources = resources, regionType = RegionType.UNCACHED, executable = executable, From 5db0e770d5ab8476dbd2dcad77465a585e1e4774 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 7 Jul 2017 21:13:48 -0700 Subject: [PATCH 9/9] tilelink: TestSRAM can emulate incompletely populated memory --- src/main/scala/devices/tilelink/TestRAM.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/devices/tilelink/TestRAM.scala b/src/main/scala/devices/tilelink/TestRAM.scala index d6d27edb..a64f0734 100644 --- a/src/main/scala/devices/tilelink/TestRAM.scala +++ b/src/main/scala/devices/tilelink/TestRAM.scala @@ -9,13 +9,13 @@ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ // Do not use this for synthesis! Only for simulation. -class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)(implicit p: Parameters) extends LazyModule +class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4, errors: Seq[AddressSet] = Nil)(implicit p: Parameters) extends LazyModule { val device = new MemoryDevice val node = TLManagerNode(Seq(TLManagerPortParameters( Seq(TLManagerParameters( - address = List(address), + address = List(address) ++ errors, resources = device.reg, regionType = RegionType.UNCACHED, executable = executable,