1
0

Merge pull request #853 from freechipsproject/sram-errors

SRAM errors
This commit is contained in:
Wesley W. Terpstra 2017-07-07 22:44:28 -07:00 committed by GitHub
commit 29f5f77817
5 changed files with 25 additions and 18 deletions

View File

@ -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),
@ -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))
}
}

View File

@ -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,
@ -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
}
}

View File

@ -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),

View File

@ -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,
@ -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)

View File

@ -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,
@ -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