FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Gem5のチュートリアル "Learning Gem5"をやってみる(Part-1)

Gem5の勉強のために、チュートリアルを1からやってみることにした。

www.gem5.org

ビルドの方法

ビルドの方法は大体わかっている。RISC-V向けのシミュレーションのためには以下のコマンドでビルドする。

scons build/RISCV/gem5.opt

このoptのオプションにはいくつか種類があるらしい。

コンフィグレーションスクリプトについて

次にコンフィグレーションスクリプトの作成。このコンフィグレーションスクリプトにより、Gem5でシミュレーションしたいシステムの構成を決定する。 これらの多くの例は、configs/examplesに格納されている。

SimObjectについて

Gem5におけるシミュレーション対象となるオブジェクト(CPU・キャッシュ・メモリコントローラ・バスなど)は、SimObjectを基底として作られている。 このオブジェクトは最終的にPythonに変換されるらしい。したがって、Python上からこれらのオブジェクトを作成したり呼び出すことができるようになる。

コンフィグレーションスクリプトの作成

まずは簡単なコンフィグレーションスクリプトを作ってみる。

mkdir configs/tutorial/part1/
touch configs/tutorial/part1/simple.py

次のコードはまあおまじないのように考えればよい。

import m5
from m5.objects import *

次にSystemオブジェクトを作成する。これには、タイミング情報を含まないシステムシミュレーション(物理メモリアドレス配置・クロックドメインなど)の環境が含まれている。

system = System()

システムクロックを作成し、システムに接続する。

system.clk_domain = SrcClockDomain()
system.clk_domain.clock = '1GHz'
system.clk_domain.voltage_domain = VoltageDomain()

次にメモリを作成する。ここでは512MBの小さなメモリを接続し、タイミングモードで動作するようにする。

system.mem_mode = 'timing'
system.mem_ranges = [AddrRange('512MB')]

CPUを接続する。X86の場合は下記だが、RiscvTimingSimpleCPUなどでもよい。

system.cpu = X86TimingSimpleCPU()

メモリのためのクロスバーと、キャッシュを接続する。

# システム内でのメモリバスを作成する
system.membus = SystemXBar()
# キャッシュを持っていないので、命令キャッシュとデータキャッシュのポートを直接メモリに接続する
system.cpu.icache_port = system.membus.cpu_side_ports
system.cpu.dcache_port = system.membus.cpu_side_ports

余談:Gem5のポート

メモリオブジェクトは、「リクエスト」と「レスポンス」のポートを持っている。

  • リクエストはrequest portsからresponse portへ
  • レスポンスはresponse portsからrequest portへ

Python=を用いて、簡単に接続できる。CPUの命令キャッシュのRequestポートを、cpu_side Responseポートに接続する。

system.cpu.icache_port = system.l1_cache.cpu_side

また、これらのポートは一方が1つの信号で、もう片方に複数のポートを接続しても良い。

下記の例では、icache_portをメモリ側のcpu_side_portsに接続しており、cpu_side_portsは配列に相当する。この例では、cpu_side_ports側に新しいポートが自動的に追加されることになる。

system.cpu.icache_port = system.membus.cpu_side_ports

とりあえずここまで。