NaxRiscvの実装を解析しながら、SystemVerilog化することで理解を深めていこうと思う。
まずはPCPluginから。このモジュールの役目は、PCの保持とアップデート、各種ハザードに応じてPCを更新することだ。
module NaxRiscv_PcPlugin ( input logic i_clk, input logic i_reset_n, PcPlugin_if.manager pcplugin_if, // output );
基本的には、PCを送出すると更新することになる。
assign output_fire = pcplugin_if.valid && pcplugin_if.ready; always_comb begin w_pc = r_pc + _zz_pc; if(w_jump_pcload_valid) begin w_pc = w_jump_pcload_pc; end if (r_pc_inc) begin w_pc[2 : 2] = 1'b0; end w_pc[1:0] = 2'b00; end always_ff ... if(output_fire) begin r_correction <= 1'b0; end else if(w_correction) begin r_correction <= 1'b1; end if(!pcplugin_if.valid && pcplugin_if.ready) begin r_pc_inc <= 1'b0; end else if(output_fire) begin r_pc_inc <= 1'b1; end else if(w_correction || w_pcPropagate) begin r_pc_inc <= 1'b0; end
各種ハザード通知に応じて、更新するPCを変えている。
always_comb begin if (PrivilegedPlugin_setup_jump_valid) begin w_jump_pcload_valid = 1'b1; w_jump_pcload_pc = PrivilegedPlugin_setup_jump_payload_pc; end else if (CommitPlugin_setup_jump_valid) begin w_jump_pcload_valid = 1'b1; w_jump_pcload_pc = CommitPlugin_setup_jump_payload_pc; end else if (DecoderPredictionPlugin_setup_decodeJump_valid) begin w_jump_pcload_valid = 1'b1; w_jump_pcload_pc = DecoderPredictionPlugin_setup_decodeJump_payload_pc; end else if (AlignerPlugin_setup_sequenceJump_valid) begin w_jump_pcload_valid = 1'b1; w_jump_pcload_pc = AlignerPlugin_setup_sequenceJump_payload_pc; end else if (FetchCachePlugin_setup_redoJump_valid) begin w_jump_pcload_valid = 1'b1; w_jump_pcload_pc = FetchCachePlugin_setup_redoJump_payload_pc; end else if (BtbPlugin_setup_btbJump_valid) begin w_jump_pcload_valid = 1'b1; w_jump_pcload_pc = BtbPlugin_setup_btbJump_payload_pc; end else begin w_jump_pcload_valid = 1'b0; w_jump_pcload_pc = 40'h0; end end // always_comb
InitCounterは単純なカウンタだが、これはここに配置する意味はあるんだろうか?128サイクル待っているようなカウンタだ。
reg [6:0] r_init_counter; wire w_init_booted; assign w_init_booted = r_init_counter[6]; always_ff @ (posedge i_clk, negedge i_reset_n) begin if (!i_reset_n) begin r_init_counter <= 7'h00; end else begin r_init_counter <= r_init_counter + ~w_init_booted; end end