FPGA開発日記

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

LiteXによるSoC環境構築を試行する (3. 自作CPUのコンフィグレーション追加試行)

https://raw.githubusercontent.com/enjoy-digital/litex/master/doc/litex.png

LiteXは自分でSoC環境を構成することができるツール。自作CPUをSoCに組み込んでみたいので、今回はこれを試行してみる。

github.com

自作のコンフィグレーションを追加するときはlitex_setup.pyの実行時に--devをつけなければならないらしい。そうしないとmasterに強制的に飛ばされてしまう。

./litex_setup.py --init --install --user --config=full --dev

litex_setup.pyに自分のCPU用のコンフィグレーションファイルを置いていたので、これがロードされることになる。

    "pythondata-cpu-ibex":         GitRepo(url="https://github.com/litex-hub/", clone="recursive", sha1=0xd3d53df),
    "pythondata-cpu-minerva":      GitRepo(url="https://github.com/litex-hub/"),
    "pythondata-cpu-naxriscv":     GitRepo(url="https://github.com/litex-hub/"),
    "pythondata-cpu-picorv32":     GitRepo(url="https://github.com/litex-hub/"),
    "pythondata-cpu-rocket":       GitRepo(url="https://github.com/litex-hub/"),
    "pythondata-cpu-serv":         GitRepo(url="https://github.com/litex-hub/"),
    "pythondata-cpu-vexriscv":     GitRepo(url="https://github.com/litex-hub/"),
    "pythondata-cpu-vexriscv-smp": GitRepo(url="https://github.com/litex-hub/", clone="recursive"),
    "pythondata-cpu-scariv":       GitRepo(url="https://github.com/msyksphinz-self/", clone="recursive"),
}

さて、SoCを構成するためのコンフィグレーションを見ていこう。CVA6のコンフィグレーションを参考にしている。

  • litex/soc/cores/cpu/scariv/__init__.py
from litex.soc.cores.cpu.scariv.core import ScariV
  • litex/soc/cores/cpu/scariv/core.py

とりあえずCVA6のものからコア名を変えて登録してみた。

# SCARIV ---------------------------------------------------------------------------------------------

class ScariV(CPU):
    category             = "softcore"
    family               = "riscv"
    name                 = "scariv"
    human_name           = "SCARIV"
    variants             = CPU_VARIANTS
    data_width           = 64
    endianness           = "little"
    gcc_triple           = CPU_GCC_TRIPLE_RISCV64
    linker_output_format = "elf64-littleriscv"
    nop                  = "nop"
    io_regions           = {0x8000_0000: 0x8000_0000} # Origin, Length.

...

これでビルドを走らせてみる。

litex_sim --cpu-type=my_cpu
 CC       complete.o
 CC       readline.o
 CC       crt0.o
 CC       bios.elf
/home/msyksphinz/riscv64/lib/gcc/riscv64-unknown-elf/11.1.0/../../../../riscv64-unknown-elf/bin/ld: crt0.o: in function `.L0 ':
/home/msyksphinz/work/litex/litex_repo/litex/litex/soc/cores/cpu/scariv/crt0.S:101: undefined reference to `plic_init'
collect2: error: ld returned 1 exit status
make: *** [/home/msyksphinz/work/litex/litex_repo/litex/litex/soc/software/bios/Makefile:72: bios.elf] Error 1
rm crt0.o
make: Leaving directory '/home/msyksphinz/work/litex/litex_repo/litex/build/sim/software/bios'

うーん、PLICを初期化するためのルーチンが足りないといわれた。これはどこから引っ張ってくればいいんだ。以下に定義があった。

litex/litex/soc/cores/cpu/cva6/crt0.S

#elif defined(__cva6__)
void plic_init(void);
void plic_init(void)
{
    int i;

    // priorities for interrupt pins 0...7
    for (i = 0; i < 8; i++)
        *((unsigned int *)PLIC_SOURCE_0 + i) = 1;
    // enable interrupt pins 0...7 (M-mode)
    *((unsigned int *)PLIC_M_ENABLE) = 0xff;
    // set priority threshold to 0 (any priority > 0 triggers interrupt)
    *((unsigned int *)PLIC_M_THRESHOLD) = 0;
}

というかこれは初期化ルーチンからスキップしていいのか。いろいろ改造していく。