Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / spc / lsu / rtl / lsu_cic_ctl.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: lsu_cic_ctl.v
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35module lsu_cic_ctl (
36 l2clk,
37 scan_in,
38 tcu_pce_ov,
39 tcu_scan_en,
40 spc_aclk,
41 spc_bclk,
42 scan_out,
43 const_cpuid,
44 cpx_pkt_vld,
45 cid_d1_rtntyp,
46 cid_d1_wv,
47 cid_d1_tid,
48 cid_d1_rmo,
49 cid_d1_pref,
50 cid_d1_cpuid,
51 cid_d1_inval,
52 cid_tid,
53 cid_cpuid,
54 cid_pkt_type,
55 cid_xinval,
56 cid_pref,
57 cid_inv_vec,
58 cid_atomic,
59 cid_rmo_ack,
60 cid_set_inval,
61 cid_set_icinval,
62 cid_st_addr,
63 cid_st_vector,
64 cid_cpq_cmp_1,
65 cid_cpq_cmp_2,
66 cid_cpq_cmp_3,
67 dcc_cache_diag_wr_b,
68 dec_ld_inst_d,
69 fgu_fdiv_stall,
70 lmc_ldd_vld,
71 sbc_bst_sel,
72 mbi_run,
73 mbi_cpq_read_en,
74 mbi_cpq_write_en,
75 mbi_addr,
76 lbist_run,
77 cic_cpq_wptr,
78 cic_cpq_rptr,
79 cic_cpq_rd_en,
80 cic_cpq_wr_en,
81 cic_d1_sel,
82 cic_cpq_sel,
83 cic_fifo_sel,
84 cic_byp_sel,
85 cic_fifo_clken,
86 cic_l2fill_vld_e,
87 cic_cpq_ld_rdy,
88 cic_cpq_ld_rdy_,
89 cic_cpq_ld_sel,
90 cic_div_stall_d,
91 cic_st_update_e,
92 cic_rtn_cmplt,
93 cic_invalidate_e,
94 cic_xinval_e,
95 cic_set_inval,
96 cic_xinval,
97 cic_oddrd_e,
98 cic_st_dequeue,
99 cic_rmo_dequeue,
100 cic_st_ack,
101 cic_inv_wen_e,
102 cic_cpq_stall,
103 cic_diag_data_sel_e,
104 cic_ext_interrupt,
105 lsu_dcsoc_err_g,
106 lsu_ext_interrupt,
107 cic_mbi_run,
108 lsu_mbi_cpq_fail);
109wire se;
110wire pce_ov;
111wire stop;
112wire siclk;
113wire soclk;
114wire l1clk;
115wire [7:0] dec_cpuid;
116wire [7:0] cpq_tid;
117wire cpq_atomic;
118wire cpq_rmo_ack;
119wire dff_cpq_state_scanin;
120wire dff_cpq_state_scanout;
121wire state_fifo;
122wire fifo_dff_enable;
123wire last_state_fifo;
124wire fifo_clken_last;
125wire state_d1;
126wire lsu_type_d1;
127wire sel_byp_last;
128wire cpq_pkt_done;
129wire state_cpq;
130wire [5:0] cpq_rptr;
131wire [5:0] cpq_wptr;
132wire sel_d1_last;
133wire mbi_run_local;
134wire block_cpq_d;
135wire dff_cpq_sel_scanin;
136wire dff_cpq_sel_scanout;
137wire cpq_wr_en;
138wire [5:0] cpq_wptr_inc;
139wire [5:0] cpq_wptr_new;
140wire dff_cpq_wptr_scanin;
141wire dff_cpq_wptr_scanout;
142wire cpq_rd_adv;
143wire dff_cpq_rptr_scanin;
144wire dff_cpq_rptr_scanout;
145wire [5:0] cpq_rptr_new;
146wire [5:0] cpq_rptr_inc;
147wire fifo_empty;
148wire [5:0] cpq_count;
149wire cpq_gte_15;
150wire reset_ll_cnt;
151wire [2:0] ll_cnt_in;
152wire [2:0] ll_cnt;
153wire dff_ll_cnt_scanin;
154wire dff_ll_cnt_scanout;
155wire cpq_set_inval;
156wire cpq_xinval;
157wire cpq_local_pkt;
158wire cpq_ld_type;
159wire cpq_inv_type;
160wire cpq_st_update;
161wire cpq_evict_type;
162wire cpq_st_type;
163wire cpq_su_type;
164wire cpq_ldd_type;
165wire cpq_nonlsu_type;
166wire cpq_ld_vld;
167wire block_cpq_e;
168wire cpq_st_vld;
169wire cpq_su_vld;
170wire cpq_inv_vld;
171wire cpq_evict;
172wire cpq_ldd_vld;
173wire dff_ld_inst_e_scanin;
174wire dff_ld_inst_e_scanout;
175wire ld_inst_e;
176wire [1:0] div_stall_in;
177wire div_stall_d;
178wire dff_div_stall_scanin;
179wire dff_div_stall_scanout;
180wire div_stall_e;
181wire dcfill_active_e;
182wire cic_ignore_fill_e;
183wire ldd_2nd_pass;
184wire cic_st_atm_cmplt;
185wire st_dequeue;
186wire ldd_1st_pass;
187wire [15:0] evict_inv_wen;
188wire [15:0] store_inv_wen;
189wire next_ldd_2nd_pass;
190wire dff_ldd_2nd_pass_scanin;
191wire dff_ldd_2nd_pass_scanout;
192wire lsu_dcsoc_err_e;
193wire dff_dcl2_err_scanin;
194wire dff_dcl2_err_scanout;
195wire dff_diag_block_scanin;
196wire dff_diag_block_scanout;
197wire cpq_fail;
198wire bist_cpq_cmp_en;
199wire dff_bist_scanin;
200wire dff_bist_scanout;
201wire bist_cpq_rd_1;
202wire spares_scanin;
203wire spares_scanout;
204
205
206// Globals
207input l2clk;
208input scan_in;
209input tcu_pce_ov; // scan signals
210input tcu_scan_en;
211input spc_aclk;
212input spc_bclk;
213output scan_out;
214
215input [2:0] const_cpuid; // 0in const -message "const_cpuid changed!"
216
217input cpx_pkt_vld;
218
219input [4:0] cid_d1_rtntyp;
220input cid_d1_wv;
221input [2:0] cid_d1_tid;
222input cid_d1_rmo;
223input cid_d1_pref;
224input [2:0] cid_d1_cpuid;
225input [1:0] cid_d1_inval;
226
227input [2:0] cid_tid;
228input [2:0] cid_cpuid;
229input [4:0] cid_pkt_type;
230input cid_xinval;
231input cid_pref;
232input [17:0] cid_inv_vec; // Invalidation vector
233input cid_atomic;
234input cid_rmo_ack;
235input cid_set_inval;
236input cid_set_icinval;
237input [5:4] cid_st_addr;
238input [15:0] cid_st_vector;
239input cid_cpq_cmp_1;
240input cid_cpq_cmp_2;
241input cid_cpq_cmp_3;
242
243input dcc_cache_diag_wr_b; // must block returns for diag write
244input dec_ld_inst_d;
245
246input fgu_fdiv_stall; // divide write to FRF W2 port pending
247
248input [7:0] lmc_ldd_vld; // LDD flags for each thread
249
250input [7:0] sbc_bst_sel;
251
252input mbi_run;
253input mbi_cpq_read_en;
254input mbi_cpq_write_en;
255input [4:0] mbi_addr;
256input lbist_run;
257
258// CPQ control
259output [4:0] cic_cpq_wptr;
260output [4:0] cic_cpq_rptr;
261output cic_cpq_rd_en;
262output cic_cpq_wr_en;
263output cic_d1_sel;
264output cic_cpq_sel;
265output cic_fifo_sel;
266output cic_byp_sel;
267output cic_fifo_clken;
268
269output cic_l2fill_vld_e; // Fill/bypass from L2 is proceeding
270output cic_cpq_ld_rdy; // Fill/bypass is ready (but not necessarily happening)
271output cic_cpq_ld_rdy_; // Fill/bypass is ready (but not necessarily happening)
272output cic_cpq_ld_sel; // Load return is at head of queue
273output cic_div_stall_d; // Divide is blocking the path to the regfiles
274output cic_st_update_e; // Store update to D$ is happening
275output cic_rtn_cmplt; // Load or atomic is complete
276output cic_invalidate_e; // Invalidation is occuring
277output cic_xinval_e; // Cross invalidate
278output cic_set_inval;
279output [7:0] cic_xinval; // xinval arrived on cpx
280output cic_oddrd_e; // Second pass of a 2 pass load
281output [7:0] cic_st_dequeue; // Dequeue the store from the stb
282output [7:0] cic_rmo_dequeue;
283output [7:0] cic_st_ack; // Store acks to each thread's stb
284output [15:0] cic_inv_wen_e; // Invalidation information
285output cic_cpq_stall;
286output cic_diag_data_sel_e;
287output cic_ext_interrupt;
288
289output lsu_dcsoc_err_g;
290output lsu_ext_interrupt;
291
292output cic_mbi_run;
293output lsu_mbi_cpq_fail;
294
295// scan renames
296assign se = tcu_scan_en;
297assign pce_ov = tcu_pce_ov;
298assign stop = 1'b0;
299assign siclk = spc_aclk;
300assign soclk = spc_bclk;
301// end scan
302
303//////////////////////////////
304// Clock header
305//////////////////////////////
306
307lsu_cic_ctl_l1clkhdr_ctl_macro clkgen (
308 .l2clk (l2clk ),
309 .l1en (1'b1 ),
310 .l1clk (l1clk ),
311 .pce_ov(pce_ov),
312 .stop(stop),
313 .se(se)
314);
315
316assign dec_cpuid[0] = ~const_cpuid[2] & ~const_cpuid[1] & ~const_cpuid[0];
317assign dec_cpuid[1] = ~const_cpuid[2] & ~const_cpuid[1] & const_cpuid[0];
318assign dec_cpuid[2] = ~const_cpuid[2] & const_cpuid[1] & ~const_cpuid[0];
319assign dec_cpuid[3] = ~const_cpuid[2] & const_cpuid[1] & const_cpuid[0];
320assign dec_cpuid[4] = const_cpuid[2] & ~const_cpuid[1] & ~const_cpuid[0];
321assign dec_cpuid[5] = const_cpuid[2] & ~const_cpuid[1] & const_cpuid[0];
322assign dec_cpuid[6] = const_cpuid[2] & const_cpuid[1] & ~const_cpuid[0];
323assign dec_cpuid[7] = const_cpuid[2] & const_cpuid[1] & const_cpuid[0];
324
325assign cpq_tid[0] = ~cid_tid[2] & ~cid_tid[1] & ~cid_tid[0];
326assign cpq_tid[1] = ~cid_tid[2] & ~cid_tid[1] & cid_tid[0];
327assign cpq_tid[2] = ~cid_tid[2] & cid_tid[1] & ~cid_tid[0];
328assign cpq_tid[3] = ~cid_tid[2] & cid_tid[1] & cid_tid[0];
329assign cpq_tid[4] = cid_tid[2] & ~cid_tid[1] & ~cid_tid[0];
330assign cpq_tid[5] = cid_tid[2] & ~cid_tid[1] & cid_tid[0];
331assign cpq_tid[6] = cid_tid[2] & cid_tid[1] & ~cid_tid[0];
332assign cpq_tid[7] = cid_tid[2] & cid_tid[1] & cid_tid[0];
333
334assign cpq_atomic = cid_atomic;
335assign cpq_rmo_ack = cid_rmo_ack;
336
337////////////////////////////////////////////////////////////////////////////////
338// The CPX interface is built around a 32 entry FIFO (the CPQ). Incoming
339// packets queue in the FIFO (or bypass if the FIFO is empty). Only the packet
340// at the head of the FIFO can be dequeued. Packets which
341// cause the dcache to update (cacheable loads from L2 and stores which update)
342// must wait until there is no load instruction in the pipeline because the
343// cache arrays are single ported. Only packets processed by the LSU are
344// handled by this interface. Ifill, SPU load, and MMU packets are ignored.
345////////////////////////////////////////////////////////////////////////////////
346
347
348////////////////////////////////////////////////////////////////////////////////
349// FIFO and bypass management
350// A packet can come from one of four sources:
351// cpx - direct bypass if fifo and bypass stages are empty
352// d1 - 1st bypass stage (fifo written during this stage)
353// cpq - read data from fifo RAM
354// fifo - data from fifo flop
355////////////////////////////////////////////////////////////////////////////////
356
357// FIFO/bypass state. An asserted state bit indicates a valid, unprocessed
358// packet exists in the respective stage. If all are deasserted, packets bypass
359// directly from the cpx.
360lsu_cic_ctl_msff_ctl_macro__width_2 dff_cpq_state (
361 .scan_in(dff_cpq_state_scanin),
362 .scan_out(dff_cpq_state_scanout),
363 .din ({state_fifo, fifo_dff_enable}),
364 .dout ({last_state_fifo,fifo_clken_last}),
365 .l1clk(l1clk),
366 .siclk(siclk),
367 .soclk(soclk)
368);
369
370assign state_d1 = lsu_type_d1 & ~(sel_byp_last & cpq_pkt_done);
371assign state_cpq = (cpq_rptr[5:0] != cpq_wptr[5:0]) & ~(sel_d1_last & cpq_pkt_done);
372assign state_fifo = (fifo_clken_last | last_state_fifo) & ~cpq_pkt_done;
373
374assign fifo_dff_enable = state_cpq & ~state_fifo;
375assign cic_fifo_clken = mbi_run_local | fifo_dff_enable;
376
377// These are priority encoded versions used to mux return packets
378// The aomux must output zeros for blocked packets and when in BIST mode.
379assign cic_fifo_sel = state_fifo & ~block_cpq_d & ~mbi_run_local;
380assign cic_cpq_sel = state_cpq & ~state_fifo & ~block_cpq_d & ~mbi_run_local;
381assign cic_d1_sel = state_d1 & ~state_cpq & ~state_fifo & ~block_cpq_d & ~mbi_run_local;
382assign cic_byp_sel = ~state_d1 & ~state_cpq & ~state_fifo & ~block_cpq_d & ~mbi_run_local;
383
384// 0in bits_on -var {cic_fifo_sel,cic_cpq_sel,cic_d1_sel,cic_byp_sel} -max 1
385
386lsu_cic_ctl_msff_ctl_macro__width_2 dff_cpq_sel (
387 .scan_in(dff_cpq_sel_scanin),
388 .scan_out(dff_cpq_sel_scanout),
389 .din ({cic_byp_sel, cic_d1_sel}),
390 .dout ({sel_byp_last,sel_d1_last}),
391 .l1clk(l1clk),
392 .siclk(siclk),
393 .soclk(soclk)
394);
395
396////////////////////////////////////////////////////////////////////////////////
397// CPQ write pointer and write enable
398// All valid packets write into the fifo array. (If timing allows for a predecode,
399// I could supress the write of non-LSU packets.) In cycle d1, the packet will be decoded.
400// If it wasn't an LSU type, the write pointer will not advance and the entry will be
401// overwritten.
402
403assign cpq_wr_en = cpx_pkt_vld;
404assign cic_cpq_wr_en = (mbi_run_local | lbist_run) ? mbi_cpq_write_en : cpq_wr_en;
405
406assign lsu_type_d1 = (cid_d1_rtntyp[4] & (cid_d1_rtntyp[2:0] == 3'b000) & ~cid_d1_pref)| // loads
407 (cid_d1_rtntyp[4:0] == 5'b10100) | // store ack
408 ((cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv) | // ifill with inval
409 (cid_d1_rtntyp[4:0] == 5'b10011) | // eviction
410 (cid_d1_rtntyp[4:0] == 5'b10110) | // stream store ack
411 (cid_d1_rtntyp[4:0] == 5'b10111) ; // interrupt return
412
413assign cpq_wptr_inc[5:0] = cpq_wptr[5:0] + {6'b000001};
414assign cpq_wptr_new[5:0] = lsu_type_d1 ? cpq_wptr_inc[5:0] : cpq_wptr[5:0];
415assign cic_cpq_wptr[4:0] = mbi_run_local ? mbi_addr[4:0] : cpq_wptr_new[4:0];
416
417lsu_cic_ctl_msff_ctl_macro__width_6 dff_cpq_wptr (
418 .scan_in(dff_cpq_wptr_scanin),
419 .scan_out(dff_cpq_wptr_scanout),
420 .din (cpq_wptr_new[5:0]),
421 .dout (cpq_wptr[5:0]),
422 .l1clk(l1clk),
423 .siclk(siclk),
424 .soclk(soclk)
425);
426
427//////////////////////////////////////////////////////////////////////////////////
428// CPQ read pointer generation
429// The read pointer increments if the a packet from a bypass stage is used or
430// when the fifo_dff pops an entry.
431
432assign cpq_rd_adv = (cpq_pkt_done & (sel_byp_last | sel_d1_last)) | fifo_dff_enable;
433
434lsu_cic_ctl_msff_ctl_macro__width_6 dff_cpq_rptr (
435 .scan_in(dff_cpq_rptr_scanin),
436 .scan_out(dff_cpq_rptr_scanout),
437 .din (cpq_rptr_new[5:0]),
438 .dout (cpq_rptr[5:0]),
439 .l1clk(l1clk),
440 .siclk(siclk),
441 .soclk(soclk)
442);
443
444assign cpq_rptr_inc[5:0] = cpq_rptr[5:0] + {6'b000001};
445assign cpq_rptr_new[5:0] = cpq_rd_adv ? cpq_rptr_inc[5:0] : cpq_rptr[5:0];
446assign cic_cpq_rptr[4:0] = mbi_run_local ? mbi_addr[4:0] : cpq_rptr_new[4:0];
447
448/// CPQ will be read whenever there is a valid entry.
449assign fifo_empty = (cpq_wptr_new[5:0] == cpq_rptr_new[5:0]);
450
451assign cic_cpq_rd_en = mbi_run_local ? mbi_cpq_read_en : ~fifo_empty;
452
453// Block the decode of any LSU op so the CPQ can drain.
454// The CPQ cannot be allowed to rise above 16 entries used so that seven outstanding
455// block loads can be accomodated.
456
457assign cpq_count[5:0] = (cpq_wptr[5:0] - cpq_rptr[5:0]);
458
459assign cpq_gte_15 = (cpq_count[5:0] >= 6'd15);
460
461// To prevent livelock, request a stall if a packet is held at the head
462// of the queue for 8 cycles.
463
464assign reset_ll_cnt = cpq_pkt_done | ~(cic_d1_sel | cic_cpq_sel | cic_fifo_sel);
465
466assign ll_cnt_in[2:0] = {3{~reset_ll_cnt}} & {ll_cnt[2:0] + 3'b001};
467lsu_cic_ctl_msff_ctl_macro__width_3 dff_ll_cnt (
468 .scan_in(dff_ll_cnt_scanin),
469 .scan_out(dff_ll_cnt_scanout),
470 .din (ll_cnt_in[2:0]),
471 .dout (ll_cnt[2:0]),
472 .l1clk(l1clk),
473 .siclk(siclk),
474 .soclk(soclk)
475);
476
477assign cic_cpq_stall = cpq_gte_15 | (&ll_cnt[2:0]);
478
479// Assertion to check for cpq overflow
480// 0in fifo -enq lsu_type_d1 -deq cpq_rd_adv -depth 32 -pass -registered
481
482////////////////////////////////////////////////////////////////////////////////
483// Process the ready packet
484////////////////////////////////////////////////////////////////////////////////
485
486assign cpq_set_inval = (cid_pkt_type[4:0] == 5'b10100) & cid_set_inval;
487assign cpq_xinval = (cid_pkt_type[4:0] == 5'b10001) & cid_xinval; // ifill xinval
488assign cpq_local_pkt = (cid_cpuid[2:0] == const_cpuid[2:0]);
489assign cpq_ld_type = cid_pkt_type[4] & (cid_pkt_type[2:0] == 3'b000) & ~cid_pref; // load; no prefetch
490assign cpq_inv_type = (cid_pkt_type[4:0] == 5'b10011) | // eviction
491 ((cid_pkt_type[4:0] == 5'b10110) & cpq_st_update) | // stream store ack
492 cpq_set_inval | // set invalidate
493 ((cid_pkt_type[4:0] == 5'b10100) &
494 (~cpq_local_pkt | // non-local store ack
495 (cid_atomic & cpq_st_update) | // atomic
496 (cid_rmo_ack & cpq_st_update))); // BIS
497assign cpq_evict_type= (cid_pkt_type[4:0] == 5'b10011);
498assign cpq_st_type = (cid_pkt_type[4:0] == 5'b10100 & cpq_local_pkt) & // store ack
499 ~(cid_set_inval | cid_set_icinval);
500assign cpq_su_type = (cid_pkt_type[4:0] == 5'b10100) & cpq_local_pkt &
501 cpq_st_update & ~(cid_set_icinval | cid_set_inval) &
502 ~cid_atomic & ~cid_rmo_ack;
503
504assign cpq_st_update = (dec_cpuid[7] & cid_st_vector[15] & ~cid_st_vector[14]) |
505 (dec_cpuid[6] & cid_st_vector[13] & ~cid_st_vector[12]) |
506 (dec_cpuid[5] & cid_st_vector[11] & ~cid_st_vector[10]) |
507 (dec_cpuid[4] & cid_st_vector[9] & ~cid_st_vector[8]) |
508 (dec_cpuid[3] & cid_st_vector[7] & ~cid_st_vector[6]) |
509 (dec_cpuid[2] & cid_st_vector[5] & ~cid_st_vector[4]) |
510 (dec_cpuid[1] & cid_st_vector[3] & ~cid_st_vector[2]) |
511 (dec_cpuid[0] & cid_st_vector[1] & ~cid_st_vector[0]);
512
513assign cpq_ldd_type = (cid_tid[2:0] == 3'b000) & cpq_ld_type & lmc_ldd_vld[0] |
514 (cid_tid[2:0] == 3'b001) & cpq_ld_type & lmc_ldd_vld[1] |
515 (cid_tid[2:0] == 3'b010) & cpq_ld_type & lmc_ldd_vld[2] |
516 (cid_tid[2:0] == 3'b011) & cpq_ld_type & lmc_ldd_vld[3] |
517 (cid_tid[2:0] == 3'b100) & cpq_ld_type & lmc_ldd_vld[4] |
518 (cid_tid[2:0] == 3'b101) & cpq_ld_type & lmc_ldd_vld[5] |
519 (cid_tid[2:0] == 3'b110) & cpq_ld_type & lmc_ldd_vld[6] |
520 (cid_tid[2:0] == 3'b111) & cpq_ld_type & lmc_ldd_vld[7] ;
521
522assign cic_ext_interrupt = (cid_pkt_type[4:0] == 5'b10111);
523
524// Because some packets may have been put into the queue that aren't interesting to the LSU,
525// they need to be thrown away.
526assign cpq_nonlsu_type = cid_pkt_type[4] & ~(cpq_ld_type | cpq_st_type | cpq_inv_type | cpq_evict_type | cpq_xinval);
527
528// Operations must be qualifed with cpq blocks
529
530assign cpq_ld_vld = cpq_ld_type & ~block_cpq_e;
531assign cpq_st_vld = cpq_st_type & ~block_cpq_e;
532assign cpq_su_vld = cpq_su_type & ~block_cpq_e;
533assign cpq_inv_vld = cpq_inv_type & ~block_cpq_e;
534assign cpq_evict = cpq_evict_type & ~block_cpq_e;
535assign cpq_ldd_vld = cpq_ldd_type;
536
537// This just blocks lmq load bypass and enables the data flop (for PM)
538assign cic_cpq_ld_rdy = cpq_ld_vld;
539assign cic_cpq_ld_rdy_ = ~cpq_ld_vld;
540
541assign cic_set_inval = cpq_set_inval;
542
543// This differentiates between load type and store/inv type. It can
544// only be used for mux selects because there is no guarantee that
545// the operation will actually happen.
546// NOTE: Further qualification with mbi_run and diag writes may be
547// required by the block(s) using this signal.
548assign cic_cpq_ld_sel = ~cid_pkt_type[2] & ~cid_pkt_type[0];
549
550// Invalidates can always be processed. Invalidates come from evict and
551// stream store packets and from non-local store acks.
552assign cic_invalidate_e = cpq_inv_vld;
553assign cic_xinval_e = cpq_xinval & ~block_cpq_e;
554
555// The load instruction in D might get flushed in E, but because ldst_complete
556// needs to go to pick in E, I don't have time to qualify it. Therefore, a
557// dcfill will only occur when there is no load instruction - flushed or not -
558// coming down the pipe.
559
560lsu_cic_ctl_msff_ctl_macro__width_1 dff_ld_inst_e (
561 .scan_in(dff_ld_inst_e_scanin),
562 .scan_out(dff_ld_inst_e_scanout),
563 .din (dec_ld_inst_d),
564 .dout (ld_inst_e),
565 .l1clk(l1clk),
566 .siclk(siclk),
567 .soclk(soclk)
568);
569
570// Divide results have highest priority to the W2 ports of the FRF.
571// FGU will signal a stall to indicate that a result will be written in the
572// future. Fills cannot proceed when the result is being written.
573// The timing is as below. Use a shift register to track the stall.
574//
575// | D | E | M
576// fdiv| | |
577// stall| | |
578// | | |
579
580assign div_stall_in[1:0] = {fgu_fdiv_stall,div_stall_d};
581lsu_cic_ctl_msff_ctl_macro__width_2 dff_div_stall (
582 .scan_in(dff_div_stall_scanin),
583 .scan_out(dff_div_stall_scanout),
584 .din (div_stall_in[1:0]),
585 .dout ({div_stall_d,div_stall_e}),
586 .l1clk(l1clk),
587 .siclk(siclk),
588 .soclk(soclk)
589);
590assign cic_div_stall_d = div_stall_d; // send to lmc to block bypass
591
592// The dcache can fill when the pipe is not blocked by a load or divide
593assign dcfill_active_e = cpq_ld_vld & ~ld_inst_e & ~div_stall_e & ~block_cpq_e;
594assign cic_l2fill_vld_e = dcfill_active_e;
595
596// Don't restart the thread on the 1st pass of ldd or an atomic load
597assign cic_ignore_fill_e = (cpq_ldd_vld & ~ldd_2nd_pass) | cpq_atomic;
598
599assign cic_rtn_cmplt = (dcfill_active_e & ~cic_ignore_fill_e) | cic_st_atm_cmplt;
600
601// Store updates follow the same rules to write to the cache as load fills;
602// i.e. can't write if a load is coming down the pipe
603assign cic_st_update_e = cpq_su_vld & ~ld_inst_e;
604
605// Dequeue stores
606assign st_dequeue = (cpq_su_vld & ~ld_inst_e) | (cpq_st_vld & ~cpq_su_vld);
607
608assign cic_st_atm_cmplt = (cid_pkt_type[4:0] == 5'b10100 & cpq_local_pkt) & cid_atomic & ~block_cpq_e;
609
610// Store deqeueing
611// 0in bits_on -var {(cpq_tid[0] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[0]} -max 1 -message "multiple dequeue in STB0"
612// 0in bits_on -var {(cpq_tid[1] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[1]} -max 1 -message "multiple dequeue in STB1"
613// 0in bits_on -var {(cpq_tid[2] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[2]} -max 1 -message "multiple dequeue in STB2"
614// 0in bits_on -var {(cpq_tid[3] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[3]} -max 1 -message "multiple dequeue in STB3"
615// 0in bits_on -var {(cpq_tid[4] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[4]} -max 1 -message "multiple dequeue in STB4"
616// 0in bits_on -var {(cpq_tid[5] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[5]} -max 1 -message "multiple dequeue in STB5"
617// 0in bits_on -var {(cpq_tid[6] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[6]} -max 1 -message "multiple dequeue in STB6"
618// 0in bits_on -var {(cpq_tid[7] & st_dequeue & ~cpq_rmo_ack),sbc_bst_sel[7]} -max 1 -message "multiple dequeue in STB7"
619
620assign cic_st_dequeue[7:0] = (cpq_tid[7:0] & {8{(st_dequeue & ~cpq_rmo_ack)}}) | sbc_bst_sel[7:0];
621assign cic_rmo_dequeue[7:0] = cpq_tid[7:0] & {8{(cpq_st_vld & cpq_rmo_ack)}};
622
623// store acks to respective store buffers - this is done when the packet is received
624assign cic_st_ack[0] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
625 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd0) & ~(|cid_d1_inval[1:0]));
626assign cic_st_ack[1] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
627 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd1) & ~(|cid_d1_inval[1:0]));
628assign cic_st_ack[2] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
629 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd2) & ~(|cid_d1_inval[1:0]));
630assign cic_st_ack[3] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
631 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd3) & ~(|cid_d1_inval[1:0]));
632assign cic_st_ack[4] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
633 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd4) & ~(|cid_d1_inval[1:0]));
634assign cic_st_ack[5] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
635 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd5) & ~(|cid_d1_inval[1:0]));
636assign cic_st_ack[6] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
637 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd6) & ~(|cid_d1_inval[1:0]));
638assign cic_st_ack[7] = ((cid_d1_rtntyp[4:0] == 5'b10100) & (cid_d1_cpuid[2:0] == const_cpuid[2:0]) &
639 ~cid_d1_rmo & (cid_d1_tid[2:0] == 3'd7) & ~(|cid_d1_inval[1:0]));
640
641// The packet is done when it gets accepted into the pipeline.
642assign cpq_pkt_done = ((dcfill_active_e & ~ldd_1st_pass) | cic_st_update_e) | (st_dequeue & ~cic_st_update_e) |
643 cpq_inv_vld | cic_xinval_e | (cpq_nonlsu_type & (~sel_byp_last | lsu_type_d1));
644
645//////////////////////////////////////////////////////////////////////////////
646// Invalidation vector decoding
647//////////////////////////////////////////////////////////////////////////////
648// For evict inval. [13:0] = {A11[2:0],A10[3:0],A01[2:0],A00[3:0]}
649// For store inval. [17:14] = {A[3:0]};
650
651assign evict_inv_wen[15] = cid_inv_vec[11] & (cid_inv_vec[13:12] == 2'b11);
652assign evict_inv_wen[14] = cid_inv_vec[11] & (cid_inv_vec[13:12] == 2'b10);
653assign evict_inv_wen[13] = cid_inv_vec[11] & (cid_inv_vec[13:12] == 2'b01);
654assign evict_inv_wen[12] = cid_inv_vec[11] & (cid_inv_vec[13:12] == 2'b00);
655
656assign evict_inv_wen[11] = cid_inv_vec[8] & ~cid_inv_vec[7] & (cid_inv_vec[10:9] == 2'b11);
657assign evict_inv_wen[10] = cid_inv_vec[8] & ~cid_inv_vec[7] & (cid_inv_vec[10:9] == 2'b10);
658assign evict_inv_wen[9] = cid_inv_vec[8] & ~cid_inv_vec[7] & (cid_inv_vec[10:9] == 2'b01);
659assign evict_inv_wen[8] = cid_inv_vec[8] & ~cid_inv_vec[7] & (cid_inv_vec[10:9] == 2'b00);
660
661assign evict_inv_wen[7] = cid_inv_vec[4] & (cid_inv_vec[6:5] == 2'b11);
662assign evict_inv_wen[6] = cid_inv_vec[4] & (cid_inv_vec[6:5] == 2'b10);
663assign evict_inv_wen[5] = cid_inv_vec[4] & (cid_inv_vec[6:5] == 2'b01);
664assign evict_inv_wen[4] = cid_inv_vec[4] & (cid_inv_vec[6:5] == 2'b00);
665
666assign evict_inv_wen[3] = cid_inv_vec[1] & ~cid_inv_vec[0] & (cid_inv_vec[3:2] == 2'b11);
667assign evict_inv_wen[2] = cid_inv_vec[1] & ~cid_inv_vec[0] & (cid_inv_vec[3:2] == 2'b10);
668assign evict_inv_wen[1] = cid_inv_vec[1] & ~cid_inv_vec[0] & (cid_inv_vec[3:2] == 2'b01);
669assign evict_inv_wen[0] = cid_inv_vec[1] & ~cid_inv_vec[0] & (cid_inv_vec[3:2] == 2'b00);
670
671assign store_inv_wen[15] = ((cid_inv_vec[17:14] == 4'b1110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b11);
672assign store_inv_wen[14] = ((cid_inv_vec[17:14] == 4'b1010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b11);
673assign store_inv_wen[13] = ((cid_inv_vec[17:14] == 4'b0110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b11);
674assign store_inv_wen[12] = ((cid_inv_vec[17:14] == 4'b0010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b11);
675
676assign store_inv_wen[11] = ((cid_inv_vec[17:14] == 4'b1110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b10);
677assign store_inv_wen[10] = ((cid_inv_vec[17:14] == 4'b1010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b10);
678assign store_inv_wen[9] = ((cid_inv_vec[17:14] == 4'b0110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b10);
679assign store_inv_wen[8] = ((cid_inv_vec[17:14] == 4'b0010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b10);
680
681assign store_inv_wen[7] = ((cid_inv_vec[17:14] == 4'b1110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b01);
682assign store_inv_wen[6] = ((cid_inv_vec[17:14] == 4'b1010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b01);
683assign store_inv_wen[5] = ((cid_inv_vec[17:14] == 4'b0110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b01);
684assign store_inv_wen[4] = ((cid_inv_vec[17:14] == 4'b0010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b01);
685
686assign store_inv_wen[3] = ((cid_inv_vec[17:14] == 4'b1110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b00);
687assign store_inv_wen[2] = ((cid_inv_vec[17:14] == 4'b1010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b00);
688assign store_inv_wen[1] = ((cid_inv_vec[17:14] == 4'b0110) | cid_set_inval) & (cid_st_addr[5:4] == 2'b00);
689assign store_inv_wen[0] = ((cid_inv_vec[17:14] == 4'b0010) | cid_set_inval) & (cid_st_addr[5:4] == 2'b00);
690
691assign cic_inv_wen_e[15:0] = cpq_evict ? evict_inv_wen[15:0] : store_inv_wen[15:0];
692
693//////////////////////////////////////////////////////////////////////////////
694// LDD/QUAD/BLD control
695//////////////////////////////////////////////////////////////////////////////
696
697// 1st pass of ldd type instructions should not retire the packet or signal
698// lsu_complete. The load return of atomics should not signal complete either.
699assign ldd_1st_pass = dcfill_active_e & cpq_ldd_vld & ~ldd_2nd_pass;
700
701assign next_ldd_2nd_pass= (cpq_ldd_vld & (dcfill_active_e ^ ldd_2nd_pass)) | (ldd_2nd_pass & block_cpq_e);
702
703lsu_cic_ctl_msff_ctl_macro__width_1 dff_ldd_2nd_pass (
704 .scan_in(dff_ldd_2nd_pass_scanin),
705 .scan_out(dff_ldd_2nd_pass_scanout),
706 .din (next_ldd_2nd_pass),
707 .dout (ldd_2nd_pass),
708 .l1clk(l1clk),
709 .siclk(siclk),
710 .soclk(soclk)
711);
712
713assign cic_oddrd_e = ldd_2nd_pass & dcfill_active_e;
714
715//////////////////////////////////////////////////////////////////////////////
716// xinval control
717// Because the IFU does not queue incoming packets, there is the possibility
718// that they process an ifill which requires D$ invalidation much earlier than
719// the LSU. This causes a problem because the fill will occur and the thread
720// could miss again before the D$ inval occurs. I will signal when an inval
721// is pending. During this time, the I$ will not service a miss from that thread.
722//////////////////////////////////////////////////////////////////////////////
723
724assign cic_xinval[0] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b000);
725assign cic_xinval[1] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b001);
726assign cic_xinval[2] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b010);
727assign cic_xinval[3] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b011);
728assign cic_xinval[4] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b100);
729assign cic_xinval[5] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b101);
730assign cic_xinval[6] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b110);
731assign cic_xinval[7] = (cid_d1_rtntyp[4:0] == 5'b10001) & cid_d1_wv & (cid_d1_tid[2:0] == 3'b111);
732
733
734//////////////////////////////////////////////////////////////////////////////
735// Must indicate to TLU whether a load error was L2 or SOC
736//////////////////////////////////////////////////////////////////////////////
737
738assign lsu_dcsoc_err_e = cid_pkt_type[3];
739
740lsu_cic_ctl_msff_ctl_macro__width_2 dff_dcl2_err (
741 .scan_in(dff_dcl2_err_scanin),
742 .scan_out(dff_dcl2_err_scanout),
743 .din ({lsu_dcsoc_err_e,cic_ext_interrupt}),
744 .dout ({lsu_dcsoc_err_g,lsu_ext_interrupt}),
745 .l1clk(l1clk),
746 .siclk(siclk),
747 .soclk(soclk)
748);
749
750//////////////////////////////////////////////////////////////////////////////
751// cpq must be blocked to accomodate diagnostic cache writes
752
753assign block_cpq_d = dcc_cache_diag_wr_b;
754
755lsu_cic_ctl_msff_ctl_macro__width_2 dff_diag_block (
756 .scan_in(dff_diag_block_scanin),
757 .scan_out(dff_diag_block_scanout),
758 .din ({block_cpq_d,block_cpq_d}),
759 .dout ({block_cpq_e,cic_diag_data_sel_e}),
760 .l1clk(l1clk),
761 .siclk(siclk),
762 .soclk(soclk)
763);
764
765// BIST
766assign cpq_fail = bist_cpq_cmp_en &
767 (~cid_cpq_cmp_1 | ~cid_cpq_cmp_2 | ~cid_cpq_cmp_3);
768
769lsu_cic_ctl_msff_ctl_macro__width_4 dff_bist (
770 .scan_in(dff_bist_scanin),
771 .scan_out(dff_bist_scanout),
772 .din ({mbi_run, mbi_cpq_read_en,bist_cpq_rd_1, cpq_fail}),
773 .dout ({mbi_run_local,bist_cpq_rd_1, bist_cpq_cmp_en,lsu_mbi_cpq_fail}),
774 .l1clk(l1clk),
775 .siclk(siclk),
776 .soclk(soclk)
777);
778
779// This drives to the cpq write mux. BIST data must be selected during lbist mode to block
780// the path from the cpx input pins.
781assign cic_mbi_run = mbi_run_local | lbist_run;
782
783//// Store ack packet should never have bits 125(BIS) and 129(atomic) asserted - move these to LSU
784//// 0in custom -fire ((cpx_spc_data_cx[145:141] == 5'b10100) & cpx_spc_data_cx[125] & cpx_spc_data_cx[129]) -message "BIS and ATOMIC both set for store_ack packet"
785//// Load rtn packet should never have bits 128(pf) and 129(atomic) asserted
786//// 0in custom -fire ((cpx_spc_data_cx[145:141] == 5'b10000) & cpx_spc_data_cx[128] & cpx_spc_data_cx[129]) -message "PF and ATOMIC both set for load rtn packet"
787//// Load rtn packet should have bit 137(nc) asserted if 129(atomic) asserted
788//// 0in custom -fire ((cpx_spc_data_cx[145:141] == 5'b10000) & cpx_spc_data_cx[129] & ~cpx_spc_data_cx[137]) -message "ATOMIC load rtn packet expects NC=1"
789//
790
791lsu_cic_ctl_spare_ctl_macro__num_2 spares (
792 .scan_in(spares_scanin),
793 .scan_out(spares_scanout),
794 .l1clk (l1clk),
795 .siclk(siclk),
796 .soclk(soclk)
797);
798
799supply0 vss;
800supply1 vdd;
801// fixscan start:
802assign dff_cpq_state_scanin = scan_in ;
803assign dff_cpq_sel_scanin = dff_cpq_state_scanout ;
804assign dff_cpq_wptr_scanin = dff_cpq_sel_scanout ;
805assign dff_cpq_rptr_scanin = dff_cpq_wptr_scanout ;
806assign dff_ll_cnt_scanin = dff_cpq_rptr_scanout ;
807assign dff_ld_inst_e_scanin = dff_ll_cnt_scanout ;
808assign dff_div_stall_scanin = dff_ld_inst_e_scanout ;
809assign dff_ldd_2nd_pass_scanin = dff_div_stall_scanout ;
810assign dff_dcl2_err_scanin = dff_ldd_2nd_pass_scanout ;
811assign dff_diag_block_scanin = dff_dcl2_err_scanout ;
812assign dff_bist_scanin = dff_diag_block_scanout ;
813assign spares_scanin = dff_bist_scanout ;
814assign scan_out = spares_scanout ;
815// fixscan end:
816endmodule
817
818
819
820
821
822
823
824// any PARAMS parms go into naming of macro
825
826module lsu_cic_ctl_l1clkhdr_ctl_macro (
827 l2clk,
828 l1en,
829 pce_ov,
830 stop,
831 se,
832 l1clk);
833
834
835 input l2clk;
836 input l1en;
837 input pce_ov;
838 input stop;
839 input se;
840 output l1clk;
841
842
843
844
845
846cl_sc1_l1hdr_8x c_0 (
847
848
849 .l2clk(l2clk),
850 .pce(l1en),
851 .l1clk(l1clk),
852 .se(se),
853 .pce_ov(pce_ov),
854 .stop(stop)
855);
856
857
858
859endmodule
860
861
862
863
864
865
866
867
868
869
870
871
872
873// any PARAMS parms go into naming of macro
874
875module lsu_cic_ctl_msff_ctl_macro__width_2 (
876 din,
877 l1clk,
878 scan_in,
879 siclk,
880 soclk,
881 dout,
882 scan_out);
883wire [1:0] fdin;
884wire [0:0] so;
885
886 input [1:0] din;
887 input l1clk;
888 input scan_in;
889
890
891 input siclk;
892 input soclk;
893
894 output [1:0] dout;
895 output scan_out;
896assign fdin[1:0] = din[1:0];
897
898
899
900
901
902
903dff #(2) d0_0 (
904.l1clk(l1clk),
905.siclk(siclk),
906.soclk(soclk),
907.d(fdin[1:0]),
908.si({scan_in,so[0:0]}),
909.so({so[0:0],scan_out}),
910.q(dout[1:0])
911);
912
913
914
915
916
917
918
919
920
921
922
923
924endmodule
925
926
927
928
929
930
931
932
933
934
935
936
937
938// any PARAMS parms go into naming of macro
939
940module lsu_cic_ctl_msff_ctl_macro__width_6 (
941 din,
942 l1clk,
943 scan_in,
944 siclk,
945 soclk,
946 dout,
947 scan_out);
948wire [5:0] fdin;
949wire [4:0] so;
950
951 input [5:0] din;
952 input l1clk;
953 input scan_in;
954
955
956 input siclk;
957 input soclk;
958
959 output [5:0] dout;
960 output scan_out;
961assign fdin[5:0] = din[5:0];
962
963
964
965
966
967
968dff #(6) d0_0 (
969.l1clk(l1clk),
970.siclk(siclk),
971.soclk(soclk),
972.d(fdin[5:0]),
973.si({scan_in,so[4:0]}),
974.so({so[4:0],scan_out}),
975.q(dout[5:0])
976);
977
978
979
980
981
982
983
984
985
986
987
988
989endmodule
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003// any PARAMS parms go into naming of macro
1004
1005module lsu_cic_ctl_msff_ctl_macro__width_3 (
1006 din,
1007 l1clk,
1008 scan_in,
1009 siclk,
1010 soclk,
1011 dout,
1012 scan_out);
1013wire [2:0] fdin;
1014wire [1:0] so;
1015
1016 input [2:0] din;
1017 input l1clk;
1018 input scan_in;
1019
1020
1021 input siclk;
1022 input soclk;
1023
1024 output [2:0] dout;
1025 output scan_out;
1026assign fdin[2:0] = din[2:0];
1027
1028
1029
1030
1031
1032
1033dff #(3) d0_0 (
1034.l1clk(l1clk),
1035.siclk(siclk),
1036.soclk(soclk),
1037.d(fdin[2:0]),
1038.si({scan_in,so[1:0]}),
1039.so({so[1:0],scan_out}),
1040.q(dout[2:0])
1041);
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054endmodule
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068// any PARAMS parms go into naming of macro
1069
1070module lsu_cic_ctl_msff_ctl_macro__width_1 (
1071 din,
1072 l1clk,
1073 scan_in,
1074 siclk,
1075 soclk,
1076 dout,
1077 scan_out);
1078wire [0:0] fdin;
1079
1080 input [0:0] din;
1081 input l1clk;
1082 input scan_in;
1083
1084
1085 input siclk;
1086 input soclk;
1087
1088 output [0:0] dout;
1089 output scan_out;
1090assign fdin[0:0] = din[0:0];
1091
1092
1093
1094
1095
1096
1097dff #(1) d0_0 (
1098.l1clk(l1clk),
1099.siclk(siclk),
1100.soclk(soclk),
1101.d(fdin[0:0]),
1102.si(scan_in),
1103.so(scan_out),
1104.q(dout[0:0])
1105);
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118endmodule
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132// any PARAMS parms go into naming of macro
1133
1134module lsu_cic_ctl_msff_ctl_macro__width_4 (
1135 din,
1136 l1clk,
1137 scan_in,
1138 siclk,
1139 soclk,
1140 dout,
1141 scan_out);
1142wire [3:0] fdin;
1143wire [2:0] so;
1144
1145 input [3:0] din;
1146 input l1clk;
1147 input scan_in;
1148
1149
1150 input siclk;
1151 input soclk;
1152
1153 output [3:0] dout;
1154 output scan_out;
1155assign fdin[3:0] = din[3:0];
1156
1157
1158
1159
1160
1161
1162dff #(4) d0_0 (
1163.l1clk(l1clk),
1164.siclk(siclk),
1165.soclk(soclk),
1166.d(fdin[3:0]),
1167.si({scan_in,so[2:0]}),
1168.so({so[2:0],scan_out}),
1169.q(dout[3:0])
1170);
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183endmodule
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193// Description: Spare gate macro for control blocks
1194//
1195// Param num controls the number of times the macro is added
1196// flops=0 can be used to use only combination spare logic
1197
1198
1199module lsu_cic_ctl_spare_ctl_macro__num_2 (
1200 l1clk,
1201 scan_in,
1202 siclk,
1203 soclk,
1204 scan_out);
1205wire si_0;
1206wire so_0;
1207wire spare0_flop_unused;
1208wire spare0_buf_32x_unused;
1209wire spare0_nand3_8x_unused;
1210wire spare0_inv_8x_unused;
1211wire spare0_aoi22_4x_unused;
1212wire spare0_buf_8x_unused;
1213wire spare0_oai22_4x_unused;
1214wire spare0_inv_16x_unused;
1215wire spare0_nand2_16x_unused;
1216wire spare0_nor3_4x_unused;
1217wire spare0_nand2_8x_unused;
1218wire spare0_buf_16x_unused;
1219wire spare0_nor2_16x_unused;
1220wire spare0_inv_32x_unused;
1221wire si_1;
1222wire so_1;
1223wire spare1_flop_unused;
1224wire spare1_buf_32x_unused;
1225wire spare1_nand3_8x_unused;
1226wire spare1_inv_8x_unused;
1227wire spare1_aoi22_4x_unused;
1228wire spare1_buf_8x_unused;
1229wire spare1_oai22_4x_unused;
1230wire spare1_inv_16x_unused;
1231wire spare1_nand2_16x_unused;
1232wire spare1_nor3_4x_unused;
1233wire spare1_nand2_8x_unused;
1234wire spare1_buf_16x_unused;
1235wire spare1_nor2_16x_unused;
1236wire spare1_inv_32x_unused;
1237
1238
1239input l1clk;
1240input scan_in;
1241input siclk;
1242input soclk;
1243output scan_out;
1244
1245cl_sc1_msff_8x spare0_flop (.l1clk(l1clk),
1246 .siclk(siclk),
1247 .soclk(soclk),
1248 .si(si_0),
1249 .so(so_0),
1250 .d(1'b0),
1251 .q(spare0_flop_unused));
1252assign si_0 = scan_in;
1253
1254cl_u1_buf_32x spare0_buf_32x (.in(1'b1),
1255 .out(spare0_buf_32x_unused));
1256cl_u1_nand3_8x spare0_nand3_8x (.in0(1'b1),
1257 .in1(1'b1),
1258 .in2(1'b1),
1259 .out(spare0_nand3_8x_unused));
1260cl_u1_inv_8x spare0_inv_8x (.in(1'b1),
1261 .out(spare0_inv_8x_unused));
1262cl_u1_aoi22_4x spare0_aoi22_4x (.in00(1'b1),
1263 .in01(1'b1),
1264 .in10(1'b1),
1265 .in11(1'b1),
1266 .out(spare0_aoi22_4x_unused));
1267cl_u1_buf_8x spare0_buf_8x (.in(1'b1),
1268 .out(spare0_buf_8x_unused));
1269cl_u1_oai22_4x spare0_oai22_4x (.in00(1'b1),
1270 .in01(1'b1),
1271 .in10(1'b1),
1272 .in11(1'b1),
1273 .out(spare0_oai22_4x_unused));
1274cl_u1_inv_16x spare0_inv_16x (.in(1'b1),
1275 .out(spare0_inv_16x_unused));
1276cl_u1_nand2_16x spare0_nand2_16x (.in0(1'b1),
1277 .in1(1'b1),
1278 .out(spare0_nand2_16x_unused));
1279cl_u1_nor3_4x spare0_nor3_4x (.in0(1'b0),
1280 .in1(1'b0),
1281 .in2(1'b0),
1282 .out(spare0_nor3_4x_unused));
1283cl_u1_nand2_8x spare0_nand2_8x (.in0(1'b1),
1284 .in1(1'b1),
1285 .out(spare0_nand2_8x_unused));
1286cl_u1_buf_16x spare0_buf_16x (.in(1'b1),
1287 .out(spare0_buf_16x_unused));
1288cl_u1_nor2_16x spare0_nor2_16x (.in0(1'b0),
1289 .in1(1'b0),
1290 .out(spare0_nor2_16x_unused));
1291cl_u1_inv_32x spare0_inv_32x (.in(1'b1),
1292 .out(spare0_inv_32x_unused));
1293
1294cl_sc1_msff_8x spare1_flop (.l1clk(l1clk),
1295 .siclk(siclk),
1296 .soclk(soclk),
1297 .si(si_1),
1298 .so(so_1),
1299 .d(1'b0),
1300 .q(spare1_flop_unused));
1301assign si_1 = so_0;
1302
1303cl_u1_buf_32x spare1_buf_32x (.in(1'b1),
1304 .out(spare1_buf_32x_unused));
1305cl_u1_nand3_8x spare1_nand3_8x (.in0(1'b1),
1306 .in1(1'b1),
1307 .in2(1'b1),
1308 .out(spare1_nand3_8x_unused));
1309cl_u1_inv_8x spare1_inv_8x (.in(1'b1),
1310 .out(spare1_inv_8x_unused));
1311cl_u1_aoi22_4x spare1_aoi22_4x (.in00(1'b1),
1312 .in01(1'b1),
1313 .in10(1'b1),
1314 .in11(1'b1),
1315 .out(spare1_aoi22_4x_unused));
1316cl_u1_buf_8x spare1_buf_8x (.in(1'b1),
1317 .out(spare1_buf_8x_unused));
1318cl_u1_oai22_4x spare1_oai22_4x (.in00(1'b1),
1319 .in01(1'b1),
1320 .in10(1'b1),
1321 .in11(1'b1),
1322 .out(spare1_oai22_4x_unused));
1323cl_u1_inv_16x spare1_inv_16x (.in(1'b1),
1324 .out(spare1_inv_16x_unused));
1325cl_u1_nand2_16x spare1_nand2_16x (.in0(1'b1),
1326 .in1(1'b1),
1327 .out(spare1_nand2_16x_unused));
1328cl_u1_nor3_4x spare1_nor3_4x (.in0(1'b0),
1329 .in1(1'b0),
1330 .in2(1'b0),
1331 .out(spare1_nor3_4x_unused));
1332cl_u1_nand2_8x spare1_nand2_8x (.in0(1'b1),
1333 .in1(1'b1),
1334 .out(spare1_nand2_8x_unused));
1335cl_u1_buf_16x spare1_buf_16x (.in(1'b1),
1336 .out(spare1_buf_16x_unused));
1337cl_u1_nor2_16x spare1_nor2_16x (.in0(1'b0),
1338 .in1(1'b0),
1339 .out(spare1_nor2_16x_unused));
1340cl_u1_inv_32x spare1_inv_32x (.in(1'b1),
1341 .out(spare1_inv_32x_unused));
1342assign scan_out = so_1;
1343
1344
1345
1346endmodule
1347