もうすぐコンテストがあるそうなので、予習してみました。(書きかけです)
機械語の読み方
引数を設定してvsmファイルをアセンブラに投げると読みやすくなる
--print-asmをつけるとコードの後ろに元の命令がコメントで付く
$ /assemble3 hello.vsm --print-asm
i 01000000...000000000000001100000000000000 # imm ui"0" $n0
--print-csvをつけると、フィールドごとに分割してくれる
i,ll,pe.mrc.imr,pe.mrc.wl,...,l2bm.darwrite,wd
m,valid,mmode,tmode,...,adrb,nw,priority
i,="01",="00000",="0",="0",="0",="0",...,="000",="11",="0000",="0",="0",="00000000",
一行目はi命令のコラム名一覧で、二行目はm命令のコラム名一覧になる。
i命令はPE命令のauto strideモードの機械語
m命令はMV命令の機械語
ここではi命令だけに注目する
PE命令のフィールド
PE命令は以下のフィールドを持つ
| PE命令 | ||||||||||||
| i | ll | pe | l1bm | l2bm | wd | |||||||
| mrc | trc | rfc0 | rfc1 | lm0 | lm1 | mauc | aluc | |||||
| i | 2bit | 20bit | 3bit | 41bit | 41bit | 32bit | 31bit | 29bit | 17bit | 40bit | 28bit | 8bit |
各フィールドに対応するコンポーネントは以下のようになる
| フィールド | コントローラ |
|---|---|
| pe.mrc | マスクレジスタ |
| pe.trc | Tレジスタ(t) |
| pe.rfc0 | RF0レジスタ(r) |
| pe.rfc1 | RF1レジスタ(s) |
| pe.lm0 | LM0メモリ(m) |
| pe.lm1 | LM1メモリ(n) |
| pe.mauc | MAU |
| pe.aluc | ALUC |
| l1bm | L1BM(b) |
| l2bm | L2BM(c) |
さらに細かいフィールドは各コンポーネントごとに記述する
PE命令の複数の出力オペランド
PE命令は複数の出力オペランドを指定できる。これは以下のような仕組みでコード化する。
例としてALUの計算結果を複数の出力先(t, r, s, m, n)に保存する命令は
| PE命令 | ||||||||||||
| i | ll | pe | l1bm | l2bm | wd | |||||||
| mrc | trc | rfc0 | rfc1 | lm0 | lm1 | mauc | aluc | |||||
| i | - | - | write=1 | write=1 | write=1 | write=1 | write=1 | - | ALUOP | - | - | - |
| isel=ALU | isel=ALU | isel=ALU | isel=ALU | isel=ALU | ||||||||
このようにalucで計算を指定し、各々の出力先(trc, rfc0, rfc1, lm0, lm1)の書き込みを有効にし(write=1)、入力セレクタにALUを指定(isel=ALU)する。
同様にMAUとALUで計算して結果を(r, s, t, m, n)に分けて保存したい場合は
| PE命令 | ||||||||||||
| i | ll | pe | l1bm | l2bm | wd | |||||||
| mrc | trc | rfc0 | rfc1 | lm0 | lm1 | mauc | aluc | |||||
| i | - | - | write=1 | write=1 | write=1 | write=1 | write=1 | MAUOP | ALUOP | - | - | - |
| isel=MAU | isel=ALU | isel=MAU | isel=ALU | isel=MAU | ||||||||
のようにコード化される。このコード化により複数出力オペランドが可能となる。
PE命令の入力オペランド
ALUは2つの入力オペランドAとBを持つ。命令によってオペランド数は0、1、2の場合がある。
MAUは3つの入力オペランドAとBとCを持つ。命令によってはBは行列となり、行列レジスタxかyを使う。
例えば、ALUの入力オペランドAがrの場合は次のようにコード化する。
| PE命令 | ||||||||||||
| i | ll | pe | l1bm | l2bm | wd | |||||||
| mrc | trc | rfc0 | rfc1 | lm0 | lm1 | mauc | aluc | |||||
| i | - | - | - | radr=アドレス | - | - | - | - | ALUOP | - | - | - |
| isela=r | ||||||||||||
このようにコード化する。出力オペランドのときとは逆にALU側のiselを設定し、データソース側はアドレスを指定する。
ALUとMAUがrから同じデータを受け取って計算する場合は次のようにコード化する。
| PE命令 | ||||||||||||
| i | ll | pe | l1bm | l2bm | wd | |||||||
| mrc | trc | rfc0 | rfc1 | lm0 | lm1 | mauc | aluc | |||||
| i | - | - | - | radr=アドレス | - | - | - | MAUOP | ALUOP | - | - | - |
| isela=r | isela=r | |||||||||||
このように同じアドレスを読む限りで、MAUとALUに同時にrから入力可能となる。
ALUのポートA
ALUのポートAは以下の入力をiselに指定できる。このポートは$peidなどの固定値を指定できる。(TODO: 15個しかないので1つ忘れてるかも???)
| 入力 |
|---|
| r |
| s |
| t |
| m |
| n |
| $peid |
| $l1bid |
| $l2bid |
| $msb1 |
| $subpeid |
| $mabid |
| $mauf |
| $aluf |
| $lbf |
| $mreadf |
ALUのポートB
ALUのポートBは以下の入力をiselに指定できる。Aと異なり固定値は指定できないのと$mreadfも指定できない。
| 入力 |
|---|
| r |
| s |
| t |
| m |
| n |
| $mauf |
| $aluf |
| $lbf |
MAUのポート
MAUのポートは以下の入力をiselに指定できる。ALUのポートBと同じ。
| 入力 |
|---|
| r |
| s |
| t |
| m |
| n |
| $mauf |
| $aluf |
| $lbf |
TRC
Tレジスタの制御を行う。
フィールドは以下の通り。
| pe | |
| trc | |
| write | isel |
| 1bit | 2bit |
write=1のときはiselで指定した入力から書き込みを行う。そうでないときは読み出しのみ行う。
アドレス指定やワード長指定はなく、2長語×4サイクルのアクセスで固定。(TODO: iselの計算結果が1長語のときを調べる)
iselに指定できる入力
| isel |
|---|
| MAU |
| ALU |
| L1BM |
| MREAD |
ハザード: 書き込み後は1ステップ休む
RFC0とRFC1
レジスタファイルの制御を行う。
フィールドは以下の通り。
| pe | |||||||||||||||
| rfc0/rfc1 | |||||||||||||||
| write | isel | wadr | wadri | wwl | radr | radri | rwl | ||||||||
| 1bit | 2bit | 9bit | 8bit | 2bit | 9bit | 8bit | 2bit | ||||||||
write=1のときはiselで指定した入力から書き込みを行う。そうでないときは読み出しのみ行う。
wadrとwadriとwwlで書き込みアドレス、書き込みアドレス増分、書き込みワード長を指定する。
radrとradriとrwlで読み出しアドレス、読み出しアドレス増分、読み出しワード長を指定する。
アクセスするアドレスはサイクルごとに
| サイクル | アドレス |
|---|---|
| 0 | adr + adri * 2 * wl * 0 |
| 1 | adr + adri * 2 * wl * 1 |
| 2 | adr + adri * 2 * wl * 2 |
| 3 | adr + adri * 2 * wl * 3 |
コード例(TODO: 動作確認して)
| コード | adr | adri | wl | アドレス |
|---|---|---|---|---|
$lr4 |
4 | 0 | 1 | (4, 4, 4, 4) |
$lr4v |
4 | 1 | 1 | (4, 6, 8, 10) |
$lr4v2 |
4 | 1 | 1 | (4, 6, 8, 10) |
$llr4v4 |
4 | 1 | 2 | (4, 8, 12, 16) |
iselに指定できる入力
| isel |
|---|
| MAU |
| ALU |
| L1BM |
| MREAD |
ハザード: 書き込み後は1ステップ休む(アドレスごとに独立)。
続きはまた書く