English Chinese(simplify)

RISC-V32IシミュレータにCGRAをくっつける方法

半導体が自炊できない国になったけどコンピュータの中身に興味ある高校生へ

音声合成マクロ付きpptm(合成mp4はyoutubeチャンネル)の元ノートを見たい人は以下
RISC-V32IシミュレータにCGRAをくっつける方法

RISCVが流行るかもと思う人が増えています.他のCPUとの違いを一言で説明するには,シミュレータを書くのが一番です.シミュレータ自体は1日で書けます.あと,コンパイラとかライブラリとか探してビルドして,なんやかんや環境を作ると,C言語で書いたプログラムがシミュレータの上で走るようになります.これで,実行形式ファイルの構造や,教科書ではよくわからないCPUの動きが観察できます.画像処理プログラムが動くまでの全3日程度の作業の様子をまとめました.最後は,昔流行ったベクトル命令ではなく,CGRAをくっつけて(単にHOSTにするのではなく)新計算原理コンピュータの研究に使います.(なかしま@ならせんたんだい)

[2022/04/05]RISCVの一番小さい構成で動くコンパイル環境を作る

RISCVの一番小さい構成は,"gcc -march=rv32i -mabi=ilp32"が出すコードが動く構成です.ああ,いきなり何だかわからないですね.gccは,GNU C-Compilerのことで,いろんなCPUに対応できるCコンパイラです.なかしまは,gcc-1.40(1991/6/1)を使って,VPPスパコンのVLIW用初期Cコンパイラを作りました.元のダウンロードリンクはなくなっていますが,ここに一式入っています.当時のgccは,ファイル数で200程度しかありませんでした.今では10万以上と500倍に増え,VPPの流れを汲むFRV用のコードも入っています.シミュレータを書く前にコンパイル環境を作る必要があって,gccは欠かせません.そして,gccでクロスコンパイラを作るために,アセンブラやリンカが入っているbinutilsが必要です.

まず,FreeBSDかLinuxが動く環境を用意します.ログインしたら,ここから一式ダウンロードします.次に,"cd; zcat proj-riscv32.tgz|tar xpf -"とすると,$HOMEに以下ができます.

proj-riscv32/src/README
proj-riscv32/src/binutils-2.35.2.tgz … アセンブラやリンカなど
proj-riscv32/src/conv-c2d/           … 工事中:CGRAコンパイラ
proj-riscv32/src/conv-mark/          … 工事中:CGRAコンパイラ
proj-riscv32/src/dsim/               … シミュレータ
proj-riscv32/src/gcc-10.3.0.tgz      … コンパイラ
proj-riscv32/src/gmp-5.1.3.tgz       … コンパイラのビルドに必要なもの
proj-riscv32/src/isl-0.18.tgz        … コンパイラのビルドに必要なもの
proj-riscv32/src/mpc-1.0.1.tgz       … コンパイラのビルドに必要なもの
proj-riscv32/src/mpfr-3.1.2.tgz      … コンパイラのビルドに必要なもの
proj-riscv32/src/newlib-3.3.0.tgz    … ライブラリ

では,binutilsに取り掛かります."cd proj-riscv32/src; zcat binutils-2.35.2.tgz|tar xpf -; cd binutils-2.35.2"とします.中にMAKE_INSTALLというファイルがあり,以下のように書いてあります.

CC=gcc;export CC
./configure -target=riscv32-elf --prefix=/usr/home/nakashim/proj-riscv32
gmake CC=gcc > Make.log 2>&1
#gmake install CC=gcc

"-target=riscv32-elf"は,32bit-ELF形式を使う指示です."--prefix=/usr/home/nakashim/proj-riscv32"は,これから作るツールの置き場所です.置き場所は適当に変えてOKです.ただし,.cshrcに,"set path = ($HOME/proj-riscv32/bin $path)"と追加するなど,コマンドサーチパスに入れておく必要があります.これを使って,"./MAKE_INSTALL"とします.ログはMake.logに書き込まれるので,別のウィンドウから,"tail -f Make.log"として,進行状況を確認できます.MAKE_INSTALLが終って,Make.logの最後にエラーが出ていなければ,"make install"とします."ls -rtl ~/proj-riscv32/bin"とすると,以下のように表示されるはずです.元々あったFreeBSD7.2R用のファイルに上書きされて,各ファイルの日付が新しくなっていることを確認しましょう.

-rwxr-xr-x  1 nakashim  usr1000  3848329  4  5 19:01 riscv32-elf-strings
-rwxr-xr-x  1 nakashim  usr1000  3850539  4  5 19:01 riscv32-elf-size
-rwxr-xr-x  2 nakashim  usr1000  4050560  4  5 19:01 riscv32-elf-ranlib
-rwxr-xr-x  2 nakashim  usr1000  5878883  4  5 19:01 riscv32-elf-objdump … 逆アセンブラができた
-rwxr-xr-x  2 nakashim  usr1000  4474035  4  5 19:01 riscv32-elf-objcopy
-rwxr-xr-x  2 nakashim  usr1000  4050529  4  5 19:01 riscv32-elf-ar
-rwxr-xr-x  2 nakashim  usr1000  4474062  4  5 19:01 riscv32-elf-strip
-rwxr-xr-x  2 nakashim  usr1000  2324702  4  5 19:01 riscv32-elf-readelf
-rwxr-xr-x  2 nakashim  usr1000  3888561  4  5 19:01 riscv32-elf-nm
-rwxr-xr-x  1 nakashim  usr1000   286691  4  5 19:01 riscv32-elf-elfedit
-rwxr-xr-x  1 nakashim  usr1000  3806974  4  5 19:01 riscv32-elf-c++filt
-rwxr-xr-x  1 nakashim  usr1000  3861838  4  5 19:01 riscv32-elf-addr2line
-rwxr-xr-x  2 nakashim  usr1000  5595075  4  5 19:01 riscv32-elf-as      … アセンブラができた
-rwxr-xr-x  1 nakashim  usr1000  4430647  4  5 19:01 riscv32-elf-gprof
-rwxr-xr-x  4 nakashim  usr1000  5875146  4  5 19:02 riscv32-elf-ld.bfd
-rwxr-xr-x  4 nakashim  usr1000  5875146  4  5 19:02 riscv32-elf-ld      … リンカができた

