BOOMと自作CPUの合成結果を比較して、ボトルネックになっている部分を調査したい。まずは面積から。
引き続きSTQの面積について調査している。LUTの量は以下まで小さくなった。Snoopを消したこと自体の効果がある。
ag -A2 LUT stq_entry3.sv | grep -v LUT | grep -v INIT | grep -v -- -- | sed 's/[0-9]//g' | sort | uniq -c
58 - \FSM_sequential_r_entry[state][]_i___ 1 - \o_stq_rs_resolve[index][]_i_ 4 - \r_entry[another_flush_grp_id][]_i___ 16 - \r_entry[br_mask][]_i___ 39 - \r_entry[except_tval][][]_i_ 4 - \r_entry[except_type][]_i___ 1 - \r_entry[except_valid]_i___ 3 - \r_entry[grp_id][]_i___ 18 - \r_entry[hazard_index][]_i_ 11 - \r_entry[hazard_index][]_i___ 2 - \r_entry[inst][oldest_valid]_i___ 7 - \r_entry[is_committed]_i___ 1 - \r_entry[is_rmw]_i___ 1 - \r_entry[is_uc]_i_ 1 - \r_entry[is_uc]_i___ 1 - \r_entry[is_valid]_i___ 3 - \r_entry[missu_haz_index_oh][]_i___ 13 - \r_entry[oldest_ready]_i___ 39 - \r_entry[paddr][]_i___ 1 - \r_entry[paddr_valid]_i___ 5 - \r_entry[rmwop][]_i___ 3 - \r_entry[rs_data][]_i___ 8 - \r_entry[size][]_i___ 27 - \r_entry[vaddr][]_i___ 2 - \r_entry_reg[inst][rds][][predict_ready]_i___ 6 - \r_entry_reg[inst][rds][][ready]_i___ 2 - \r_entry_reg[inst][rds][][valid]_i___ 115 - \r_ex_aligned_data[]_i_ 10 - \r_ex_aligned_data[]_i___ 1 - \r_return_dec[]_i_ 1 - \r_uc_wr_paddr[]_i_ 28 - i____i_ 10 - i____i___ 29 - r_ex_mis_valid_i_ 16 - r_ex_mis_valid_i___
一番大きいのが、r_ex_aligned_data[]
だ。これはレジスタなのか?LUTなのか...?
もうちょっとLUTの使用頻度を絞ってみた。
$ ag LUT -A10 stq_entry3.sv | ag -A10 r_ex3_aligned_data | ag " \.O" | sed 's/[0-9]//g' | sort | uniq -c 14 - .O(\fwd_loop[].byte_loop[].w_ex_fwd_strb_valid )); 40 - .O(\r_ex_aligned_data[]_i__n_ )); 64 - .O(\w_aligned_rs_data_array[]_ [])); 7 - .O(gen_dw_return[]));
w_aligned_rs_data_array
とかr_ex_aligned_data
とかが消費量が大きいな。
// ========================= // STQ Forwarding Logic // ========================= scariv_pkg::alen_t w_aligned_rs2_data_array[scariv_conf_pkg::STQ_SIZE]; generate for (genvar s_idx = 0; s_idx < scariv_conf_pkg::STQ_SIZE; s_idx++) begin : stq_rs2_loop assign w_aligned_rs2_data_array[s_idx] = w_stq_entries[s_idx].rs2_data << {w_stq_entries[s_idx].paddr[$clog2(scariv_pkg::ALEN_W/8)-1:0], 3'b000}; end endgenerate
こういうシフタの書き方をするとVivadoのLUTは大きくなるのかな。ちょっと変えてみる。
function scariv_pkg::alen_t align_byte (scariv_pkg::alen_t data, logic [$clog2(scariv_pkg::ALEN_W/8)-1:0] pa); if (scariv_pkg::ALEN_W == 64) begin case (pa) 'b000: return data; 'b001: return {data[scariv_pkg::ALEN_W- 8-1: 0], 8'h00}; 'b010: return {data[scariv_pkg::ALEN_W-16-1: 0], 16'h00}; 'b011: return {data[scariv_pkg::ALEN_W-24-1: 0], 24'h00}; 'b100: return {data[scariv_pkg::ALEN_W-32-1: 0], 32'h00}; 'b101: return {data[scariv_pkg::ALEN_W-40-1: 0], 40'h00}; 'b110: return {data[scariv_pkg::ALEN_W-48-1: 0], 48'h00}; 'b111: return {data[scariv_pkg::ALEN_W-56-1: 0], 56'h00}; default : return 'h0; endcase // case (pa) end else begin // if (scariv_pkg::ALEN_W == 64) case (pa) 'b00: return data; 'b01: return {data[scariv_pkg::ALEN_W- 8-1: 0], 8'h00}; 'b10: return {data[scariv_pkg::ALEN_W-16-1: 0], 16'h00}; 'b11: return {data[scariv_pkg::ALEN_W-24-1: 0], 24'h00}; default : return 'h0; endcase // case (pa) end // else: !if(scariv_pkg::ALEN_W == 64) endfunction // align_byte
多少マシになった気がする。ただ、まだまだ大きい。
ag LUT -A10 scariv_stq_entry.synth.v | ag -A10 r_ex3_aligned_data | ag " \.O" | sed 's/[0-9]//g' | sort | uniq -c 3 - .O(\fwd_loop[].byte_loop[].w_ex_fwd_strb_valid )); 16 - .O(\r_entry_reg[rs_data][]_ )); 12 - .O(\r_entry_reg[size][]_ )); 24 - .O(\r_entry_reg[vaddr][]_ )); 6 - .O(\r_ex_aligned_data[]_i____n_ )); 34 - .O(\r_ex_aligned_data[]_i__n_ )); 1 - .O(\r_ex_paddr_reg[]_rep )); 3 - .O(\r_ex_paddr_reg[]_rep_ )); 3 - .O(\r_ex_paddr_reg[]_rep___ )); 3 - .O(\r_ex_pipe_ctrl_reg[size][] )); 1 - .O(\r_ex_pipe_ctrl_reg[size][]_ )); 32 - .O(align_byte[])); 8 - .O(p__in_out[]));