FPGA開発日記

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

OpenSPARC T1の調査(5. S1coreをModelSimで動かす環境の構築)

OpenSPARC T1のラッパーであるS1Coreは、デフォルトではVcsもしくはIcarus Verilogで動作するようになっているが、これらで動作するのだったらModelsim Starter Editionでも動作するはずだ。 デバッグにあたり、やはりModelSimの方が簡単なので、Modelsimへの環境を以降しておこう。

まずは、S1Coreのためのリポジトリを作成した。

github.com

環境変数の設定

S1Coreの環境変数では、S1CoreそのものとOpenSPARC T1の場所を設定する必要がある。 これに加えて、ModelSim用のファイルリストを作成する記述を追加した。

  • s1_core/sourceme
diff --git a/s1_core/sourceme b/s1_core/sourceme
index 8f8d03b..01112cb 100755
--- a/s1_core/sourceme
+++ b/s1_core/sourceme
@@ -6,6 +6,7 @@ export PATH=.:$S1_ROOT/tools/bin:$PATH

 # Filelist names
 export FILELIST_ICARUS=$S1_ROOT/hdl/filelist.icarus
+export FILELIST_QUESTA=$S1_ROOT/hdl/filelist.questa
 export FILELIST_VCS=$S1_ROOT/hdl/filelist.vcs
 export FILELIST_FPGA=$S1_ROOT/hdl/filelist.fpga
 export FILELIST_DC=$S1_ROOT/hdl/filelist.dc

さらに、build_questa および run_questaを作成した。

  • build_questa
#!/bin/bash

if [ -z "$S1_ROOT" ]; then echo "***ERROR***: S1_ROOT variable is undefined, please set it and run 'source sourceme'."; exit 1; fi
if ! [ -d "$S1_ROOT" ]; then echo "***ERROR***: directory '$S1_ROOT' does not exist, please check it and run 'source sourceme' again."; exit 1; fi

echo "Building testbench using QuestaSim simulator..."
mkdir -p $S1_ROOT/run/sim/questa
cd $S1_ROOT/run/sim/questa
# rm -rf *
vlib worklib
vlog -work worklib -f $FILELIST_QUESTA
echo -e "Done!"
  • run_questa
#!/bin/bash

if [ -z "$S1_ROOT" ]; then echo "***ERROR***: S1_ROOT variable is undefined, please set it and run 'source sourceme'."; exit 1; fi
if ! [ -d "$S1_ROOT" ]; then echo "***ERROR***: directory '$S1_ROOT' does not exist, please check it and run 'source sourceme' again."; exit 1; fi

cd $S1_ROOT/run/sim/questa
ln -f -s $S1_ROOT/tests/boot/rom_harness.hex .
ln -f -s $S1_ROOT/tests/ram_harness.hex .

vsim -c worklib.testbench -voptargs="+acc" -l sim.log -do "run -all; quit"
echo "Simulation completed!"
echo "To see the output:"
echo "        less $S1_ROOT/run/sim/questa/sim.log"
echo "Too watch the waveforms:"
echo "        gtkwave $S1_ROOT/run/sim/questa/trace.vcd"

動作させるプログラムをコンパイル

S1Coreのリポジトリにはhello.cというサンプルプログラムが用意されているが、これを動作させるためにはもちろんSparcコンパイラコンパイルしなければならない。

  • tests/hello.c
// Sample program that writes two words at a predefined address

int main() {
  unsigned long* address;
  address = (unsigned long*)0x0000CAC0;
  (*address) = 0xC1A0C1A0;  // First store
  address = (unsigned long*)0x0000CAC0;
  (*address) = 0xFABA1210;  // Second store
  return 0;
}

このためにUbuntuのパッケージとしてgcc-sparc64-linux-gnuをインストールした。

sudo aptitude install -y gcc-sparc64-linux-gnu

そしてcompile_testコマンドをいくつか改造する必要がある。 と言っても、sparc64-linux-sparc64-linux-gnu-に変更しただけだ。

  • compile_test
diff --git a/s1_core/tools/bin/compile_test b/s1_core/tools/bin/compile_test
index 5684c25..060ab69 100755
--- a/s1_core/tools/bin/compile_test
+++ b/s1_core/tools/bin/compile_test
@@ -6,7 +6,7 @@
 # Parameter is test name without extension (e.g. to compile
 # $S1_ROOT/tests/hello.c) just run "compile_test hello".
 #