[2022/04/05]gccとnewlibを作る

次に,gccを作るのに必要なものを入れていきます.binutilsと同じように,以下を実行します.自信のない人は,";"毎に区切って実行します.

cd ..; zcat gmp-5.1.3.tgz |tar xpf -; cd gmp-5.1.3;  vi MAKE_INSTALL; ./MAKE_INSTALL; make install
cd ..; zcat mpfr-3.1.2.tgz|tar xpf -; cd mpfr-3.1.2; vi MAKE_INSTALL; ./MAKE_INSTALL; make install
cd ..; zcat mpc-1.0.1.tgz |tar xpf -; cd mpc-1.0.1;  vi MAKE_INSTALL; ./MAKE_INSTALL; make install
cd ..; zcat isl-0.18.tgz  |tar xpf -; cd isl-0.18;   vi MAKE_INSTALL; ./MAKE_INSTALL; make install

いよいよ,gcc本体です.Make.logは,gcc-10.3.0の隣のgcc-objdirにできます.MAKE_INSTALLの中にある,"-target=riscv32-elf"が重要です.
"cd ..; zcat gcc-10.3.0.tgz |tar xpf -; cd gcc-10.3.0; vi MAKE_INSTALL; ./MAKE_INSTALL"
Make.logの最後に,"[configure-target-libbacktrace]"というエラーが出ている場合は,気にする必要はありません.他のエラーは対処する必要があります.うまくできたら,"cd ../gcc-objdir; make install"を実行します. "ls -rtl ~/proj-riscv32/bin"とすると,以下のように追加されているはずです.gccも上書きされて,各ファイルの日付が新しくなっていることを確認しましょう.

-rwxr-xr-x  2 nakashim  usr1000    3492386  4  5 20:17 riscv32-elf-g++
-rwxr-xr-x  2 nakashim  usr1000    3492386  4  5 20:17 riscv32-elf-c++
-rwxr-xr-x  1 nakashim  usr1000    3493114  4  5 20:17 riscv32-elf-gfortran
-rwxr-xr-x  1 nakashim  usr1000  117629379  4  5 20:17 riscv32-elf-lto-dump
-rwxr-xr-x  1 nakashim  usr1000    1937887  4  5 20:17 riscv32-elf-gcov-tool
-rwxr-xr-x  1 nakashim  usr1000    1828991  4  5 20:17 riscv32-elf-gcov-dump
-rwxr-xr-x  1 nakashim  usr1000    2722939  4  5 20:17 riscv32-elf-gcov
-rwxr-xr-x  1 nakashim  usr1000    3490095  4  5 20:17 riscv32-elf-cpp
-rwxr-xr-x  1 nakashim  usr1000      91604  4  5 20:17 riscv32-elf-gcc-ranlib
-rwxr-xr-x  1 nakashim  usr1000      91592  4  5 20:17 riscv32-elf-gcc-nm
-rwxr-xr-x  1 nakashim  usr1000      91640  4  5 20:17 riscv32-elf-gcc-ar
-rwxr-xr-x  2 nakashim  usr1000    3476640  4  5 20:17 riscv32-elf-gcc-10.3.0
-rwxr-xr-x  2 nakashim  usr1000    3476640  4  5 20:17 riscv32-elf-gcc

最後に,newlibを入れます.newlibは,C言語でよく使う関数がたくさん入ったライブラリです.馴染みのprintf()も入っています.binutilsと同じように,以下を実行します.

cd ..; zcat newlib-3.3.0.tgz |tar xpf -; cd newlib-3.3.0; vi MAKE_INSTALL; ./MAKE_INSTALL; make install

[2022/04/05]スタートアップファイルを作る

コンパイラ,アセンブラ,リンカ,ライブラリが揃いました.でも,あと1つ,シミュレータで動く実行形式ファイルを作るために大事なものが欠けています.C言語で書いたプログラムは,どこから実行されるでしょう.main()という関数から実行されることは知っていますね.でも,実行形式ファイルの先頭は,そうではありません._startというラベルが付いた命令が,最初に実行される機械語命令です._startは,いくつかのレジスタに初期値をセットして,main()を呼び出し,main()から戻ってきたら,最後にexit()に繋ぐ役割りを果たします._startは,アセンブリ言語で書いて,アセンブルしておく必要があります.具体的には以下にあります._start.sがアセンブリ言語で書いたソースプログラムです.Makefileがあるので,この場所で,"make"とします.さっき作ったアセンブラを使って,オブジェクトである_start.oが生成されます.

