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

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

レジスタファイル設置

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

MIPSレジスタは32bit×32個あります。
それぞれの使い方はここらへんを見ると、

名前 番号 用途
$zero 0 常に0(書き込み不可)
$at 1 アセンブラ使用
$v0 - $v1 2-3 戻り値
$a0 - $a3 4-7 引数
$t0 - $t7 8-15 一時変数用
$s0 - $s7 16-23 退避が必要な変数用
$t8 - $t9 24-25 一時変数用
$k0 - $k1 26-27 OS用
$gp 28 グローバルポインタ
$sp 29 スタックポインタ
$fp 30 フレームポインタ
$ra 31 戻りアドレス記憶用

レジスタファイルの仕様は
入力:読出データのレジスタ番号×2、書込データ、書込データのレジスタ番号
出力:レジスタファイルの中身(データ)×2

module regfile(
  input clk,
  input[4:0] rra1, rra2, wra, // read/write register-file address
  input[31:0] wrd, // write register-file data
  output[31:0] rrd1, rrd2 // read register-file data
  );

  reg[31:0] rf[0:31]; // 32bitのレジスタファイルrf0, ... , rf31を生成

  always @(posedge clk) begin
    rf[wra] <= wrd;
  end

  assign rrd1 = rf[rra1];
  assign rrd2 = rf[rra2];

endmodule

Adderの結果をレジスタファイルに書き込めるようにします。Adderから出たresultをレジスタファイルの書込データwrdに配線するように、トップモジュールを書き換える。
トップモジュールを含めた全体のコードはこちら。

/****レジスタファイル****/
module reg_file(
  input clk,
  input[4:0] rra1, rra2, wra, // read/write register-file address
  input[31:0] wrd, // write register-file data
  output[31:0] rrd1, rrd2 // read register-file data
  );

  reg[31:0] rf[0:31]; // 32bitのレジスタファイルrf0, ... , rf31を生成

  always @(posedge clk) begin
    rf[wra] <= wrd;
  end

  assign rrd1 = rf[rra1];
  assign rrd2 = rf[rra2];

endmodule

/****加算器****/
module adder(
  input[31:0] in1, in2,
  output[31:0] result
  );
  assign result = in1 + in2;
endmodule

/****トップモジュール****/
module top();
  reg clk;
  wire[4:0] rra1, rra2, wra;
  wire[31:0] in1, in2, result;

  regfile regfile_body(
    .clk(clk),
    .rra1(rra1),
    .rra2(rra2),
    .wra(wra),
    .wrd(result),
    .rrd1(in1),
    .rrd2(in2)
    );
  adder adder_body(in1, in2, result);

  //以下シミュレーション
  initial $monitor("result=%h", result);
endmodule