Diplomacyを使ったOCPプロトコルの作成、次にXbarの作成を行う。Xbarというのはクロスバで、複数のマスターとスレーブを接続する。まずは1マスターから複数スレーブに向けて接続する回路を作成する。
Diplomacyのクロスバの考え方はこうだ。まずはすべてのマスターからのリクエストを集約し、Arbiterに接続する。
chisel-hw/src/main/scala/ocp/Xbar.scala
val in = Wire(Vec(io_in.size, OCPBundle(wide_bundle))) for (i <- 0 until in.size) { val r = inputIdRanges(i) in(i).cmd <> io_in(i).cmd in(i).cmd.bits.tagId := io_in(i).cmd.bits.tagId | UInt(r.start) in(i).data <> io_in(i).data in(i).data.bits.tagId := io_in(i).data.bits.tagId | UInt(r.start) io_in(i).resp <> in(i).resp }
これらのin
配列に入った信号をどのように処理するのか。以下のようにしてアウトプット毎にArbiterを配置してソースを選択する論理を入れる。
// Arbitrate amongst the sources for (o <- 0 until out.size) { OCPArbiter(policy, out(o).cmd, filter(beatsCmdI zip portsCmdOI(o), connectAOI(o)):_*) OCPArbiter(policy, out(o).data, filter(beatsDataI zip portsDataOI(o), connectCOI(o)):_*) }
一方で戻り側はどうするか。これと逆方向に接続する。
for (i <- 0 until in.size) { OCPArbiter(policy, in(i).resp, filter(beatsRespO zip portsRespIO(i), connectDIO(i)):_*) }
// Transform output bundle sinks (sources use global namespace on both sides) val out = Wire(Vec(io_out.size, OCPBundle(wide_bundle))) for (o <- 0 until out.size) { val r = outputIdRanges(o) io_out(o).cmd <> out(o).cmd io_out(o).data <> out(o).data out(o).resp <> io_out(o).resp out(o).resp.bits.tagId := io_out(o).resp.bits.tagId | UInt(r.start) }
さて、テストを行う。以下のようなテストコードを作成した。
class OCPUnitXbar()(implicit p: Parameters) extends LazyModule { val pusher1 = LazyModule(new OCPPatternPusher("pat1", Seq( new WriteReqPattern (0, 0x100, 0x2), new WriteDataPattern (0, 0x012345678L), ... ))) val ram0 = LazyModule(new OCPRAM(AddressSet(0x000, 0x3ff))) val ram1 = LazyModule(new OCPRAM(AddressSet(0x400, 0x3ff))) val xbar = LazyModule(new OCPXbar()) xbar.node := pusher1.node ram0.node := xbar.node ram1.node := xbar.node lazy val module = new LazyModuleImp(this) with UnitTestModule { pusher1.module.io.run := true.B io.finished := pusher1.module.io.done } }
GraphMLを作成する。Pusher1が1つのマスターで、ram0とram1がスレーブとなっている。
一応、正しく動作しているようだ。
$ make tilelink CONFIG=OCPUnitXbarTestConfig
Started UnitTest OCPUnitXbarTest Resp Fired : same as expected. 12345678 Resp Fired : same as expected. abcdef01 Resp Fired : same as expected. deadbeef Resp Fired : same as expected. 87654321