111 lines
3.5 KiB
Scala
111 lines
3.5 KiB
Scala
// See LICENSE.SiFive for license details.
|
|
|
|
package freechips.rocketchip.amba.axi4
|
|
|
|
import Chisel._
|
|
import freechips.rocketchip.config.Parameters
|
|
import freechips.rocketchip.diplomacy._
|
|
import freechips.rocketchip.tilelink._
|
|
import freechips.rocketchip.util._
|
|
import freechips.rocketchip.subsystem.{CrossingWrapper, AsynchronousCrossing}
|
|
|
|
class AXI4AsyncCrossingSource(sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
|
{
|
|
val node = AXI4AsyncSourceNode(sync)
|
|
|
|
lazy val module = new LazyModuleImp(this) {
|
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
|
val depth = edgeOut.slave.depth
|
|
|
|
out.ar <> ToAsyncBundle(in.ar, depth, sync)
|
|
out.aw <> ToAsyncBundle(in.aw, depth, sync)
|
|
out. w <> ToAsyncBundle(in. w, depth, sync)
|
|
in .r <> FromAsyncBundle(out.r, sync)
|
|
in .b <> FromAsyncBundle(out.b, sync)
|
|
}
|
|
}
|
|
}
|
|
|
|
class AXI4AsyncCrossingSink(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
|
{
|
|
val node = AXI4AsyncSinkNode(depth, sync)
|
|
|
|
lazy val module = new LazyModuleImp(this) {
|
|
(node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) =>
|
|
out.ar <> FromAsyncBundle(in.ar, sync)
|
|
out.aw <> FromAsyncBundle(in.aw, sync)
|
|
out. w <> FromAsyncBundle(in. w, sync)
|
|
in .r <> ToAsyncBundle(out.r, depth, sync)
|
|
in .b <> ToAsyncBundle(out.b, depth, sync)
|
|
}
|
|
}
|
|
}
|
|
|
|
object AXI4AsyncCrossingSource
|
|
{
|
|
def apply(sync: Int = 3)(implicit p: Parameters) = {
|
|
val axi4asource = LazyModule(new AXI4AsyncCrossingSource(sync))
|
|
axi4asource.node
|
|
}
|
|
}
|
|
|
|
object AXI4AsyncCrossingSink
|
|
{
|
|
def apply(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) = {
|
|
val axi4asink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
|
|
axi4asink.node
|
|
}
|
|
}
|
|
|
|
@deprecated("AXI4AsyncCrossing is fragile. Use AXI4AsyncCrossingSource and AXI4AsyncCrossingSink", "rocket-chip 1.2")
|
|
class AXI4AsyncCrossing(depth: Int = 8, sync: Int = 3)(implicit p: Parameters) extends LazyModule
|
|
{
|
|
val source = LazyModule(new AXI4AsyncCrossingSource(sync))
|
|
val sink = LazyModule(new AXI4AsyncCrossingSink(depth, sync))
|
|
val node = NodeHandle(source.node, sink.node)
|
|
|
|
sink.node := source.node
|
|
|
|
lazy val module = new LazyModuleImp(this) {
|
|
val io = IO(new Bundle {
|
|
val in_clock = Clock(INPUT)
|
|
val in_reset = Bool(INPUT)
|
|
val out_clock = Clock(INPUT)
|
|
val out_reset = Bool(INPUT)
|
|
})
|
|
|
|
source.module.clock := io.in_clock
|
|
source.module.reset := io.in_reset
|
|
sink.module.clock := io.out_clock
|
|
sink.module.reset := io.out_reset
|
|
}
|
|
}
|
|
|
|
/** Synthesizeable unit tests */
|
|
import freechips.rocketchip.unittest._
|
|
|
|
class AXI4RAMAsyncCrossing(txns: Int)(implicit p: Parameters) extends LazyModule {
|
|
val model = LazyModule(new TLRAMModel("AsyncCrossing"))
|
|
val fuzz = LazyModule(new TLFuzzer(txns))
|
|
val toaxi = LazyModule(new TLToAXI4)
|
|
val island = LazyModule(new CrossingWrapper(AsynchronousCrossing(8)))
|
|
val ram = island { LazyModule(new AXI4RAM(AddressSet(0x0, 0x3ff))) }
|
|
|
|
model.node := fuzz.node
|
|
toaxi.node := model.node
|
|
ram.node := island.crossAXI4In := toaxi.node
|
|
|
|
lazy val module = new LazyModuleImp(this) with UnitTestModule {
|
|
io.finished := fuzz.module.io.finished
|
|
|
|
// Shove the RAM into another clock domain
|
|
val clocks = Module(new Pow2ClockDivider(2))
|
|
island.module.clock := clocks.io.clock_out
|
|
}
|
|
}
|
|
|
|
class AXI4RAMAsyncCrossingTest(txns: Int = 5000, timeout: Int = 500000)(implicit p: Parameters) extends UnitTest(timeout) {
|
|
val dut = Module(LazyModule(new AXI4RAMAsyncCrossing(txns)).module)
|
|
io.finished := dut.io.finished
|
|
}
|