Line data Source code
1 : //********************************************************************************
2 : // SPDX-License-Identifier: Apache-2.0
3 : // Copyright 2020 Western Digital Corporation or its affiliates.
4 : //
5 : // Licensed under the Apache License, Version 2.0 (the "License");
6 : // you may not use this file except in compliance with the License.
7 : // You may obtain a copy of the License at
8 : //
9 : // http://www.apache.org/licenses/LICENSE-2.0
10 : //
11 : // Unless required by applicable law or agreed to in writing, software
12 : // distributed under the License is distributed on an "AS IS" BASIS,
13 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : // See the License for the specific language governing permissions and
15 : // limitations under the License.
16 : //********************************************************************************
17 :
18 : //********************************************************************************
19 : // Function: Instruction aligner
20 : //********************************************************************************
21 : module el2_ifu_aln_ctl
22 : import el2_pkg::*;
23 : #(
24 : `include "el2_param.vh"
25 : )
26 : (
27 :
28 : // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
29 : /*verilator coverage_off*/
30 : input logic scan_mode, // Flop scan mode control
31 : /*verilator coverage_on*/
32 338 : input logic rst_l, // reset, active low
33 69840565 : input logic clk, // Clock only while core active. Through one clock header. For flops with second clock header built in. Connected to ACTIVE_L2CLK.
34 69840565 : input logic active_clk, // Clock only while core active. Through two clock headers. For flops without second clock header built in.
35 :
36 8 : input logic ifu_async_error_start, // ecc/parity related errors with current fetch - not sent down the pipe
37 :
38 4 : input logic [1:0] iccm_rd_ecc_double_err, // This fetch has a double ICCM ecc error.
39 :
40 180 : input logic [1:0] ic_access_fault_f, // Instruction access fault for the current fetch.
41 172 : input logic [1:0] ic_access_fault_type_f, // Instruction access fault types
42 :
43 673974 : input logic exu_flush_final, // Flush from the pipeline.
44 :
45 6195679 : input logic dec_i0_decode_d, // Valid instruction at D-stage and not blocked
46 :
47 2166762 : input logic [31:0] ifu_fetch_data_f, // fetch data in memory format - not right justified
48 :
49 6333593 : input logic [1:0] ifu_fetch_val, // valids on a 2B boundary, right justified
50 443 : input logic [31:1] ifu_fetch_pc, // starting pc of fetch
51 :
52 :
53 :
54 6010401 : output logic ifu_i0_valid, // Instruction 0 is valid
55 206 : output logic ifu_i0_icaf, // Instruction 0 has access fault
56 274 : output logic [1:0] ifu_i0_icaf_type, // Instruction 0 access fault type
57 86 : output logic ifu_i0_icaf_second, // Instruction 0 has access fault on second 2B of 4B inst
58 :
59 2 : output logic ifu_i0_dbecc, // Instruction 0 has double bit ecc error
60 468702 : output logic [31:0] ifu_i0_instr, // Instruction 0
61 1321 : output logic [31:1] ifu_i0_pc, // Instruction 0 PC
62 5770511 : output logic ifu_i0_pc4,
63 :
64 5986539 : output logic ifu_fb_consume1, // Consumed one buffer. To fetch control fetch for buffer mass balance
65 1761739 : output logic ifu_fb_consume2, // Consumed two buffers.To fetch control fetch for buffer mass balance
66 :
67 :
68 376431 : input logic [pt.BHT_GHR_SIZE-1:0] ifu_bp_fghr_f, // fetch GHR
69 518479 : input logic [31:1] ifu_bp_btb_target_f, // predicted RET target
70 2176718 : input logic [11:0] ifu_bp_poffset_f, // predicted target offset
71 0 : input logic [1:0] [$clog2(pt.BTB_SIZE)-1:0] ifu_bp_fa_index_f, // predicted branch index (fully associative option)
72 :
73 1823494 : input logic [1:0] ifu_bp_hist0_f, // history counters for all 4 potential branches, bit 1, right justified
74 2024478 : input logic [1:0] ifu_bp_hist1_f, // history counters for all 4 potential branches, bit 1, right justified
75 408365 : input logic [1:0] ifu_bp_pc4_f, // pc4 indication, right justified
76 2374031 : input logic [1:0] ifu_bp_way_f, // way indication, right justified
77 956919 : input logic [1:0] ifu_bp_valid_f, // branch valid, right justified
78 70446 : input logic [1:0] ifu_bp_ret_f, // predicted ret indication, right justified
79 :
80 :
81 206055 : output el2_br_pkt_t i0_brp, // Branch packet for I0.
82 651059 : output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] ifu_i0_bp_index, // BP index
83 628591 : output logic [pt.BHT_GHR_SIZE-1:0] ifu_i0_bp_fghr, // BP FGHR
84 21223 : output logic [pt.BTB_BTAG_SIZE-1:0] ifu_i0_bp_btag, // BP tag
85 :
86 0 : output logic [$clog2(pt.BTB_SIZE)-1:0] ifu_i0_fa_index, // Fully associt btb index
87 :
88 6195679 : output logic ifu_pmu_instr_aligned, // number of inst aligned this cycle
89 :
90 1427480 : output logic [15:0] ifu_i0_cinst // 16b compress inst for i0
91 : );
92 :
93 :
94 :
95 6782653 : logic ifvalid;
96 51594 : logic shift_f1_f0, shift_f2_f0, shift_f2_f1;
97 271300 : logic fetch_to_f0, fetch_to_f1, fetch_to_f2;
98 :
99 686016 : logic [1:0] f2val_in, f2val;
100 1522402 : logic [1:0] f1val_in, f1val;
101 4310909 : logic [1:0] f0val_in, f0val;
102 77535 : logic [1:0] sf1val, sf0val;
103 :
104 1361254 : logic [31:0] aligndata;
105 5770512 : logic first4B, first2B;
106 :
107 241378 : logic [31:0] uncompress0;
108 6195679 : logic i0_shift;
109 4372102 : logic shift_2B, shift_4B;
110 3312033 : logic f1_shift_2B;
111 578883 : logic f2_valid, sf1_valid, sf0_valid;
112 :
113 1361254 : logic [31:0] ifirst;
114 4646540 : logic [1:0] alignval;
115 2130775 : logic [31:1] firstpc, secondpc;
116 :
117 2077583 : logic [11:0] f1poffset;
118 554300 : logic [11:0] f0poffset;
119 395019 : logic [pt.BHT_GHR_SIZE-1:0] f1fghr;
120 603477 : logic [pt.BHT_GHR_SIZE-1:0] f0fghr;
121 1872690 : logic [1:0] f1hist1;
122 2524577 : logic [1:0] f0hist1;
123 1629731 : logic [1:0] f1hist0;
124 2343603 : logic [1:0] f0hist0;
125 :
126 0 : logic [1:0][$clog2(pt.BTB_SIZE)-1:0] f0index, f1index, alignindex;
127 :
128 126 : logic [1:0] f1ictype;
129 188 : logic [1:0] f0ictype;
130 :
131 310624 : logic [1:0] f1pc4;
132 476060 : logic [1:0] f0pc4;
133 :
134 13698 : logic [1:0] f1ret;
135 79380 : logic [1:0] f0ret;
136 3407588 : logic [1:0] f1way;
137 3984021 : logic [1:0] f0way;
138 :
139 513326 : logic [1:0] f1brend;
140 803785 : logic [1:0] f0brend;
141 :
142 2271543 : logic [1:0] alignbrend;
143 2125415 : logic [1:0] alignpc4;
144 :
145 81894 : logic [1:0] alignret;
146 4381218 : logic [1:0] alignway;
147 4644199 : logic [1:0] alignhist1;
148 4153481 : logic [1:0] alignhist0;
149 4112425 : logic [1:1] alignfromf1;
150 2365947 : logic i0_ends_f1;
151 9628 : logic i0_br_start_error;
152 :
153 381470 : logic [31:1] f1prett;
154 439415 : logic [31:1] f0prett;
155 2 : logic [1:0] f1dbecc;
156 2 : logic [1:0] f0dbecc;
157 132 : logic [1:0] f1icaf;
158 200 : logic [1:0] f0icaf;
159 :
160 2 : logic [1:0] aligndbecc;
161 118 : logic [1:0] alignicaf;
162 2550497 : logic i0_brp_pc4;
163 :
164 611525 : logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] firstpc_hash, secondpc_hash;
165 :
166 0 : logic first_legal;
167 :
168 4430856 : logic [1:0] wrptr, wrptr_in;
169 3625701 : logic [1:0] rdptr, rdptr_in;
170 4275505 : logic [2:0] qwen;
171 321444 : logic [31:0] q2,q1,q0;
172 2750383 : logic q2off_in, q2off;
173 2743805 : logic q1off_in, q1off;
174 2775229 : logic q0off_in, q0off;
175 3735880 : logic f0_shift_2B;
176 :
177 1289961 : logic [31:0] q0eff;
178 899020 : logic [31:0] q0final;
179 4904978 : logic q0ptr;
180 4904978 : logic [1:0] q0sel;
181 :
182 1133585 : logic [31:0] q1eff;
183 1320997 : logic [15:0] q1final;
184 3425636 : logic q1ptr;
185 3425636 : logic [1:0] q1sel;
186 :
187 3625693 : logic [2:0] qren;
188 :
189 1888526 : logic consume_fb1, consume_fb0;
190 120 : logic [1:0] icaf_eff;
191 :
192 : localparam BRDATA_SIZE = pt.BTB_ENABLE ? 16+($clog2(pt.BTB_SIZE)*2*pt.BTB_FULLYA) : 4;
193 : localparam BRDATA_WIDTH = pt.BTB_ENABLE ? 8+($clog2(pt.BTB_SIZE)*pt.BTB_FULLYA) : 2;
194 60904 : logic [BRDATA_SIZE-1:0] brdata_in, brdata2, brdata1, brdata0;
195 193629 : logic [BRDATA_SIZE-1:0] brdata1eff, brdata0eff;
196 179151 : logic [BRDATA_SIZE-1:0] brdata1final, brdata0final;
197 :
198 : localparam MHI = 1+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE));
199 : localparam MSIZE = 2+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE));
200 :
201 144293 : logic [MHI:0] misc_data_in, misc2, misc1, misc0;
202 512941 : logic [MHI:0] misc1eff, misc0eff;
203 :
204 16657 : logic [pt.BTB_BTAG_SIZE-1:0] firstbrtag_hash, secondbrtag_hash;
205 :
206 8 : logic error_stall_in, error_stall;
207 :
208 : assign error_stall_in = (error_stall | ifu_async_error_start) & ~exu_flush_final;
209 :
210 : rvdff #(.WIDTH(7)) bundle1ff (.*,
211 : .clk(active_clk),
212 : .din ({wrptr_in[1:0],rdptr_in[1:0],q2off_in,q1off_in,q0off_in}),
213 : .dout({wrptr[1:0], rdptr[1:0], q2off, q1off, q0off})
214 : );
215 :
216 : rvdffie #(.WIDTH(7),.OVERRIDE(1)) bundle2ff (.*,
217 : .din ({error_stall_in,f2val_in[1:0],f1val_in[1:0],f0val_in[1:0]}),
218 : .dout({error_stall, f2val[1:0], f1val[1:0], f0val[1:0] })
219 : );
220 :
221 : if(pt.BTB_ENABLE==1) begin : genblock1
222 : rvdffe #(BRDATA_SIZE) brdata2ff (.*, .clk(clk), .en(qwen[2]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata2[BRDATA_SIZE-1:0]));
223 : rvdffe #(BRDATA_SIZE) brdata1ff (.*, .clk(clk), .en(qwen[1]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata1[BRDATA_SIZE-1:0]));
224 : rvdffe #(BRDATA_SIZE) brdata0ff (.*, .clk(clk), .en(qwen[0]), .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[BRDATA_SIZE-1:0]));
225 : rvdffe #(MSIZE) misc2ff (.*, .clk(clk), .en(qwen[2]), .din(misc_data_in[MHI:0]), .dout(misc2[MHI:0]));
226 : rvdffe #(MSIZE) misc1ff (.*, .clk(clk), .en(qwen[1]), .din(misc_data_in[MHI:0]), .dout(misc1[MHI:0]));
227 : rvdffe #(MSIZE) misc0ff (.*, .clk(clk), .en(qwen[0]), .din(misc_data_in[MHI:0]), .dout(misc0[MHI:0]));
228 : end
229 : else begin : genblock1
230 :
231 : rvdffie #((MSIZE*3)+(BRDATA_SIZE*3)) miscff (.*,
232 : .din({qwen[2] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc2[MHI:0], brdata2[BRDATA_SIZE-1:0]},
233 : qwen[1] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc1[MHI:0], brdata1[BRDATA_SIZE-1:0]},
234 : qwen[0] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]}}),
235 : .dout({misc2[MHI:0], brdata2[BRDATA_SIZE-1:0],
236 : misc1[MHI:0], brdata1[BRDATA_SIZE-1:0],
237 : misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]})
238 : );
239 : end
240 :
241 337 : logic [31:1] q2pc, q1pc, q0pc;
242 :
243 : rvdffe #(31) q2pcff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_pc[31:1]), .dout(q2pc[31:1]));
244 : rvdffe #(31) q1pcff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_pc[31:1]), .dout(q1pc[31:1]));
245 : rvdffe #(31) q0pcff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_pc[31:1]), .dout(q0pc[31:1]));
246 :
247 : rvdffe #(32) q2ff (.*, .clk(clk), .en(qwen[2]), .din(ifu_fetch_data_f[31:0]), .dout(q2[31:0]));
248 : rvdffe #(32) q1ff (.*, .clk(clk), .en(qwen[1]), .din(ifu_fetch_data_f[31:0]), .dout(q1[31:0]));
249 : rvdffe #(32) q0ff (.*, .clk(clk), .en(qwen[0]), .din(ifu_fetch_data_f[31:0]), .dout(q0[31:0]));
250 :
251 :
252 : // new queue control logic
253 :
254 : assign qren[2:0] = { rdptr[1:0] == 2'b10,
255 : rdptr[1:0] == 2'b01,
256 : rdptr[1:0] == 2'b00 };
257 :
258 : assign qwen[2:0] = { (wrptr[1:0] == 2'b10) & ifvalid,
259 : (wrptr[1:0] == 2'b01) & ifvalid,
260 : (wrptr[1:0] == 2'b00) & ifvalid };
261 :
262 :
263 : assign rdptr_in[1:0] = ({2{ qren[0] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b01 ) |
264 : ({2{ qren[1] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b10 ) |
265 : ({2{ qren[2] & ifu_fb_consume1 & ~exu_flush_final}} & 2'b00 ) |
266 : ({2{ qren[0] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b10 ) |
267 : ({2{ qren[1] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b00 ) |
268 : ({2{ qren[2] & ifu_fb_consume2 & ~exu_flush_final}} & 2'b01 ) |
269 : ({2{~ifu_fb_consume1 & ~ifu_fb_consume2 & ~exu_flush_final}} & rdptr[1:0]);
270 :
271 : assign wrptr_in[1:0] = ({2{ qwen[0] & ~exu_flush_final}} & 2'b01 ) |
272 : ({2{ qwen[1] & ~exu_flush_final}} & 2'b10 ) |
273 : ({2{ qwen[2] & ~exu_flush_final}} & 2'b00 ) |
274 : ({2{~ifvalid & ~exu_flush_final}} & wrptr[1:0]);
275 :
276 :
277 :
278 : assign q2off_in = ( ~qwen[2] & (rdptr[1:0]==2'd2) & (q2off | f0_shift_2B) ) |
279 : ( ~qwen[2] & (rdptr[1:0]==2'd1) & (q2off | f1_shift_2B) ) |
280 : ( ~qwen[2] & (rdptr[1:0]==2'd0) & q2off );
281 :
282 : assign q1off_in = ( ~qwen[1] & (rdptr[1:0]==2'd1) & (q1off | f0_shift_2B) ) |
283 : ( ~qwen[1] & (rdptr[1:0]==2'd0) & (q1off | f1_shift_2B) ) |
284 : ( ~qwen[1] & (rdptr[1:0]==2'd2) & q1off );
285 :
286 : assign q0off_in = ( ~qwen[0] & (rdptr[1:0]==2'd0) & (q0off | f0_shift_2B) ) |
287 : ( ~qwen[0] & (rdptr[1:0]==2'd2) & (q0off | f1_shift_2B) ) |
288 : ( ~qwen[0] & (rdptr[1:0]==2'd1) & q0off );
289 :
290 :
291 :
292 : assign q0ptr = ( (rdptr[1:0]==2'b00) & q0off ) |
293 : ( (rdptr[1:0]==2'b01) & q1off ) |
294 : ( (rdptr[1:0]==2'b10) & q2off );
295 :
296 : assign q1ptr = ( (rdptr[1:0]==2'b00) & q1off ) |
297 : ( (rdptr[1:0]==2'b01) & q2off ) |
298 : ( (rdptr[1:0]==2'b10) & q0off );
299 :
300 : assign q0sel[1:0] = {q0ptr,~q0ptr};
301 :
302 : assign q1sel[1:0] = {q1ptr,~q1ptr};
303 :
304 : // end new queue control logic
305 :
306 :
307 : // misc data that is associated with each fetch buffer
308 :
309 : if(pt.BTB_ENABLE==1)
310 : assign misc_data_in[MHI:0] = {
311 :
312 : ic_access_fault_type_f[1:0],
313 : ifu_bp_btb_target_f[31:1],
314 : ifu_bp_poffset_f[11:0],
315 : ifu_bp_fghr_f[pt.BHT_GHR_SIZE-1:0]
316 : };
317 : else
318 : assign misc_data_in[MHI:0] = {
319 : ic_access_fault_type_f[1:0]
320 : };
321 :
322 :
323 : assign {misc1eff[MHI:0],misc0eff[MHI:0]} = (({MSIZE*2{qren[0]}} & {misc1[MHI:0],misc0[MHI:0]}) |
324 : ({MSIZE*2{qren[1]}} & {misc2[MHI:0],misc1[MHI:0]}) |
325 : ({MSIZE*2{qren[2]}} & {misc0[MHI:0],misc2[MHI:0]}));
326 :
327 : if(pt.BTB_ENABLE==1) begin
328 : assign {
329 : f1ictype[1:0],
330 : f1prett[31:1],
331 : f1poffset[11:0],
332 : f1fghr[pt.BHT_GHR_SIZE-1:0]
333 : } = misc1eff[MHI:0];
334 :
335 : assign {
336 : f0ictype[1:0],
337 : f0prett[31:1],
338 : f0poffset[11:0],
339 : f0fghr[pt.BHT_GHR_SIZE-1:0]
340 : } = misc0eff[MHI:0];
341 :
342 : if(pt.BTB_FULLYA) begin
343 : assign brdata_in[BRDATA_SIZE-1:0] = {
344 : ifu_bp_fa_index_f[1], iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
345 : ifu_bp_fa_index_f[0], iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
346 : };
347 : assign {f0index[1],f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
348 : f0index[0],f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
349 :
350 : assign {f1index[1],f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1],
351 : f1index[0],f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0];
352 :
353 : end
354 : else begin
355 : assign brdata_in[BRDATA_SIZE-1:0] = {
356 : iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
357 : iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
358 : };
359 : assign {f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
360 : f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
361 :
362 : assign {f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1],
363 : f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0];
364 :
365 : end
366 :
367 :
368 :
369 :
370 : assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) |
371 : ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) |
372 : ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]}));
373 :
374 : assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & { brdata0eff[2*BRDATA_WIDTH-1:0]}) |
375 : ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
376 :
377 : assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[2*BRDATA_WIDTH-1:0]}) |
378 : ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
379 :
380 : end // if (pt.BTB_ENABLE==1)
381 : else begin
382 : assign {
383 : f1ictype[1:0]
384 : } = misc1eff[MHI:0];
385 :
386 : assign {
387 : f0ictype[1:0]
388 : } = misc0eff[MHI:0];
389 :
390 : assign brdata_in[BRDATA_SIZE-1:0] = {
391 : iccm_rd_ecc_double_err[1],ic_access_fault_f[1],
392 : iccm_rd_ecc_double_err[0],ic_access_fault_f[0]
393 : };
394 : assign {f0dbecc[1],f0icaf[1],
395 : f0dbecc[0],f0icaf[0]} = brdata0final[BRDATA_SIZE-1:0];
396 :
397 : assign {f1dbecc[1],f1icaf[1],
398 : f1dbecc[0],f1icaf[0]} = brdata1final[BRDATA_SIZE-1:0];
399 :
400 : assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) |
401 : ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) |
402 : ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]}));
403 :
404 : assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & { brdata0eff[2*BRDATA_WIDTH-1:0]}) |
405 : ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
406 :
407 : assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & { brdata1eff[2*BRDATA_WIDTH-1:0]}) |
408 : ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
409 :
410 : end // else: !if(pt.BTB_ENABLE==1)
411 :
412 :
413 : // possible states of { sf0_valid, sf1_valid, f2_valid }
414 : //
415 : // 000 if->f0
416 : // 100 if->f1
417 : // 101 illegal
418 : // 010 if->f1, f1->f0
419 : // 110 if->f2
420 : // 001 if->f1, f2->f0
421 : // 011 if->f2, f2->f1, f1->f0
422 : // 111 !if, no shift
423 :
424 : assign f2_valid = f2val[0];
425 : assign sf1_valid = sf1val[0];
426 : assign sf0_valid = sf0val[0];
427 :
428 : // interface to fetch
429 :
430 : assign consume_fb0 = ~sf0val[0] & f0val[0];
431 :
432 : assign consume_fb1 = ~sf1val[0] & f1val[0];
433 :
434 : assign ifu_fb_consume1 = consume_fb0 & ~consume_fb1 & ~exu_flush_final;
435 : assign ifu_fb_consume2 = consume_fb0 & consume_fb1 & ~exu_flush_final;
436 :
437 : assign ifvalid = ifu_fetch_val[0];
438 :
439 : assign shift_f1_f0 = ~sf0_valid & sf1_valid;
440 : assign shift_f2_f0 = ~sf0_valid & ~sf1_valid & f2_valid;
441 : assign shift_f2_f1 = ~sf0_valid & sf1_valid & f2_valid;
442 :
443 : assign fetch_to_f0 = ~sf0_valid & ~sf1_valid & ~f2_valid & ifvalid;
444 :
445 : assign fetch_to_f1 = (~sf0_valid & ~sf1_valid & f2_valid & ifvalid) |
446 : (~sf0_valid & sf1_valid & ~f2_valid & ifvalid) |
447 : ( sf0_valid & ~sf1_valid & ~f2_valid & ifvalid);
448 :
449 : assign fetch_to_f2 = (~sf0_valid & sf1_valid & f2_valid & ifvalid) |
450 : ( sf0_valid & sf1_valid & ~f2_valid & ifvalid);
451 :
452 :
453 : assign f2val_in[1:0] = ({2{ fetch_to_f2 & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
454 : ({2{~fetch_to_f2 & ~shift_f2_f1 & ~shift_f2_f0 & ~exu_flush_final}} & f2val[1:0] );
455 :
456 :
457 : assign sf1val[1:0] = ({2{ f1_shift_2B}} & {1'b0,f1val[1]}) |
458 : ({2{~f1_shift_2B}} & f1val[1:0] );
459 :
460 : assign f1val_in[1:0] = ({2{ fetch_to_f1 & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
461 : ({2{ shift_f2_f1 & ~exu_flush_final}} & f2val[1:0] ) |
462 : ({2{~fetch_to_f1 & ~shift_f2_f1 & ~shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0] );
463 :
464 :
465 :
466 : assign sf0val[1:0] = ({2{ shift_2B }} & {1'b0,f0val[1]}) |
467 : ({2{~shift_2B & ~shift_4B}} & f0val[1:0]);
468 :
469 : assign f0val_in[1:0] = ({2{fetch_to_f0 & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
470 : ({2{ shift_f2_f0 & ~exu_flush_final}} & f2val[1:0] ) |
471 : ({2{ shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0] ) |
472 : ({2{~fetch_to_f0 & ~shift_f2_f0 & ~shift_f1_f0 & ~exu_flush_final}} & sf0val[1:0] );
473 :
474 : assign {q1eff[31:0],q0eff[31:0]} = (({64{qren[0]}} & {q1[31:0],q0[31:0]}) |
475 : ({64{qren[1]}} & {q2[31:0],q1[31:0]}) |
476 : ({64{qren[2]}} & {q0[31:0],q2[31:0]}));
477 :
478 : assign q0final[31:0] = ({32{q0sel[0]}} & { q0eff[31:0]}) |
479 : ({32{q0sel[1]}} & {16'b0,q0eff[31:16]});
480 :
481 : assign q1final[15:0] = ({16{q1sel[0]}} & q1eff[15:0] ) |
482 : ({16{q1sel[1]}} & q1eff[31:16]);
483 1321 : logic [31:1] q0pceff, q0pcfinal;
484 341 : logic [31:1] q1pceff;
485 :
486 : assign {q1pceff[31:1],q0pceff[31:1]} = (({62{qren[0]}} & {q1pc[31:1],q0pc[31:1]}) |
487 : ({62{qren[1]}} & {q2pc[31:1],q1pc[31:1]}) |
488 : ({62{qren[2]}} & {q0pc[31:1],q2pc[31:1]}));
489 :
490 :
491 : assign q0pcfinal[31:1] = ({31{q0sel[0]}} & ( q0pceff[31:1])) |
492 : ({31{q0sel[1]}} & ( q0pceff[31:1] + 31'd1));
493 :
494 : assign aligndata[31:0] = ({32{ f0val[1] }} & {q0final[31:0]}) |
495 : ({32{~f0val[1] & f0val[0]}} & {q1final[15:0],q0final[15:0]});
496 :
497 : assign alignval[1:0] = ({ 2{ f0val[1] }} & {2'b11}) |
498 : ({ 2{~f0val[1] & f0val[0]}} & {f1val[0],1'b1});
499 :
500 : assign alignicaf[1:0] = ({ 2{ f0val[1] }} & f0icaf[1:0] ) |
501 : ({ 2{~f0val[1] & f0val[0]}} & {f1icaf[0],f0icaf[0]});
502 :
503 : assign aligndbecc[1:0] = ({ 2{ f0val[1] }} & f0dbecc[1:0] ) |
504 : ({ 2{~f0val[1] & f0val[0]}} & {f1dbecc[0],f0dbecc[0]});
505 :
506 : if (pt.BTB_ENABLE==1) begin
507 :
508 : // for branch prediction
509 :
510 : assign alignbrend[1:0] = ({ 2{ f0val[1] }} & f0brend[1:0] ) |
511 : ({ 2{~f0val[1] & f0val[0]}} & {f1brend[0],f0brend[0]});
512 :
513 : assign alignpc4[1:0] = ({ 2{ f0val[1] }} & f0pc4[1:0] ) |
514 : ({ 2{~f0val[1] & f0val[0]}} & {f1pc4[0],f0pc4[0]});
515 :
516 : if(pt.BTB_FULLYA) begin
517 : assign alignindex[0] = f0index[0];
518 : assign alignindex[1] = f0val[1] ? f0index[1] : f1index[0];
519 : end
520 :
521 : assign alignret[1:0] = ({ 2{ f0val[1] }} & f0ret[1:0] ) |
522 : ({ 2{~f0val[1] & f0val[0]}} & {f1ret[0],f0ret[0]});
523 :
524 : assign alignway[1:0] = ({ 2{ f0val[1] }} & f0way[1:0] ) |
525 : ({ 2{~f0val[1] & f0val[0]}} & {f1way[0],f0way[0]});
526 :
527 : assign alignhist1[1:0] = ({ 2{ f0val[1] }} & f0hist1[1:0] ) |
528 : ({ 2{~f0val[1] & f0val[0]}} & {f1hist1[0],f0hist1[0]});
529 :
530 : assign alignhist0[1:0] = ({ 2{ f0val[1] }} & f0hist0[1:0] ) |
531 : ({ 2{~f0val[1] & f0val[0]}} & {f1hist0[0],f0hist0[0]});
532 :
533 : assign secondpc[31:1] = ({31{ f0val[1] }} & (q0pceff[31:1] + 31'd1)) |
534 : // you need the base pc for 2nd one only (4B max, 2B for the 1st and 2B for the 2nd)
535 : ({31{~f0val[1] & f0val[0]}} & q1pceff[31:1] );
536 :
537 :
538 : assign firstpc[31:1] = q0pcfinal[31:1];
539 : end // if (pt.BTB_ENABLE==1)
540 :
541 : assign alignfromf1[1] = ~f0val[1] & f0val[0];
542 :
543 :
544 : assign ifu_i0_pc[31:1] = q0pcfinal[31:1];
545 :
546 :
547 : assign ifu_i0_pc4 = first4B;
548 :
549 :
550 : assign ifu_i0_cinst[15:0] = aligndata[15:0];
551 :
552 : assign first4B = (aligndata[1:0] == 2'b11);
553 : assign first2B = ~first4B;
554 :
555 : assign ifu_i0_valid = (first4B & alignval[1]) |
556 : (first2B & alignval[0]);
557 :
558 : // inst access fault on any byte of inst results in access fault for the inst
559 : assign ifu_i0_icaf = (first4B & (|alignicaf[1:0])) |
560 : (first2B & alignicaf[0] );
561 :
562 : assign ifu_i0_icaf_type[1:0] = (first4B & ~f0val[1] & f0val[0] & ~alignicaf[0] & ~aligndbecc[0]) ? f1ictype[1:0] : f0ictype[1:0];
563 :
564 :
565 : assign icaf_eff[1:0] = alignicaf[1:0] | aligndbecc[1:0];
566 :
567 : assign ifu_i0_icaf_second = first4B & ~icaf_eff[0] & icaf_eff[1];
568 :
569 : assign ifu_i0_dbecc = (first4B & (|aligndbecc[1:0])) |
570 : (first2B & aligndbecc[0] );
571 :
572 :
573 : assign ifirst[31:0] = aligndata[31:0];
574 :
575 :
576 : assign ifu_i0_instr[31:0] = ({32{first4B & alignval[1]}} & ifirst[31:0]) |
577 : ({32{first2B & alignval[0]}} & uncompress0[31:0]);
578 :
579 : if(pt.BTB_ENABLE==1) begin : genblock2
580 :
581 : // if you detect br does not start on instruction boundary
582 :
583 : el2_btb_addr_hash #(.pt(pt)) firsthash (.pc(firstpc [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
584 : .hash(firstpc_hash [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
585 : el2_btb_addr_hash #(.pt(pt)) secondhash(.pc(secondpc[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
586 : .hash(secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
587 :
588 : if(pt.BTB_FULLYA) begin
589 : assign firstbrtag_hash = firstpc;
590 : assign secondbrtag_hash = secondpc;
591 : end
592 : else begin
593 : if(pt.BTB_BTAG_FOLD) begin : btbfold
594 : el2_btb_tag_hash_fold #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
595 : .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
596 : el2_btb_tag_hash_fold #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
597 : .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
598 : end
599 : else begin : btbfold
600 : el2_btb_tag_hash #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
601 : .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
602 : el2_btb_tag_hash #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
603 : .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
604 : end
605 : end // else: !if(pt.BTB_FULLYA)
606 :
607 :
608 : // start_indexing - you want pc to be based on where the end of branch is prediction
609 : // normal indexing pc based that's incorrect now for pc4 cases it's pc4 + 2
610 :
611 339 : always_comb begin
612 :
613 339 : i0_brp = '0;
614 :
615 339 : i0_br_start_error = (first4B & alignval[1] & alignbrend[0]);
616 :
617 339 : i0_brp.valid = (first2B & alignbrend[0]) |
618 339 : (first4B & alignbrend[1]) |
619 339 : i0_br_start_error;
620 :
621 339 : i0_brp_pc4 = (first2B & alignpc4[0]) |
622 339 : (first4B & alignpc4[1]);
623 :
624 339 : i0_brp.ret = (first2B & alignret[0]) |
625 339 : (first4B & alignret[1]);
626 :
627 339 : i0_brp.way = (first2B | alignbrend[0]) ? alignway[0] : alignway[1];
628 :
629 339 : i0_brp.hist[1] = (first2B & alignhist1[0]) |
630 339 : (first4B & alignhist1[1]);
631 :
632 339 : i0_brp.hist[0] = (first2B & alignhist0[0]) |
633 339 : (first4B & alignhist0[1]);
634 :
635 339 : i0_ends_f1 = first4B & alignfromf1[1];
636 :
637 339 : i0_brp.toffset[11:0] = (i0_ends_f1) ? f1poffset[11:0] : f0poffset[11:0];
638 :
639 339 : i0_brp.prett[31:1] = (i0_ends_f1) ? f1prett[31:1] : f0prett[31:1];
640 :
641 339 : i0_brp.br_start_error = i0_br_start_error;
642 :
643 339 : i0_brp.bank = (first2B | alignbrend[0]) ? firstpc[1] : secondpc[1];
644 :
645 339 : i0_brp.br_error = (i0_brp.valid & i0_brp_pc4 & first2B) |
646 339 : (i0_brp.valid & ~i0_brp_pc4 & first4B);
647 :
648 339 : if(pt.BTB_FULLYA)
649 0 : ifu_i0_fa_index = (first2B | alignbrend[0]) ? alignindex[0] : alignindex[1];
650 : else
651 339 : ifu_i0_fa_index = '0;
652 :
653 : end
654 :
655 :
656 : assign ifu_i0_bp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = (first2B | alignbrend[0]) ? firstpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] :
657 : secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO];
658 :
659 : assign ifu_i0_bp_fghr[pt.BHT_GHR_SIZE-1:0] = (i0_ends_f1) ? f1fghr[pt.BHT_GHR_SIZE-1:0] :
660 : f0fghr[pt.BHT_GHR_SIZE-1:0];
661 :
662 : assign ifu_i0_bp_btag[pt.BTB_BTAG_SIZE-1:0] = (first2B | alignbrend[0]) ? firstbrtag_hash[pt.BTB_BTAG_SIZE-1:0] :
663 : secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0];
664 : end
665 : else begin
666 : assign i0_brp = '0;
667 : assign ifu_i0_bp_index = '0;
668 : assign ifu_i0_bp_fghr = '0;
669 : assign ifu_i0_bp_btag = '0;
670 : end // else: !if(pt.BTB_ENABLE==1)
671 :
672 : // decompress
673 :
674 : // quiet inputs for 4B inst
675 : el2_ifu_compress_ctl compress0 (.din((first2B) ? aligndata[15:0] : '0), .dout(uncompress0[31:0]));
676 :
677 :
678 :
679 : assign i0_shift = dec_i0_decode_d & ~error_stall;
680 :
681 : assign ifu_pmu_instr_aligned = i0_shift;
682 :
683 :
684 : // compute how many bytes are being shifted from f0
685 :
686 : assign shift_2B = i0_shift & first2B;
687 :
688 : assign shift_4B = i0_shift & first4B;
689 :
690 : // exact equations for the queue logic
691 : assign f0_shift_2B = (shift_2B & f0val[0] ) |
692 : (shift_4B & f0val[0] & ~f0val[1]);
693 :
694 :
695 : // f0 valid states
696 : // 11
697 : // 10
698 : // 00
699 :
700 : assign f1_shift_2B = f0val[0] & ~f0val[1] & shift_4B;
701 :
702 :
703 :
704 : endmodule
|