RISC-Vの実装であるRocket-Chipは、RISC-Vの最新使用に追従しているため最初に見るべきデザインとしてはよくできているが、
- Chiselで記述されており(初心者には)可読性が低い。
- 外部のSoCプラットフォームについて情報がない
ことから、なかなかオリジナルのSoCをくみ上げるためのデザインとしてポーティングしにくい。
とはいえ、TileLinkは単なるバスのはずだし、クロックとリセットさえ突っ込めばとりあえずフェッチリクエストが上がってくるはずだ。 そのあたりを解析して、Rocket-Chipを利用したオリジナルSoCプラットフォーム構築のための情報収集を行っていこう。
Freedom SoCはRocket-Coreを含むRISC-VのSoCプラットフォームだが、主にコアとなるTile部分と、外部のペリフェラル部分から構成されている。

Freedom E300 システムのソースファイル全体像
Freedom E300システムは、Rocket-Chipと、外部のSoC部に分かれて構成されている。
freedom
src/main/
└── scala
├── everywhere
│ └── e300artydevkit
└── unleashed
└── u500vc707devkit
rocket-chip/src/
└── main
└── scala
├── amba
│ ├── ahb
│ ├── apb
│ └── axi4
├── config
├── coreplex
├── devices
│ ├── debug
│ └── tilelink
├── diplomacy
├── groundtest
├── interrupts
├── jtag
├── regmapper
├── rocket
├── system
├── tile
├── tilelink
├── unittest
└── util
Freedom E300 Platform のメモリマップ
Freedom E300 Platform は、以下のメモリマップを持っている。 このなかで、最初の0x0000_0000から0x0FFF_FFFFまでは、E3 Coreplex Manualを参照すること、と書いてある通り、こちらに掲載しているのはあくまでもSoCのメモリマップだ。 さらにSoC内部のCoreplex IPについては、E3 Coreplex Manualを参照する必要がある。


といっても、実際にはリセット後にBootROMに命令フェッチが入っており、そちらからジャンプする仕組みなっている。 BootROMには、以下のプログラムがコンパイルされて格納されている。
.section .text.init .option norvc .globl _start _start: csrr a0, mhartid la a1, dtb li t0, XIP_TARGET_ADDR jr t0 .section .rodata dtb: .incbin DEVICE_TREE
XIP_TARGET_ADDRは、以下のコンパイルコマンドで決定されている。
$(elf): xip.S $(dtb)
$(CC) $(CFLAGS) -DXIP_TARGET_ADDR=0x20400000 -DDEVICE_TREE='"$(dtb)"' $(LFLAGS) -o $@ $<
TARGET_ADDRを見てわかるとおり、まずは0x2040_0000に配置されているQSPIへ命令をフェッチするようになっている。 つまりBootROMのターゲットアドレスを書き換えれば、所望の場所からプログラムをロードしてフェッチできそうな気がしている。
最初にブートするMaskROMは、System.scalaでmaskROMとして定義されている。
class E300ArtyDevKitSystemModule[+L <: E300ArtyDevKitSystem](_outer: L) extends RocketCoreplexModule(_outer) with HasPeripheryDebugModuleImp with HasPeripheryUARTModuleImp ...
trait HasPeripheryMaskROMSlave extends HasPeripheryBus { val maskROMParams = p(PeripheryMaskROMKey) val maskROMs = maskROMParams map { params => val maskROM = LazyModule(new TLMaskROM(params)) maskROM.node := pbus.toFixedWidthSingleBeatSlave(maskROM.beatBytes) maskROM } }
RTLシミュレーション
一応E300 Freedom SoCのVerilogファイルだけ抜き出して適当にテストベンチをつなげ、ClockとResetをつなげてシミュレーションをしてみると、 とりあえずMaskROMへのフェッチが発生しているところまでは確認できる。
BootROMから、QSPIの領域(0x2040_0000)へジャンプしているため、そこからQSPIへのアクセスに移っているようだ。これをDRAMの領域に差し替えて、外部のRAMから命令をフェッチできるようにしてみよう。

関連記事
- SiFiveのFreedom E300 Platformを単体でカスタマイズできるようにする (1. 全体構造からブートROMへのリクエストまでの仕組み)
- SiFiveのFreedom E300 Platformを単体でカスタマイズできるようにする (2. バスのマップと新しいモジュールの追加)
- SiFiveのFreedom E300 Platformを単体でカスタマイズできるようにする (3. SRAMモジュールを作成して接続、テストパタンで動作を確認する)
- SiFiveのFreedom E300 Platformを単体でカスタマイズできるようにする (4. TileLinkの解析とコンフィグレーション設定)