2011年11月24日木曜日

独自のCPUを創ってみる(2)


by yosikawa » 2011年11月24日(木) 09:41
独自のCPUを創ってみるで創ったCPUを、さらに発展させた。

2011/11/13 v5

普通、アドレスはバイト単位で数えるが、これまでは32bit単位で数えていた。
1ワードが4バイトだからpcは4ずつ増えるのが普通なので、そのように修正した。
pcは30bitとし、下位2bitは常に0とする。関節アドレッシングにおいても、
ワード境界以外でアクセスするのは禁止して、下位2bitは常に0とする。

2011/11/13 v6

これまで、レジスタは A(アキュムレータのつもり), IX(インデックスレジスタ),PC(プログラムカウンタ) の3個だった。
これを世間でよく見られるような16個の汎用レジスタで置き換える。
R0 ~ R15 (R15 はPCの機能を兼ねる)

命令コードの体系をとりあえず以下のようにしてみる。
instr[31:24] 命令の種別 (8)
instr[23:20] 予備 (4)
instr[19:16] 結果を格納するレジスタの指定 (4)
instr[15:12] オペランドレジスタの指定-1 (4)
instr[11: 8] オペランドレジスタの指定-2 (4) まだ使わない
instr[ 7: 0] 予備 (4)

命令体系を整理した結果、NOPとJMPは不要になった。
新しい命令は以下の通り。

MV Rn,Rm
MV Rn,im
MV Rn,[Rm]
MV Rn,[im]
MV [Rn],Rm
MV [im],Rm

NOPとJMPは以下のように置き換えられる。
NOP => MV R0,R0
JMP im => MV R15,im

複数のレジスタを自由に使えるようになったため、だんだんそれらしくなってきた。

2011/11/13 v7

ALUをサポートする。
演算の種類は以下のようにしてみる。

// 0: MV Rd = Rj 代入
// 1: ADC Rd = Ri + Rj + C キャリー付き加算
// 2: SBC Rd = Ri - Rj - C キャリー付き減算
// 3: RSC Rd = Rj - Ri - C オペランド逆転減算
// 4: AND Rd = Ri AND Rj 論理積
// 5: OR Rd = Ri OR Rj 論理和
// 6: XOR Rd = Ri XOR Rj 排他的論理和
// 7: CMP Ri - Rj 比較
// 8: TST Ri AND Rj テスト

命令の体系は以下のように拡張した。
// 命令コードの体系
// instr[31:28] アドレッシングモード (4)
// instr[27:24] 演算の種別 (4)
// instr[23:20] 予備 (4)
// instr[19:16] 結果を格納するレジスタRdの指定 (4)
// instr[15:12] オペランドレジスタRiの指定 (4)
// instr[11: 8] オペランドレジスタRjの指定 (4)
// instr[ 7: 0] 予備 (8)

2011/11/13 v8

ARMの条件付き実行フラグのような機能をサポートする。
(これによって条件分岐も利用できる)

余っている instr[23:20] を条件付き実行フラグとする。

0: AL 無条件
2: CC Ri >= Rj,C=0
3: CS Ri < Rj,C=1
4: NE Ri != Rj,Z=0
5: EQ Ri == Rj,Z=1
6: PL Rd >= 0, N=0
7: MI Rd < 0, N=1
8: VC オーバフローでない,V=0
9: VS オーバフロー,V=1
10:HI Ri > Rj (符号なし), C=0 AND Z=0
11:LS Ri <= Rj (符号なし), C=1 OR Z=1
12:LT Ri < Rj, N!=V
13:GE Ri >= Rj, N==V
14:GT Ri > Rj, Z=0 AND N==V
15:LE Ri <= Rj, Z=1 AND N!=V

ついでに、シフト命令を追加する。演算の体系は以下のように豪華になってきた。

// ALU
// 0: MV Rd = Rj 代入
// 1: MV Rd = ~Rj 反転代入
// 2: ADD Rd = Ri + Rj 加算
// 3: ADC Rd = Ri + Rj + C キャリー付き加算
// 4: SUB Rd = Ri - Rj 減算
// 5: SBC Rd = Ri - Rj - C キャリー付き減算
// 6: RSC Rd = Rj - Ri - C オペランド逆転減算
// 7: RSC Rd = Rj - Ri - C オペランド逆転減算
// 8: AND Rd = Ri AND Rj 論理積
// 9: OR Rd = Ri OR Rj 論理和
//10: XOR Rd = Ri XOR Rj 排他的論理和
//11: LSL Rd = Rj<<1 左シフト
//12: LSR Rd = Rj>>1 右シフト
//13: ASR Rd = Rj[31],Rj>>1 算術右シフト
//14: CMP Ri - Rj 比較
//15: TST Ri AND Rj テスト

命令体系は以下のようにした。

// 命令コードの体系
// instr[31:28] アドレッシングモード (4)
// instr[27:24] 演算の種別 (4)
// instr[23:20] 条件付き実行フラグ (4)
// instr[19:16] 結果を格納するレジスタRdの指定 (4)
// instr[15:12] オペランドレジスタRiの指定 (4)
// instr[11: 8] オペランドレジスタRjの指定 (4)
// instr[ 7: 0] 予備 (8)

CPUの創り方がだいぶ身についてきたようで、ここまでスイスイと進んだ。
ただし、ぜんぜんテストしてないので多分バグだらけで動かないだろう。
そこで開発と並行してテストをやり始めたのだが、これが大変で10日ほどハマることに。。。

0 件のコメント:

コメントを投稿