proj-riscv32/lib/dsim32-lib/Makefile
proj-riscv32/lib/dsim32-lib/_start.s
proj-riscv32/lib/dsim32-lib/_start.o

また,同じ場所に,マップファイルがあります.中身は以下です.これを使うと,_startが0x00010000番地になるようにコンパイルできます.使い方はあとで説明します.

proj-riscv32/lib/dsim32-lib/_map
SECTIONS {
  .text 0x00010000 : { *(.text) }
}

では,_start.sの中身を見てみましょう.★は,シミュレータとの連携が必要な部分です.0x1008はシミュレータがスタックポインタの初期値を書き込む場所で,_start.sが拾ってスタックポインタに対応するレジスタspにセットします.同様に,0x100cはシミュレーション対象プログラムの引数の数で,レジスタa0にセットします.0x1010は個々の引数に対応する文字列先頭アドレス群の先頭番地で,レジスタa1にセットします.そして,レジスタa2には0をセットします.main()を呼び出して戻ってきたら,レジスタa7にexit()に対応する0x0011をセットして,システムコール(ecall)命令を実行します.シミュレータは,この命令を実行したらシミュレーションを終了します.以上が実行形式ファイルの扱い方です.なお,0x0011というのは,ベースにした,リオーダバッファ/コヒーレントキャッシュ/マルチスレッディングを備えるARMv8シミュレータ(これも自作)が使っていた番号なので,ここだけの方言です.

        .section .text.startup
        .align   2
        .globl   _start
        .type    _start, @function
_start: .option  push
        .option  norelax
1:      auipc    gp, %pcrel_hi(__global_pointer$)
        addi     gp, gp, %pcrel_lo(1b)
        .option  pop
★      la       a0, 0x1008
★      lw       sp, 0(a0)             # init SP
        la       a0, __libc_fini_array # Register global termination functions
        call     atexit                #  to be called upon exit
        call     __libc_init_array     # Run global initialization functions
★      la       a2, 0x100c
★      lw       a0, 0(a2)             # a0 = argc
★      la       a1, 0x1010            # a1 = argv
★      li       a2, 0                 # a2 = envp = NULL
        call     main
        .globl   exit
exit:   .globl   _exit
_exit:  .globl   _kill
_kill:  .globl   _halt
_halt:
★      li      a7,0x0011
★      ecall

[2022/04/06]サンプルプログラムのコンパイル

コンパイル環境ができあがったので,以下のプログラムをコンパイルしてみましょう.

proj-riscv32/sample/test/Makefile-bsd
proj-riscv32/sample/test/Makefile-dsim
proj-riscv32/sample/test/test000.c

プログラムの本体はtest000.cです.中身は以下です.

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <math.h>

main(argc,argv) int argc; char **argv;
{
 typedef long double Dll;

 printf("sizeof DLL=%d\n", sizeof(Dll));
 puts("Hello");

}

まず,FreeBSDかLinuxが動いている環境で直接動く実行形式ファイルを作ってみましょう. Makefile-bsdを使って,この場所で,"make -f Makefile-bsd"とします.test000-bsdが生成されます."objdump -D test000-bsd | less"とすると,逆アセンブル結果が表示されます. ほとんどの人はIntel命令を観察できます.CPUにARMを使っている人はARM命令を観察できます.この実行形式ファイルは,"./test000-bsd"により,すぐに動かすことができ,

Intelでは sizeof DLL=12
          Hello

ARMv8では sizeof DLL=16
          Hello

と表示されます.sizeof DLL=の後ろに表示される数字は,long double型データのバイト長です.IEEE754-2008の単精度浮動小数点数(float)は4, 倍精度浮動小数点数(double)は8ですが,long doubleがCPUによって違うことを知るために表示しています.この値は,プログラムをコンパイルして動かしてみなくても,"echo | gcc -dM -E - | egrep '__SIZEOF_LONG_DOUBLE__'" として,コンパイラに教えてもらえる場合もあります.教えてくれるコンパイラであれば,プログラムの中で__SIZEOF_LONG_DOUBLE__を参照することもできます.

次に,さっき作ったRISCV32Iのコンパイラを使ってみましょう.今度は"make -f Makefile-dsim"です.Makefile-dsimの中身には,以下が書いてあります.

PROJTOP       = ../../
CC            = riscv32-elf-gcc
CFLAGS        = -I. -O3 $(OPTION) -mstrict-align -march=rv32i -mabi=ilp32
AS            = riscv32-elf-as
ASFLAGS       = 
LD            = riscv32-elf-ld
LDFLAGS       = -static -M $(PROJTOP)/lib/dsim32-lib/_map 
LIBS          = -lgcc -lm -lc
LIBFLAGS      = -L$(PROJTOP)/lib/gcc/riscv32-elf/10.3.0/rv32i/ilp32 -L$(PROJTOP)/riscv32-elf/lib/

test000-dsim: test000.o
              $(LD) $(LDFLAGS) -o $@ $(PROJTOP)/lib/dsim32-lib/_start.o $< $(LIBFLAGS) --start-group $(LIBS) --end-group

