2.アーキテクチャ

 命令幅、演算語長


 設計が簡単なのは32ビット幅です。いきなり32ビットなんて、、と心配する必要はありません。本当に簡単なのは32ビットなのです。8ビットCPUにしようものなら、デコーダが複雑になりすぎます。では、16ビットではどうかというと、非常に簡単なインストラクションしかサポートしないのならいいのですが、後で独自命令を付け加えられることを考えるとやっぱり足りない、実用的かつ、設計が簡単ということを考えるなら、32ビット以上でRISCが、お勧めです。
 3オペランドというのは、c=a+bです。つまり、aレジスタ + bレジスタ => cレジスタと言う具合に3つのレジスタ
を、独立に指定できます。これに対し16ビット以下のCPUの殆どは、a=a+bという命令しか実装していません。考え方としてどちらが自然かは自明でしょう。どうしてこのようになったかというと命令フィールドが足りないからです。たとえば、16レジスタあったとして、それを指定するのは、4ビット必要です。それが、独立に3個分要ると12ビットを消費してしまいます。固定長フォーマット16ビット固定を仮定すると、16-12で残り4ビットしかありません。残り4ビットでは、3オペランドを取る限り16命令しか実装できません。ということで、16ビットでも厳しいことが分かると思います。という訳で、32ビットはごくごく自然な結果なのです。

 
プログラムカウンタ 

26ビットにしていますが、手持ちのFPGA内蔵RAMは、16KBしか積めないので実際的には、FPGA搭載RAM容量で制限されてしまいます。外部RAMをアクセスする機構は、実装しておりません。

プログラムカウンタ(PC)
26ビット


レジスタ
32x32の32ビットです。リードは2ポート、ライトは1ポート、計3ポートが必要です。Alteraでは、3ポートRAMがありますので、それを使えばよいです。Xilinxでは、3ポートがありません。分散RAMを使えば合成できますが、それをやってしまうとスタータキットでは、リソース不足になってしまうので、どうしてもBLOCK RAMを使わざるえず、3ポートRAMは、使えません。そこで、Xilinxは、同じレジスタファイルを2個使います。ライトは共通とすることで、レジスタファイルの中身は常に同じになります。従って、2ポートRAMx2=>3ポートRAMとして使えることになります。


命令フォーマット
32ビット固定長、5段パイプラインに決定しました。


インストラクション

下表は、インプリメントする全命令です。全命令を5ステージパイプラインで実行します。ジャンプ、ブランチ系命令でブランチした場合3-4クロックかかる他は、メモリのR/Wを含め全て1クロックで実行します。 ただし、ブランチハザード、データハザードは対応していませんので、コンパイラやアセンブラで対応する必要があります。

余談です。MIPS互換を狙って最初から設計したのではないのですが、設計していくうちに同じなってしまいました。GCCの成果を利用できるなら、と割りきりました。CPUのパイプラインの設計は筆者も初めてなのですが、設計を通じてディレイドブランチや、zeroレジスタ、Jump&Link等、RISCだと必ずでてくる言葉の必然性を理解することができました。加えてCPUのどこがCritical Pathかであるか身を持って知ることができました。なにが問題かを知ることができたのは収穫でした。RISCが出た頃、斬新だった手法も、いまや古典の趣があります。MIPS(TM)アーキテクチャは、今やRISC、否CPUの教科書ではないでしょうか?

パイプラインの割付は、Stratixで合成しながら、チューニングするという原始的な方法で行いました。


以下のMIPSインストラクション-Iの内、未実装はで示しています。 とりあえず、現サポートの命令セットで、ドライストーン、リードソロモン、等いくつかのCプログラムを走らせましたが、支障はありませんでした。(サポートしていない命令は出現しませんでした。特に、分岐リンク等は、命令の存在意義について筆者は疑問を持っています。加えて現在Critical Pathになっているところに追加なので、なるべくならハードはいじりたくない気分です。GCCのコードジェネレートでなんとかならないでしょうか?)
 また、LWL,SWL,LWR,SWRはアラインされていないメモリに対する転送命令ですが、パテントになっており今後共、実装予定はありません。MTHI,MTLOは、恐らく割り込みと乗除算がかさなったときの退避のために存在する命令ですが、現在は乗除中の割り込みを禁止していることと、まともな割り込みコントローラを実装していないのでインプリメントしていません。

