前回の続き。TileLinkがデータをインオーダで返してこない件、受信側でデータの並べ替えを担保しなければならない。 これには根本的な実装の変更が必要だなあ。
これまでは、データを受け取った順番に乗算器に流し込んでいた。 これは、リクエストしたデータがそのまま帰ってくるという前提で設計していた。 これを変更しなければならない。このためには、リオーダバッファでデータを並び替えなければならない。
このためには、Chiselで記述されたReorderQueueというものを使わせてもらった。 これは、Tagを使ってバラバラに入ってきたデータを並び替えるためのモジュールらしい。
src/main/scala/util/ReorderQueue.scala
class ReorderQueue[T <: Data](dType: T, tagWidth: Int, size: Option[Int] = None) extends Module { val io = new Bundle { val enq = new ReorderEnqueueIO(dType, tagWidth).flip val deq = new ReorderDequeueIO(dType, tagWidth) } val tagSpaceSize = 1 << tagWidth val actualSize = size.getOrElse(tagSpaceSize) if (tagSpaceSize > actualSize) { val roq_data = Reg(Vec(actualSize, dType)) val roq_tags = Reg(Vec(actualSize, UInt(width = tagWidth)))
Chiselでのモジュールインスタンス方法
例えば、ログを格納するためにブロックRAMを配置するために以下のLoggerRAM
モジュールを定義したとする。
class LoggerRAM (DataWidth: Int, Length: Int) extends Module { val io = IO(new Bundle { val WData_In = Input(UInt(width = DataWidth)) val WAddr_In = Input(UInt(width = log2Ceil(Length))) val We_In = Input(Bool()) val RAddr_In = Input(UInt(width = log2Ceil(Length))) val Data_Out = Output(UInt(width = DataWidth)) }) val memory = Mem(1024, UInt(width = DataWidth)) when (io.We_In) { memory(io.WAddr_In) := io.WData_In } val w_data_out = Reg(UInt(width = DataWidth)) w_data_out := memory(io.RAddr_In) io.Data_Out := w_data_out }
この時に、モジュールのインタフェースはioとして定義されている。ここでは、
io.WData_In
: 入力データ。DataWidth幅io.WAddr_In
: 入力データアドレス。io.We_In
: 書き込み信号io.RAddr_In
: 読み込みデータアドレスio.Data_Out
: 読み込みデータ
としている。これらを上位のモジュールで定義するためには以下のようにして定義する。 Verilogではインタフェースを接続するが、Chiselではwireをassignしていくようなイメージだ。
val ResultRAM = Module (new LoggerRAM(32, 1024)) ResultRAM.io.WData_In := (r_total + w_result).asUInt() ResultRAM.io.We_In := we_resultram ResultRAM.io.WAddr_In := r_result_log_count ResultRAM.io.RAddr_In := r_log_addr w_result_MemOutput := ResultRAM.io.Data_Out
これでLogger用のブロックRAMと、ReorderQueueによるデータ整列、さらに固定小数点加算回路をブロック化したものを配置し、シミュレーションと論理合成を行ってみた。
シミュレーションはうまく動作したようだ。次に実機に持っていこう。
うーん、精度は多少良くなったけど、それでもまだオールSWに比べて精度が低い。性能はソフトウェアに比べて大体4倍くらいだ。 どこかにまだ問題があるはずだ。引き続きデバッグしていく。