コンパイラは"riscv32-elf-gcc -march=rv32i -mabi=ilp32",アセンブラは"riscv32-elf-as"を使います.そして,リンカは,
"riscv32-elf-ld -static -M ../..//lib/dsim32-lib/_map -o test000-dsim ../..//lib/dsim32-lib/_start.o test000.o -L../..//lib/gcc/riscv32-elf/10.3.0/rv32i/ilp32 -L../..//riscv32-elf/lib/ --start-group -lgcc -lm -lc --end-group"と使います.前に用意した_mapと_start.o,オブジェクトであるtest.o,newlibで作ったライブラリを使って,実行形式ファイルtest000-dsimができ上がります.中身がどうなっているか確認しましょう. "riscv32-elf-objdump -D test000-dsim | less"とすると,以下のように表示されるはずです.先頭に_startがあって,指定通り0x10000から始まっています.そして,jal <main>の後ろに_exitがあって,ecallで終っています.うまくできているようです.

  10000 <_start>:
  10000:  00012197  auipc   gp,0x12
  10004:  80018193  addi    gp,gp,-2048 # 21800 <__global_pointer$>
  10008:  00001537  lui     a0,0x1
  1000c:  00850513  addi    a0,a0,8 # 1008 <_start-0xeff8>
  10010:  00052103  lw      sp,0(a0)
  10014:  00000517  auipc   a0,0x0
  10018:  22c50513  addi    a0,a0,556 # 10240 <__libc_fini_array>
  1001c:  1e4000ef  jal     ra,10200 <atexit>
  10020:  2a4000ef  jal     ra,102c4 <__libc_init_array>
  10024:  00001637  lui     a2,0x1
  10028:  00c60613  addi    a2,a2,12 # 100c <_start-0xeff4>
  1002c:  00062503  lw      a0,0(a2)
  10030:  000015b7  lui     a1,0x1
  10034:  01058593  addi    a1,a1,16 # 1010 <_start-0xeff0>
  10038:  00000613  li      a2,0
  1003c:  190000ef  jal     ra,101cc <main>
  10040 <_exit>:
  10040:  01100893  li      a7,17
  10044:  00000073          ecall

[2022/04/06]シミュレータには目的に応じて種類がある

さっきは,IntelやARMのコンパイラを使って実行形式ファイルを作ったので,IntelやARMの本物CPU上でプログラムが動きました.でも,これから動かす実行形式ファイルはRISCV32I用です.本物CPUがなければ,動きもどうもしません.そこで役に立つのがシミュレータです.シミュレータには,機能の違いによって大きく2種類あります.1つは,OSも動かせる,本物CPUと全く同じ機能があるシミュレータ,もう1つは,OSは動かないけど,さっき作ったtest000-dsimのようなアプリケーションなら動かせるシミュレータです.OSの開発やデバッグには前者が必要ですが,この記事ではそこまで必要ないので,後者を作ります.

さらに,シミュレータには,必要な精度の違いによって大きく4種類の作り方があります.(1)トレースベースシミュレータは,実機の機能を使って,実行した命令列から,条件分岐命令に関するアドレス情報や,メモリ参照に関するアドレス情報を取り出し,キャッシュメモリのヒット率などの性能を見積もるシミュレータです.命令デコード機能を作る必要がないので,シミュレータの構造も簡単で高速ですが,実機がなけれは情報を取り出せないので,この記事の目的には合いません.(2)アーキテクチャシミュレータ(命令アキュレート)は,機械語命令を1つずつ逐次実行します.自身で命令デコーダを持っているので,実機がなくてもプログラムを実行できます.アーキテクチャの機能検証や,コンパイラのデバッグなどに使うことができます.ただし,実行した命令数を数えることができますが,実行に要したクロックサイクル数,つまり,性能については見積ることが困難です.(3)パイプラインシミュレータ(サイクルアキュレート)は,ハードウェアのパイプライン構造をある程度模倣して,キャッシュミスやCPU間通信遅延も含めたクロックサイクル数の見積りが可能なシミュレータです.本物に近いので,シミュレーション速度は遅くなりますが,アーキテクチャ研究によく使われるタイプです.(4)RTLシミュレータ(クロックアキュレート)は,ハードウェアが有するレジスタを模倣し,レジスタからレジスタまでの処理をハードウェアと同じようにソフトウェアで記述することで,マイクロアーキテクチャをほぼ再現するシミュレータです.シミュレーション速度はさらに遅くなります.代わりに,設計したハードウェアの各部分の状態も再現できるので,ハードウェアのデバッグのために大変役に立つシミュレータです.もちろん,ハードウェア記述言語(HDL)で書いて,HDLシミュレータで動かすこともできます.しかし,HDLシミュレータの動作速度は極めて遅いので,大きなプログラムを走らせることは事実上不可能です.この記事で作るシミュレータは(3)と(4)の混成です.

[2022/04/06]シミュレータを書く

前に,ARMv8シミュレータ(これも自作)をベースにしたと言いました.元のARMv8シミュレータは,ここに入っています."proj-arm64/src/csim"です.これを全部説明したら,ものすごい時間がかかりますので,ここからは,RISCV32Iに変えるために必要だった改造について説明します.ARMv8との違いもわかります.改造後のシミュレータは,最初に展開した,"proj-riscv32/src/dsim"にあります.主に違うのは,以下のファイルです.

まずARMv8です.ファイル名はリンクになっています.
  proj-arm64/src/csim/decode.c   … ARMv8命令デコーダ(4009行)
  proj-arm64/src/csim/exec.c     … 実行制御(162行)
  proj-arm64/src/csim/alu.c      … ALUの動作(444行)
