| 1 | // ========== Copyright Header Begin ========================================== |
| 2 | // |
| 3 | // OpenSPARC T2 Processor File: tx_xmac.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 : tx_xmac.v |
| 40 | * Author Name : John Lo |
| 41 | * Description : |
| 42 | * Parent Module: xmac |
| 43 | * Child Module: |
| 44 | * Interface Mod: |
| 45 | * Date Created : 6/2/00 |
| 46 | * |
| 47 | * Copyright (c) 2002, Sun Microsystems, Inc. |
| 48 | * Sun Proprietary and Confidential |
| 49 | * |
| 50 | * Design Notes: When OPP underrun txfifo (txfifo_empty & ~eop_txclk) |
| 51 | * the crc is intentionally corrupted. |
| 52 | * The "E" is generated also. |
| 53 | * |
| 54 | * |
| 55 | * Modification : |
| 56 | * |
| 57 | * Synthesis Notes: |
| 58 | * |
| 59 | ******************************************************************/ |
| 60 | |
| 61 | `include "xmac.h" |
| 62 | |
| 63 | module tx_xmac |
| 64 | (/*AUTOARG*/ |
| 65 | // Outputs |
| 66 | xgmii_txc, xgmii_txd, xpcs_txc, xpcs_txd, txc_image, txd_image, |
| 67 | tx_err_image, tx_byte_count, paused_state, txfifo_xfr_err, |
| 68 | tx_max_pkt_size_err, set_tx_pkt_ok, toggle_txframe_count, |
| 69 | toggle_tx_bcount, txfifo_g_rd_ptr_txclk, txfifo_rd_ptr_txclk, |
| 70 | txfifo_underrun_txclk, eop_txclk, tx_data_valid, |
| 71 | stfifo_g_rd_ptr_txclk, stfifo_rd_ptr_txclk, stfifo_underrun_txclk, |
| 72 | tx_swap_reg, tx_on_reg, tx_on_half_reg, back2back_swap_reg1, |
| 73 | replace_txd_time_reg, adjust2crc_full_case_last_byte_position_reg, |
| 74 | adjust2crc_full_case_last_byte_position_is_3_or_7_reg, |
| 75 | stretch_clks_reg, full_case_last_byte_position_reg, |
| 76 | stretch_full_case_last_byte_position_reg, stretch_bytes_reg, |
| 77 | minus_4bytes_reg, B_eop_reg, stretch_1_more_clk_reg, |
| 78 | no_wasted_BW_reg, ipg_done_trail_temp_reg, tx_byte0_reg0, |
| 79 | restart_ipg_timer_reg, eop_txclk_reg0, eop_w_fcs_reg0, |
| 80 | tx_abort_reg0, eop_w_fcs_reg1, tx_abort_reg1, ipg_done_reg, |
| 81 | ipg_done_lead_temp_reg, force_ipg_done_lead_reg, |
| 82 | set_back2back_reg, back2back_reg, xtlm_state, |
| 83 | // Inputs |
| 84 | tx_clk, tx_reset, xgmii_mode, txfifo_dout, no_crc, |
| 85 | last_byte_position, max_pkt_size, tx_min_pkt_size, |
| 86 | no_tx_min_pkt_size_chk, mac_unique_addr, ipg_value, stretch_ratio, |
| 87 | stretch_constant, stretch_mode, rx_fc_pkt_ok_txclk, pause_time, |
| 88 | slot_time, txfifo_g_wr_ptr_sync, stfifo_g_wr_ptr_sync, |
| 89 | tx_enable_txclk, always_no_crc, tx_output_en_txclk, |
| 90 | var_min_ipg_en, mii_mode, gmii_mode, warning_msg_en, |
| 91 | remote_fault_oc_txclk, local_fault_oc_txclk |
| 92 | ); |
| 93 | |
| 94 | |
| 95 | input tx_clk; |
| 96 | input tx_reset; |
| 97 | input xgmii_mode; |
| 98 | input [65:0] txfifo_dout; |
| 99 | input no_crc; |
| 100 | input [2:0] last_byte_position; |
| 101 | input [13:0] max_pkt_size; |
| 102 | // vlint flag_input_port_not_connected off |
| 103 | input [9:0] tx_min_pkt_size; |
| 104 | input no_tx_min_pkt_size_chk; |
| 105 | // vlint flag_input_port_not_connected on |
| 106 | input [47:0] mac_unique_addr; |
| 107 | input [2:0] ipg_value; |
| 108 | input [4:0] stretch_ratio; |
| 109 | input [2:0] stretch_constant; |
| 110 | input stretch_mode; |
| 111 | input rx_fc_pkt_ok_txclk;// syncd from address_decoder.v |
| 112 | input [15:0] pause_time; // async from address_decoder.v |
| 113 | input [`BYTE] slot_time; |
| 114 | input [4:0] txfifo_g_wr_ptr_sync; |
| 115 | input [4:0] stfifo_g_wr_ptr_sync; |
| 116 | input tx_enable_txclk; |
| 117 | input always_no_crc; |
| 118 | input tx_output_en_txclk; |
| 119 | input var_min_ipg_en; |
| 120 | input mii_mode; |
| 121 | input gmii_mode; |
| 122 | // vlint flag_input_port_not_connected off |
| 123 | input warning_msg_en; |
| 124 | // vlint flag_input_port_not_connected on |
| 125 | input remote_fault_oc_txclk; |
| 126 | input local_fault_oc_txclk; |
| 127 | // outputs |
| 128 | output [3:0] xgmii_txc; |
| 129 | output [31:0] xgmii_txd; |
| 130 | output [7:0] xpcs_txc; |
| 131 | output [63:0] xpcs_txd; |
| 132 | // loopback path |
| 133 | output [7:0] txc_image; |
| 134 | output [63:0] txd_image; |
| 135 | output tx_err_image; |
| 136 | output [13:0] tx_byte_count; |
| 137 | output paused_state; |
| 138 | output txfifo_xfr_err; |
| 139 | output tx_max_pkt_size_err; |
| 140 | output set_tx_pkt_ok; |
| 141 | // RMON signals to xmac_sync |
| 142 | output toggle_txframe_count; |
| 143 | output toggle_tx_bcount; |
| 144 | // txfifo stuff |
| 145 | output [4:0] txfifo_g_rd_ptr_txclk; |
| 146 | output [4:0] txfifo_rd_ptr_txclk; |
| 147 | output txfifo_underrun_txclk; |
| 148 | output eop_txclk; |
| 149 | output tx_data_valid; |
| 150 | // stfifo stuff |
| 151 | output [4:0] stfifo_g_rd_ptr_txclk; |
| 152 | output [4:0] stfifo_rd_ptr_txclk; |
| 153 | output stfifo_underrun_txclk; |
| 154 | // internal tx_xmac signals to xmac_slv debug_port. |
| 155 | output tx_swap_reg; |
| 156 | output tx_on_reg; |
| 157 | output tx_on_half_reg; |
| 158 | output back2back_swap_reg1; |
| 159 | output replace_txd_time_reg; |
| 160 | output [2:0] adjust2crc_full_case_last_byte_position_reg; |
| 161 | output adjust2crc_full_case_last_byte_position_is_3_or_7_reg; |
| 162 | output [`BYTE] stretch_clks_reg; |
| 163 | output [2:0] full_case_last_byte_position_reg; |
| 164 | output [3:0] stretch_full_case_last_byte_position_reg; |
| 165 | output [2:0] stretch_bytes_reg; |
| 166 | output minus_4bytes_reg; |
| 167 | output B_eop_reg; |
| 168 | output stretch_1_more_clk_reg; |
| 169 | output no_wasted_BW_reg; |
| 170 | output ipg_done_trail_temp_reg; |
| 171 | output [7:0] tx_byte0_reg0; |
| 172 | output restart_ipg_timer_reg; |
| 173 | output eop_txclk_reg0; |
| 174 | output eop_w_fcs_reg0; |
| 175 | output tx_abort_reg0; |
| 176 | output eop_w_fcs_reg1; |
| 177 | output tx_abort_reg1; |
| 178 | output ipg_done_reg; |
| 179 | output ipg_done_lead_temp_reg; |
| 180 | output force_ipg_done_lead_reg; |
| 181 | output set_back2back_reg; |
| 182 | output back2back_reg; |
| 183 | // state machine |
| 184 | output [2:0] xtlm_state; |
| 185 | |
| 186 | reg last_B_in_B0; // last byte is byte0 |
| 187 | reg last_B_in_B1; // last byte is byte1 |
| 188 | reg last_B_in_B2; // last byte is byte2 |
| 189 | reg last_B_in_B3; // last byte is byte3 |
| 190 | reg last_B_in_B4; // last byte is byte4 |
| 191 | reg last_B_in_B5; // last byte is byte5 |
| 192 | reg last_B_in_B6; // last byte is byte6 |
| 193 | reg last_B_in_B7; // last byte is byte7 |
| 194 | reg [7:0] mod_tx_en_8bit_reg0; |
| 195 | reg [7:0] mod_tx_en_8bit_reg1; |
| 196 | reg [63:0] mod_tx_data_64bit_reg0; |
| 197 | reg [63:0] mod_tx_data_64bit_reg1; |
| 198 | reg [7:0] T_position; |
| 199 | reg [7:0] tx_en_8bit; |
| 200 | reg link_up; |
| 201 | reg link_fault_dly; |
| 202 | reg [31:0] dly; |
| 203 | wire [63:0] tx_data_source; |
| 204 | wire [63:0] tx_data_64bit; |
| 205 | wire [63:0] tx_data_64bit_reg0; |
| 206 | wire [63:0] tx_data_64bit_reg1; |
| 207 | wire [63:0] tx_data_64bit_reg0_mux; |
| 208 | wire [63:0] tx_data_64bit_reg1_mux; |
| 209 | wire [63:0] tx_data_64bit_reg1_mux2; // "T" generation |
| 210 | wire [31:0] tx_data_32_A; |
| 211 | wire [31:0] tx_data_32_B; |
| 212 | wire [31:0] d_tx_data_32_B; |
| 213 | wire [31:0] tx_data_32bit_A; |
| 214 | wire [31:0] tx_data_32bit_B; |
| 215 | wire [63:0] p_txd_mux; |
| 216 | wire [63:0] p_txd; |
| 217 | wire [63:0] txd_image; |
| 218 | wire [63:0] txd; |
| 219 | wire [63:0] xpcs_txd; |
| 220 | wire [7:0] tx_en_8bit_reg0; |
| 221 | wire [7:0] tx_en_8bit_reg1; |
| 222 | wire [7:0] tx_en_8bit_reg0_mux; |
| 223 | wire [7:0] tx_en_8bit_reg1_mux; |
| 224 | wire [3:0] tx_en_4_A = tx_en_8bit_reg1_mux[3:0]; |
| 225 | wire [3:0] tx_en_4_B = tx_en_8bit_reg1_mux[7:4]; |
| 226 | wire [3:0] d_tx_en_4_B; |
| 227 | wire [3:0] tx_en_4bit_A; |
| 228 | wire [3:0] tx_en_4bit_B; |
| 229 | wire [7:0] p_txc_mux; |
| 230 | wire [7:0] p_txc; |
| 231 | wire [7:0] txc_image; |
| 232 | wire [7:0] txc; |
| 233 | wire [7:0] xpcs_txc; |
| 234 | wire eop_oc; |
| 235 | wire replace_txd_time; |
| 236 | wire [13:0] tx_byte_count; |
| 237 | wire min_pkt_size_limit_txclk; |
| 238 | wire tx_on; |
| 239 | wire tx_on_half; |
| 240 | wire [31:0] tx_crc_result; |
| 241 | wire max_pkt_size_limit_txclk; |
| 242 | wire new_paused_state; |
| 243 | wire back2back_swap_reg1; |
| 244 | wire [`BYTE] final_ipg_clks; |
| 245 | wire tx_swap; |
| 246 | wire txfifo_empty_txclk; |
| 247 | wire eop_txclk; |
| 248 | wire add_fcs; |
| 249 | wire pa_time; |
| 250 | wire eop_tag = txfifo_dout[64] & (~txfifo_empty_txclk); |
| 251 | wire force_tx_err; |
| 252 | // 10-29-2001, loj replaced opp_txma_sa_repl with opp_txmac_abort. |
| 253 | // sa_repl is not used from now on. |
| 254 | // wire sa_repl = txfifo_dout[65] & (~txfifo_empty_txclk); |
| 255 | wire sa_repl = 1'b0; |
| 256 | wire tx_abort = force_tx_err | txfifo_dout[65] & (~txfifo_empty_txclk); |
| 257 | wire [7:0] sfd = 8'hD5; |
| 258 | wire [63:0] pa_data = {sfd,{6{8'h55}},`S}; |
| 259 | wire remote_fault_oc_txclk; |
| 260 | wire local_fault_oc_txclk; |
| 261 | wire link_fault = remote_fault_oc_txclk | local_fault_oc_txclk; |
| 262 | wire [2:0] last_byte_position; |
| 263 | wire [2:0] adjust2crc_full_case_last_byte_position; |
| 264 | wire adjust2crc_full_case_last_byte_position_is_3_or_7; |
| 265 | wire [`BYTE] stretch_clks; |
| 266 | wire [2:0] full_case_last_byte_position; |
| 267 | wire [3:0] stretch_full_case_last_byte_position; |
| 268 | wire [2:0] stretch_bytes; |
| 269 | wire minus_4bytes; |
| 270 | wire B_eop; |
| 271 | wire stretch_1_more_clk; |
| 272 | wire no_wasted_BW; |
| 273 | wire ipg_done_trail_temp; |
| 274 | wire [7:0] tx_byte0_reg0 = tx_data_64bit_reg0[`BYTE0]; |
| 275 | wire restart_ipg_timer; |
| 276 | wire eop_txclk_reg0; |
| 277 | wire eop_w_fcs_reg0; |
| 278 | wire tx_abort_reg0; |
| 279 | wire eop_w_fcs_reg1; |
| 280 | wire tx_abort_reg1; |
| 281 | wire ipg_done; |
| 282 | wire ipg_done_lead_temp; |
| 283 | wire force_ipg_done_lead; |
| 284 | wire set_back2back; |
| 285 | wire back2back; |
| 286 | |
| 287 | // vlint flag_net_has_no_load off |
| 288 | // vlint flag_dangling_net_within_module off |
| 289 | wire [13:0] nx_temp_tx_byte_count; |
| 290 | wire [13:0] temp_tx_byte_count; |
| 291 | wire [13:0] not_used_tx_byte_count; |
| 292 | wire [31:0] new_crc5_result; |
| 293 | wire sa1_time; |
| 294 | wire sa2_time; |
| 295 | wire txfifo_rd_en; |
| 296 | wire txfifo_unload_rdy; |
| 297 | wire d_pa_time; |
| 298 | wire tx_crc_error; |
| 299 | wire warning_msg_en; |
| 300 | wire back2back_swap; |
| 301 | wire stfifo_empty_txclk; |
| 302 | wire txfifo_full_txclk; |
| 303 | wire [9:0] tx_min_pkt_size; |
| 304 | wire no_tx_min_pkt_size_chk; |
| 305 | // vlint flag_dangling_net_within_module on |
| 306 | // vlint flag_net_has_no_load on |
| 307 | |
| 308 | |
| 309 | |
| 310 | // --------------------------------------- |
| 311 | // DA: 01-80-c2-00-00-01 , T/L: 0x8808 |
| 312 | // --------------------------------------- |
| 313 | // ab cd ef |
| 314 | // mac_unique_addr [15:0] [31:16] [47:32], |
| 315 | // --------------------------------------- |
| 316 | wire [63:0] sa2_data = {txfifo_dout[63:32], |
| 317 | mac_unique_addr[`BYTE4], // f (sa6) |
| 318 | mac_unique_addr[`BYTE5], // e (sa5) |
| 319 | mac_unique_addr[`BYTE2], // d (sa4) |
| 320 | mac_unique_addr[`BYTE3]}; // c (sa3) |
| 321 | wire [63:0] sa1_data = {mac_unique_addr[`BYTE0], // b (sa2) |
| 322 | mac_unique_addr[`BYTE1], // a (sa1) |
| 323 | txfifo_dout[47:0]}; |
| 324 | |
| 325 | // crc gen |
| 326 | wire [7:0] crc_byte0 = {tx_crc_result[24],tx_crc_result[25], |
| 327 | tx_crc_result[26],tx_crc_result[27], |
| 328 | tx_crc_result[28],tx_crc_result[29], |
| 329 | tx_crc_result[30],tx_crc_result[31]}; |
| 330 | |
| 331 | wire [7:0] crc_byte1 = {tx_crc_result[16],tx_crc_result[17], |
| 332 | tx_crc_result[18],tx_crc_result[19], |
| 333 | tx_crc_result[20],tx_crc_result[21], |
| 334 | tx_crc_result[22],tx_crc_result[23]}; |
| 335 | |
| 336 | wire [7:0] crc_byte2 = {tx_crc_result[8],tx_crc_result[9], |
| 337 | tx_crc_result[10],tx_crc_result[11], |
| 338 | tx_crc_result[12],tx_crc_result[13], |
| 339 | tx_crc_result[14],tx_crc_result[15]}; |
| 340 | |
| 341 | wire [7:0] crc_byte3 = {tx_crc_result[0],tx_crc_result[1], |
| 342 | tx_crc_result[2],tx_crc_result[3], |
| 343 | tx_crc_result[4],tx_crc_result[5], |
| 344 | tx_crc_result[6],tx_crc_result[7]}; |
| 345 | |
| 346 | wire [7:0] tx_byte0 = tx_en_8bit[0] ? txfifo_dout[`BYTE0] : `I; |
| 347 | wire [7:0] tx_byte1 = tx_en_8bit[1] ? txfifo_dout[`BYTE1] : `I; |
| 348 | wire [7:0] tx_byte2 = tx_en_8bit[2] ? txfifo_dout[`BYTE2] : `I; |
| 349 | wire [7:0] tx_byte3 = tx_en_8bit[3] ? txfifo_dout[`BYTE3] : `I; |
| 350 | wire [7:0] tx_byte4 = tx_en_8bit[4] ? txfifo_dout[`BYTE4] : `I; |
| 351 | wire [7:0] tx_byte5 = tx_en_8bit[5] ? txfifo_dout[`BYTE5] : `I; |
| 352 | wire [7:0] tx_byte6 = tx_en_8bit[6] ? txfifo_dout[`BYTE6] : `I; |
| 353 | wire [7:0] tx_byte7 = tx_en_8bit[7] ? txfifo_dout[`BYTE7] : `I; |
| 354 | wire [7:0] tx_byte1_reg0 = tx_data_64bit_reg0[`BYTE1]; |
| 355 | wire [7:0] tx_byte2_reg0 = tx_data_64bit_reg0[`BYTE2]; |
| 356 | wire [7:0] tx_byte3_reg0 = tx_data_64bit_reg0[`BYTE3]; |
| 357 | wire [7:0] tx_byte4_reg0 = tx_data_64bit_reg0[`BYTE4]; |
| 358 | wire [7:0] tx_byte5_reg0 = tx_data_64bit_reg0[`BYTE5]; |
| 359 | wire [7:0] tx_byte6_reg0 = tx_data_64bit_reg0[`BYTE6]; |
| 360 | wire [7:0] tx_byte7_reg0 = tx_data_64bit_reg0[`BYTE7]; |
| 361 | |
| 362 | |
| 363 | wire [7:0] tx_byte0_reg1 = tx_data_64bit_reg1[`BYTE0]; |
| 364 | wire [7:0] tx_byte1_reg1 = tx_data_64bit_reg1[`BYTE1]; |
| 365 | wire [7:0] tx_byte2_reg1 = tx_data_64bit_reg1[`BYTE2]; |
| 366 | wire [7:0] tx_byte3_reg1 = tx_data_64bit_reg1[`BYTE3]; |
| 367 | wire [7:0] tx_byte4_reg1 = tx_data_64bit_reg1[`BYTE4]; |
| 368 | wire [7:0] tx_byte5_reg1 = tx_data_64bit_reg1[`BYTE5]; |
| 369 | wire [7:0] tx_byte6_reg1 = tx_data_64bit_reg1[`BYTE6]; |
| 370 | wire [7:0] tx_byte7_reg1 = tx_data_64bit_reg1[`BYTE7]; |
| 371 | |
| 372 | assign tx_data_64bit_reg1_mux2[`BYTE0] = T_position[0] ? `T : |
| 373 | tx_data_64bit_reg1_mux[`BYTE0]; |
| 374 | |
| 375 | assign tx_data_64bit_reg1_mux2[`BYTE1] = T_position[1] ? `T : |
| 376 | tx_data_64bit_reg1_mux[`BYTE1]; |
| 377 | |
| 378 | assign tx_data_64bit_reg1_mux2[`BYTE2] = T_position[2] ? `T : |
| 379 | tx_data_64bit_reg1_mux[`BYTE2]; |
| 380 | |
| 381 | assign tx_data_64bit_reg1_mux2[`BYTE3] = T_position[3] ? `T : |
| 382 | tx_data_64bit_reg1_mux[`BYTE3]; |
| 383 | |
| 384 | assign tx_data_64bit_reg1_mux2[`BYTE4] = T_position[4] ? `T : |
| 385 | tx_data_64bit_reg1_mux[`BYTE4]; |
| 386 | |
| 387 | assign tx_data_64bit_reg1_mux2[`BYTE5] = T_position[5] ? `T : |
| 388 | tx_data_64bit_reg1_mux[`BYTE5]; |
| 389 | |
| 390 | assign tx_data_64bit_reg1_mux2[`BYTE6] = T_position[6] ? `T : |
| 391 | tx_data_64bit_reg1_mux[`BYTE6]; |
| 392 | |
| 393 | assign tx_data_64bit_reg1_mux2[`BYTE7] = T_position[7] ? `T : |
| 394 | tx_data_64bit_reg1_mux[`BYTE7]; |
| 395 | |
| 396 | assign tx_data_32_A = tx_data_64bit_reg1_mux2[31:0]; |
| 397 | assign tx_data_32_B = tx_data_64bit_reg1_mux2[63:32]; |
| 398 | |
| 399 | /* ----------------- first stage pipeline ----------------------- */ |
| 400 | |
| 401 | wire qualified_no_crc = always_no_crc | no_crc; |
| 402 | |
| 403 | wire add_crc = (~qualified_no_crc) | add_fcs; |
| 404 | |
| 405 | wire eop_w_fcs = eop_txclk & add_crc; |
| 406 | |
| 407 | RegDff #(8) tx_en_8bit_reg0_RegDff (.din(tx_en_8bit), |
| 408 | .clk(tx_clk),.qout(tx_en_8bit_reg0)); |
| 409 | RegDff #(64) tx_data_64bit_reg0_RegDff(.din(tx_data_64bit), |
| 410 | .clk(tx_clk),.qout(tx_data_64bit_reg0)); |
| 411 | FD1 eop_txclk_reg0_FD1(.D(eop_txclk), .CP(tx_clk),.Q(eop_txclk_reg0)); |
| 412 | FD1 eop_w_fcs_reg0_FD1(.D(eop_w_fcs), .CP(tx_clk),.Q(eop_w_fcs_reg0)); |
| 413 | |
| 414 | FD1 tx_abort_reg0_FD1 (.D(tx_abort), .CP(tx_clk),.Q(tx_abort_reg0)); |
| 415 | /* ----------------- second stage pipeline ---------------------- */ |
| 416 | RegDff #(8) tx_en_8bit_reg1_RegDff (.din(tx_en_8bit_reg0_mux), |
| 417 | .clk(tx_clk),.qout(tx_en_8bit_reg1)); |
| 418 | RegDff #(64) tx_data_64bit_reg1_RegDff(.din(tx_data_64bit_reg0_mux), |
| 419 | .clk(tx_clk),.qout(tx_data_64bit_reg1)); |
| 420 | FD1 eop_w_fcs_reg1_FD1(.D(eop_w_fcs_reg0),.CP(tx_clk),.Q(eop_w_fcs_reg1)); |
| 421 | FD1 tx_abort_reg1_FD1 (.D(tx_abort_reg0), .CP(tx_clk),.Q(tx_abort_reg1)); |
| 422 | /* ----- delay regs between second and third stage pipeline ----- */ |
| 423 | RegDff #(4) d_tx_en_4_B_RegDff(.din(tx_en_4_B),.clk(tx_clk), |
| 424 | .qout(d_tx_en_4_B)); |
| 425 | RegDff #(32) d_tx_data_32_B_RegDff(.din(tx_data_32_B),.clk(tx_clk), |
| 426 | .qout(d_tx_data_32_B)); |
| 427 | |
| 428 | /* ----------------- third stage pipeline ----------------------- */ |
| 429 | RegDff #(8) txc_RegDff(.din(p_txc),.clk(tx_clk),.qout(txc)); |
| 430 | RegDff #(64) txd_RegDff(.din(p_txd),.clk(tx_clk),.qout(txd)); |
| 431 | |
| 432 | RegDff #(8) txc_image_RegDff(.din(~tx_en_8bit_reg1_mux), .clk(tx_clk),.qout(txc_image)); |
| 433 | RegDff #(64) txd_image_RegDff(.din(tx_data_64bit_reg1_mux2),.clk(tx_clk),.qout(txd_image)); |
| 434 | FD1 tx_err_image_FD1 (.D(tx_abort_reg1), .CP(tx_clk),.Q(tx_err_image)); |
| 435 | |
| 436 | // final output mux |
| 437 | xMUX_2to1 #(32) xgmii_txd_xMUX_2to1(.din0(txd[63:32]),.din1(txd[31:0]),.sel(tx_clk),.dout(xgmii_txd)); |
| 438 | xMUX_2to1 #(4) xgmii_txc_xMUX_2to1(.din0(txc[7:4]), .din1(txc[3:0]), .sel(tx_clk),.dout(xgmii_txc)); |
| 439 | |
| 440 | my_buffers #(8) xpcs_txc_my_buffers(.z(xpcs_txc),.a(txc)); |
| 441 | my_buffers #(64) xpcs_txd_my_buffers(.z(xpcs_txd),.a(txd)); |
| 442 | |
| 443 | /* ------------------- tx_xencap_logic -------------------------- */ |
| 444 | // vlint flag_empty_block off |
| 445 | // vlint flag_variable_in_sensitivity_list_not_used_in_block off |
| 446 | always @ (/*AUTOSENSE*/crc_byte0 or crc_byte1 or crc_byte2 |
| 447 | or crc_byte3 or tx_byte0_reg1 or tx_byte1_reg0 |
| 448 | or tx_byte1_reg1 or tx_byte2_reg0 or tx_byte2_reg1 |
| 449 | or tx_byte3_reg0 or tx_byte3_reg1 or tx_byte4_reg0 |
| 450 | or tx_byte4_reg1 or tx_byte5_reg0 or tx_byte5_reg1 |
| 451 | or tx_byte6_reg0 or tx_byte6_reg1 or tx_byte7_reg0 |
| 452 | or tx_byte7_reg1 or tx_data_64bit_reg0 or tx_data_64bit_reg1 |
| 453 | or tx_en_8bit_reg0 or tx_en_8bit_reg1 or tx_reset) |
| 454 | begin |
| 455 | last_B_in_B0 = 0; |
| 456 | last_B_in_B1 = 0; |
| 457 | last_B_in_B2 = 0; |
| 458 | last_B_in_B3 = 0; |
| 459 | last_B_in_B4 = 0; |
| 460 | last_B_in_B5 = 0; |
| 461 | last_B_in_B6 = 0; |
| 462 | last_B_in_B7 = 0; |
| 463 | mod_tx_en_8bit_reg0 = tx_en_8bit_reg0; |
| 464 | mod_tx_en_8bit_reg1 = tx_en_8bit_reg1; |
| 465 | mod_tx_data_64bit_reg0 = tx_data_64bit_reg0; |
| 466 | mod_tx_data_64bit_reg1 = tx_data_64bit_reg1; |
| 467 | casex(tx_en_8bit_reg1) // synopsys parallel_case full_case |
| 468 | 8'b00000001: begin // insert_crc only |
| 469 | last_B_in_B0 = 1; |
| 470 | mod_tx_en_8bit_reg1 = 8'b00011111; |
| 471 | mod_tx_data_64bit_reg1 = {tx_byte7_reg1, |
| 472 | tx_byte6_reg1, |
| 473 | tx_byte5_reg1, |
| 474 | crc_byte3, |
| 475 | crc_byte2, |
| 476 | crc_byte1, |
| 477 | crc_byte0, |
| 478 | tx_byte0_reg1}; |
| 479 | end // case: 8'b00000001 |
| 480 | |
| 481 | 8'b00000011: begin // insert_crc only |
| 482 | last_B_in_B1 = 1; |
| 483 | mod_tx_en_8bit_reg1 = 8'b00111111; |
| 484 | mod_tx_data_64bit_reg1 = {tx_byte7_reg1, |
| 485 | tx_byte6_reg1, |
| 486 | crc_byte3, |
| 487 | crc_byte2, |
| 488 | crc_byte1, |
| 489 | crc_byte0, |
| 490 | tx_byte1_reg1, |
| 491 | tx_byte0_reg1}; |
| 492 | end // case: 8'b00000011 |
| 493 | |
| 494 | 8'b00000111: begin // insert_crc only |
| 495 | last_B_in_B2 = 1; |
| 496 | mod_tx_en_8bit_reg1 = 8'b01111111; |
| 497 | mod_tx_data_64bit_reg1 = {tx_byte7_reg1, |
| 498 | crc_byte3, |
| 499 | crc_byte2, |
| 500 | crc_byte1, |
| 501 | crc_byte0, |
| 502 | tx_byte2_reg1, |
| 503 | tx_byte1_reg1, |
| 504 | tx_byte0_reg1}; |
| 505 | end // case: 8'b00000111 |
| 506 | |
| 507 | 8'b00001111: begin // insert_crc only |
| 508 | last_B_in_B3 = 1; |
| 509 | mod_tx_en_8bit_reg1 = 8'b11111111; |
| 510 | mod_tx_data_64bit_reg1 = {crc_byte3, |
| 511 | crc_byte2, |
| 512 | crc_byte1, |
| 513 | crc_byte0, |
| 514 | tx_byte3_reg1, |
| 515 | tx_byte2_reg1, |
| 516 | tx_byte1_reg1, |
| 517 | tx_byte0_reg1}; |
| 518 | end // case: 8'b00001111 |
| 519 | |
| 520 | 8'b00011111: begin // both i and a |
| 521 | last_B_in_B4 = 1; |
| 522 | mod_tx_en_8bit_reg1 = 8'b11111111; |
| 523 | mod_tx_data_64bit_reg1 = {crc_byte2, |
| 524 | crc_byte1, |
| 525 | crc_byte0, |
| 526 | tx_byte4_reg1, |
| 527 | tx_byte3_reg1, |
| 528 | tx_byte2_reg1, |
| 529 | tx_byte1_reg1, |
| 530 | tx_byte0_reg1}; |
| 531 | mod_tx_en_8bit_reg0 = 8'b00000001; |
| 532 | mod_tx_data_64bit_reg0 = {tx_byte7_reg0, |
| 533 | tx_byte6_reg0, |
| 534 | tx_byte5_reg0, |
| 535 | tx_byte4_reg0, |
| 536 | tx_byte3_reg0, |
| 537 | tx_byte2_reg0, |
| 538 | tx_byte1_reg0, |
| 539 | crc_byte3}; |
| 540 | end // case: 8'b00011111 |
| 541 | |
| 542 | 8'b00111111: begin // both i and a |
| 543 | last_B_in_B5 = 1; |
| 544 | mod_tx_en_8bit_reg1 = 8'b11111111; |
| 545 | mod_tx_data_64bit_reg1 = {crc_byte1, |
| 546 | crc_byte0, |
| 547 | tx_byte5_reg1, |
| 548 | tx_byte4_reg1, |
| 549 | tx_byte3_reg1, |
| 550 | tx_byte2_reg1, |
| 551 | tx_byte1_reg1, |
| 552 | tx_byte0_reg1}; |
| 553 | mod_tx_en_8bit_reg0 = 8'b00000011; |
| 554 | mod_tx_data_64bit_reg0 = {tx_byte7_reg0, |
| 555 | tx_byte6_reg0, |
| 556 | tx_byte5_reg0, |
| 557 | tx_byte4_reg0, |
| 558 | tx_byte3_reg0, |
| 559 | tx_byte2_reg0, |
| 560 | crc_byte3, |
| 561 | crc_byte2}; |
| 562 | end // case: 8'b00111111 |
| 563 | |
| 564 | 8'b01111111: begin // both i and a |
| 565 | last_B_in_B6 = 1; |
| 566 | mod_tx_en_8bit_reg1 = 8'b11111111; |
| 567 | mod_tx_data_64bit_reg1 = {crc_byte0, |
| 568 | tx_byte6_reg1, |
| 569 | tx_byte5_reg1, |
| 570 | tx_byte4_reg1, |
| 571 | tx_byte3_reg1, |
| 572 | tx_byte2_reg1, |
| 573 | tx_byte1_reg1, |
| 574 | tx_byte0_reg1}; |
| 575 | |
| 576 | mod_tx_en_8bit_reg0 = 8'b00000111; |
| 577 | mod_tx_data_64bit_reg0 = {tx_byte7_reg0, |
| 578 | tx_byte6_reg0, |
| 579 | tx_byte5_reg0, |
| 580 | tx_byte4_reg0, |
| 581 | tx_byte3_reg0, |
| 582 | crc_byte3, |
| 583 | crc_byte2, |
| 584 | crc_byte1}; |
| 585 | end // case: 8'b01111111 |
| 586 | |
| 587 | 8'b11111111: begin // append_crc only |
| 588 | last_B_in_B7 = 1; |
| 589 | mod_tx_en_8bit_reg0 = 8'b00001111; |
| 590 | mod_tx_data_64bit_reg0 = {tx_byte7_reg0, |
| 591 | tx_byte6_reg0, |
| 592 | tx_byte5_reg0, |
| 593 | tx_byte4_reg0, |
| 594 | crc_byte3, |
| 595 | crc_byte2, |
| 596 | crc_byte1, |
| 597 | crc_byte0}; |
| 598 | end // case: 8'b11111111 |
| 599 | |
| 600 | 8'b00000000: begin // do nothing |
| 601 | end // case: 8'b00000000 |
| 602 | |
| 603 | 8'b11111110: begin // do nothing |
| 604 | end // case: 8'b00000000 |
| 605 | |
| 606 | default: |
| 607 | begin |
| 608 | // synopsys translate_off |
| 609 | if (tx_reset == 0) |
| 610 | $display("(* ERROR: at sim time = %d, (2) in tx_xmac.v tx_en_8bit_reg1 contains invalid combination. tx_en_8bit_reg1 = %b *) \n", $time, tx_en_8bit_reg1); |
| 611 | // synopsys translate_on |
| 612 | end // case: default |
| 613 | endcase // casex(tx_en_8bit_reg1) |
| 614 | end // always @ (tx_en_8bit_reg0 or tx_en_8bit_reg1 or... |
| 615 | // vlint flag_variable_in_sensitivity_list_not_used_in_block on |
| 616 | // vlint flag_empty_block on |
| 617 | |
| 618 | |
| 619 | wire last_B_in_B_0to3 = last_B_in_B0 | last_B_in_B1 | |
| 620 | last_B_in_B2 | last_B_in_B3; |
| 621 | wire last_B_in_B_4to6 = last_B_in_B4 | last_B_in_B5 | |
| 622 | last_B_in_B6; |
| 623 | wire insert_crc = eop_w_fcs_reg1 & |
| 624 | (last_B_in_B_0to3 | last_B_in_B_4to6); |
| 625 | wire append_crc = eop_w_fcs_reg1 & |
| 626 | (last_B_in_B7 | last_B_in_B_4to6); |
| 627 | |
| 628 | assign tx_en_8bit_reg0_mux = append_crc ? mod_tx_en_8bit_reg0: |
| 629 | tx_en_8bit_reg0; |
| 630 | |
| 631 | assign tx_data_64bit_reg0_mux = append_crc ? mod_tx_data_64bit_reg0: |
| 632 | tx_data_64bit_reg0; |
| 633 | // corrupt CRC |
| 634 | // In mii_mode|gmii_mode the tx_en_8bit_reg1 has to be as is so that the tx_err can be transmitted correctly. |
| 635 | // In xgmii_mode the tx_en_8bit_reg1 will become txc (txc == ~tx_en). It has to be 8'b0 to make txc == 1 |
| 636 | // so that the "E" char can be sent out with txc= 1. |
| 637 | assign tx_en_8bit_reg1_mux = (tx_abort_reg0 & xgmii_mode) ? 8'b0 : // lookahead to avoid corrupt "T" |
| 638 | (tx_abort_reg1 & ~xgmii_mode) ? tx_en_8bit_reg1 : |
| 639 | insert_crc ? mod_tx_en_8bit_reg1: |
| 640 | tx_en_8bit_reg1; |
| 641 | |
| 642 | assign tx_data_64bit_reg1_mux = (tx_abort_reg0 & xgmii_mode) ? {8{`E}} : |
| 643 | (tx_abort_reg1 & ~xgmii_mode) ? tx_data_64bit_reg1 : |
| 644 | insert_crc ? mod_tx_data_64bit_reg1: |
| 645 | tx_data_64bit_reg1; |
| 646 | |
| 647 | assign tx_data_32bit_A = back2back_swap_reg1 ? d_tx_data_32_B: |
| 648 | tx_data_32_A; |
| 649 | |
| 650 | assign tx_data_32bit_B = back2back_swap_reg1 ? tx_data_32_A : |
| 651 | tx_data_32_B ; |
| 652 | |
| 653 | assign tx_en_4bit_A = back2back_swap_reg1 ? d_tx_en_4_B: |
| 654 | tx_en_4_A; |
| 655 | |
| 656 | assign tx_en_4bit_B = back2back_swap_reg1 ? tx_en_4_A : |
| 657 | tx_en_4_B ; |
| 658 | assign p_txd_mux = { tx_data_32bit_B,tx_data_32bit_A}; |
| 659 | |
| 660 | assign p_txc_mux = {~tx_en_4bit_B, ~tx_en_4bit_A}; |
| 661 | |
| 662 | wire output_en_sel = tx_output_en_txclk & xgmii_mode; |
| 663 | |
| 664 | // assign p_txd = output_en_sel ? p_txd_mux : {8{`I}}; // send I char |
| 665 | assign p_txd = remote_fault_oc_txclk ? {8{`I}} : // generate idle |
| 666 | local_fault_oc_txclk ? `REMOTE_FAULT_SEQ : |
| 667 | output_en_sel ? p_txd_mux : {8{`I}}; // send I char |
| 668 | |
| 669 | // assign p_txc = output_en_sel ? p_txc_mux : 8'hFF; |
| 670 | assign p_txc = remote_fault_oc_txclk ? 8'hFF : // generate idle |
| 671 | local_fault_oc_txclk ? {8'b0001_0001} : |
| 672 | output_en_sel ? p_txc_mux : 8'hFF; |
| 673 | // `define REMOTE_FAULT_SEQ {8'h02,8'h00,8'h00,`SEQ,8'h02,8'h00,8'h00,`SEQ} |
| 674 | |
| 675 | // RMON support in tx_encap_logic |
| 676 | TFF toggle_tx_bcount_TFF(.toggle(tx_on), |
| 677 | .clk(tx_clk), |
| 678 | .reset(tx_reset), |
| 679 | .qout(toggle_tx_bcount)); |
| 680 | |
| 681 | /* ---------- start of tx_en_8bit_decoder logic ------------- */ |
| 682 | reg [7:0] decoded_tx_en_8bit; |
| 683 | always @ (tx_on_half or last_byte_position) |
| 684 | if (tx_on_half) |
| 685 | decoded_tx_en_8bit = 8'b00001111; // last byte is byte3 |
| 686 | else |
| 687 | case (last_byte_position) // synopsys parallel_case full_case |
| 688 | 3'h0: decoded_tx_en_8bit = 8'b00000001; // last byte is byte0 |
| 689 | 3'h1: decoded_tx_en_8bit = 8'b00000011; // last byte is byte1 |
| 690 | 3'h2: decoded_tx_en_8bit = 8'b00000111; // last byte is byte2 |
| 691 | 3'h3: decoded_tx_en_8bit = 8'b00001111; // last byte is byte3 |
| 692 | 3'h4: decoded_tx_en_8bit = 8'b00011111; // last byte is byte4 |
| 693 | 3'h5: decoded_tx_en_8bit = 8'b00111111; // last byte is byte5 |
| 694 | 3'h6: decoded_tx_en_8bit = 8'b01111111; // last byte is byte6 |
| 695 | 3'h7: decoded_tx_en_8bit = 8'b11111111; // last byte is byte7 |
| 696 | default:decoded_tx_en_8bit=8'b00000000; |
| 697 | endcase // case(last_byte_position) |
| 698 | |
| 699 | /* ---------- end of tx_en_8bit_decoder logic --------------- */ |
| 700 | |
| 701 | /* ---------- start of T_position decoder logic ------------- */ |
| 702 | |
| 703 | always @ (eop_oc or tx_en_8bit_reg1_mux) |
| 704 | if (eop_oc) |
| 705 | begin |
| 706 | T_position = 8'b00000000; |
| 707 | casex (tx_en_8bit_reg1_mux) // synopsys parallel_case full_case |
| 708 | 8'b00000000: T_position = 8'b00000001; // no data |
| 709 | 8'b00000001: T_position = 8'b00000010; // last byte is byte0 |
| 710 | 8'b00000011: T_position = 8'b00000100; // last byte is byte1 |
| 711 | 8'b00000111: T_position = 8'b00001000; // last byte is byte2 |
| 712 | 8'b00001111: T_position = 8'b00010000; // last byte is byte3 |
| 713 | 8'b00011111: T_position = 8'b00100000; // last byte is byte4 |
| 714 | 8'b00111111: T_position = 8'b01000000; // last byte is byte5 |
| 715 | 8'b01111111: T_position = 8'b10000000; // last byte is byte6 |
| 716 | 8'b11111111: T_position = 8'b00000000; // last byte is byte7 or regular data. |
| 717 | default : begin |
| 718 | T_position = 8'b00000001; |
| 719 | // synopsys translate_off |
| 720 | $display("(* ERROR: at sim time = %d, tx_xmac.v contains invalid tx_en_8bit_reg1_mux = %b *) \n", $time, tx_en_8bit_reg1_mux); |
| 721 | // synopsys translate_on |
| 722 | end |
| 723 | endcase // casex(tx_en_8bit_reg1_mux) |
| 724 | end |
| 725 | else |
| 726 | begin |
| 727 | T_position = 8'b00000000; |
| 728 | end |
| 729 | |
| 730 | wire rst_eop_oc = (|T_position); |
| 731 | RS_FF eop_oc_RS_FF(.set(eop_txclk_reg0),.rst(rst_eop_oc),.clk(tx_clk), |
| 732 | .reset(tx_reset),.qout(eop_oc)); |
| 733 | |
| 734 | /* ---------- end of T_position decoder logic --------------- */ |
| 735 | |
| 736 | always @ (tx_on or pa_time or eop_txclk or decoded_tx_en_8bit) |
| 737 | if (~(tx_on | pa_time)) |
| 738 | tx_en_8bit = 0; // no data transfer |
| 739 | else |
| 740 | casex ({pa_time,eop_txclk}) // synopsys parallel_case full_case |
| 741 | 2'b00: tx_en_8bit = 8'hFF; // regular control |
| 742 | 2'b01: tx_en_8bit = decoded_tx_en_8bit; // eop_time control |
| 743 | 2'b1x: tx_en_8bit = 8'hfe; // pa_time control |
| 744 | default:tx_en_8bit = 0; |
| 745 | endcase |
| 746 | |
| 747 | assign max_pkt_size_limit_txclk = (tx_byte_count > max_pkt_size); |
| 748 | |
| 749 | `ifdef ENABLE_XMAC_PAD_64_BYTES |
| 750 | wire cond1, cond2, cond3, cond4; |
| 751 | wire [13:0] tx_min_pkt_size_minus_4 = {4'b0,tx_min_pkt_size} - 4; |
| 752 | wire [13:0] tx_min_pkt_size_minus_8 = {4'b0,tx_min_pkt_size} - 8; |
| 753 | wire [13:0] tx_min_pkt_size_minus_16= {4'b0,tx_min_pkt_size} -16; |
| 754 | |
| 755 | assign min_pkt_size_limit_txclk = cond1 | cond2 | cond3 | cond4; |
| 756 | // 63~61 |
| 757 | assign cond1 = (nx_temp_tx_byte_count > tx_min_pkt_size_minus_4) & |
| 758 | (nx_temp_tx_byte_count < {4'b0,tx_min_pkt_size}) & |
| 759 | ~no_tx_min_pkt_size_chk; |
| 760 | |
| 761 | // 60~57 |
| 762 | assign cond2 = (nx_temp_tx_byte_count > tx_min_pkt_size_minus_8) & |
| 763 | ((nx_temp_tx_byte_count < tx_min_pkt_size_minus_4) | |
| 764 | (nx_temp_tx_byte_count == tx_min_pkt_size_minus_4)) & |
| 765 | ~no_tx_min_pkt_size_chk; |
| 766 | |
| 767 | // 56~49 |
| 768 | assign cond3 = (nx_temp_tx_byte_count > tx_min_pkt_size_minus_16) & |
| 769 | ((nx_temp_tx_byte_count < tx_min_pkt_size_minus_8) | |
| 770 | (nx_temp_tx_byte_count == tx_min_pkt_size_minus_8)) & |
| 771 | ~no_tx_min_pkt_size_chk; |
| 772 | |
| 773 | // 48~1 |
| 774 | assign cond4 = (nx_temp_tx_byte_count > 0) & |
| 775 | ((nx_temp_tx_byte_count < tx_min_pkt_size_minus_16) | |
| 776 | (nx_temp_tx_byte_count == tx_min_pkt_size_minus_16)) & |
| 777 | ~no_tx_min_pkt_size_chk; |
| 778 | |
| 779 | `else |
| 780 | assign min_pkt_size_limit_txclk = 0; |
| 781 | `endif |
| 782 | |
| 783 | FD1 sa1_time_FD1 (.D(pa_time), .CP(tx_clk),.Q(sa1_time)); |
| 784 | FD1 sa2_time_FD1 (.D(sa1_time),.CP(tx_clk),.Q(sa2_time)); |
| 785 | FD1 d_pa_time_FD1 (.D(pa_time),.CP(tx_clk),.Q(d_pa_time)); // spare part, not used |
| 786 | |
| 787 | assign replace_txd_time = pa_time | sa_repl & (sa1_time | sa2_time); |
| 788 | assign tx_data_source = pa_time ? pa_data : |
| 789 | sa1_time ? sa1_data: sa2_data; |
| 790 | |
| 791 | assign tx_data_64bit = replace_txd_time ? tx_data_source : |
| 792 | {tx_byte7,tx_byte6,tx_byte5,tx_byte4,tx_byte3,tx_byte2,tx_byte1,tx_byte0}; |
| 793 | |
| 794 | FD1 tx_data_valid_FD1 (.D(tx_on),.CP(tx_clk),.Q(tx_data_valid)); |
| 795 | |
| 796 | PlsGen2 ipg_done_lead_temp_PlsGen2 (.sig_in(ipg_done),.clk(tx_clk), |
| 797 | .lead(ipg_done_lead_temp),.trail(ipg_done_trail_temp)); |
| 798 | |
| 799 | // loj 12/14/00 |
| 800 | wire p1_force_ipg_done_lead = eop_txclk & (final_ipg_clks[`BYTE] == 8'h0 ); |
| 801 | |
| 802 | FD1 force_ipg_done_lead_FD1 (.D(p1_force_ipg_done_lead), |
| 803 | .CP(tx_clk),.Q(force_ipg_done_lead)); |
| 804 | |
| 805 | wire ipg_done_lead = ipg_done_lead_temp | force_ipg_done_lead; |
| 806 | |
| 807 | |
| 808 | xREG #(1) back2back_xREG(.din(set_back2back), |
| 809 | .clk(tx_clk), |
| 810 | .en(pa_time), |
| 811 | .reset(tx_reset), |
| 812 | .qout(back2back)); |
| 813 | |
| 814 | assign back2back_swap = back2back & tx_swap; |
| 815 | FD1 back2back_swap_reg1_FD1 (.D(back2back_swap),.CP(tx_clk), |
| 816 | .Q(back2back_swap_reg1)); |
| 817 | |
| 818 | /* ------------------- end of tx_encap_logic -------------------- */ |
| 819 | |
| 820 | |
| 821 | /* ------------------- tx_fc logic ------------------------------ */ |
| 822 | // Well-know multicase address DA reserved for Pause Frame: |
| 823 | // DA: 01-80-c2-00-00-01 , T/L: 0x8808 |
| 824 | // mac control opcode: 0x0001 |
| 825 | // The Pause frame time unit: 512 bits (64 bytes) time == slot time. |
| 826 | // For the 156.25Mhz, every clock is 8-byte time. |
| 827 | // 8 clock is 64 byte time. |
| 828 | // Recommended slot_time value is 8 (clocks). |
| 829 | |
| 830 | wire [7:0] slot_time_count; |
| 831 | wire [15:0] pause_time_count; |
| 832 | wire slot_time_count_eq_slot_time = (slot_time_count == slot_time); |
| 833 | |
| 834 | // slot timer, each increment indicates 8 byte time. |
| 835 | wire clr_slot_timer = tx_reset | rx_fc_pkt_ok_txclk | |
| 836 | pa_time | slot_time_count_eq_slot_time; |
| 837 | |
| 838 | counter_X8 FC_SLOT_TIMER(.clk(tx_clk), |
| 839 | .clr(clr_slot_timer), |
| 840 | .enable(paused_state & (!tx_on)), |
| 841 | .count(slot_time_count)); |
| 842 | |
| 843 | // pause_timer |
| 844 | counter_ld_dn_X16 PAUSE_TIMER( |
| 845 | .clk(tx_clk), |
| 846 | .clr(tx_reset), |
| 847 | .enable(paused_state & slot_time_count_eq_slot_time), |
| 848 | .load(rx_fc_pkt_ok_txclk), // load pause_time |
| 849 | .din(pause_time), // async from rxbclk |
| 850 | .count(pause_time_count) |
| 851 | ); |
| 852 | |
| 853 | assign new_paused_state = (pause_time_count != 16'h0); |
| 854 | FD1 PAUSED_STATE_FF(.D(new_paused_state),.CP(tx_clk),.Q(paused_state)); |
| 855 | /* ------------------- end of tx_fc logic ----------------------- */ |
| 856 | |
| 857 | /* ------------------- xtlm_sm logic ---------------------------- */ |
| 858 | // RMON spport |
| 859 | TFF toggle_txframe_count_TFF(.toggle(eop_txclk_reg0), |
| 860 | .clk(tx_clk), |
| 861 | .reset(tx_reset), |
| 862 | .qout(toggle_txframe_count)); |
| 863 | |
| 864 | /* ------------------- end of xtlm_sm logic ---------------------- */ |
| 865 | |
| 866 | /* ------------------- tx_byte_counters instantiation ------------ */ |
| 867 | |
| 868 | wire reset_tx_byte_counters = tx_reset | (~tx_on); |
| 869 | |
| 870 | // tx_byte_counter is for counting real tx_byte_count number which |
| 871 | // is used to compare with rx_byte_count in the loopback mode. |
| 872 | byte_counter tx_byte_counter( |
| 873 | .clk(tx_clk), |
| 874 | .reset(reset_tx_byte_counters), |
| 875 | .byte_count_en(tx_on), |
| 876 | .dv_en_8bit(tx_en_8bit), |
| 877 | // outputs |
| 878 | .byte_count(tx_byte_count), |
| 879 | .nx_byte_count(not_used_tx_byte_count)); |
| 880 | |
| 881 | `ifdef ENABLE_XMAC_PAD_64_BYTES |
| 882 | // tx_byte_counter is for generation of cond1, cond2, cond3, cond4, and |
| 883 | // min_pkt_size_limit_txclk which are use by xtlm_sm. |
| 884 | // nx_tx_byte_count will not generate logic loop while nx_tx_byte_count |
| 885 | // will. |
| 886 | tx_byte_counter temp_tx_byte_counter ( |
| 887 | .tx_clk(tx_clk), |
| 888 | .tx_reset(reset_tx_byte_counters), |
| 889 | .last_byte_position(last_byte_position), |
| 890 | .eop_tag(eop_tag), |
| 891 | .tx_byte_count_en(tx_on), |
| 892 | // outputs |
| 893 | .tx_byte_count(temp_tx_byte_count[13:0]), |
| 894 | .nx_tx_byte_count(nx_temp_tx_byte_count[13:0]) |
| 895 | ); |
| 896 | `else |
| 897 | assign temp_tx_byte_count = 0; |
| 898 | assign nx_temp_tx_byte_count = 0; |
| 899 | `endif |
| 900 | |
| 901 | /* ------------------ txfiflo_unload instantiation -------------- */ |
| 902 | txfifo_unload txfifo_unload( |
| 903 | .tx_clk(tx_clk), |
| 904 | .tx_reset(tx_reset), |
| 905 | .txfifo_g_wr_ptr_sync(txfifo_g_wr_ptr_sync), |
| 906 | .txfifo_rd_en(txfifo_rd_en), |
| 907 | .stfifo_rd_en(eop_txclk), |
| 908 | .stfifo_g_wr_ptr_sync(stfifo_g_wr_ptr_sync), |
| 909 | // outputs |
| 910 | //txfifo stuff |
| 911 | .txfifo_unload_rdy(txfifo_unload_rdy), |
| 912 | .txfifo_g_rd_ptr_txclk(txfifo_g_rd_ptr_txclk), |
| 913 | .txfifo_rd_ptr_txclk(txfifo_rd_ptr_txclk), |
| 914 | .txfifo_empty_txclk(txfifo_empty_txclk), |
| 915 | .txfifo_full_txclk(txfifo_full_txclk), |
| 916 | //stfifo stuff |
| 917 | .stfifo_g_rd_ptr_txclk(stfifo_g_rd_ptr_txclk), |
| 918 | .stfifo_rd_ptr_txclk(stfifo_rd_ptr_txclk), |
| 919 | .stfifo_empty_txclk(stfifo_empty_txclk), |
| 920 | .stfifo_underrun_txclk(stfifo_underrun_txclk) |
| 921 | ); |
| 922 | |
| 923 | /* ------------------ xdeferral instantiation ------------------- */ |
| 924 | xdeferral xdeferral( |
| 925 | .tx_clk(tx_clk), |
| 926 | .tx_reset(tx_reset), |
| 927 | .mii_mode(mii_mode), |
| 928 | .gmii_mode(gmii_mode), |
| 929 | .tx_byte_count_en(tx_on), |
| 930 | .tx_en_8bit(tx_en_8bit), |
| 931 | .stretch_mode(stretch_mode), |
| 932 | .stretch_constant(stretch_constant), |
| 933 | .stretch_ratio(stretch_ratio), |
| 934 | .ipg_value(ipg_value[2:0]), // only part of it |
| 935 | .tx_on_half(tx_on_half), // to modify last_byte_position |
| 936 | .add_crc(add_crc), |
| 937 | .eop_txclk(eop_txclk), |
| 938 | .last_byte_position(last_byte_position), |
| 939 | .var_min_ipg_en(var_min_ipg_en), |
| 940 | .pa_time(pa_time), |
| 941 | .back2back_swap_reg1(back2back_swap_reg1), |
| 942 | .set_back2back(set_back2back), |
| 943 | // outputs |
| 944 | .tx_swap(tx_swap), |
| 945 | .ipg_done(ipg_done), |
| 946 | .final_ipg_clks(final_ipg_clks), |
| 947 | // internal observation |
| 948 | .full_case_last_byte_position(full_case_last_byte_position), |
| 949 | .adjust2crc_full_case_last_byte_position(adjust2crc_full_case_last_byte_position[2:0]), |
| 950 | .adjust2crc_full_case_last_byte_position_is_3_or_7(adjust2crc_full_case_last_byte_position_is_3_or_7), |
| 951 | .stretch_full_case_last_byte_position(stretch_full_case_last_byte_position), |
| 952 | .stretch_clks(stretch_clks[`BYTE]), |
| 953 | .stretch_bytes(stretch_bytes[2:0]), |
| 954 | .stretch_1_more_clk(stretch_1_more_clk), |
| 955 | .B_eop(B_eop), |
| 956 | .minus_4bytes(minus_4bytes), |
| 957 | .no_wasted_BW(no_wasted_BW) |
| 958 | ); |
| 959 | |
| 960 | /* ------------------ xmac_fcs instantiation -------------------- */ |
| 961 | wire initialize_tx_crc = tx_reset | sa1_time; |
| 962 | wire tx_crc_compute_en = tx_data_valid & (~tx_reset); |
| 963 | |
| 964 | xmac_fcs xmac_fcs( |
| 965 | .clk(tx_clk), |
| 966 | .initialize_crc(initialize_tx_crc), |
| 967 | .compute_en(tx_crc_compute_en), |
| 968 | .crc_chk_dis(1'b0), |
| 969 | .data_valid(tx_data_valid), |
| 970 | .dv_8bit(tx_en_8bit_reg0), |
| 971 | .data_64bit(tx_data_64bit_reg0), |
| 972 | // outputs |
| 973 | .new_crc5_result(new_crc5_result[31:0]), |
| 974 | .crc_result(tx_crc_result), |
| 975 | .crc_error(tx_crc_error)); |
| 976 | |
| 977 | /* ------------------- xtlm_sm ---------------------------------- */ |
| 978 | xtlm_sm xtlm_sm( |
| 979 | .tx_clk(tx_clk), |
| 980 | .tx_reset(tx_reset), |
| 981 | .link_up(link_up), |
| 982 | .txfifo_unload_rdy(txfifo_unload_rdy), |
| 983 | .tx_enable_txclk(tx_enable_txclk), |
| 984 | .txfifo_empty_txclk(txfifo_empty_txclk), |
| 985 | .eop_tag(eop_tag), |
| 986 | .ipg_done(ipg_done), |
| 987 | .ipg_done_lead(ipg_done_lead), |
| 988 | .max_pkt_size_limit_txclk(max_pkt_size_limit_txclk), |
| 989 | .min_pkt_size_limit_txclk(min_pkt_size_limit_txclk), |
| 990 | `ifdef ENABLE_XMAC_PAD_64_BYTES |
| 991 | .cond1(cond1), |
| 992 | .cond2(cond2), |
| 993 | .cond3(cond3), |
| 994 | .cond4(cond4), |
| 995 | `else |
| 996 | `endif |
| 997 | .pause(paused_state), |
| 998 | // outputs |
| 999 | .txfifo_rd_en(txfifo_rd_en), |
| 1000 | .tx_on(tx_on), |
| 1001 | .tx_on_half(tx_on_half), |
| 1002 | .set_back2back(set_back2back), |
| 1003 | .pa_time(pa_time), |
| 1004 | .txfifo_xfr_err(txfifo_xfr_err), |
| 1005 | .tx_max_pkt_size_err(tx_max_pkt_size_err), |
| 1006 | .set_tx_pkt_ok(set_tx_pkt_ok), |
| 1007 | .restart_ipg_timer(restart_ipg_timer), |
| 1008 | .eop_txclk(eop_txclk), |
| 1009 | .add_fcs(add_fcs), |
| 1010 | .force_tx_err(force_tx_err), |
| 1011 | .txfifo_underrun_txclk(txfifo_underrun_txclk), |
| 1012 | .xtlm_state(xtlm_state)); |
| 1013 | |
| 1014 | /* ------------------- lfs glue logic ------------------------- */ |
| 1015 | // Added delay 32 idle tx_clk clocks for xpcs to recover from |
| 1016 | // SEQ order set back to normal IDLE order set. |
| 1017 | always @ (posedge tx_clk) |
| 1018 | begin |
| 1019 | dly[0 ] <= link_fault; |
| 1020 | dly[1 ] <= dly[0 ]; |
| 1021 | dly[2 ] <= dly[1 ]; |
| 1022 | dly[3 ] <= dly[2 ]; |
| 1023 | dly[4 ] <= dly[3 ]; |
| 1024 | dly[5 ] <= dly[4 ]; |
| 1025 | dly[6 ] <= dly[5 ]; |
| 1026 | dly[7 ] <= dly[6 ]; |
| 1027 | dly[8 ] <= dly[7 ]; |
| 1028 | dly[9 ] <= dly[8 ]; |
| 1029 | dly[10] <= dly[9 ]; |
| 1030 | dly[11] <= dly[10]; |
| 1031 | dly[12] <= dly[11]; |
| 1032 | dly[13] <= dly[12]; |
| 1033 | dly[14] <= dly[13]; |
| 1034 | dly[15] <= dly[14]; |
| 1035 | dly[16] <= dly[15]; |
| 1036 | dly[17] <= dly[16]; |
| 1037 | dly[18] <= dly[17]; |
| 1038 | dly[19] <= dly[18]; |
| 1039 | dly[20] <= dly[19]; |
| 1040 | dly[21] <= dly[20]; |
| 1041 | dly[22] <= dly[21]; |
| 1042 | dly[23] <= dly[22]; |
| 1043 | dly[24] <= dly[23]; |
| 1044 | dly[25] <= dly[24]; |
| 1045 | dly[26] <= dly[25]; |
| 1046 | dly[27] <= dly[26]; |
| 1047 | dly[28] <= dly[27]; |
| 1048 | dly[29] <= dly[28]; |
| 1049 | dly[30] <= dly[29]; |
| 1050 | dly[31] <= dly[30]; |
| 1051 | link_fault_dly <= dly[31]; |
| 1052 | end |
| 1053 | |
| 1054 | // _________ ______________ |
| 1055 | // link_fault |____________________| |
| 1056 | // _______________ ________ |
| 1057 | // link_fault_dly |____________________| |
| 1058 | // _______________ |
| 1059 | // link_up _______________| |______________ |
| 1060 | // ^^^^^^^ |
| 1061 | // delay for xpcs||||||| <- 32 clocks |
| 1062 | always @ (posedge tx_clk) |
| 1063 | begin |
| 1064 | link_up <= (~link_fault_dly) & (~link_fault); |
| 1065 | end |
| 1066 | |
| 1067 | /* ------------------- test logic -------------------------------- */ |
| 1068 | // synopsys translate_off |
| 1069 | //summit modcovoff -bpe |
| 1070 | //VCS coverage off |
| 1071 | ipg_checker ipg_checker( |
| 1072 | .tx_clk(tx_clk), |
| 1073 | .tx_reset(tx_reset), |
| 1074 | .xgmii_txc(xgmii_txc), |
| 1075 | .xgmii_txd(xgmii_txd), |
| 1076 | .var_min_ipg_en(var_min_ipg_en), |
| 1077 | .add_crc(add_crc), |
| 1078 | .eop_txclk(eop_txclk), |
| 1079 | .B_eop(B_eop), |
| 1080 | .stretch_mode(stretch_mode), |
| 1081 | .warning_msg_en(warning_msg_en) |
| 1082 | ); |
| 1083 | //VCS coverage on |
| 1084 | //summit modcovon -bpe |
| 1085 | // synopsys translate_on |
| 1086 | /* ------------------- end of test logic ------------------------- */ |
| 1087 | |
| 1088 | /* ------------------- debug mux logic --------------------------- */ |
| 1089 | |
| 1090 | |
| 1091 | RegDff #(1) tx_swap_RegDff (.din(tx_swap),.clk(tx_clk),.qout(tx_swap_reg)); |
| 1092 | RegDff #(1) tx_on_RegDff (.din(tx_on),.clk(tx_clk),.qout(tx_on_reg)); |
| 1093 | RegDff #(1) tx_on_half_RegDff (.din(tx_on_half),.clk(tx_clk),.qout(tx_on_half_reg)); |
| 1094 | RegDff #(1) replace_txd_time_RegDff (.din(replace_txd_time),.clk(tx_clk),.qout(replace_txd_time_reg)); |
| 1095 | RegDff #(3) adjust2crc_full_case_last_byte_position_RegDff (.din(adjust2crc_full_case_last_byte_position),.clk(tx_clk),.qout(adjust2crc_full_case_last_byte_position_reg[2:0])); |
| 1096 | RegDff #(1) adjust2crc_full_case_last_byte_position_is_3_or_7_RegDff (.din(adjust2crc_full_case_last_byte_position_is_3_or_7),.clk(tx_clk),.qout(adjust2crc_full_case_last_byte_position_is_3_or_7_reg)); |
| 1097 | RegDff #(8) stretch_clks_RegDff (.din(stretch_clks),.clk(tx_clk),.qout(stretch_clks_reg)); |
| 1098 | RegDff #(3) full_case_last_byte_position_RegDff (.din(full_case_last_byte_position),.clk(tx_clk),.qout(full_case_last_byte_position_reg)); |
| 1099 | RegDff #(4) stretch_full_case_last_byte_position_RegDff (.din(stretch_full_case_last_byte_position),.clk(tx_clk),.qout(stretch_full_case_last_byte_position_reg)); |
| 1100 | RegDff #(3) stretch_bytes_RegDff (.din(stretch_bytes),.clk(tx_clk),.qout(stretch_bytes_reg)); |
| 1101 | RegDff #(1) minus_4bytes_RegDff (.din(minus_4bytes),.clk(tx_clk),.qout(minus_4bytes_reg)); |
| 1102 | RegDff #(1) B_eop_RegDff (.din(B_eop),.clk(tx_clk),.qout(B_eop_reg)); |
| 1103 | RegDff #(1) stretch_1_more_clk_RegDff (.din(stretch_1_more_clk),.clk(tx_clk),.qout(stretch_1_more_clk_reg)); |
| 1104 | RegDff #(1) no_wasted_BW_RegDff (.din(no_wasted_BW),.clk(tx_clk),.qout(no_wasted_BW_reg)); |
| 1105 | RegDff #(1) ipg_done_trail_temp_RegDff (.din(ipg_done_trail_temp),.clk(tx_clk),.qout(ipg_done_trail_temp_reg)); |
| 1106 | RegDff #(1) restart_ipg_timer_RegDff (.din(restart_ipg_timer),.clk(tx_clk),.qout(restart_ipg_timer_reg)); |
| 1107 | RegDff #(1) ipg_done_RegDff (.din(ipg_done),.clk(tx_clk),.qout(ipg_done_reg)); |
| 1108 | RegDff #(1) ipg_done_lead_temp_RegDff (.din(ipg_done_lead_temp),.clk(tx_clk),.qout(ipg_done_lead_temp_reg)); |
| 1109 | RegDff #(1) force_ipg_done_lead_RegDff (.din(force_ipg_done_lead),.clk(tx_clk),.qout(force_ipg_done_lead_reg)); |
| 1110 | RegDff #(1) set_back2back_RegDff (.din(set_back2back),.clk(tx_clk),.qout(set_back2back_reg)); |
| 1111 | RegDff #(1) back2back_RegDff (.din(back2back),.clk(tx_clk),.qout(back2back_reg)); |
| 1112 | |
| 1113 | |
| 1114 | |
| 1115 | endmodule // tx_xmac |
| 1116 | |