ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

sparc_ifu その2

sparc_ifuの続きです。リセット時のPCの値を決めているtlu_ifu_trappc_w2を追いました。

tlu_ifu_trappc_w2

tlu_ifu_trappc_w2は、tlu(Trap logic unit)の中のtlu_misctl.vにあります。
同じ要領で信号を追っていきます。

dff_ny #(49) dff_trap_pc_w2 (
    .din (trap_pc_w1[48:0]), 	
    .q   (trap_pc_w2[48:0]),
    .clk (clk),
    .se  (se),       
    .si  (),          
    .so  ()

assign tlu_ifu_trappc_w2[48:0] = trap_pc_w2[48:0];

// code moved from tlu_tdp
mux2ds #(49) mx_trap_pc_w1 (
       .in0  (normal_trap_pc_w1[48:0]), 
       .in1  (tlu_restore_pc_w1[48:0]),
       .sel0 (~tlu_restore_pc_sel_w1),  
       .sel1 (tlu_restore_pc_sel_w1),
       .dout (trap_pc_w1[48:0])
);           
//

tlu_restore_pc_sel_w1 は1なので normal_trap_pc_w1 が選ばれています。mux2dsは正論理に注意しましょう。最終的にはこうなります。

assign	normal_trap_pc_w1[48:0] = 
            {1'b0, tlu_partial_trap_pc_w1[33:0],
             tlu_final_offset_w1[9-1:0], 5'b00000};

tlu_partial_trap_pc_w1 = 0x3FFFFC000;
tlu_final_offset_w1 = 0x001

なので、次はこの2つの信号を追います。

tlu_partial_trap_pc_w1

tlu_partial_trap_pc_w1は、tlu_tdp.vの中にあります。
ちなみにtdpはTrap Datapath、tclはTrap Control Logicの略です。

assign tlu_partial_trap_pc_w1[33:0] = partial_trap_pc_w2[33:0]; 

mux3ds #(34) nrmlpc_sel_w2 (
       .in0  (tlu_rstvaddr_base[33:0]),
	   .in1  ({tba_data[32:0], tlu_tl_gt_0_w2}),
	   .in2  ({htba_data[33:1], pc_bit15_sel}),
       .sel0 (tlu_pc_mxsel_w2[0]),
	   .sel1 (tlu_pc_mxsel_w2[1]),
	   .sel2 (tlu_pc_mxsel_w2[2]),
       .dout (partial_trap_pc_w2[33:0])
);

tlu_pc_mxsel_w2 == 1なので、tlu_rstvaddr_baseです。

ここでようやく定数値にぶつかりました。

assign tlu_rstvaddr_base[33:0] = 34'h3_ffff_c000;

オリジナルのT1ですと、tlu.h内でRSTVADDR_BASEで定義しています。

assign tlu_rstvaddr_base[33:0] = `RSTVADDR_BASE;

tlu_final_offset_w1

tlu_final_offset_w1は、tlu_tcl.vの中にあります。

assign tlu_final_offset_w1[9-1:0] =
           final_offset_w1[9-1:0];

mux3ds #(9) mx_final_offset_w1 (
    .sel0 (final_offset_sel_w1[0]),
    .sel1 (final_offset_sel_w1[1]),
    .sel2 (final_offset_sel_w1[2]),
    .in0  (9'b000000101),
    .in1  (9'b000000010),
    .in2  (tba_ttype_w1[9-1:0]),
    .dout (final_offset_w1[9-1:0])
); 

final_offset_sel_w1 == 1なので、tba_ttype_w1が選択されています。

mux2ds #(9) mx_tba_ttype_w2 (
    .sel0 (tba_ttype_sel_w2),
    .sel1 (~tba_ttype_sel_w2),
    .in0  ({2'b0,rst_hwdr_ttype_w2[9-3:0]}),
    .in1  (final_ttype_w2[9-1:0]),
    .dout (tba_ttype_w1[9-1:0])
); 

tba_ttype_sel_w2 == 1なので、{2'b0,rst_hwdr_ttype_w2[9-3:0]}が選択されています。

mux2ds #(9-2) mx_rst_hwdr_ttype_w2 (
    .sel0  (rst_hwdr_ttype_sel_w2),
    .sel1  (~rst_hwdr_ttype_sel_w2),
    .in0 ({7'b0000010}),
    .in1 (rst_ttype_w2[9-3:0]),
    .dout (rst_hwdr_ttype_w2[9-3:0])
); 

rst_hwdr_ttype_sel_w2 == 1なので、こちらも定数値{7'b0000010})で決まりです。

まとめ

リセット時のPCを変える場合は、これらの定数値をいじれば何とかなりそうです。
データの流れを図にまとめました。

PCの値は分かったので、次は命令を取りに行きましょう。