Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: dmu_mmu_srq_iommu.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 ============================================ | |
35 | module dmu_mmu_srq_iommu | |
36 | ( | |
37 | l2clk, // clock for ram | |
38 | clk, // clock | |
39 | rst_l, // synchronous reset | |
40 | por_l, // por synchronous reset | |
41 | scan_in, | |
42 | tcu_array_bypass, | |
43 | tcu_scan_en, | |
44 | tcu_se_scancollar_in, | |
45 | tcu_array_wr_inhibit, | |
46 | tcu_pce_ov, | |
47 | tcu_aclk, | |
48 | tcu_bclk, | |
49 | scan_out, | |
50 | ||
51 | ld, // load | |
52 | ds, // data select | |
53 | di, // data in | |
54 | sun4v_mode, // 1 if sun4v_mode | |
55 | do, // data out | |
56 | srq2vab_sun4v_pgsz, // sun4v page size to vab to zero before tlb lookup | |
57 | srq2vab_sun4v_byp_ps0, // true if sun4v mode and bypass | |
58 | srq2tmc_sun4v_pgsz_err, // true if sun4v mode and illegal sun4v page size | |
59 | iotsbno, // iotsb number in stage ps0 to vtb and vab | |
60 | iotsb_basepa, // iotsb base pa for tablewalks | |
61 | srq2vab_np, // number of pages out of iotsb for sun4v out of range calc | |
62 | srq2vab_adva, // adjusted va after offset | |
63 | srq2tmc_ivld, // iotsb valid bit and'ed with sun4v_mode | |
64 | srq2tmc_ipe, // iotsb parity error or tmc block | |
65 | csr2dev_iotsb_wd, | |
66 | dev_iotsb2csr_rd, | |
67 | csr2dev2iotsb_we, | |
68 | csr2dev2iotsb_re, | |
69 | csr2IotsbDesc_we, | |
70 | csr2IotsbDesc_re, | |
71 | csr2dev_iotsb_rwa, | |
72 | busid_sel, | |
73 | lkup_deque_en, | |
74 | csr_done, | |
75 | dsn_dmc_iei, // NCU can force a parity error on deviotsb reads | |
76 | dmu_mb0_run, | |
77 | ||
78 | dmu_mb0_addr, | |
79 | dmu_mb0_wdata, | |
80 | dmu_mb0_dev_wr_en, | |
81 | dmu_mb0_dev_rd_en, | |
82 | dmu_mb0_tsb_wr_en, | |
83 | dmu_mb0_tsb_rd_en, | |
84 | //efu wires | |
85 | efu_dmu_data, // input efu to devtsb | |
86 | efu_dmu_xfer_en, // input efu to devtsb | |
87 | efu_dmu_clr , // input efu to devtsb | |
88 | dmu_efu_data, // output of devtsb to efu | |
89 | dmu_efu_xfer_en // output of devtsb to efu | |
90 | ); | |
91 | ||
92 | // ---------------------------------------------------------------------------- | |
93 | // Parameters | |
94 | // ---------------------------------------------------------------------------- | |
95 | parameter QD = 4, // queue depth | |
96 | // QW = 2; // queue width | |
97 | QW = 85; // queue width | |
98 | ||
99 | // ---------------------------------------------------------------------------- | |
100 | // Ports | |
101 | // ---------------------------------------------------------------------------- | |
102 | input l2clk; | |
103 | input clk; | |
104 | input rst_l; | |
105 | input por_l; | |
106 | input scan_in; | |
107 | input tcu_array_bypass; | |
108 | input tcu_scan_en; | |
109 | input tcu_se_scancollar_in; | |
110 | input tcu_array_wr_inhibit; | |
111 | input tcu_pce_ov; | |
112 | input tcu_aclk; | |
113 | input tcu_bclk; | |
114 | output scan_out; | |
115 | ||
116 | input [QD-1:0] ld; | |
117 | input [QD-2:0] ds; | |
118 | ||
119 | input [QW-1:0] di; | |
120 | input sun4v_mode; | |
121 | input [`FIRE_CSR_DATA_BITS] csr2dev_iotsb_wd; | |
122 | input csr2dev2iotsb_we; | |
123 | input csr2dev2iotsb_re; | |
124 | input csr2IotsbDesc_we; | |
125 | input csr2IotsbDesc_re; | |
126 | input [4:0] csr2dev_iotsb_rwa; | |
127 | input busid_sel; | |
128 | ||
129 | output [2:0] srq2vab_sun4v_pgsz; | |
130 | output srq2vab_sun4v_byp_ps0; | |
131 | output srq2tmc_sun4v_pgsz_err; | |
132 | output [QW-1:0] do; | |
133 | output [4:0] iotsbno; | |
134 | output [25:0] iotsb_basepa; | |
135 | output [3:0] srq2vab_np; | |
136 | output [27:0] srq2vab_adva; | |
137 | output srq2tmc_ivld; | |
138 | output srq2tmc_ipe; | |
139 | output [`FIRE_CSR_DATA_BITS] dev_iotsb2csr_rd; | |
140 | output lkup_deque_en; | |
141 | output csr_done; | |
142 | input dsn_dmc_iei; | |
143 | ||
144 | input dmu_mb0_run; | |
145 | ||
146 | input [4:0] dmu_mb0_addr; | |
147 | input [7:0] dmu_mb0_wdata; | |
148 | input dmu_mb0_dev_wr_en; | |
149 | input dmu_mb0_dev_rd_en; | |
150 | input dmu_mb0_tsb_wr_en; | |
151 | input dmu_mb0_tsb_rd_en; | |
152 | //efu wires | |
153 | input efu_dmu_data ; // input efu to devtsb | |
154 | input efu_dmu_xfer_en; // input efu to devtsb | |
155 | input efu_dmu_clr; // input efu to devtsb | |
156 | output dmu_efu_data; // output of devtsb to efu | |
157 | output dmu_efu_xfer_en ; // output of devtsb to efu | |
158 | ||
159 | wire dmu_efu_data ; | |
160 | wire dmu_efu_xfer_en ; | |
161 | ||
162 | // ---------------------------------------------------------------------------- | |
163 | // Variables | |
164 | // ---------------------------------------------------------------------------- | |
165 | wire [QW-1:0] do; | |
166 | // reg [QW-1:0] que [0:QD-1]; | |
167 | reg [QW-1:0] que_0; | |
168 | reg [QW-1:0] que_1; | |
169 | reg [QW-1:0] que_2; | |
170 | reg [QW-1:0] que_3; | |
171 | ||
172 | // integer i; | |
173 | ||
174 | wire [27:0] srq2vab_adva; | |
175 | // SRAM header to EFU | |
176 | wire hdr_efu_read_data; | |
177 | wire hdr_efu_xfer_en; | |
178 | ||
179 | // SRAM header to SRAM | |
180 | //wire [10:0] hdr_sram_rvalue; | |
181 | //wire [10:0] hdr_sram_rid; | |
182 | //wire hdr_sram_wr_en; | |
183 | //wire hdr_sram_red_clr; | |
184 | // ---------------------------------------------------------------------------- | |
185 | // Combinational | |
186 | // ---------------------------------------------------------------------------- | |
187 | wire [27:0] adj_va; | |
188 | reg [26:0] out_va; | |
189 | wire [3:0] fuse; | |
190 | wire bypass; | |
191 | wire [2:0] page_size; | |
192 | // NOTE: the adj_va is the full ppn but because the ptb holds 8 entries and | |
193 | // thus align the ppn to a cacheline boundary since the tte's are fetched as cachelines | |
194 | // and this alignment is done in dmu_mmu_vaq.v | |
195 | assign do = (sun4v_mode & ~bypass) ? {que_0[84:38],out_va[26:0],que_0[10:0]} : que_0 ; | |
196 | ||
197 | always @(page_size or que_0 or adj_va) begin | |
198 | ||
199 | out_va[26:0] = 27'b0; | |
200 | ||
201 | case (page_size) | |
202 | 3'b000: out_va = adj_va[26:0]; // 8k pages | |
203 | 3'b001: out_va = {adj_va[23:0],que_0[13:11]}; // 64 pages | |
204 | 3'b010: out_va = {27{1'b0}}; // invalid | |
205 | 3'b011: out_va = {adj_va[17:0],que_0[19:11]}; // 4M pages | |
206 | 3'b100: out_va = {27{1'b0}}; // invalid | |
207 | 3'b101: out_va = {adj_va[11:0],que_0[25:11]}; // 4M pages | |
208 | 3'b110: out_va = {27{1'b0}}; // invalid | |
209 | 3'b111: out_va = {27{1'b0}}; // invalid | |
210 | default: out_va = {27{1'b0}}; | |
211 | endcase | |
212 | end | |
213 | ||
214 | assign srq2vab_sun4v_pgsz[2:0] = page_size[2:0]; // send to vab to zero out for tlb compare | |
215 | ||
216 | assign srq2vab_sun4v_byp_ps0 = sun4v_mode & bypass; // used in vab for translation/bypass error | |
217 | ||
218 | assign srq2tmc_sun4v_pgsz_err = sun4v_mode & ( | |
219 | (page_size==3'b010) || | |
220 | (page_size==3'b100) || | |
221 | (page_size==3'b110) || | |
222 | (page_size==3'b111) ); | |
223 | ||
224 | // do bypass detect here, and in vab it logs the errors and does the actual bypass, | |
225 | // this bypass just short-circuits the new iotsb translation | |
226 | assign bypass = (que_0[61:37] == 25'h1fff800); // note que_0 adr starts at adr[2] | |
227 | //BP n2for fire , matches value in dmu_mmu_vab.v | |
228 | //assign bypass = (que_0[61:37] == 25'h1fff80); | |
229 | // ---------------------------------------------------------------------------- | |
230 | // Sequential | |
231 | // ---------------------------------------------------------------------------- | |
232 | // always @ (posedge clk) | |
233 | // if(~rst_l) begin : que_rst | |
234 | // integer j; | |
235 | // for (j = 0; j < QD; j = j + 1) begin | |
236 | // que[j] <= {QW{1'b0}}; | |
237 | // end | |
238 | // end | |
239 | // else begin | |
240 | // for (i = 0; i < QD-1; i = i + 1) begin | |
241 | // if (ld[i]) que[i] <= ds[i] ? que[i+1] : di; | |
242 | // end | |
243 | // if (ld[QD-1]) que[QD-1] <= di; | |
244 | // end | |
245 | ||
246 | always @ (posedge clk) | |
247 | if(~rst_l) begin : que_rst | |
248 | que_0 <= {QW{1'b0}}; | |
249 | que_1 <= {QW{1'b0}}; | |
250 | que_2 <= {QW{1'b0}}; | |
251 | que_3 <= {QW{1'b0}}; | |
252 | end | |
253 | else begin | |
254 | if (ld[0]) que_0 <= ds[0] ? que_1 : di; | |
255 | if (ld[1]) que_1 <= ds[1] ? que_2 : di; | |
256 | if (ld[2]) que_2 <= ds[2] ? que_3 : di; | |
257 | if (ld[3]) que_3 <= di; | |
258 | end | |
259 | ||
260 | ||
261 | // ---------------------------------------------------------------------------- | |
262 | // N2 BP 8-02-04 | |
263 | // add the new N2 IOMMU ram here, | |
264 | // NOTE: the flops at the input to the IOMMU ram are at the same stage in | |
265 | // the pipeline as que[0], so que[0] has 2 purposes | |
266 | // 1. used for SUN4U mode (old fire mode) | |
267 | // 2. used as part of the logic to make the new IOMMU input flops | |
268 | // appear as que[0] entry for the SUN4V mode | |
269 | // ---------------------------------------------------------------------------- | |
270 | // grab address bit 63 and the 8 bits of bus id to load into the new iommu ram address ff. | |
271 | wire adr_63,q1_or_di_63,reqid_sel; | |
272 | wire adr_0_63,adr_1_63; | |
273 | wire [6:0] q1_or_di_req_id; | |
274 | wire [5:0] req_id,q1_or_di_req_id_sel,req_id_in; | |
275 | assign adr_0_63 = que_0[61]; | |
276 | assign adr_1_63 = que_1[61]; | |
277 | // select address bit 63 into the iommu ram address port | |
278 | assign q1_or_di_63 = ds[0] ? adr_1_63 : di[61]; | |
279 | assign adr_63 = ld[0] ? q1_or_di_63 : adr_0_63; | |
280 | ||
281 | // now select the bus_id to load into the iommu ram address port | |
282 | // select which bus_id to load | |
283 | assign q1_or_di_req_id[6:0] = ds[0] ? que_1[76:70] : di[76:70]; // shift or di | |
284 | assign req_id[5:0] = reqid_sel ? que_0[75:70] : que_0[76:71]; // select which bits to hold | |
285 | assign q1_or_di_req_id_sel[5:0] = reqid_sel ? q1_or_di_req_id[5:0] : q1_or_di_req_id[6:1]; // select which new bits to load | |
286 | assign req_id_in[5:0] = ld[0] ? q1_or_di_req_id_sel[5:0] : req_id[5:0]; // hold term | |
287 | ||
288 | //temp | |
289 | wire devtsb_csr; | |
290 | wire [4:0] adr_r_in, devtsb_csr_adr; | |
291 | //SV assign reqid_sel = 1'b0; | |
292 | //SV assign devtsb_csr = 1'b0; | |
293 | assign adr_r_in[4:0] = devtsb_csr ? devtsb_csr_adr[4:0] : {1'b0,adr_63,req_id_in[5:3]}; | |
294 | wire [63:0] iotsb_out; | |
295 | wire [4:0] iotsbno; | |
296 | wire iotsb_par62,iotsb_par61; | |
297 | ||
298 | // SV | |
299 | wire csrequest, dev_rd, dev_wr, tsb_rd, tsb_wr, arb_winner; | |
300 | wire [63:0] devtsb_din; | |
301 | ||
302 | assign devtsb_csr_adr = csr2dev_iotsb_rwa; | |
303 | assign dev_iotsb2csr_rd = iotsb_out; | |
304 | assign reqid_sel = busid_sel; | |
305 | assign devtsb_csr = ~arb_winner; | |
306 | assign dev_rd = arb_winner ? 1'b1 : csr2dev2iotsb_re; | |
307 | assign dev_wr = ~arb_winner & csr2dev2iotsb_we; | |
308 | assign tsb_rd = arb_winner ? 1'b1 : csr2IotsbDesc_re; | |
309 | assign tsb_wr = ~arb_winner & csr2IotsbDesc_we; | |
310 | assign csrequest = csr2dev2iotsb_re | csr2dev2iotsb_we | csr2IotsbDesc_re | csr2IotsbDesc_we; | |
311 | assign lkup_deque_en = arb_winner; | |
312 | assign iotsb_par62 = ~(^{csr2dev_iotsb_wd[63],csr2dev_iotsb_wd[59:32]}); | |
313 | assign iotsb_par61 = ~(^{csr2dev_iotsb_wd[31:1],(csr2dev_iotsb_wd[0] ^ dsn_dmc_iei)}); | |
314 | assign devtsb_din = csr2dev2iotsb_we ? {3'b0,csr2dev_iotsb_wd[60:56],3'b0,csr2dev_iotsb_wd[52:48],3'b0,csr2dev_iotsb_wd[44:40],3'b0,csr2dev_iotsb_wd[36:32],3'b0,csr2dev_iotsb_wd[28:24],3'b0,csr2dev_iotsb_wd[20:16],3'b0,csr2dev_iotsb_wd[12:8],3'b0,csr2dev_iotsb_wd[4:0]} : {csr2dev_iotsb_wd[63],iotsb_par62,iotsb_par61,1'b0,csr2dev_iotsb_wd[59:0]}; | |
315 | ||
316 | /* arb -req csrrequest -gnt ~lkupreq | |
317 | -round_robin | |
318 | */ | |
319 | dmu_mmu_arbiter_rrobin arbiter_rrobin | |
320 | ( | |
321 | .next_grant (arb_winner), | |
322 | .csr_done (csr_done), | |
323 | .clk (clk), | |
324 | .rst_l (rst_l), | |
325 | .csrequest (csrequest) | |
326 | ); | |
327 | ||
328 | //BP n2 9-23-04 add the bypass mux | |
329 | // note devtsb_din derives from csr2dev_iotsb_wd which comes from flops in dmu_mmu_csr_cim.v | |
330 | // | |
331 | wire [`FIRE_CSR_DATA_BITS] devtsb_out; | |
332 | assign iotsb_out = tcu_array_bypass ? csr2dev_iotsb_wd : devtsb_out; | |
333 | ||
334 | //SV 02/24/05 added BIST logic | |
335 | wire [63:0] din_ram ; | |
336 | wire [4:0] rd_addr_ram, wr_addr_ram ; | |
337 | wire tsbwr_en_ram, tsbrd_en_ram ; | |
338 | wire devwr_en_ram, devrd_en_ram ; | |
339 | wire devtsb_lkup_en ; | |
340 | ||
341 | assign din_ram = dmu_mb0_run ? ({8{dmu_mb0_wdata}}) : devtsb_din ; | |
342 | assign rd_addr_ram = dmu_mb0_run ? dmu_mb0_addr[4:0] : adr_r_in[4:0] ; | |
343 | assign wr_addr_ram = dmu_mb0_run ? dmu_mb0_addr[4:0] : csr2dev_iotsb_rwa ; | |
344 | assign devwr_en_ram = dmu_mb0_run ? dmu_mb0_dev_wr_en : dev_wr ; | |
345 | assign devrd_en_ram = dmu_mb0_run ? dmu_mb0_dev_rd_en : dev_rd ; | |
346 | assign tsbwr_en_ram = dmu_mb0_run ? dmu_mb0_tsb_wr_en : tsb_wr ; | |
347 | assign tsbrd_en_ram = dmu_mb0_run ? dmu_mb0_tsb_rd_en : tsb_rd ; | |
348 | assign devtsb_lkup_en = dmu_mb0_run ? 1'b0 : arb_winner ; | |
349 | ||
350 | // -0in assert_follower -leader arb_winner -follower tsb_rd -max 0 -min 0 | |
351 | // -0in assert_follower -leader arb_winner -follower dev_rd -max 0 -min 0 | |
352 | // 0in never -var (tsb_rd & tsb_wr) -group mbist_mode | |
353 | // 0in never -var (dev_rd & dev_wr) -group mbist_mode | |
354 | ||
355 | n2_iom_sp_devtsb_cust srq_iommu | |
356 | ( | |
357 | // address ports | |
358 | .adr_r (rd_addr_ram), | |
359 | .adr_bs (req_id_in[2:0]), | |
360 | .adr_w (wr_addr_ram), | |
361 | ||
362 | // clock ports | |
363 | .clk (l2clk), | |
364 | ||
365 | // data input ports | |
366 | .din (din_ram), | |
367 | ||
368 | // data output ports | |
369 | // .dout (iotsb_out), | |
370 | .dout (devtsb_out), | |
371 | .tsb_adr_r (iotsbno), | |
372 | ||
373 | // port enables | |
374 | .dev_wr (devwr_en_ram), | |
375 | .dev_rd (devrd_en_ram), | |
376 | .tsb_wr (tsbwr_en_ram), | |
377 | .tsb_rd (tsbrd_en_ram), | |
378 | ||
379 | // | |
380 | .lkup_en (devtsb_lkup_en), | |
381 | ||
382 | ||
383 | ||
384 | ||
385 | // scan ports | |
386 | .scan_in (scan_in), | |
387 | .tcu_se_scancollar_in (tcu_se_scancollar_in), | |
388 | .tcu_scan_en (tcu_scan_en), | |
389 | .tcu_array_wr_inhibit (tcu_array_wr_inhibit), | |
390 | .tcu_pce_ov (tcu_pce_ov), | |
391 | .pce (1'b1), | |
392 | .tcu_aclk (tcu_aclk), | |
393 | .tcu_bclk (tcu_bclk), | |
394 | .scan_out (scan_out), | |
395 | .efu_bits (fuse[3:0]) | |
396 | ); | |
397 | ||
398 | ||
399 | // do the SUN4V address relocation | |
400 | ||
401 | wire [25:0] iotsb_basepa; | |
402 | wire [26:0] offset; | |
403 | wire [3:0] srq2vab_np; // number of pages out of iotsb | |
404 | reg [26:0] shft_va; | |
405 | reg [4:0] rdcount; | |
406 | reg [21:0] sync_read; | |
407 | wire data_en,read_en,wr_en; | |
408 | reg sync_clr; | |
409 | ||
410 | assign srq2tmc_ivld = ~iotsb_out[63] && sun4v_mode; | |
411 | assign iotsb_basepa[25:0] = iotsb_out[59:34]; | |
412 | assign offset[26:0] = iotsb_out[33:7]; | |
413 | assign page_size[2:0] = iotsb_out[6:4]; | |
414 | assign srq2vab_np[3:0] = iotsb_out[3:0]; | |
415 | ||
416 | wire iotsb_out_par62 = ~(^{iotsb_out[63],iotsb_out[59:32]}); | |
417 | wire iotsb_out_par61 = ~(^{iotsb_out[31:0]}); | |
418 | //assign srq2tmc_ipe = sun4v_mode && iotsb_out[63] && (iotsb_out_par62 ^ iotsb_out[62]) | (iotsb_out_par61 ^ iotsb_out[61]); | |
419 | assign srq2tmc_ipe = sun4v_mode && (iotsb_out_par62 ^ iotsb_out[62]) | (iotsb_out_par61 ^ iotsb_out[61]); | |
420 | ||
421 | // note: that que_0 contains va[63:2] not va[61:0]!!! | |
422 | always @( page_size or que_0 )begin | |
423 | ||
424 | shft_va[26:0] = 27'b0; | |
425 | ||
426 | case (page_size) | |
427 | 3'b000: shft_va = que_0[37:11]; // 8k pages | |
428 | 3'b001: shft_va = {{3{1'b0}},que_0[37:14]}; // 64k pages | |
429 | 3'b010: shft_va = {27{1'b0}}; | |
430 | 3'b011: shft_va = {{9{1'b0}},que_0[37:20]}; // 4M pages | |
431 | 3'b100: shft_va = {27{1'b0}}; | |
432 | 3'b101: shft_va = {{15{1'b0}},que_0[37:26]}; // 256M pages | |
433 | 3'b110: shft_va = {27{1'b0}}; | |
434 | 3'b111: shft_va = {27{1'b0}}; | |
435 | default: shft_va = {27{1'b0}}; | |
436 | endcase | |
437 | end | |
438 | ||
439 | assign adj_va[27:0] = {1'b0,shft_va[26:0]} - {1'b0,offset[26:0]}; | |
440 | assign srq2vab_adva[27:0] = adj_va[27:0]; | |
441 | ||
442 | ||
443 | //BP N2 3-31-05 convert sv file to .v to drive devtsb ram | |
444 | // the .sv code is located at cdmspp/libs/rtl/n2_efuhdr_ctl.sv | |
445 | ||
446 | //module n2_efuhdr_ctl ; | |
447 | reg efu_dmu_xfer_en_r1,efu_dmu_data_r1,efu_dmu_clr_r1,efu_dmu_xfer_en_r2; | |
448 | reg [21:0] instr; | |
449 | wire [21:0] efu_instr,sram_read_data,received_instr; | |
450 | reg [4:0] count; | |
451 | wire [4:0] count_in; | |
452 | wire dispatch_read_data,load_shift_reg,load_en,reset_count; | |
453 | wire rdreset_count,ld_rd_en; | |
454 | wire [4:0] rdcount_in; | |
455 | reg [21:0] sync_instr; | |
456 | ||
457 | //msff_ctl_macro ff_input_all_enable (width=4) | |
458 | // ( | |
459 | // .scan_in(ff_input_all_enable_scanin), | |
460 | // .scan_out(ff_input_all_enable_scanout), | |
461 | // .dout ({efu_hdr_xfer_en_r1,efu_hdr_write_data_r1,efu_hdr_clr_r1,efu_hdr_xfer_en_r2}), | |
462 | // .din ({efu_hdr_xfer_en, efu_hdr_write_data ,efu_hdr_clr, efu_hdr_xfer_en_r1}), | |
463 | // .l1clk (l1clk_efu) | |
464 | // ); | |
465 | ||
466 | always @ (posedge clk) | |
467 | if(~por_l) begin | |
468 | efu_dmu_xfer_en_r1 <= 1'b0; | |
469 | efu_dmu_data_r1 <= 1'b0; | |
470 | efu_dmu_clr_r1 <= 1'b0; | |
471 | efu_dmu_xfer_en_r2 <= 1'b0; | |
472 | end | |
473 | else begin | |
474 | efu_dmu_xfer_en_r1 <= efu_dmu_xfer_en; | |
475 | efu_dmu_data_r1 <= efu_dmu_data; | |
476 | efu_dmu_clr_r1 <= efu_dmu_clr; | |
477 | efu_dmu_xfer_en_r2 <= efu_dmu_xfer_en_r1; | |
478 | end | |
479 | ||
480 | ||
481 | assign efu_instr[21:0] = {instr[20:0],efu_dmu_data_r1}; | |
482 | ||
483 | assign sram_read_data[21:0] = {18'b0,fuse[3:0]}; | |
484 | ||
485 | assign received_instr[21:0] = efu_dmu_xfer_en_r1 ? efu_instr[21:0] : | |
486 | (rdcount==5'd23) ? sync_read : | |
487 | dispatch_read_data ? ({instr[20:0],1'b0}) : 22'b0; | |
488 | ||
489 | assign load_shift_reg = efu_dmu_xfer_en_r1 | dispatch_read_data | (rdcount == 5'd23); | |
490 | ||
491 | //msff_ctl_macro ff_receiver_instr_slice (width=22,en=1) | |
492 | // ( | |
493 | // .scan_in(ff_receiver_instr_slice_scanin), | |
494 | // .scan_out(ff_receiver_instr_slice_scanout), | |
495 | // .dout (instr[21:0]), | |
496 | // .din (received_instr[21:0]), | |
497 | // .en (load_shift_reg), | |
498 | // .l1clk (l1clk_efu) | |
499 | // ); | |
500 | ||
501 | always @ (posedge clk) begin | |
502 | if(~por_l) begin | |
503 | instr[21:0] <= 22'b0; | |
504 | end | |
505 | else if (load_shift_reg) begin | |
506 | instr[21:0] <= received_instr[21:0]; | |
507 | end | |
508 | else begin | |
509 | instr[21:0] <= instr[21:0]; | |
510 | end | |
511 | end | |
512 | ||
513 | assign data_en = (count==5'd8) ; | |
514 | assign wr_en = ((count==5'd7) | ~(sync_instr[21]) ); | |
515 | assign read_en = (count==5'd1); | |
516 | ||
517 | always @ (posedge clk) begin | |
518 | if(~por_l|| sync_clr) begin | |
519 | sync_instr[1:0] <= 2'b0; | |
520 | sync_instr[2] <= 1'b1; | |
521 | sync_instr[21:3] <= 19'b0; | |
522 | end | |
523 | else if (data_en & | |
524 | // (~received_instr[21] & received_instr[11] & received_instr[0]) ) begin | |
525 | (~instr[21] & instr[11] & instr[0]) ) begin | |
526 | sync_instr[21:0] <= instr[21:0]; | |
527 | end | |
528 | else begin | |
529 | sync_instr[21:0] <= sync_instr[21:0]; | |
530 | end | |
531 | end | |
532 | assign fuse[3:0] = sync_instr[4:1]; | |
533 | ||
534 | always @ (posedge clk) begin | |
535 | if(~por_l) begin | |
536 | sync_read[21:0] <= 22'b0; | |
537 | end | |
538 | else if (read_en) begin | |
539 | sync_read[21:0] <= sram_read_data[21:0]; | |
540 | end | |
541 | else begin | |
542 | sync_read[21:0] <= sync_read[21:0]; | |
543 | end | |
544 | end | |
545 | ||
546 | ||
547 | always @ (posedge clk) | |
548 | if(~por_l) begin | |
549 | sync_clr <= 1'b0; | |
550 | end | |
551 | else begin | |
552 | sync_clr <= efu_dmu_clr_r1; | |
553 | end | |
554 | ||
555 | ||
556 | // always @ (posedge clk) | |
557 | // if(~por_l || sync_clr) begin | |
558 | // fuse[0] <= 1'b0; | |
559 | // fuse[1] <= 1'b1; | |
560 | // fuse[3:2] <= 2'b0; | |
561 | // end | |
562 | // else if (load_en & received_instr[11] & received_instr[0]) begin | |
563 | // else if (efu_dmu_xfer_en_r2 & ~efu_dmu_xfer_en_r1 & | |
564 | // ~received_instr[21] & received_instr[11] & received_instr[0]) begin | |
565 | // fuse[3:0] <= received_instr[4:1]; | |
566 | // end | |
567 | // else begin | |
568 | // fuse[3:0] <= fuse[3:0]; | |
569 | // end | |
570 | ||
571 | assign load_en = (~efu_dmu_xfer_en_r2 & efu_dmu_xfer_en_r1); | |
572 | assign ld_rd_en = (count==5'd1); | |
573 | ||
574 | assign reset_count = ( count == 5'd0 ); | |
575 | assign rdreset_count = ( rdcount == 5'd0 ); | |
576 | ||
577 | assign count_in = load_en ? 5'd29 : reset_count ? 5'b0 : (count - 5'b1); | |
578 | assign rdcount_in = ld_rd_en ? 5'd23 : rdreset_count ? 5'b0 : (rdcount - 5'b1); | |
579 | ||
580 | //msff_ctl_macro ff_counter_slice (width=5,en=1) | |
581 | // ( | |
582 | // .scan_in(ff_counter_slice_scanin), | |
583 | // .scan_out(ff_counter_slice_scanout), | |
584 | // .dout (count[4:0]), | |
585 | // .din (count_in[4:0]), | |
586 | // .en (load_en), | |
587 | // .l1clk (l1clk_efu) | |
588 | // ); | |
589 | ||
590 | always @ (posedge clk) | |
591 | if(~por_l) begin | |
592 | count[4:0] <= 5'b0; | |
593 | end | |
594 | // else if (load_en) begin | |
595 | // else if (efu_dmu_xfer_en_r1) begin | |
596 | else begin | |
597 | count[4:0] <= count_in[4:0]; | |
598 | end | |
599 | ||
600 | always @ (posedge clk) | |
601 | if(~por_l) begin | |
602 | rdcount[4:0] <= 5'b0; | |
603 | end | |
604 | // else if (ld_rd_en) begin | |
605 | else begin | |
606 | rdcount[4:0] <= rdcount_in[4:0]; | |
607 | end | |
608 | ||
609 | //assign hdr_sram_rvalue[10:0] = instr[10:0]; | |
610 | //assign hdr_sram_rid[10:0] = instr[21:11]; | |
611 | //assign hdr_sram_red_clr = efu_dmu_clr_r1; | |
612 | //assign hdr_sram_wr_en = |(count[1:0]); | |
613 | //assign hdr_sram_rvalue[10:0] = sync_instr[10:0]; | |
614 | //assign hdr_sram_rid[10:0] = sync_instr[21:11]; | |
615 | //assign hdr_sram_red_clr = sync_clr; | |
616 | //assign hdr_sram_wr_en = sync_wr; | |
617 | ||
618 | ||
619 | //assign dispatch_read_data = (count[4:0]<5'd23) & (rdcount[4:0]!= 5'd0); | |
620 | assign dispatch_read_data = (rdcount[4:0]<5'd23) & (rdcount[4:0]!=5'd0); | |
621 | ||
622 | //assign hdr_efu_read_data = instr[21]; | |
623 | //assign hdr_efu_xfer_en = dispatch_read_data; | |
624 | assign dmu_efu_data = instr[21]; | |
625 | assign dmu_efu_xfer_en = dispatch_read_data; | |
626 | ||
627 | endmodule // dmu_mmu_srq | |
628 |