[Weekly Review] 2020/02/10-16
2020/02/10-16
This week, I continued my survey at AI for HPC
and the implementation of Eyeriss V2.
I found a visualization tool named Netron
to translate the Neural Network from .onnx
etc. files to graphs.
Matrix Multiply
A Geometrical View
Chisel Syntax
DataMirror
Defined there.
object DataMirror {
def widthOf(target: Data): Width = target.width
def specifiedDirectionOf(target: Data): SpecifiedDirection = target.specifiedDirection
def directionOf(target: Data): ActualDirection = {
requireIsHardware(target, "node requested directionality on")
target.direction
}
// Returns the top-level module ports
// TODO: maybe move to something like Driver or DriverUtils, since this is mainly for interacting
// with compiled artifacts (vs. elaboration-time reflection)?
def modulePorts(target: BaseModule): Seq[(String, Data)] = target.getChiselPorts
// Returns all module ports with underscore-qualified names
def fullModulePorts(target: BaseModule): Seq[(String, Data)] = {
def getPortNames(name: String, data: Data): Seq[(String, Data)] = Seq(name -> data) ++ (data match {
case _: Element => Seq()
case r: Record => r.elements.toSeq flatMap { case (eltName, elt) => getPortNames(s"${name}_${eltName}", elt) }
case v: Vec[_] => v.zipWithIndex flatMap { case (elt, index) => getPortNames(s"${name}_${index}", elt) }
})
modulePorts(target).flatMap { case (name, data) =>
getPortNames(name, data).toList
}
}
}
// usage
DataMirror.modulePorts(adder).foreach { case (name, port) => {
println(s"Found port $name: $port")
}}
assert(DataMirror.directionOf(flippedVec.head.a) == Direction.Output)
val specifiedDirs = Seq(
a.fizz.foo -> SpecifiedDirection.Input,
a.fizz.bar -> SpecifiedDirection.Output,
a.fizz -> SpecifiedDirection.Unspecified,
a.buzz.foo -> SpecifiedDirection.Input,
a.buzz.bar -> SpecifiedDirection.Output,
a.buzz -> SpecifiedDirection.Flip
)
val actualDirs = Seq(
b.fizz.foo -> Direction.Input,
b.fizz.bar -> Direction.Output,
b.fizz -> Direction.Bidirectional(Direction.Default),
b.buzz.foo -> Direction.Output,
b.buzz.bar -> Direction.Input,
b.buzz -> Direction.Bidirectional(Direction.Flipped)
)
for ((data, dir) <- specifiedDirs) {
DataMirror.specifiedDirectionOf(data) shouldBe (dir)
}
for ((data, dir) <- actualDirs) {
DataMirror.directionOf(data) shouldBe (dir)
}
Chipyard
How to Access DMA
From this post at chisel China, the RoCC
accelerators can communicate with main memory via DMA with TileLink
's help. I got that post from this issue blog.
I found one DMA project written in Chisel with TileLink protocol. So maybe I will utilize this design directedly.
How to Access Level 2 Cache
Although an earlier document shows that RoCC
accelerators can communicate with L2 memory via Uncached Tile Link
(UTL), but we can not find this port now from the class RoCCIO
.
From the discussing in HW Dev Google Group, one said that we can learn the details from Hwacha
and Gemmini
, so I fetched some details in those projects.
Hwacha
From the document Hardware Acceleration for Memory to Memory Copies
, we can see that the submodules of Hwacha: SMU
, VMU
, VRU
and one L1 cache connect to L1-to-L2 TileLink Crossbar
, which might be SystemBus
now. So maybe we can find some common ports in those modules and then we can get the method to communicate with L2 cache.
class SMUReq(implicit p: Parameters) extends SMUBundle()(p)
with SMUData {
val fn = new SMUFn
val addr = UInt(width = bVAddrExtended)
val status = new freechips.rocketchip.rocket.MStatus
}
class SMUResp(implicit p: Parameters) extends SMUBundle()(p)
with SMUData {
val store = Bool()
}
class SMUIO(implicit p: Parameters) extends HwachaBundle()(p) {
val req = Decoupled(new SMUReq)
val resp = Decoupled(new SMUResp).flip
val confirm = Bool(INPUT)
}
class VMUMemReq(implicit p: Parameters) extends VMUMemOp
with VMUTag with VMUData {
val mask = UInt(width = tlDataBytes)
val pred = Bool()
}
class VMUMemResp(implicit p: Parameters) extends VMULoadData()(p) {
val store = Bool()
}
class VMUMemIO(implicit p: Parameters) extends VMUBundle()(p) {
val req = Decoupled(new VMUMemReq)
val resp = Decoupled(new VMUMemResp).flip
}
abstract class HwachaBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
with UsesHwachaParameters
abstract class VMUBundle(implicit p: Parameters)
extends HwachaBundle()(p) with VMUParameters
trait VMUAddr extends VMUBundle {
val addr = UInt(width = bPAddr)
}
trait VMUMemOp extends VMUAddr {
val fn = new VMUMemFn
}
trait VMUTag extends VMUBundle {
val tag = UInt(width = bVMUTag)
}
trait VMUData extends VMUBundle {
val data = Bits(width = tlDataBits)
}
class VMULoadData(implicit p: Parameters) extends VMUData with VMUTag