-# Note: requires sparc64-linux-gcc (see Download section on
+# Note: requires sparc64-linux-gnu-gcc (see Download section on
 # http://www.srisc.com).

 if [ -z "$S1_ROOT" ]; then echo "***ERROR***: S1_ROOT variable is undefined, please set it and run 'source sourceme'."; exit 1; fi
@@ -32,15 +32,14 @@ fi
 gcc -o $S1_ROOT/tools/bin/dump2hex.bin $S1_ROOT/tools/src/dump2hex.c

 # Compile the boot code
-sparc64-linux-as -ah -am -o boot/boot.bin boot/boot.s
-sparc64-linux-objdump -d -EB -w -z boot/boot.bin > boot/boot.dump
-grep "  " boot/boot.dump | egrep -v "file format" | dump2hex.bin > boot/rom_harness.hex
+sparc64-linux-gnu-as -ah -am -o boot/boot.bin boot/boot.s
+sparc64-linux-gnu-objdump -d -EB -w -z boot/boot.bin > boot/boot.dump
+grep "  " boot/boot.dump | egrep -v "elf64-sparc" | dump2hex.bin > boot/rom_harness.hex

 # Compile the C test
-sparc64-linux-gcc -c -O0 $1.c
-sparc64-linux-ld -Ur --script=$S1_ROOT/tools/src/linker.map -EB -o $1.bin $1.o
-sparc64-linux-objdump -d -EB -w -z $1.bin > $1.dump
-grep "  " $1.dump | egrep -v "file format" | dump2hex.bin > ram_harness.hex
+sparc64-linux-gnu-gcc -c -O0 $1.c
+sparc64-linux-gnu-ld -Ur --script=$S1_ROOT/tools/src/linker.map -EB -o $1.bin $1.o
+sparc64-linux-gnu-objdump -d -EB -w -z $1.bin > $1.dump
+grep "  " $1.dump | egrep -v "elf64-sparc" | dump2hex.bin > ram_harness.hex

 #rm -f *.o *~ *.bin *.dump           # Make clean
-

最初は何のことだか分からなかったのだが、以下のfile formatを除去するのは、dumpファイルの先頭行を除去したいようなのだが、環境変数が日本語だと違う文字列になってしまうので、共通のelf64-sparcに変更した。

-grep "  " $1.dump | egrep -v "file format" | dump2hex.bin > ram_harness.hex
+grep "  " $1.dump | egrep -v "elf64-sparc" | dump2hex.bin > ram_harness.hex

これで、build_questa && run_questarun/sim/questa/にシミュレーションログが出力された。 正しく動作しているようだ。

cd run/sim/questa
less sim.log

...
# INFO: MEMH testbench.ram_harness: R @             35410000 ns, AD=0800000000040018 SEL=ff DAT=8410a1a0c4704000
# INFO: WBM2SPC: *** RETURN PACKET TO SPARC CORE ***
# INFO: WBM2SPC: Valid bit is 1
# INFO: WBM2SPC: Return Packet of Type IFILL_RET
# INFO: WBM2SPC: L2 Miss is 0
# INFO: WBM2SPC: Error is 0
# INFO: WBM2SPC: Non-Cacheable bit is 1
# INFO: WBM2SPC: Thread is 0
# INFO: WBM2SPC: Way Valid is 0
# INFO: WBM2SPC: Replaced L2 Way is 0
# INFO: WBM2SPC: Fetch for Boot is 0
# INFO: WBM2SPC: Atomic LD/ST or 2nd IFill Packet is 1
# INFO: WBM2SPC: PFL is 0
# INFO: WBM2SPC: Data is c25fa7f7053068308410a1a0c4704000
# INFO: TBENCH: Completed Simply RISC S1 Core simulation!
# ** Note: $finish    : /home/masayuki/work/s1_core_opensparc_t1/s1_core/hdl/behav/testbench/testbench.v(94)
#    Time: 50 us  Iteration: 0  Instance: /testbench
# End time: 01:15:23 on Mar 04,2017, Elapsed time: 0:09:38
# Errors: 0, Warnings: 43

f:id:msyksphinz:20170304014111p:plain