次にRISCV32Iです.ファイル名はリンクになっています.
  proj-riscv32/src/dsim/decode.c … RISCV32I命令デコーダ(459行)
  proj-riscv32/src/dsim/exec.c   … 実行制御(105行)
  proj-riscv32/src/dsim/alu.c    … ALUの動作(55行)

ARMv8には浮動小数点命令やSIMD命令がたくさん入っているので,単純比較はできませんが,それでも,RISCV32Iはずいぶん少ない行数で書けています. RISCV32Iのシミュレータを書いて気づいた点は以下です.(1)とにかく機能が最小限(SPARCと同レベル)で条件付き実行もない.(2)条件分岐命令自身にレジスタsrc1とsrc2を比較する機能が入っているので,条件フラグ(NZCV)がいらない.いろいろいらないので,シミュレータが早く作れました.

[2022/04/06]シミュレータを作る

では,シミュレータをコンパイルしましょう.各種Makefileがあります.

proj-riscv32/src/dsim/Makefile-bsd    … FreeBSD用
proj-riscv32/src/dsim/Makefile-cent   … CentOS用
proj-riscv32/src/dsim/Makefile-fugaku … Fugaku用
proj-riscv32/src/dsim/Makefile-zynq   … ZYNQ用

使っている環境がCentOSの場合,proj-riscv32/src/dsim/の中で,"make -f Makefile-cent all clean"とすると,dsim-centができます.他も同様です.FugakuとかZYNQがない人は,うちの研究室に遊びに来れば使えます.

[2022/04/06]シミュレータを使う

最初に作ったtest000-dsimをシミュレータで動かしてみましょう."cd ~/proj-riscv32/sample/test ; ../../src/dsim/dsim test000-dsim"とすると,以下のように表示されるはずです.★部分が,test000.cの出力と実行完了報告です.全部で16スレッドを動かす能力がありますが,test000.cは1スレッドしか使わないので,スレッド0だけが動きます.ちなみに,このシミュレータは,dsim.hを書き換えることで,最大64コア,2048スレッドまで増やすことができます.

RISCV+EMAX6 Simulator Version 1.3 2022/04/02 08:04:35 nakashim Exp nakashim $
 MAXTHRD     =  16                                                 ※スレッド数は16
 MAXCORE     =  4                                                  ※コア数は4
 THR/CORE    =  4.000000 (should be integer)                       ※コア当たりのスレッド数は4
 ROBSIZE     =  16 (actives are CORE_ROBSIZE-1)                    ※リオーダバッファのエントリ数
 LINESIZE    =  64B                                                ※キャッシュラインのサイズ
 I1SIZE      =  16384B (4way delay=16)                             ※命令L1キャッシュサイズ
 D1SIZE      =  16384B (4way delay=16)                             ※データL1キャッシュサイズ
 L2SIZE      =  131072B (4way dirdl=50, cc=100, mm=150)            ※データL1キャッシュサイズ
 MAXL1BK     =  8                                                  ※L1キャッシュバンク数
 MAXL2BK     =  8                                                  ※L2キャッシュバンク数
 MAXMMBK     =  4                                                  ※主記憶バンク数
 memspace    =  00000000-4fffffff                                  ※主記憶空間
 riscv_hdr   =  00001000-                                          ※ELFヘッダ情報,スタックポインタ初期値,引数情報
 riscv_param =  00001080-                                          ※コマンド引数文字列
 aloclimit   = -4dffff00                                           ※malloc()上限
 stack/thr   =  00010000                                           ※スレッドあたりスタックサイズ上限
 stackinit   = -4fffff00                                           ※スタックポインタ初期値
 ELF:text=0001014c rodt=000008e4 data=0000099c sdat=00000010 sbss=00000014 bss=00000034 symt=000013c0 strt=00000bbf
 BSD:text=00011a38 data=000009f8 bss=-------- symt=-------- strt=00000bbf
 init text=00010000-00021a37                                       ※text領域
 init data=00021a38-0002242f                                       ※data領域

 start_address=0x00010000                                          ※実行開始アドレス
 malloc_topadr=0x00022440                                          ※malloc()アドレス初期値
 malloc_latest=0x00022440                                          ※malloc()アドレス最終値
 stack_pointer=0x4fffff00                                          ※スタックポインタ値
