Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: mif.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 | /*%W% %G%*/ | |
36 | ||
37 | /************************************************************************* | |
38 | * | |
39 | * File Name : mif | |
40 | * Author Name : John Lo | |
41 | * Description : | |
42 | * Parent Module: | |
43 | * Child Module: many | |
44 | * Interface Mod: many. | |
45 | * Date Created : 7/24/03 | |
46 | * | |
47 | * Copyright (c) 2008, Sun Microsystems, Inc. | |
48 | * Sun Proprietary and Confidential | |
49 | * | |
50 | * | |
51 | * Design Notes: the MDC clock is generated by | |
52 | * clk divided by 2 to the power of `IDLE_CNT_SIZE. | |
53 | * The IEEE spec requires the MDC clock | |
54 | * to be less or equal to 400ns. | |
55 | * But today's phy can support upto 12.5Mhz | |
56 | * MDC clock. | |
57 | * If the clk is higher than 125 mhz | |
58 | * user of this IP needs to make sure | |
59 | * the MDC clock can still work with | |
60 | * Phy chip. | |
61 | * | |
62 | * When ST (Start of Frame) = 2'b01 | |
63 | * 1. ST (Start of Frame) = 2'b01 for original phy | |
64 | * register address space per | |
65 | * IEEE 802.3u Clause 22 MII specification. | |
66 | * 2. ST (Start of Frame) = 2'b00 for a new | |
67 | * indirect access cycle of extra register | |
68 | * address space per | |
69 | * IEEE 802.3ae Clause 45 MDIO specification. | |
70 | * | |
71 | * | |
72 | * There are only two places that need to be modified | |
73 | * when moving up core_clk frequency. | |
74 | * | |
75 | * 1. Change the following define variable to fit | |
76 | * specific core_clk freq in a propotional linear scale way. | |
77 | * 2. Add more digital delay for MDIO and mdo_en | |
78 | * to satisfy 10ns (min) setup and hold time requirements. | |
79 | * Please refer to Clause 22.3.4 for detail | |
80 | * | |
81 | * * mif_init_done_stat, send_init_fm, mif_init_fm | |
82 | * are three key signals for the new auto init feature. | |
83 | * | |
84 | * * Auto inti frame function is merged with | |
85 | * regular ld_frame since these two behavior are simular. | |
86 | * | |
87 | * | |
88 | * BUG to be fixed: Must fix the poll_fm_rd_opcode bug. 1-30-06 | |
89 | * | |
90 | * | |
91 | * | |
92 | ***************************************************************/ | |
93 | ||
94 | `include "mif.h" | |
95 | ||
96 | ||
97 | `define IDLE_CNT_SIZE 7 // 250mhz core clk | |
98 | `define IDLE_CNT_TEMP1 `IDLE_CNT_SIZE'b0 // 7'b0 | |
99 | `define IDLE_CNT_BASE ~(`IDLE_CNT_TEMP1) // 7'b111_1111 == 7'h7F | |
100 | `define IDLE_CNT_MSB `IDLE_CNT_SIZE - 1 // 6 <- MSB | |
101 | `define IDLE_CNT_R `IDLE_CNT_MSB:0 // 6:0 | |
102 | `define TX_BIT_DN 7'b100_0000 // 7'h40 = 64 = 7'b100_0000 | |
103 | `define RX_BIT_DN `TX_BIT_DN - 7'd1 // 7'h3F = 63 = 7'b011_1111 | |
104 | `define CLAUSE22_ST 2'b01 | |
105 | `define CLAUSE45_ST 2'b00 | |
106 | ||
107 | module mif( | |
108 | `ifdef NEPTUNE | |
109 | xge_mif_error_0, | |
110 | xge_mif_error_1, | |
111 | peu_mif_error, | |
112 | peu_mif_rdy, | |
113 | spc_mif_rdy, | |
114 | mif_spc_req, | |
115 | mif_spc_addr, | |
116 | spc_mif_ack, | |
117 | spc_mif_rdata, | |
118 | mif_initdone, | |
119 | `else | |
120 | `endif | |
121 | clk, | |
122 | pio_core_reset, | |
123 | sel_mif, // sel | |
124 | pio_rd, // r/w | |
125 | pio_addr, // address | |
126 | pio_wdata, // wr_data | |
127 | ack_mif, | |
128 | rdata_mif, // rd_data | |
129 | pio_err_mif, | |
130 | atca_GE, | |
131 | MDINT0, | |
132 | MDINT1, | |
133 | PHY_MDINT0_L, | |
134 | PHY_MDINT1_L, | |
135 | // mdio output signals | |
136 | mdclk, | |
137 | mdo, | |
138 | mif_pio_intr, | |
139 | // mdio input signals | |
140 | mdi, | |
141 | mdi_0, | |
142 | mdi_1, | |
143 | mdi_2 | |
144 | ); | |
145 | ||
146 | `ifdef NEPTUNE | |
147 | /* ----- serdes related --------- */ | |
148 | input xge_mif_error_0; | |
149 | input xge_mif_error_1; | |
150 | input peu_mif_error; | |
151 | input peu_mif_rdy; | |
152 | input spc_mif_rdy; | |
153 | output mif_spc_req; | |
154 | output [4:0] mif_spc_addr; | |
155 | input spc_mif_ack; | |
156 | input [15:0] spc_mif_rdata; | |
157 | output mif_initdone; | |
158 | `else | |
159 | `endif | |
160 | input clk; | |
161 | input pio_core_reset; | |
162 | input sel_mif; // sel | |
163 | input pio_rd; // r/w | |
164 | input [8:0] pio_addr; // address | |
165 | input [31:0] pio_wdata; // wr_data | |
166 | output ack_mif; | |
167 | output [31:0] rdata_mif; // rd_data | |
168 | output pio_err_mif; | |
169 | output atca_GE; | |
170 | output MDINT0; | |
171 | output MDINT1; | |
172 | input PHY_MDINT0_L; | |
173 | input PHY_MDINT1_L; | |
174 | // mdio output outputs | |
175 | output mdclk; | |
176 | output mdo; | |
177 | output mif_pio_intr; | |
178 | // mdio input signals | |
179 | input mdi; | |
180 | input mdi_0; | |
181 | input mdi_1; | |
182 | input mdi_2; // pcie serdes | |
183 | ||
184 | /*AUTOWIRE*/ | |
185 | // Beginning of automatic wires (for undeclared instantiated-module outputs) | |
186 | wire clr_idle_timer; // From mif_exec_sm of mif_exec_sm.v | |
187 | wire clr_mdo_en; // From mif_exec_sm of mif_exec_sm.v | |
188 | wire clr_read_instr; // From mif_exec_sm of mif_exec_sm.v | |
189 | wire mdi_en; // From mif_exec_sm of mif_exec_sm.v | |
190 | wire set_mdo_en; // From mif_exec_sm of mif_exec_sm.v | |
191 | wire set_read_instr; // From mif_exec_sm of mif_exec_sm.v | |
192 | wire shift_en; // From mif_exec_sm of mif_exec_sm.v | |
193 | wire ta_clr_mdo_en; // From mif_exec_sm of mif_exec_sm.v | |
194 | // End of automatics | |
195 | wire rd_op_code; | |
196 | wire wr_op_code; | |
197 | ||
198 | wire instr_pnd,wr_done,rd_done,illegal_instr,fetch_instr, | |
199 | poll_instr,ld_instr,ld_output_reg,ld_poll_status,tx_bit_done,rx_bit_done, | |
200 | frame_mdo,shift_out,rac_pls, | |
201 | poll_en,bb_mode,bb_mdc,new_bb_mdc,new_bb_mdo,new_bb_mdo_en, | |
202 | bb_mdo,bb_mdo_en,mdo_fclk,mdo_en_fclk,mdo_en, | |
203 | read_instr; | |
204 | wire mdclk; | |
205 | wire mdo; | |
206 | wire mdo_temp; | |
207 | wire mdio_en; | |
208 | wire wr_en; | |
209 | wire fclk; | |
210 | wire [4:0] port_addr; | |
211 | wire [4:0] poll_dev_addr; | |
212 | wire [4:0] poll_prt_addr; | |
213 | wire [4:0] idle_count2; | |
214 | wire [`IDLE_CNT_R]idle_count1, div_count; // loj | |
215 | wire mif_init_done_stat; | |
216 | wire [31:0] output_reg; | |
217 | wire [31:0] new_poll_status; | |
218 | wire [31:0] poll_status; | |
219 | wire [31:0] instr_din; | |
220 | wire [31:0] frame_dout; | |
221 | wire indirect_mode; | |
222 | wire [31:0] config1; | |
223 | reg mdi_mux; | |
224 | reg ld_mif_status; | |
225 | reg ld_mif_mask; | |
226 | reg rac_mif_status; | |
227 | ||
228 | /* ------------------------------ Slave I/F -------------------------------- */ | |
229 | reg ld_bb_mdc; | |
230 | reg ld_bb_mdo; | |
231 | reg ld_bb_mdo_en; | |
232 | reg ld_frame_pio; // ld frame caused by PIO | |
233 | wire ld_frame; | |
234 | reg ld_config; | |
235 | reg ld_poll_mask; | |
236 | reg rac_poll_status; | |
237 | reg non_qualified_addr_err; | |
238 | reg [31:0] rd_data; | |
239 | wire idle_done; | |
240 | wire addr_err; | |
241 | wire [31:0] rdata_mif; | |
242 | wire [31:0] pio_wdata; | |
243 | wire [31:0] wr_data; | |
244 | wire [8:0] reg_offset; | |
245 | wire [1:0] int_ser_sel; | |
246 | wire mdi_1; | |
247 | wire mdi_0; | |
248 | wire reset; | |
249 | wire [5:0] ex_state; | |
250 | wire [2:0] ctl_state; | |
251 | wire [31:0] poll_mask; | |
252 | wire [31:0] mif_state_machine; | |
253 | wire int_ser0; | |
254 | wire int_ser1; | |
255 | wire int_ser2; | |
256 | wire spc_rdy; | |
257 | wire spc_req; | |
258 | wire spc_ack; | |
259 | // vlint flag_net_has_no_load off | |
260 | // vlint flag_dangling_net_within_module off | |
261 | wire [31:0] shift_dout; | |
262 | wire core_sel_trail; | |
263 | wire frame_mdo_en; | |
264 | wire manual_mode; | |
265 | wire mif_initdone; | |
266 | // vlint flag_dangling_net_within_module on | |
267 | // vlint flag_net_has_no_load on | |
268 | ||
269 | wire [31:0] mif_status; | |
270 | wire [31:0] mif_mask; | |
271 | wire mif_interrupt; | |
272 | wire [1:0] st; | |
273 | wire [31:0] poll_fm; | |
274 | wire [31:0] mif_init_fm; | |
275 | wire send_init_fm; | |
276 | wire send_init_fm_pls; | |
277 | wire [3:0] mif_init_state; | |
278 | ||
279 | wire rd_wr,core_sel,core_sel_lead,shift_in,reset_pls,fclk_pls, | |
280 | d1_mdo_en_fclk,d2_mdo_en_fclk,d3_mdo_en_fclk, | |
281 | d1_mdo_fclk,d2_mdo_fclk,d3_mdo_fclk; | |
282 | ||
283 | ||
284 | assign mif_state_machine = {3'h0, | |
285 | spc_rdy, | |
286 | spc_req, | |
287 | spc_ack, | |
288 | send_init_fm, | |
289 | mif_init_state[3:0], | |
290 | port_addr[4:0], | |
291 | mdi_2,mdi_1,mdi_0, | |
292 | mdclk,mdo_en,mdo,mdi, | |
293 | ctl_state[2:0],ex_state[5:0]}; | |
294 | ||
295 | ||
296 | /* ------------------------------------------------------------------------- */ | |
297 | ||
298 | //***** Register the mif interface signals ********************* | |
299 | // To reduce gate count -> take register away | |
300 | // If there is a timing problem, register them again here. | |
301 | //************************************************************** | |
302 | ||
303 | ||
304 | FD1 core_reset_FD1 (.D(pio_core_reset),.CP(clk),.Q(reset)); | |
305 | ||
306 | FD1 rd_wr_FD1 (.D(pio_rd), .CP(clk),.Q(rd_wr)); | |
307 | FD1 core_sel_FD1 (.D(sel_mif), .CP(clk),.Q(core_sel)); | |
308 | // the following reset_pls guarantees the MDC clock being funcitonal | |
309 | // in the reset state. | |
310 | pls_gen pls_gen(.clk(clk),.in(reset),.out(reset_pls)); | |
311 | ||
312 | RegDff #(9) reg_offset_RegDff(.din(pio_addr[8:0]), | |
313 | .clk(clk), | |
314 | .qout(reg_offset[8:0])); | |
315 | ||
316 | RegDff #(32) wr_data_RegDff (.din(pio_wdata[31:0]), | |
317 | .clk(clk), | |
318 | .qout(wr_data[31:0])); | |
319 | ||
320 | PlsGen2 core_sel_PlsGen2(.sig_in(core_sel),.clk(clk), | |
321 | .lead(core_sel_lead), | |
322 | .trail(core_sel_trail)); | |
323 | ||
324 | wire rac_ok = core_sel_lead & rd_wr; | |
325 | assign wr_en = core_sel_lead & (~rd_wr); | |
326 | ||
327 | RegDff #(32) rdata_mif_RegDff (.din(rd_data),.clk(clk), | |
328 | .qout(rdata_mif[31:0])); | |
329 | ||
330 | FD1 ack_mif_FD1 (.D(core_sel_lead),.CP(clk),.Q(ack_mif)); | |
331 | FD1 rac_pls_FD1 (.D(rac_ok),.CP(clk),.Q(rac_pls)); | |
332 | assign addr_err = non_qualified_addr_err & core_sel_lead; | |
333 | FD1 pio_err_mif_FD1 (.D(addr_err),.CP(clk),.Q(pio_err_mif)); | |
334 | ||
335 | ||
336 | always @ (/*AUTOSENSE*/bb_mdc or bb_mdo or bb_mdo_en or config1 | |
337 | or frame_dout or mif_init_fm or mif_mask | |
338 | or mif_state_machine or mif_status or output_reg or poll_fm | |
339 | or poll_mask or poll_status or rac_pls or reg_offset | |
340 | or wr_en) | |
341 | begin | |
342 | non_qualified_addr_err = 0; | |
343 | rd_data = 32'hDEADBEEF; | |
344 | ld_bb_mdc = 0; | |
345 | ld_bb_mdo = 0; | |
346 | ld_bb_mdo_en = 0; | |
347 | ld_frame_pio = 0; | |
348 | ld_config = 0; | |
349 | ld_poll_mask = 0; | |
350 | rac_poll_status = 0; | |
351 | ld_mif_status = 0; | |
352 | ld_mif_mask = 0; | |
353 | rac_mif_status = 0; | |
354 | ||
355 | ||
356 | case (reg_offset[8:0]) // synopsys parallel_case full_case infer_mux | |
357 | // mif addr range is from 1_0000_0000 to 1_1111_1111 (9'h100 to 9'h1FF) | |
358 | 9'h000: begin | |
359 | ld_bb_mdc = wr_en; | |
360 | rd_data = {31'h0,bb_mdc}; | |
361 | end | |
362 | 9'h001: begin | |
363 | ld_bb_mdo = wr_en; | |
364 | rd_data = {31'h0,bb_mdo}; | |
365 | end | |
366 | 9'h002: begin | |
367 | ld_bb_mdo_en = wr_en; | |
368 | rd_data = {31'h0,bb_mdo_en}; | |
369 | end | |
370 | 9'h003: begin | |
371 | ld_frame_pio = wr_en; | |
372 | rd_data = output_reg; | |
373 | end | |
374 | 9'h004: begin | |
375 | ld_config = wr_en; | |
376 | rd_data = config1; | |
377 | end | |
378 | 9'h005: begin | |
379 | rac_poll_status = rac_pls; | |
380 | rd_data = poll_status; | |
381 | end | |
382 | 9'h006: begin | |
383 | ld_poll_mask = wr_en; | |
384 | rd_data = poll_mask; | |
385 | end | |
386 | 9'h007: begin | |
387 | rd_data = mif_state_machine; | |
388 | end | |
389 | 9'h008: begin | |
390 | ld_mif_status = wr_en; | |
391 | rd_data = mif_status; | |
392 | end | |
393 | 9'h009: begin | |
394 | ld_mif_mask = wr_en; | |
395 | rd_data = mif_mask; | |
396 | end | |
397 | 9'h00A: begin | |
398 | rd_data = mif_init_fm; | |
399 | end | |
400 | 9'h00B: begin | |
401 | rd_data = frame_dout; | |
402 | end | |
403 | 9'h00C: begin | |
404 | rd_data = poll_fm; | |
405 | end | |
406 | default:begin | |
407 | rd_data = 32'hdead_beef; | |
408 | non_qualified_addr_err = 1; | |
409 | end | |
410 | endcase | |
411 | ||
412 | end // always @ (... | |
413 | ||
414 | ///////////////////////////////////////////////////////////////// | |
415 | // register instantiation | |
416 | ///////////////////////////////////////////////////////////////// | |
417 | ||
418 | /* ---------------------------- Bit-Bang I/F ------------------------------- */ | |
419 | assign new_bb_mdc = reset ? 1'b0 : | |
420 | (ld_bb_mdc ? wr_data[0] : bb_mdc); | |
421 | assign new_bb_mdo = reset ? 1'b0 : | |
422 | (ld_bb_mdo ? wr_data[0] : bb_mdo); | |
423 | assign new_bb_mdo_en = reset ? 1'b0 : | |
424 | (ld_bb_mdo_en ? wr_data[0] : bb_mdo_en); | |
425 | FD1 BB_MDC_FF(.D(new_bb_mdc),.CP(clk),.Q(bb_mdc)); | |
426 | FD1 BB_MDO_FF(.D(new_bb_mdo),.CP(clk),.Q(bb_mdo)); | |
427 | FD1 BB_MDO_EN_FF(.D(new_bb_mdo_en),.CP(clk),.Q(bb_mdo_en)); | |
428 | /* ------------------------------------------------------------------------- */ | |
429 | ||
430 | /* ---------------------------- Frame Register ----------------------------- */ | |
431 | assign ld_frame = ld_frame_pio | send_init_fm_pls; | |
432 | wire [31:0] frame_din = send_init_fm ? mif_init_fm : wr_data; | |
433 | xREG #(32) FRAME_REG_xREG(.clk(clk),.reset(reset),.en(ld_frame),.din(frame_din),.qout(frame_dout)); | |
434 | /* ------------------------------------------------------------------------- */ | |
435 | ||
436 | ||
437 | /* ------------------------- Output Register ------------------------------- */ | |
438 | xREG #(16) output16b_xREG(.clk(clk),.reset(reset),.en(ld_output_reg),.din(shift_dout[15:0]),.qout(output_reg[15:0])); | |
439 | ||
440 | ||
441 | // When polling for completion: output_reg[16] serves as a "execution done". | |
442 | // When this bit is set to'1', the instruction execution has been completed. | |
443 | reg output_reg_b16; | |
444 | always @ (posedge clk) | |
445 | if (reset) | |
446 | output_reg_b16 <= 1'b0; | |
447 | else if (ld_frame) | |
448 | output_reg_b16 <= 1'b0; | |
449 | else if (ld_output_reg) | |
450 | output_reg_b16 <= 1'b1; | |
451 | else | |
452 | output_reg_b16 <= output_reg_b16; | |
453 | ||
454 | assign output_reg[16] = output_reg_b16; | |
455 | ||
456 | ||
457 | assign output_reg[31:17] = 0; | |
458 | ||
459 | /* ------------------------------------------------------------------------- */ | |
460 | ||
461 | /* ------------------------ Configuration Register ------------------------- */ | |
462 | xREG2 #(20) config1_xREG2(.clk(clk), | |
463 | .reset(reset), | |
464 | .reset_value({20'b0000_1000_0000_0000_0000}), | |
465 | .load(ld_config), | |
466 | .din(wr_data[19:0]), | |
467 | .qout(config1[19:0])); | |
468 | ||
469 | assign manual_mode = config1[0]; | |
470 | assign int_ser_sel = config1[2:1]; | |
471 | assign poll_en = config1[3]; | |
472 | assign bb_mode = config1[4]; | |
473 | assign poll_dev_addr = config1[9:5]; | |
474 | assign poll_prt_addr = config1[14:10]; | |
475 | assign indirect_mode = config1[15]; | |
476 | assign atca_GE = config1[16]; // por = 0 | |
477 | // status | |
478 | assign config1[31:20] = 0; | |
479 | ||
480 | /* ------------------------------------------------------------------------- */ | |
481 | ||
482 | /* ----------------------- Poll Mask Register ------------------------------ */ | |
483 | xREG2 #(16) poll_mask_xREG2(.clk(clk),.reset(reset),.reset_value(16'hFFFF), | |
484 | .load(ld_poll_mask),.din(wr_data[15:0]),.qout(poll_mask[15:0])); | |
485 | assign poll_mask[31:16] = 0; | |
486 | ||
487 | /* ------------------------------------------------------------------------- */ | |
488 | ||
489 | /* --------------------------- Status Register ----------------------------- */ | |
490 | assign new_poll_status[31:16] = reset ? 16'h0 : | |
491 | (ld_poll_status ? shift_dout[15:0] : poll_status[31:16]); | |
492 | ||
493 | assign new_poll_status[0] = reset ? 1'b0 : (ld_poll_status ? | |
494 | (poll_status[16] ^ shift_dout[0]) : (rac_poll_status ? 1'b0 : poll_status[0])); | |
495 | assign new_poll_status[1] = reset ? 1'b0 : (ld_poll_status ? | |
496 | (poll_status[17] ^ shift_dout[1]) : (rac_poll_status ? 1'b0 : poll_status[1])); | |
497 | assign new_poll_status[2] = reset ? 1'b0 : (ld_poll_status ? | |
498 | (poll_status[18] ^ shift_dout[2]) : (rac_poll_status ? 1'b0 : poll_status[2])); | |
499 | assign new_poll_status[3] = reset ? 1'b0 : (ld_poll_status ? | |
500 | (poll_status[19] ^ shift_dout[3]) : (rac_poll_status ? 1'b0 : poll_status[3])); | |
501 | assign new_poll_status[4] = reset ? 1'b0 : (ld_poll_status ? | |
502 | (poll_status[20] ^ shift_dout[4]) : (rac_poll_status ? 1'b0 : poll_status[4])); | |
503 | assign new_poll_status[5] = reset ? 1'b0 : (ld_poll_status ? | |
504 | (poll_status[21] ^ shift_dout[5]) : (rac_poll_status ? 1'b0 : poll_status[5])); | |
505 | assign new_poll_status[6] = reset ? 1'b0 : (ld_poll_status ? | |
506 | (poll_status[22] ^ shift_dout[6]) : (rac_poll_status ? 1'b0 : poll_status[6])); | |
507 | assign new_poll_status[7] = reset ? 1'b0 : (ld_poll_status ? | |
508 | (poll_status[23] ^ shift_dout[7]) : (rac_poll_status ? 1'b0 : poll_status[7])); | |
509 | assign new_poll_status[8] = reset ? 1'b0 : (ld_poll_status ? | |
510 | (poll_status[24] ^ shift_dout[8]) : (rac_poll_status ? 1'b0 : poll_status[8])); | |
511 | assign new_poll_status[9] = reset ? 1'b0 : (ld_poll_status ? | |
512 | (poll_status[25] ^ shift_dout[9]) : (rac_poll_status ? 1'b0 : poll_status[9])); | |
513 | assign new_poll_status[10] = reset ? 1'b0 : (ld_poll_status ? | |
514 | (poll_status[26] ^ shift_dout[10]) : (rac_poll_status ? 1'b0 : poll_status[10])); | |
515 | assign new_poll_status[11] = reset ? 1'b0 : (ld_poll_status ? | |
516 | (poll_status[27] ^ shift_dout[11]) : (rac_poll_status ? 1'b0 : poll_status[11])); | |
517 | assign new_poll_status[12] = reset ? 1'b0 : (ld_poll_status ? | |
518 | (poll_status[28] ^ shift_dout[12]) : (rac_poll_status ? 1'b0 : poll_status[12])); | |
519 | assign new_poll_status[13] = reset ? 1'b0 : (ld_poll_status ? | |
520 | (poll_status[29] ^ shift_dout[13]) : (rac_poll_status ? 1'b0 : poll_status[13])); | |
521 | assign new_poll_status[14] = reset ? 1'b0 : (ld_poll_status ? | |
522 | (poll_status[30] ^ shift_dout[14]) : (rac_poll_status ? 1'b0 : poll_status[14])); | |
523 | assign new_poll_status[15] = reset ? 1'b0 : (ld_poll_status ? | |
524 | (poll_status[31] ^ shift_dout[15]) : (rac_poll_status ? 1'b0 : poll_status[15])); | |
525 | ||
526 | RegDff #(32) STATUS_RegDff(.clk(clk),.din(new_poll_status),.qout(poll_status)); | |
527 | ||
528 | /* ------------------------------------------------------------------------- */ | |
529 | ||
530 | /* ------------------------------ Interrupts ------------------------------- */ | |
531 | ||
532 | wire poll_interrupt = |(poll_status[15:0] & (~poll_mask[15:0])); | |
533 | ||
534 | reg mif_pio_intr; | |
535 | ||
536 | always @ (posedge clk) | |
537 | mif_pio_intr <= poll_interrupt | mif_interrupt; | |
538 | ||
539 | /* ------------------------------------------------------------------------- */ | |
540 | /* ---------- common serdes status and mask register ----------- */ | |
541 | ||
542 | wire mac_err0_pls; | |
543 | wire mac_err1_pls; | |
544 | wire peu_err_pls; | |
545 | wire sync_MDINT0_L; | |
546 | wire sync_MDINT1_L; | |
547 | wire MDINT0; | |
548 | wire MDINT1; | |
549 | wire PHY_MDINT0_L; | |
550 | wire PHY_MDINT1_L; | |
551 | ||
552 | `ifdef NEPTUNE | |
553 | wire xge_err0; | |
554 | wire xge_err1; | |
555 | wire peu_err; | |
556 | ||
557 | SYNC_CELL xge_err0_SYNC_CELL(.D(xge_mif_error_0),.CP(clk),.Q(xge_err0)); | |
558 | SYNC_CELL xge_err1_SYNC_CELL(.D(xge_mif_error_1),.CP(clk),.Q(xge_err1)); | |
559 | SYNC_CELL peu_err_SYNC_CELL(.D(peu_mif_error), .CP(clk),.Q(peu_err)); | |
560 | pls_gen mac_err0_pls_gen (.clk(clk),.in(xge_err0),.out(mac_err0_pls)); | |
561 | pls_gen mac_err1_pls_gen (.clk(clk),.in(xge_err1),.out(mac_err1_pls)); | |
562 | pls_gen peu_err_pls_gen (.clk(clk),.in(peu_err), .out(peu_err_pls)); | |
563 | ||
564 | assign mif_status[4] = ~sync_MDINT0_L; | |
565 | assign mif_status[5] = ~sync_MDINT1_L; | |
566 | ||
567 | assign MDINT0 = mif_status[4]; | |
568 | assign MDINT1 = mif_status[5]; | |
569 | ||
570 | `else // !ifdef NEPTUNE | |
571 | assign mac_err0_pls = 1'b0; | |
572 | assign mac_err1_pls = 1'b0; | |
573 | assign peu_err_pls = 1'b0; | |
574 | ||
575 | assign mif_status[4] = 1'b0; // cc 081106 | |
576 | assign mif_status[5] = 1'b0; // cc 081106 | |
577 | ||
578 | assign MDINT0 = ~sync_MDINT0_L; // cc 081106 | |
579 | assign MDINT1 = ~sync_MDINT1_L; // cc 081106 | |
580 | ||
581 | `endif // !ifdef NEPTUNE | |
582 | ||
583 | // eco @ 7-25-06 | |
584 | SYNC_CELL sync_MDION0_L_SYNC_CELL(.D(PHY_MDINT0_L),.CP(clk),.Q(sync_MDINT0_L)); | |
585 | SYNC_CELL sync_MDION1_L_SYNC_CELL(.D(PHY_MDINT1_L),.CP(clk),.Q(sync_MDINT1_L)); | |
586 | ||
587 | assign mif_status[0] = mif_init_done_stat; | |
588 | ||
589 | FD1 mif_initdone_FD1 (.D(mif_init_done_stat),.CP(clk),.Q(mif_initdone)); | |
590 | ||
591 | ||
592 | RAC_FF stat0_RAC_FF(.clk(clk),.reset(reset),.set(mac_err0_pls),.rst(rac_mif_status),.load(ld_mif_status),.load_data(wr_data[1]),.dout(mif_status[1])); | |
593 | ||
594 | RAC_FF stat1_RAC_FF(.clk(clk),.reset(reset),.set(mac_err1_pls),.rst(rac_mif_status),.load(ld_mif_status),.load_data(wr_data[2]),.dout(mif_status[2])); | |
595 | ||
596 | RAC_FF stat2_RAC_FF(.clk(clk),.reset(reset),.set(peu_err_pls), .rst(rac_mif_status),.load(ld_mif_status),.load_data(wr_data[3]),.dout(mif_status[3])); | |
597 | ||
598 | // assign mif_status[4] = ~sync_MDINT0_L; // cc 081106 | |
599 | // assign mif_status[5] = ~sync_MDINT1_L; // cc 081106 | |
600 | ||
601 | assign mif_status[31:6] = 0; | |
602 | assign mif_mask[31:6] = 0; | |
603 | ||
604 | // assign MDINT0 = mif_status[4]; // cc 081106 | |
605 | // assign MDINT1 = mif_status[5]; // cc 081106 | |
606 | ||
607 | ||
608 | assign mif_interrupt = (mif_status[0] & (~mif_mask[0])) | | |
609 | (mif_status[1] & (~mif_mask[1])) | | |
610 | (mif_status[2] & (~mif_mask[2])) | | |
611 | (mif_status[3] & (~mif_mask[3])) | | |
612 | (mif_status[4] & (~mif_mask[4])) | | |
613 | (mif_status[5] & (~mif_mask[5])) ; | |
614 | ||
615 | xREG2 #(6) mif_mask_xREG2 ( | |
616 | .clk(clk), | |
617 | .reset(reset), | |
618 | .reset_value({6{1'b1}}), | |
619 | .load(ld_mif_mask), | |
620 | .din(wr_data[5:0]), | |
621 | .qout(mif_mask[5:0])); | |
622 | ||
623 | // cc081106 | |
624 | // assign mif_interrupt = (mif_status[0] & (~mif_mask[0])) | | |
625 | // (mif_status[1] & (~mif_mask[1])) | | |
626 | // (mif_status[2] & (~mif_mask[2])) | | |
627 | // (mif_status[3] & (~mif_mask[3])) | | |
628 | // (mif_status[4] & (~mif_mask[4])) | | |
629 | // (mif_status[5] & (~mif_mask[5])) ; | |
630 | ||
631 | /* ------------------------------------------------------------------------- */ | |
632 | ||
633 | ||
634 | /* ------------------------- Frame Mode Engine ----------------------------- */ | |
635 | mif_control_sm mif_control_sm | |
636 | (/*AUTOINST*/ | |
637 | // Outputs | |
638 | .fetch_instr (fetch_instr), | |
639 | .poll_instr (poll_instr), | |
640 | .ld_output_reg (ld_output_reg), | |
641 | .ld_poll_status (ld_poll_status), | |
642 | .ctl_state (ctl_state[2:0]), | |
643 | // Inputs | |
644 | .clk (clk), | |
645 | .reset (reset), | |
646 | .instr_pnd (instr_pnd), | |
647 | .poll_en (poll_en), | |
648 | .mif_pio_intr (mif_pio_intr), | |
649 | .wr_done (wr_done), | |
650 | .rd_done (rd_done), | |
651 | .illegal_instr (illegal_instr)); | |
652 | ||
653 | ||
654 | mif_exec_sm mif_exec_sm | |
655 | (/*AUTOINST*/ | |
656 | // Outputs | |
657 | .illegal_instr (illegal_instr), | |
658 | .set_read_instr (set_read_instr), | |
659 | .clr_read_instr (clr_read_instr), | |
660 | .set_mdo_en (set_mdo_en), | |
661 | .clr_mdo_en (clr_mdo_en), | |
662 | .ta_clr_mdo_en (ta_clr_mdo_en), | |
663 | .mdi_en (mdi_en), | |
664 | .shift_en (shift_en), | |
665 | .clr_idle_timer (clr_idle_timer), | |
666 | .wr_done (wr_done), | |
667 | .rd_done (rd_done), | |
668 | .ex_state (ex_state[5:0]), | |
669 | // Inputs | |
670 | .clk (clk), | |
671 | .reset (reset), | |
672 | .ld_instr (ld_instr), | |
673 | .rd_op_code (rd_op_code), | |
674 | .wr_op_code (wr_op_code), | |
675 | .read_instr (read_instr), | |
676 | .idle_done (idle_done), | |
677 | .tx_bit_done (tx_bit_done), | |
678 | .rx_bit_done (rx_bit_done)); | |
679 | ||
680 | // bit_shifter_en_ld_X32 SHIFTER(clk,ld_instr,shift_en,shift_in,instr_din, | |
681 | // shift_out,shift_dout); | |
682 | bit_shifter_en_ld_X32 SHIFTER( | |
683 | .reset(reset), | |
684 | .clk(clk), | |
685 | .ld_en(ld_instr), | |
686 | .shift_en(shift_en), | |
687 | .shift_in(shift_in), | |
688 | .din(instr_din), | |
689 | .shift_out(shift_out), | |
690 | .dout(shift_dout)); | |
691 | ||
692 | assign shift_in = mdi_en ? mdi_mux : shift_out; | |
693 | ||
694 | // rd_op_code and wr_op_code are used by mif_exec_sm to see which action to take. | |
695 | // | |
696 | // Clause 22 MDIO (ST=2'b01) Clause 45 MDIO (ST=2'b00) | |
697 | // | | | |
698 | // V V | |
699 | assign rd_op_code = (shift_dout[31:28] == {`CLAUSE22_ST,2'b10}) | (shift_dout[31:29] == {`CLAUSE45_ST,1'b1}); | |
700 | assign wr_op_code = (shift_dout[31:28] == {`CLAUSE22_ST,2'b01}) | (shift_dout[31:29] == {`CLAUSE45_ST,1'b0}); | |
701 | ||
702 | RS_FF read_instr_RS_FF( | |
703 | .set(set_read_instr), | |
704 | .rst(clr_read_instr), | |
705 | .clk(clk), | |
706 | .reset(reset), | |
707 | .qout(read_instr)); | |
708 | ||
709 | RS_FF RS_FF( | |
710 | .set(set_mdo_en), | |
711 | .rst(clr_mdo_en | ta_clr_mdo_en), | |
712 | .clk(clk), | |
713 | .reset(reset), | |
714 | .qout(mdo_en)); | |
715 | ||
716 | // IDLE counter | |
717 | Counter #(`IDLE_CNT_SIZE) idle_count1_Counter (.reset(reset_pls | clr_idle_timer), // loj | |
718 | .clk(clk), | |
719 | .ce(!idle_done), | |
720 | .count(idle_count1)); | |
721 | ||
722 | wire idle_count_en = !idle_done & (idle_count1 == `IDLE_CNT_BASE); | |
723 | ||
724 | counter_X5 IDLE_CNT2 (.clk(clk), // loj, count 32 bit time for idle period. | |
725 | .clr(reset_pls | clr_idle_timer), | |
726 | .enable(idle_count_en), // loj | |
727 | .count(idle_count2) | |
728 | ); | |
729 | ||
730 | RS_FF idle_done_RS_FF( | |
731 | .set(idle_count_en & (idle_count2 == 5'h1F)), | |
732 | .rst(clr_idle_timer), | |
733 | .clk(clk), | |
734 | .reset(reset), | |
735 | .qout(idle_done)); | |
736 | ||
737 | // free running counter. core_clk/(2 to the power of `IDLE_CNT_SIZE) | |
738 | Counter #(`IDLE_CNT_SIZE) div_count_Counter (.reset(reset_pls), // loj | |
739 | .clk(clk), | |
740 | .ce(1'b1), | |
741 | .count(div_count)); | |
742 | ||
743 | assign fclk = div_count[`IDLE_CNT_MSB]; | |
744 | ||
745 | RS_FF instr_pnd_RS_FF(.set(ld_frame),.rst(ld_output_reg),.clk(clk), | |
746 | .reset(reset),.qout(instr_pnd)); | |
747 | ||
748 | assign tx_bit_done = (div_count == `TX_BIT_DN); // loj 6'h20-> 7'h40; 7'b100_0000 | |
749 | assign rx_bit_done = (div_count == `RX_BIT_DN); // loj 6'h1E-> 7'h3E; | |
750 | ||
751 | assign ld_instr = fetch_instr | poll_instr; | |
752 | assign st = indirect_mode ? `CLAUSE45_ST : `CLAUSE22_ST; | |
753 | ||
754 | assign poll_fm = {st,2'b10,poll_prt_addr,poll_dev_addr,2'b10,16'h0}; | |
755 | assign instr_din = poll_instr ? poll_fm[31:0] : | |
756 | frame_dout[31:0]; | |
757 | ||
758 | PlsGen fclk_pls_PlsGen (.reset(reset),.clk(clk),.iSigIn(fclk),.oPlsOut(fclk_pls)); | |
759 | ||
760 | xREG #(5) port_addr_xREG(.clk(clk),.reset(reset),.en(ld_instr),.din(instr_din[27:23]),.qout(port_addr[4:0])); | |
761 | ||
762 | //************************************************************************* | |
763 | // To meet minimum hold time 10ns, this piece of logic should be changed | |
764 | // for system clock other than 300Mhz. - loj | |
765 | //************************************************************************* | |
766 | // mdo_en | |
767 | xREG #(1) mdo_en_fclk_xREG(.din(mdo_en), // mdo_en is used as internal signal. | |
768 | .clk(clk), | |
769 | .en(fclk_pls), | |
770 | .reset(reset | ta_clr_mdo_en), | |
771 | .qout(mdo_en_fclk)); // create 1 core_clk delay | |
772 | FD1 FRAME_MDO_EN_d1(.D(mdo_en_fclk), .CP(clk),.Q(d1_mdo_en_fclk));// create 1 core_clk delay | |
773 | FD1 FRAME_MDO_EN_d2(.D(d1_mdo_en_fclk),.CP(clk),.Q(d2_mdo_en_fclk));// create 1 core_clk delay | |
774 | FD1 FRAME_MDO_EN_d3(.D(d2_mdo_en_fclk),.CP(clk),.Q(d3_mdo_en_fclk));// create 1 core_clk delay | |
775 | FD1 FRAME_MDO_EN_d4(.D(d3_mdo_en_fclk),.CP(clk),.Q(frame_mdo_en)); // create 1 core_clk delay | |
776 | ||
777 | // mdo | |
778 | xREG #(1) mdo_fclk_xREG(.din(!idle_done | shift_out), | |
779 | .clk(clk), | |
780 | .en(fclk_pls), | |
781 | .reset(reset), | |
782 | .qout(mdo_fclk)); // create 1 core_clk delay | |
783 | FD1 FRAME_MDO_FF_d1(.D(mdo_fclk), .CP(clk),.Q(d1_mdo_fclk)); // create 1 core_clk delay | |
784 | FD1 FRAME_MDO_FF_d2(.D(d1_mdo_fclk),.CP(clk),.Q(d2_mdo_fclk)); // create 1 core_clk delay | |
785 | FD1 FRAME_MDO_FF_d3(.D(d2_mdo_fclk),.CP(clk),.Q(d3_mdo_fclk)); // create 1 core_clk delay | |
786 | FD1 FRAME_MDO_FF_d4(.D(d3_mdo_fclk),.CP(clk),.Q(frame_mdo)); // create 1 core_clk delay | |
787 | ||
788 | /* ------------------------------------------------------------------------- */ | |
789 | ||
790 | /* -------------------------------- MIF ------------------------------------ */ | |
791 | // Do not disable mdclk when niu_reset_l is active. Hedwig needs it to clock | |
792 | // in synchronous reset. | |
793 | assign mdclk = bb_mode ? bb_mdc : fclk; | |
794 | assign mdo_temp= bb_mode ? bb_mdo : frame_mdo; // loj 1-27-06 // unqualified mdo | |
795 | assign mdio_en = bb_mode ? bb_mdo_en : frame_mdo_en; // loj 1-24-06 | |
796 | assign mdo = mdo_temp | (~mdio_en); // loj 1-27-06 | |
797 | ||
798 | assign int_ser0 = int_ser_sel[1:0] == 2'b00; | |
799 | assign int_ser1 = int_ser_sel[1:0] == 2'b01; | |
800 | assign int_ser2 = int_ser_sel[1:0] == 2'b10; | |
801 | ||
802 | always @ (bb_mode or int_ser0 or int_ser1 or int_ser2 or mdi | |
803 | or mdi_0 or mdi_1 or mdi_2 or port_addr) | |
804 | begin | |
805 | if (bb_mode) | |
806 | mdi_mux = int_ser0 ? mdi_0 : | |
807 | int_ser1 ? mdi_1 : | |
808 | int_ser2 ? mdi_2 : | |
809 | mdi; | |
810 | else // frame_mode | |
811 | mdi_mux = (port_addr == `PORT_ADDR_0) ? mdi_0 : | |
812 | (port_addr == `PORT_ADDR_1) ? mdi_1 : | |
813 | (port_addr == `PORT_ADDR_2) ? mdi_2 : | |
814 | mdi; | |
815 | end | |
816 | /* ------------------------------------------------------------------------- */ | |
817 | ||
818 | ||
819 | `ifdef NEPTUNE | |
820 | mif_init_ctl mif_init_ctl | |
821 | ( | |
822 | // Outputs | |
823 | .mif_spc_req (mif_spc_req), | |
824 | .mif_spc_addr (mif_spc_addr[4:0]), | |
825 | .mif_init_done_stat (mif_init_done_stat), | |
826 | .mif_init_state (mif_init_state[3:0]), | |
827 | .send_init_fm (send_init_fm), | |
828 | .send_init_fm_pls (send_init_fm_pls), | |
829 | .mif_init_fm (mif_init_fm[31:0]), | |
830 | .spc_rdy (spc_rdy), | |
831 | .spc_req (spc_req), | |
832 | .spc_ack (spc_ack), | |
833 | // Inputs | |
834 | .clk (clk), | |
835 | .reset (reset), | |
836 | .st (st[1:0]), | |
837 | .peu_mif_rdy (peu_mif_rdy), | |
838 | .spc_mif_rdy (spc_mif_rdy), | |
839 | .spc_mif_ack (spc_mif_ack), | |
840 | .spc_mif_rdata (spc_mif_rdata[15:0]), | |
841 | .ld_output_reg (ld_output_reg)); | |
842 | `else // N2 | |
843 | assign mif_init_done_stat = 1'b1; | |
844 | assign mif_init_state = 4'b0; | |
845 | assign send_init_fm = 1'b0; | |
846 | assign send_init_fm_pls = 1'b0; | |
847 | assign mif_init_fm =32'b0; | |
848 | assign spc_rdy = 1'b1; | |
849 | assign spc_req = 1'b0; | |
850 | assign spc_ack = 1'b0; | |
851 | `endif // !ifdef NEPTUNE | |
852 | ||
853 | /* --------------- spare gates --------------- */ | |
854 | `ifdef NEPTUNE | |
855 | wire [3:0] do_nad; | |
856 | wire [3:0] do_nor; | |
857 | wire [3:0] do_inv; | |
858 | wire [3:0] do_mux; | |
859 | wire [3:0] do_q; | |
860 | wire so; | |
861 | ||
862 | mac_spare_gates mac_mif_spare_gates ( | |
863 | .di_nd3 ({1'h1, 1'h1, do_q[3]}), | |
864 | .di_nd2 ({1'h1, 1'h1, do_q[2]}), | |
865 | .di_nd1 ({1'h1, 1'h1, do_q[1]}), | |
866 | .di_nd0 ({1'h1, 1'h1, do_q[0]}), | |
867 | .di_nr3 ({1'h0, 1'h0}), | |
868 | .di_nr2 ({1'h0, 1'h0}), | |
869 | .di_nr1 ({1'h0, 1'h0}), | |
870 | .di_nr0 ({1'h0, 1'h0}), | |
871 | .di_inv (do_nad[3:0]), | |
872 | .di_mx3 ({1'h0, 1'h0}), | |
873 | .di_mx2 ({1'h0, 1'h0}), | |
874 | .di_mx1 ({1'h0, 1'h0}), | |
875 | .di_mx0 ({1'h0, 1'h0}), | |
876 | .mx_sel (do_nor[3:0]), | |
877 | .di_reg (do_inv[3:0]), | |
878 | .wt_ena (do_mux[3:0]), | |
879 | .rst ({4{reset}}), | |
880 | .si (1'h0), | |
881 | .se (1'h0), | |
882 | .clk (clk), | |
883 | .do_nad (do_nad[3:0]), | |
884 | .do_nor (do_nor[3:0]), | |
885 | .do_inv (do_inv[3:0]), | |
886 | .do_mux (do_mux[3:0]), | |
887 | .do_q (do_q[3:0]), | |
888 | .so (so) | |
889 | ); | |
890 | ||
891 | `else | |
892 | `endif | |
893 | ||
894 | ||
895 | ||
896 | endmodule // mif | |
897 |