ADD -- Add

Description: Adds two registers and stores the result in a register(Overflowで例外発生)
Operation: $d = $s + $t;
Syntax: add $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5ビット 6'b100_000

ADDI -- Add immediate

Description: Adds a register and a signed immediate value and stores the result in a register
Operation: $t = $s + imm;
Syntax: addi $t, $s, imm
Encoding:
OPCODE Source Target Immediate
6'b001000 5ビット 5ビット 16ビット

ADDIU -- Add immediate unsigned

Description: Adds a register and an unsigned immediate value and stores the result in a register
Operation: $t = $s + imm;
Syntax: addiu $t, $s, imm
Encoding:
OPCODE Source Target Immediate
6'b001001 5ビット 5ビット 16ビット

ADDU -- Add unsigned

Description: Adds two registers and stores the result in a register
Operation: $d = $s + $t;
Syntax: addu $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b100_001

AND -- Bitwise and

Description: Bitwise ands two registers and stores the result in a register
Operation: $d = $s & $t;
Syntax: and $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b100100

ANDI -- Bitwise and immediate

Description: Bitwise ands a register and an immediate value and stores the result in a register
Operation: $t = $s & imm;
Syntax: andi $t, $s, imm
Encoding:
OPCODE Source Target Immediate
6'b001100 5ビット 5ビット 16ビット

BEQ -- Branch on equal

Description: Branches if the two registers are equal
Operation: if $s == $t PC +=imm << 2;
Syntax: beq $s, $t, imm
Encoding:
OPCODE Source Target Immediate
6'b000100 5ビット 5'h0 16ビット

BGEZ -- Branch on greater than or equal to zero

Description: Branches if the register is greater than or equal to zero
Operation: if $s >= 0 PC +=offset << 2;
Syntax: bgez $s, offset
Encoding:
OPCODE Source Target Immediate
6'b000001 5ビット 5'b00001 16ビット

BGEZAL -- Branch on greater than or equal to zero and link

Description: Branches if the register is greater than or equal to zero and saves the return address in $31
Operation: if $s >= 0 $31 = PC + 8 ; PC +=imm << 2;
Syntax: bgezal $s, imm
Encoding:
OPCODE Source Target Immediate
6'b000001 5ビット 5'h10001 16ビット

BGTZ -- Branch on greater than zero

Description: Branches if the register is greater than zero
Operation: if $s > 0 PC +=imm << 2;
Syntax: bgtz $s, imm
Encoding:
OPCODE Source Target Immediate
6'b000111 5ビット 5'h0 16ビット

BLEZ -- Branch on less than or equal to zero

Description: Branches if the register is less than or equal to zero
Operation: if $s <= 0 PC +=imm << 2;
Syntax: blez $s, imm
Encoding:
OPCODE Source Target Immediate
6'b000110 5ビット 5'h0 16ビット

BLTZ -- Branch on less than zero

Description: Branches if the register is less than zero
Operation: if $s < 0 PC+=imm << 2;
Syntax: bltz $s, imm
Encoding:
OPCODE Source Target Immediate
6'b00001 5ビット 5'b00000 16ビット

BLTZAL -- Branch on less than zero and link

Description: Branches if the register is less than zero and saves the return address in $31
Operation: if $s < 0 $31 = PC + 8 ; PC+=imm << 2;
Syntax: bltzal $s, imm
Encoding:
OPCODE Source Target Immediate
6'b000001 5ビット 5'b10000 16ビット

BNE -- Branch on not equal

Description: Branches if the two registers are not equal
Operation: if $s != $t PC+=imm << 2;
Syntax: bne $s, $t, imm
Encoding:
OPCODE Source Target Immediate
6'b000101 5ビット 5'h0 16ビット

Break -- Break

Description: Generates break point.
Operation:
Syntax: break
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 ????? ????? ????? ????? 6'b001101



DIV -- Divide

Description: Divides $s by $t and stores the quotient in $LO and the remainder in $HI
Operation: $LO = $s / $t; $HI = $s % $t;
Syntax: div $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5'h0 5'h0 6'b011010

DIVU -- Divide unsigned

Description: Divides $s by $t and stores the quotient in $LO and the remainder in $HI
Operation: $LO = $s / $t; $HI = $s % $t;
Syntax: divu $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5'h0 5'h0 6'b011011