00001000: 00022440 00022440 4fffff00 00000001 00001080 00000000 00000000 00000000 ※ELFヘッダ情報,スタックポインタ初期値,引数情報
00001020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00001040: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00001060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00001080: 74736574 2d303030 6d697364 58455400 00000000 00000000 00000000 00000000 ※コマンド引数文字列
000010a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
000010c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
000010e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Monitor-000:00000000_00000000 00010000 IPC=0.000 ROB=
004:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#04待機通知
008:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#08待機通知
012:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#12待機通知
001:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#01待機通知
005:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#05待機通知
009:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#09待機通知
013:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#13待機通知
002:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#02待機通知
006:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#06待機通知
010:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#10待機通知
014:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#14待機通知
003:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#03待機通知
007:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#07待機通知
011:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#11待機通知
015:STOP/COMPLETE steps/cycle=00000000_00000000/00000000_00000001  ※仕事がないのでThread#15待機通知
sizeof DLL=16                                                      ★★★test000.cの出力
Hello                                                              ★★★test000.cの出力
000:EXCSVC RISCV normal end                                        ★★★test000.c正常終了
000:STOP/COMPLETE steps/cycle=00000000_00000d52/00000000_0000c0eb  ★★★test000.c実行命令数とサイクル数
riscv_malloc_top = 0x3a457000                                      ※malloc()アドレス最終値
==== Program normal end. ==== Hit any key in X.                    ※全スレッド停止
====debug information (all bitmaps should be 0)====
l2rq.v_stat:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ※L2ディレクトリの正常動作確認用
d[00].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
d[01].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
d[02].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
d[03].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
d[04].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
d[05].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
d[06].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
d[07].bm/lk:0000/00000000_00000000                                          ※L2ディレクトリの正常動作確認用
====execution time====
exec_ptime=5/128(_SC_CLK_TCK)                                               ※以下は,各スレッドの実行命令数,サイクル数,各キャッシュ利用情報
malloc_top=0070453a
====PE steps, cycles, cache statistics (l1:I$ d1:D$ l2:incore-L2$ g2:other-L2$)====
000:step=00000000_00000d52 cycle=00000000_0000c0eb i1( 94.7%)wait=00000000_00000789 d1( 96.7% hit=00000000_00000663 mis=00000000_00000038)wait=00000000_000015c4 l2(  0.0% hit=00000000_00000000 mis=00000000_000000f2) g2(  0.0% hit=00000000_00000000 mis=00000000_000000e6) flush(L1->00000000_00000ab5cycle, L2->00000000_00000000cycle)
001:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
002:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
003:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
004:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000ab5cycle, L2->00000000_00000000cycle)
005:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
006:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
007:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
008:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000ab5cycle, L2->00000000_00000000cycle)
009:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
010:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
011:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
012:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000ab5cycle, L2->00000000_00000000cycle)
013:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
014:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
015:step=00000000_00000000 cycle=00000000_0000c0eb i1(  nan%)wait=00000000_00000000 d1(  nan% hit=00000000_00000000 mis=00000000_00000000)wait=00000000_00000000 l2(  nan% hit=00000000_00000000 mis=00000000_00000000) g2(  nan% hit=00000000_00000000 mis=00000000_00000000) flush(L1->00000000_00000000cycle, L2->00000000_00000000cycle)
====SELF===
 ru_utime   = 0.043054sec  ru_stime   = 0.001344sec
 ru_maxrss  =   2004KB   ru_ixrss   =    216KB   ru_idrss   = 1840648KB   ru_isrss   =    128KB
 ru_minflt  =      252   ru_majflt  =        0   ru_nswap   =        0   ru_inblock =        0
 ru_oublock =        0   ru_msgsnd  =        0   ru_msgrcv  =        0   ru_nsignals=        0
 ru_nvcsww  =        3   ru_nivcsw  =        0
====CHILD===
 ru_utime   = 0.000000sec  ru_stime   = 0.000000sec
 ru_maxrss  =      0KB   ru_ixrss   =      0KB   ru_idrss   =      0KB   ru_isrss   =      0KB
 ru_minflt  =        0   ru_majflt  =        0   ru_nswap   =        0   ru_inblock =        0
 ru_oublock =        0   ru_msgsnd  =        0   ru_msgrcv  =        0   ru_nsignals=        0
 ru_nvcsww  =        0   ru_nivcsw  =        0

[2022/04/06]シミュレータでCPUの動きを覗く

ところで,この実行方法では,多少の付加情報が出力されますが,命令がどう動いているかはわかりません.シミュレータのいいところは,本物CPUでは覗くことができない内部状態を表示できる点です.今度は,"../../src/dsim/dsim -b0 test000-dsim | less"としてみましょう.全部の内部情報が表示されます.これを見慣れると,立派にコンピュータの専門家です.でも最初は目が回りますね.

" ../../src/dsim/dsim -b0 test000-dsim | egrep '^000:RT' | egrep -v PENDING | uniq | less"としてみましょう.スレッド0の命令実行完了(RETIRE:RT)部分のみが表示されます.これなら,命令が順に実行されている様子を観察できます.初心者向きです.

