リムナンテスは愉快な気分

徒然なるままに、言語、数学、音楽、プログラミング、時々人生についての記事を書きます

デコーダーを作る

Verilogでマイクロプロセッサ設計第4回

多忙でなかなか更新できなかったのですが、続き。

制作中のマイクロプロセッサ、現時点では計算らしいことは足し算くらいしかできませんが、第4回から第5回、第6回、と3回にわたり計算モジュールの拡張(ALUの実装)をしていきます。

さて、MISPでは32bitの命令形式が3種(R型、I型、A型)あります。

当面は以下の命令を実行できるようにすることを目標にします(MISPの命令はこれら以外にもあります)。

R型命令
ニーモニック 命令型 オペコード AUX 動作 説明
ADD R 0 0 rd <- rs + rt
SUB R 0 2 rd <- rs - rt
AND R 0 8 rd <- rs & rt
OR R 0 9 rd <- rs | rt
XOR R 0 10 rd <- rs ^ rt
NOR R 0 11 rd <- ~( rs | rt )
I型命令
ニーモニック 命令型 オペコード AUX 動作 説明
ADDI I 1 imm rd <- rs + imm immは符号拡張
LUI I 3 imm rd <- imm << 16
ANDI I 4 imm rd <- rs & imm immはゼロ拡張
ORI I 5 imm rd <- rs | imm immはゼロ拡張
XORI I 6 imm rd <- rs ^ imm immはゼロ拡張

先に述べた通り、MIPSの命令は32bit、32桁の2進数の羅列なのですが、そのままではハードウェアに命令の「意味」は伝わりません。命令をどのように「解釈」すべきかはこちらが教えてあげなければならない。その為に必要なのが「デコーダー」、ということなのです。第4回ではデコーダーを設計していきます。

入力と出力を考えてみましょう。入力はとりあえず命令(ins)だけです。出力は読み込みレジスタ番号2つ(rra1, rra2)、書き込みレジスタ番号1つ(rwa)、即値(imm)、といったところでしょうか。

module decode(
  input[31:0] ins,
  output[4:0] rra1, rra2, wra,
  output[15:0] imm
  );
  wire[5:0] op;
  wire[4:0] rs, rt, rd;

  // parse
  assign op = ins[31:26];
  assign rs = ins[25:21];
  assign rt = ins[20:16];
  assign rd = ins[15:11];

  assign imm = ins[15:0];
  assign rra1 = rs;
  assign rra2 = (op==6'd0)? rt: rd;
  assign rwa = rd;

endmodule

3項演算子を使っていますが、(条件式)? 真: 偽 のように使います。慣れないうちはよく分からないかもしれませんが、慣れるとif文で記述するよりも見通しがいいです。あくまでも個人の感想ですが。