OpenSPARC T1のラッパーであるS1Coreは、デフォルトではVcsもしくはIcarus Verilogで動作するようになっているが、これらで動作するのだったらModelsim Starter Editionでも動作するはずだ。 デバッグにあたり、やはりModelSimの方が簡単なので、Modelsimへの環境を以降しておこう。
まずは、S1Coreのためのリポジトリを作成した。
環境変数の設定
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_questa
で run/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