000:RT 00000000_00000000 00010000 * [cond=e:updt=0]  add/s:R03<-00000000_00022000    ★先頭アドレスから実行開始
000:RT 00000000_00000001 00010004 * [cond=e:updt=0]  add/s:R03<-00000000_00021800
000:RT 00000000_00000002 00010008 * [cond=e:updt=0]  add/s:R10<-00000000_00001000
000:RT 00000000_00000003 0001000c * [cond=e:updt=0]  add/s:R10<-00000000_00001008
000:RT 00000000_00000004 00010010 * [cond=e:updt=0]  lw   :R02<-00000000_4fffff00
000:RT 00000000_00000005 00010014 * [cond=e:updt=0]  add/s:R10<-00000000_00010014
000:RT 00000000_00000006 00010018 * [cond=e:updt=0]  add/s:R10<-00000000_00010240
000:RT 00000000_00000007 0001001c * [cond=e:updt=0]  bl   :R01<-00000000_00010020
000:RT 00000000_00000008 00010200 * [cond=e:updt=0]  add/s:R02<-00000000_4ffffee0
000:RT 00000000_00000009 00010204 * [cond=e:updt=0]  sw   
000:RT 00000000_00000009 00010204 * [cond=e:updt=0]  sw   :A=4ffffefc,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00010020:D1W miss (l1bank=3 A=4ffffefc rq_push=0 pushA=00000000) D1W ENQUEUED stat=2 A=4ffffefc STBF=00000000_00000000_00000000_00010020
000:RT 00000000_0000000a 00010208 * [cond=e:updt=0]  sw   
000:RT 00000000_0000000a 00010208 * [cond=e:updt=0]  sw   :A=4ffffef8,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000:D1W miss (l1bank=3 A=4ffffef8 rq_push=0 pushA=00000000) D1W D1RQWAIT stat=2 A=4ffffef8 STBF=00000000_00000000_00000000_00000000
000:RT 00000000_0000000a 00010208 * [cond=e:updt=0]  sw   :A=4ffffef8,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000:l1bank=3,index=7,way=0,A=4ffffef8,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000,d=1,s=0 D1W COMPLETED:d1w L2 includes l2bank=3 index=63 w=0 A=4ffffef8
000:RT 00000000_0000000b 0001020c * [cond=e:updt=0]  add/s:R08<-00000000_4fffff00
000:RT 00000000_0000000c 00010210 * [cond=e:updt=0]  sw   
000:RT 00000000_0000000c 00010210 * [cond=e:updt=0]  sw   :A=4ffffeec,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00010240:l1bank=3,index=7,way=0,A=4ffffeec,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00010240,d=1,s=0 D1W COMPLETED:d1w L2 includes l2bank=3 index=63 w=0 A=4ffffeec
000:RT 00000000_0000000d 00010214 * [cond=e:updt=0]  add/s:R13<-00000000_00000000
000:RT 00000000_0000000e 00010218 * [cond=e:updt=0]  add/s:R12<-00000000_00000000
000:RT 00000000_0000000f 0001021c * [cond=e:updt=0]  lw   :R11<-00000000_00010240
000:RT 00000000_00000010 00010220 * [cond=e:updt=0]  add/s:R10<-00000000_00000000
000:RT 00000000_00000011 00010224 * [cond=e:updt=0]  bl   :R01<-00000000_00010228
000:RT 00000000_00000012 00012e18 * [cond=e:updt=0]  add/s:R02<-00000000_4ffffeb0
000:RT 00000000_00000013 00012e1c * [cond=e:updt=0]  sw   
000:RT 00000000_00000013 00012e1c * [cond=e:updt=0]  sw   :A=4ffffedc,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_4fffff00:l1bank=3,index=7,way=0,A=4ffffedc,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_4fffff00,d=1,s=0 D1W COMPLETED:d1w L2 includes l2bank=3 index=63 w=0 A=4ffffedc
000:RT 00000000_00000014 00012e20 * [cond=e:updt=0]  sw   
000:RT 00000000_00000014 00012e20 * [cond=e:updt=0]  sw   :A=4ffffed8,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000:l1bank=3,index=7,way=0,A=4ffffed8,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000,d=1,s=0 D1W COMPLETED:d1w L2 includes l2bank=3 index=63 w=0 A=4ffffed8
000:RT 00000000_00000015 00012e24 * [cond=e:updt=0]  add/s:R08<-00000000_4ffffee0
000:RT 00000000_00000016 00012e28 * [cond=e:updt=0]  sw   
000:RT 00000000_00000016 00012e28 * [cond=e:updt=0]  sw   :A=4ffffebc,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000:D1W miss (l1bank=2 A=4ffffebc rq_push=0 pushA=00000000) D1W ENQUEUED stat=2 A=4ffffebc STBF=00000000_00000000_00000000_00000000

                                             【途中省略】

