Link命令をどう実装するか(SCP vs. Pipelined)

jump and link

「31番」レジスタ$ra = リターンアドレス)に「PC+4」を格納しつつ、即値で与えられたアドレスにPCを切り替える。という命令

SCPの場合

f:id:varmil:20171211215027p:plain http://meseec.ce.rit.edu/eecc550-winter2005/550-chapter5-exercises.pdf

上記のように、 RegDstMemToReg のselectorを拡張する実装が多い。

Pipelinedの場合

    /*** EX Rs Forwarding Mux ***/
    Mux4 #(.WIDTH(32)) EXRsFwd_Mux (
        .sel  (EX_RsFwdSel),
        .in0  (EX_ReadData1_PR),
        .in1  (M_ALUResult),
        .in2  (WB_WriteData),
        .in3  (EX_RestartPC),
        .out  (EX_ReadData1_Fwd)
    );

    /*** EX Rt Forwarding / Link Mux ***/
    Mux4 #(.WIDTH(32)) EXRtFwdLnk_Mux (
        .sel  (EX_RtFwdSel),
        .in0  (EX_ReadData2_PR),
        .in1  (M_ALUResult),
        .in2  (WB_WriteData),
        .in3  (32'h00000008),
        .out  (EX_ReadData2_Fwd)
    );

    /*** EX ALU Immediate Mux ***/
    Mux2 #(.WIDTH(32)) EXALUImm_Mux (
        .sel  (EX_ALUSrcImm),
        .in0  (EX_ReadData2_Fwd),
        .in1  (EX_SignExtImm),
        .out  (EX_ReadData2_Imm)
    );

    /*** EX RtRd / Link Mux ***/
    Mux4 #(.WIDTH(5)) EXRtRdLnk_Mux (
        .sel  (EX_LinkRegDst),
        .in0  (EX_Rt),
        .in1  (EX_Rd),
        .in2  (5'b11111),
        .in3  (5'bxxxxx),
        .out  (EX_RtRd)
    );

https://github.com/grantae/mips32r1_core/blob/master/mips32r1/Processor.v#L497-L533

この例では、 RegDst の方(31番のレジスタを指定する、5bitアドレスの方)は同じように実装している。が、「PC+4」はフォワーディングの方を絡めて実装している。Link命令の際は、ハザード制御ユニットを経由して

  • Rs へ現在のPCをフォワード
  • Rt へ即値「8」をフォワード
  • ALUに計算させた結果をレジスタファイルに書き込み(MemToRegはmux2のまま拡張なし)

という感じで実装しているようだ。こちらがスタンダード?