Chiselを使ったDiplomacyのデザイン作成、ELFファイルのメモリへのロードパスは完成したので、CPUからフェッチを実行してみる。
CPUはメモリロード中はリセットしており、これを解除するためのシーケンスを作成する。特定のメモリアドレスにアクセスするとCPUをリセットするようにした。しかしこれもダサいのでなんとかしたいなあ。
case 1 : { *debug_req_valid = 1; *debug_req_bits_addr = 0x20000000; *debug_req_bits_data = 1; state = 2;
Chisel側の実装は以下。
lazy val module = new LazyModuleImp(this) { val io = IO(new Bundle { val req = Input(Bool()) val addr = Input(UInt(32.W)) val data = Input(UInt(32.W)) val ready = Output(Bool()) }) loader.module.io.req := io.req && (io.addr =/= 0x20000000.U) loader.module.io.addr := io.addr loader.module.io.data := io.data io.ready := loader.module.io.ready // CPU Core Contorl val cpu_run = RegInit(false.B) cpu_run := Mux(io.req && (io.addr === 0x20000000.U), io.data(0), cpu_run) core.module.io.run := cpu_run
CPU側のフェッチ動作を確認する。メモリから命令をフェッチして正しく実行できるようだ。最初のジャンプに対応してフェッチ先の命令が変わっている。
このプログラムは最終的にメモリに値をストアして終了なので、TileLinkのDチャネルからデータを書き込んでいればよろしい。この動作は正しく動いているようだ。
CPUの数を増やしてみる
試しにCPUの数を2つに増やして、ちゃんとフェッチ動作できるか見てみた。
val core0 = LazyModule(new CoreTop("core0")) val core1 = LazyModule(new CoreTop("core1")) val xbar = LazyModule(new TLXbar) val memory = LazyModule(new TLRAM(AddressSet(0x80000000L, 0x0fff), beatBytes = ramBeatBytes)) xbar.node := loader.node xbar.node := /* TLDelayer(0.0001) := */ core0.inst_node xbar.node := /* TLDelayer(0.0001) := */ core0.data_node xbar.node := core1.inst_node xbar.node := core1.data_node
結果は上手く行っていない。というか、XBarの所でどちらかのReady信号が落ちてしまうのは当然で、CPUのFetcherをReady信号に対応させないとどうしようもない。この辺も実装していこう。