000:RT 00000000_00000cfe 00016554 * [cond=e:updt=0]  add/s:R15<-00000000_00000000
000:RT 00000000_00000cff 00016558 * [cond=e:updt=0]  bne  
000:RT 00000000_00000cff 00016558 RESTARTING
000:RT 00000000_00000d00 0001655c * [cond=e:updt=0]  sw   
000:RT 00000000_00000d00 0001655c * [cond=e:updt=0]  sw   :A=4ffffe5c,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000:l1bank=1,index=7,way=0,A=4ffffe5c,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000,d=1,s=0 D1W COMPLETED:d1w L2 includes l2bank=1 index=63 w=0 A=4ffffe5c
000:RT 00000000_00000d01 00016560 * [cond=e:updt=0]  add/s:R15<-00000000_00000001
000:RT 00000000_00000d02 00016564 * [cond=e:updt=0]  add/s:R20<-00000000_00020169
000:RT 00000000_00000d03 00016568 * [cond=e:updt=0]  add/s:R15<-00000000_00000001
000:RT 00000000_00000d04 0001656c * [cond=e:updt=0]  add/s:R19<-00000000_00000000
000:RT 00000000_00000d05 00016570 * [cond=e:updt=0]  lw   :R15<-00000000_00000001
000:RT 00000000_00000d06 00016574 * [cond=e:updt=0]  add/s:R14<-00000000_00000001
000:RT 00000000_00000d07 00016578 * [cond=e:updt=0]  add/s:R15<-00000000_00000000
000:RT 00000000_00000d08 0001657c * [cond=e:updt=0]  sw   
000:RT 00000000_00000d08 0001657c * [cond=e:updt=0]  sw   :A=4ffffeac,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000:l1bank=2,index=7,way=0,A=4ffffeac,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_00000000,d=1,s=0 D1W COMPLETED:d1w L2 includes l2bank=2 index=63 w=1 A=4ffffeac
000:RT 00000000_00000d09 00016580 * [cond=e:updt=0]  lw   :R15<-00000000_00000000
000:RT 00000000_00000d0a 00016584 * [cond=e:updt=0]  bne  
000:RT 00000000_00000d0a 00016584 RESTARTING
000:RT 00000000_00000d0b 00016588 * [cond=e:updt=0]  add/s:R15<-00000000_00000000
000:RT 00000000_00000d0c 0001658c * [cond=e:updt=0]  b    
000:RT 00000000_00000d0d 000165bc * [cond=e:updt=0]  add/s:R10<-00000000_00000000
000:RT 00000000_00000d0e 000165c0 * [cond=e:updt=0]  lw   :R01<-00000000_000105a8
000:RT 00000000_00000d0f 000165c4 * [cond=e:updt=0]  lw   :R08<-00000000_4ffffed0
000:RT 00000000_00000d10 000165c8 * [cond=e:updt=0]  lw   :R09<-00000000_00000000
000:RT 00000000_00000d11 000165cc * [cond=e:updt=0]  lw   :R18<-00000000_00000000
000:RT 00000000_00000d12 000165d0 * [cond=e:updt=0]  lw   :R19<-00000000_00000000
000:RT 00000000_00000d13 000165d4 * [cond=e:updt=0]  lw   :R20<-00000000_00000000
000:RT 00000000_00000d14 000165d8 * [cond=e:updt=0]  lw   :R21<-00000000_00000000
000:RT 00000000_00000d15 000165dc * [cond=e:updt=0]  lw   :R22<-00000000_00000000
000:RT 00000000_00000d16 000165e0 * [cond=e:updt=0]  add/s:R02<-00000000_4ffffe80
000:RT 00000000_00000d17 000165e4 * [cond=e:updt=0]  br   
000:RT 00000000_00000d17 000165e4 RESTARTING
000:RT 00000000_00000d18 000105a8 * [cond=e:updt=0]  add/s:R15<-00000000_00000000
000:RT 00000000_00000d19 000105ac * [cond=e:updt=0]  beq  
000:RT 00000000_00000d1a 000105b8 * [cond=e:updt=0]  add/s:R15<-00000000_0000000a
000:RT 00000000_00000d1b 000105bc * [cond=e:updt=0]  sw   
000:RT 00000000_00000d1b 000105bc * [cond=e:updt=0]  sw   :A=4ffffeb0,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_0000000a:l1bank=2,index=7,way=0,A=4ffffeb0,M=00000000_00000000_00000000_ffffffff<-00000000_00000000_00000000_0000000a,d=1,s=0 D1W COMPLETED:d1w L2 includes l2bank=2 index=63 w=1 A=4ffffeb0
000:RT 00000000_00000d1c 000105c0 * [cond=e:updt=0]  lw   :R15<-00000000_0000000a
000:RT 00000000_00000d1d 000105c4 * [cond=e:updt=0]  add/s:R10<-00000000_0000000a
000:RT 00000000_00000d1e 000105c8 * [cond=e:updt=0]  lw   :R01<-00000000_000105fc
000:RT 00000000_00000d1f 000105cc * [cond=e:updt=0]  lw   :R08<-00000000_4ffffef0
000:RT 00000000_00000d20 000105d0 * [cond=e:updt=0]  add/s:R02<-00000000_4ffffed0
000:RT 00000000_00000d21 000105d4 * [cond=e:updt=0]  br   
000:RT 00000000_00000d21 000105d4 RESTARTING
000:RT 00000000_00000d22 000105fc * [cond=e:updt=0]  add/s:R15<-00000000_0000000a
000:RT 00000000_00000d23 00010600 * [cond=e:updt=0]  add/s:R10<-00000000_0000000a
000:RT 00000000_00000d24 00010604 * [cond=e:updt=0]  lw   :R01<-00000000_000101f0
000:RT 00000000_00000d25 00010608 * [cond=e:updt=0]  lw   :R08<-00000000_00000000
000:RT 00000000_00000d26 0001060c * [cond=e:updt=0]  add/s:R02<-00000000_4ffffef0
000:RT 00000000_00000d27 00010610 * [cond=e:updt=0]  br   
000:RT 00000000_00000d27 00010610 RESTARTING
000:RT 00000000_00000d28 000101f0 * [cond=e:updt=0]  lw   :R01<-00000000_00010040
000:RT 00000000_00000d29 000101f4 * [cond=e:updt=0]  add/s:R10<-00000000_00000000
000:RT 00000000_00000d2a 000101f8 * [cond=e:updt=0]  add/s:R02<-00000000_4fffff00
000:RT 00000000_00000d2b 000101fc * [cond=e:updt=0]  br   
000:RT 00000000_00000d2b 000101fc RESTARTING
000:RT 00000000_00000d2c 00010040 * [cond=e:updt=0]  add/s:R17<-00000000_00000011    ★_start.sに戻ってきました
000:RT 00000000_00000d2d 00010044 * [cond=e:updt=0]  ecal                            ★exit()システムコールに到達して実行完了

[2022/04/06]画像処理プログラムを試す

最後に,画像処理プログラムを試しましょう."cd ~/proj-riscv32/sample/filter; ../../src/dsim/dsim -x filter-dsim -f 81.ppm 82.ppm"です.

[2022/04/06]評価

ARMv8と比べたコード効率とか,まだいろいろ書きたいですが,またいずれ.CGRAくっつける話は,Youtubeチャンネルに続きます.

© Copyrights Computing Architecture Lab. All Rights Reserved

Created with Link template by TemplateMag