J -- Jump

Description: Jumps to the calculated address
Operation: PC = nPC; nPC = (PC & 0xf0000000) | (imm26 << 2);
Syntax: j imm26
Encoding:
OPCODE Immediate
6'b000010 26ビット

JAL -- Jump and link

Description: Jumps to the calculated address and stores the return address in $31
Operation: $31 = PC + 8 ; PC = nPC; nPC = (PC & 0xf0000000) | (imm26 << 2);
Syntax: jal imm26
Encoding:
OPCODE Immediate
6'b000011 26ビット

JALR -- Jump and link Register

Description: Jump to the address contained in register $s and stores the return address in $d
Operation: $d = PC + 8 ; PC = $s
Syntax: jalr $d,$s
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5'h0 5ビット 5'h0 6'b001001

JR -- Jump register

Description: Jump to the address contained in register $s
Operation: PC = nPC; nPC = $s;
Syntax: jr $s
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5'h0 5'h0 5'h0 6'b001000

LB -- Load byte

Description: A signed extented byte is loaded into a register from the specified address.
Operation: $t = MEM[$s + imm]; ;
Syntax: lb $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b100000 5ビット 5ビット 16ビット

LBU -- Load byte unsigned

Description: A unsigned extented byte is loaded into a register from the specified address.
Operation: $t = MEM[$s + imm]; ;
Syntax: lbu $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b100100 5ビット 5ビット 16ビット


LH -- Load Half

Description: A signed extented half word is loaded into a register from the specified address.
Operation: $t = MEM[$s + imm]; ;
Syntax: lh $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b100001 5ビット 5ビット 16ビット


LHU -- Load Half unsigned

Description: A byte is loaded into a register from the specified address.
Operation: $t = MEM[$s + imm]; ;
Syntax: lhu $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b100101 5ビット 5ビット 16ビット


LUI -- Load upper immediate

Description: The immediate value is shifted left 16 bits and stored in the register. The lower 16 bits are zeroes.
Operation: $t = (imm << 16);
Syntax: lui $t, imm
Encoding:
OPCODE Source Target Immediate
6'b001111 ????? 5ビット 16ビット

LW -- Load word

Description: A word is loaded into a register from the specified address.
Operation: $t = MEM[$s + imm];
Syntax: lw $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b100011 5ビット 5ビット 16ビット

MFHI -- Move from HI

Description: The contents of register HI are moved to the specified register.
Operation: $d = $HI;
Syntax: mfhi $d
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5'h0 5'h0 5ビット 5'h0 6'b010000

MFLO -- Move from LO

Description: The contents of register LO are moved to the specified register.
Operation: $d = $LO;
Syntax: mflo $d
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5'h0 5'h0 5ビット 5'h0 6'b010010

MTHI -- Move to HI

Description: The contents of register $s are moved to $HI.
Operation: $HI=$s;
Syntax: mthi $s
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5'ビット 5'h0 5'h0 5'h0 6'b010001

MTLO -- Move to LO

Description: The contents of register $s are moved to $HI.
Operation: $LO=$s;
Syntax: mtlo $s
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5'ビット 5'h0 5'h0 5'h0 6'b010011


MULT -- Multiply

Description: Multiplies $s by $t and stores the result in $LO.
Operation: $LO = $s * $t;
Syntax: mult $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5'h0 5'h0 6'b011000

MULTU -- Multiply unsigned

Description: Multiplies $s by $t and stores the result in $LO.
Operation: $LO = $s * $t;
Syntax: multu $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5'h0 5'h0 6'b011001

NOR -- Bitwise nor

Description: Bitwise logical nors two registers and stores the result in a register
Operation: $d = ~($s | $t);
Syntax: nor $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b100111


OR -- Bitwise or

Description: Bitwise logical ors two registers and stores the result in a register
Operation: $d = $s | $t;
Syntax: or $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b100101

ORI -- Bitwise or immediate

Description: Bitwise ors a register and an immediate value and stores the result in a register
Operation: $t = $s | imm;
Syntax: ori $t, $s, imm
Encoding:
OPCODE Source Target Immediate
6'b001101 5ビット 5ビット 16ビット

SB -- Store byte

