commit
29f5f77817
@ -7,11 +7,11 @@ import freechips.rocketchip.config.Parameters
|
|||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.util._
|
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(
|
val node = AHBSlaveNode(Seq(AHBSlavePortParameters(
|
||||||
Seq(AHBSlaveParameters(
|
Seq(AHBSlaveParameters(
|
||||||
address = List(address),
|
address = List(address) ++ errors,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
supportsRead = TransferSizes(1, beatBytes * AHBParameters.maxTransfer),
|
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_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_address = Cat((mask zip (in.haddr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse)
|
||||||
val a_write = in.hwrite
|
val a_write = in.hwrite
|
||||||
|
val a_legal = address.contains(in.haddr)
|
||||||
|
|
||||||
// The data phase signals
|
// The data phase signals
|
||||||
val d_wdata = Vec.tabulate(beatBytes) { i => in.hwdata(8*(i+1)-1, 8*i) }
|
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
|
val read = a_request && !a_write
|
||||||
// In case we choose to stall, we need to hold the read data
|
// In case we choose to stall, we need to hold the read data
|
||||||
val d_rdata = mem.readAndHold(a_address, read)
|
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
|
// Whenever the port is not needed for reading, execute pending writes
|
||||||
when (!read && p_valid) {
|
when (!read && p_valid) {
|
||||||
p_valid := Bool(false)
|
p_valid := Bool(false)
|
||||||
@ -75,7 +77,7 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4
|
|||||||
|
|
||||||
// Record the request for later?
|
// Record the request for later?
|
||||||
p_latch_d := a_request && a_write
|
p_latch_d := a_request && a_write
|
||||||
when (a_request && a_write) {
|
when (a_request && a_write && a_legal) {
|
||||||
p_valid := Bool(true)
|
p_valid := Bool(true)
|
||||||
p_address := a_address
|
p_address := a_address
|
||||||
p_mask := a_mask
|
p_mask := a_mask
|
||||||
@ -96,7 +98,7 @@ class AHBRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4
|
|||||||
|
|
||||||
// Finally, the outputs
|
// Finally, the outputs
|
||||||
in.hreadyout := (if(fuzzHreadyout) { !d_request || LFSR16(Bool(true))(0) } else { Bool(true) })
|
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))
|
in.hrdata := Mux(in.hreadyout, muxdata.asUInt, UInt(0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,11 @@ import freechips.rocketchip.config.Parameters
|
|||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.util._
|
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(
|
val node = APBSlaveNode(Seq(APBSlavePortParameters(
|
||||||
Seq(APBSlaveParameters(
|
Seq(APBSlaveParameters(
|
||||||
address = List(address),
|
address = List(address) ++ errors,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
supportsRead = true,
|
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)
|
if (x == 0) tail.reverse else bigBits(x >> 1, ((x & 1) == 1) :: tail)
|
||||||
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
||||||
val paddr = Cat((mask zip (in.paddr >> log2Ceil(beatBytes)).toBools).filter(_._1).map(_._2).reverse)
|
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
|
// Use single-ported memory with byte-write enable
|
||||||
val mem = SeqMem(1 << mask.filter(b=>b).size, Vec(beatBytes, Bits(width = 8)))
|
val mem = SeqMem(1 << mask.filter(b=>b).size, Vec(beatBytes, Bits(width = 8)))
|
||||||
|
|
||||||
val read = in.psel && !in.penable && !in.pwrite
|
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)
|
mem.write(paddr, Vec.tabulate(beatBytes) { i => in.pwdata(8*(i+1)-1, 8*i) }, in.pstrb.toBools)
|
||||||
}
|
}
|
||||||
|
|
||||||
in.pready := Bool(true)
|
in.pready := Bool(true)
|
||||||
in.pslverr := Bool(false)
|
in.pslverr := RegNext(!legal)
|
||||||
in.prdata := mem.readAndHold(paddr, read).asUInt
|
in.prdata := mem.readAndHold(paddr, read).asUInt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,11 @@ import freechips.rocketchip.config.Parameters
|
|||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.util._
|
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(
|
val node = AXI4SlaveNode(Seq(AXI4SlavePortParameters(
|
||||||
Seq(AXI4SlaveParameters(
|
Seq(AXI4SlaveParameters(
|
||||||
address = List(address),
|
address = List(address) ++ errors,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
supportsRead = TransferSizes(1, beatBytes),
|
supportsRead = TransferSizes(1, beatBytes),
|
||||||
|
@ -9,13 +9,13 @@ import freechips.rocketchip.tilelink._
|
|||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
// Do not use this for synthesis! Only for simulation.
|
// 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 device = new MemoryDevice
|
||||||
|
|
||||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
Seq(TLManagerParameters(
|
Seq(TLManagerParameters(
|
||||||
address = List(address),
|
address = List(address) ++ errors,
|
||||||
resources = device.reg,
|
resources = device.reg,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
@ -49,12 +49,13 @@ class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int
|
|||||||
in.d.valid := in.a.valid
|
in.d.valid := in.a.valid
|
||||||
|
|
||||||
val hasData = edge.hasData(in.a.bits)
|
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) }
|
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.data := Cat(mem(memAddress).reverse)
|
||||||
in.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData)
|
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
|
// Tie off unused channels
|
||||||
in.b.valid := Bool(false)
|
in.b.valid := Bool(false)
|
||||||
|
@ -8,14 +8,14 @@ import freechips.rocketchip.config.Parameters
|
|||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.util._
|
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 =
|
private val resources =
|
||||||
name.map(new SimpleDevice(_, Seq("sifive,sram0")).reg("mem")).getOrElse(new MemoryDevice().reg)
|
name.map(new SimpleDevice(_, Seq("sifive,sram0")).reg("mem")).getOrElse(new MemoryDevice().reg)
|
||||||
|
|
||||||
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
val node = TLManagerNode(Seq(TLManagerPortParameters(
|
||||||
Seq(TLManagerParameters(
|
Seq(TLManagerParameters(
|
||||||
address = List(address),
|
address = List(address) ++ errors,
|
||||||
resources = resources,
|
resources = resources,
|
||||||
regionType = RegionType.UNCACHED,
|
regionType = RegionType.UNCACHED,
|
||||||
executable = executable,
|
executable = executable,
|
||||||
@ -43,6 +43,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4,
|
|||||||
val edge = node.edgesIn(0)
|
val edge = node.edgesIn(0)
|
||||||
|
|
||||||
val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2)
|
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 memAddress = Cat(addrBits.reverse)
|
||||||
val mem = SeqMem(1 << addrBits.size, Vec(beatBytes, Bits(width = 8)))
|
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_source = Reg(UInt())
|
||||||
val d_addr = Reg(UInt())
|
val d_addr = Reg(UInt())
|
||||||
val d_data = Wire(UInt())
|
val d_data = Wire(UInt())
|
||||||
|
val d_legal = Reg(Bool())
|
||||||
|
|
||||||
// Flow control
|
// Flow control
|
||||||
when (in.d.fire()) { d_full := Bool(false) }
|
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.d.valid := d_full
|
||||||
in.a.ready := in.d.ready || !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
|
// avoid data-bus Mux
|
||||||
in.d.bits.data := d_data
|
in.d.bits.data := d_data
|
||||||
in.d.bits.opcode := Mux(d_read, TLMessages.AccessAckData, TLMessages.AccessAck)
|
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_size := in.a.bits.size
|
||||||
d_source := in.a.bits.source
|
d_source := in.a.bits.source
|
||||||
d_addr := edge.addr_lo(in.a.bits)
|
d_addr := edge.addr_lo(in.a.bits)
|
||||||
|
d_legal := a_legal
|
||||||
}
|
}
|
||||||
|
|
||||||
// exactly this pattern is required to get a RWM memory
|
// 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)
|
mem.write(memAddress, wdata, in.a.bits.mask.toBools)
|
||||||
}
|
}
|
||||||
val ren = in.a.fire() && read
|
val ren = in.a.fire() && read
|
||||||
|
Loading…
Reference in New Issue
Block a user