Description: The least significant byte of $t is stored at the specified address.
Operation: MEM[$s + imm] = (0xff & $t);
Syntax: sb $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b101000 5ビット 5ビット 16ビット

SH -- Store Half

Description: The least significant half word of $t is stored at the specified address.
Operation: MEM[$s + imm] = (0xffff & $t);
Syntax: sh $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b101001 5ビット 5ビット 16ビット


SLL -- Shift left logical

Description: Shifts a register value left by the shift amount listed in the instruction and places the result in a third register. Zeroes are shifted in.
Operation: $d = $t << h;
Syntax: sll $d, $t, h
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット h 6'b000000

SLLV -- Shift left logical variable

Description: Shifts a register value left by the value in a second register and places the result in a third register. Zeroes are shifted in.
Operation: $d = $t << $s;
Syntax: sllv $d, $t, $s
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット ????? 6'b000100

SLT -- Set on less than (signed)

Description: If $s is less than $t, $d is set to one. It gets zero otherwise.
Operation: if $s < $t $d = 1; else $d = 0;
Syntax: slt $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b101010

SLTI -- Set on less than immediate (signed)

Description: If $s is less than immediate, $t is set to one. It gets zero otherwise.
Operation: if $s < imm $t = 1; else $t = 0;
Syntax: slti $t, $s, imm
Encoding:
OPCODE Source Target Immediate
6'b001010 5ビット 5ビット 16ビット

SLTIU -- Set on less than immediate unsigned

Description: If $s is less than the unsigned immediate, $t is set to one. It gets zero otherwise.
Operation: if $s < imm $t = 1; else $t = 0;
Syntax: sltiu $t, $s, imm
Encoding:
OPCODE Source Target Immediate
6'b001011 5ビット 5ビット 16ビット

SLTU -- Set on less than unsigned

Description: If $s is less than $t, $d is set to one. It gets zero otherwise.
Operation: if $s < $t $d = 1; else $d = 0;
Syntax: sltu $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b101011

SRA -- Shift right arithmetic

Description: Shifts a register value right by the shift amount (shamt) and places the value in the destination register. The sign bit is shifted in.
Operation: $d = $t >> h;
Syntax: sra $d, $t, h
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット h 6'b000011


SRAV -- Shift right arithmatic variable

Description: Shifts a register value right by the value in a second register and places the result in a third register. the sign bit is shifterd in.
Operation: $d = $t >> $s;
Syntax: srav $d, $t, $s
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット ????? 6'b000111


SRL -- Shift right logical

Description: Shifts a register value right by the shift amount (shamt) and places the value in the destination register. Zeroes are shifted in.
Operation: $d = $t >> h;
Syntax: srl $d, $t, h
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット h 6'b000010

SRLV -- Shift right logical variable

Description: Shifts a register value right by the amount specified in $s and places the value in the destination register. Zeroes are shifted in.
Operation: $d = $t >> $s;
Syntax: srlv $d, $t, $s
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b000110

SUB -- Subtract

Description: Subtracts two registers and stores the result in a register(Overflowで例外発生)
Operation: $d = $s - $t;
Syntax: sub $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b100010

SUBU -- Subtract unsigned

Description: Subtracts two registers and stores the result in a register
Operation: $d = $s - $t;
Syntax: subu $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット 5'h0 6'b100011

SW -- Store word

Description: The contents of $t is stored at the specified address.
Operation: MEM[$s + imm] = $t;
Syntax: sw $t, imm($s)
Encoding:
OPCODE Source Target Immediate
6'b101011 5ビット 5ビット 16ビット

SYSCALL -- System call

Description: Generates a software interrupt.
Operation:
Syntax: syscall
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 ????? ????? ????? ????? 6'b001100

XOR -- Bitwise exclusive or

Description: Exclusive ors two registers and stores the result in a register
Operation: $d = $s ^ $t;
Syntax: xor $d, $s, $t
Encoding:
OPCODE Source Target Destination Shift Function
6’b000000 5ビット 5ビット 5ビット ????? 6'b100110

XORI -- Bitwise exclusive or immediate

Description: Bitwise exclusive ors a register and an immediate value and stores the result in a register
Operation: $t = $s ^ imm;
Syntax: xori $t, $s, imm
Encoding:
OPCODE Source Target Immediate
6'b001110 5ビット 5ビット 16ビット