3 (input clk125, input reset,
4 output GMII_GTX_CLK, output reg GMII_TX_EN, output reg GMII_TX_ER, output reg [7:0] GMII_TXD,
5 output tx_clk, input [7:0] tx_data, input tx_valid, input tx_error, output tx_ack,
6 input [7:0] ifg, input [47:0] mac_addr,
7 input pause_req, input [15:0] pause_time,
8 input pause_apply, output reg paused
11 reg tx_en_pre, tx_er_pre;
14 assign GMII_GTX_CLK = clk125;
15 assign tx_clk = clk125;
19 reg [15:0] frame_len_ctr;
20 reg [7:0] pause_ctr, pause_dat;
22 wire in_ifg = (ifg_ctr != 0);
26 localparam MIN_FRAME_LEN = 64 + 8 - 4; // Min frame length includes preamble but not CRC
27 localparam MAX_FRAME_LEN = 8192; // How big are the jumbo frames we want to handle?
28 always @(posedge tx_clk)
29 if(reset |(tx_state == TX_IDLE))
32 frame_len_ctr <= frame_len_ctr + 1;
34 localparam TX_IDLE = 0;
35 localparam TX_PREAMBLE = 1;
36 localparam TX_SOF_DEL = TX_PREAMBLE + 7;
37 localparam TX_FIRSTBYTE = TX_SOF_DEL + 1;
38 localparam TX_IN_FRAME = TX_FIRSTBYTE + 1;
39 localparam TX_IN_FRAME_2 = TX_IN_FRAME + 1;
40 localparam TX_PAD = TX_IN_FRAME_2 + 1;
41 localparam TX_CRC_0 = 16;
42 localparam TX_CRC_1 = TX_CRC_0 + 1;
43 localparam TX_CRC_2 = TX_CRC_0 + 2;
44 localparam TX_CRC_3 = TX_CRC_0 + 3;
45 localparam TX_ERROR = 32;
46 localparam TX_PAUSE = 55;
47 localparam TX_PAUSE_SOF = TX_PAUSE + 7;
48 localparam TX_PAUSE_FIRST = TX_PAUSE_SOF + 1;
49 localparam TX_PAUSE_END = TX_PAUSE_SOF + 18;
52 reg [15:0] pause_time_held;
54 always @(posedge tx_clk)
59 else if(tx_state == TX_PAUSE)
62 always @(posedge tx_clk)
64 pause_time_held <= pause_time;
66 always @(posedge tx_clk)
75 else if(tx_valid & ~pause_apply)
76 tx_state <= TX_PREAMBLE;
79 tx_state <= TX_ERROR; // underrun
83 tx_state <= TX_IN_FRAME;
86 tx_state <= TX_ERROR; // underrun
89 else if(frame_len_ctr == MIN_FRAME_LEN - 1)
90 tx_state <= TX_IN_FRAME_2;
93 tx_state <= TX_ERROR; // underrun
97 if(frame_len_ctr == MIN_FRAME_LEN)
106 tx_state <= tx_state + 1;
107 endcase // case (tx_state)
109 always @(posedge tx_clk)
124 TX_PREAMBLE, TX_PAUSE :
129 TX_SOF_DEL, TX_PAUSE_SOF :
131 TX_FIRSTBYTE, TX_IN_FRAME, TX_IN_FRAME_2 :
132 txd_pre <= tx_valid ? tx_data : 0;
142 TX_PAUSE_FIRST, 8'b01xx_xxxx : // In Pause Frame
143 txd_pre <= pause_dat;
144 endcase // case (tx_state)
146 localparam SGE_FLOW_CTRL_ADDR = 48'h01_80_C2_00_00_01;
147 always @(posedge tx_clk)
150 pause_dat <= SGE_FLOW_CTRL_ADDR[47:40]; // Note everything must be 1 cycle early
152 pause_dat <= SGE_FLOW_CTRL_ADDR[39:32];
154 pause_dat <= SGE_FLOW_CTRL_ADDR[31:24];
156 pause_dat <= SGE_FLOW_CTRL_ADDR[23:16];
158 pause_dat <= SGE_FLOW_CTRL_ADDR[15:8];
160 pause_dat <= SGE_FLOW_CTRL_ADDR[7:0];
162 pause_dat <= mac_addr[47:40];
164 pause_dat <= mac_addr[39:32];
166 pause_dat <= mac_addr[31:24];
168 pause_dat <= mac_addr[23:16];
170 pause_dat <= mac_addr[15:8];
172 pause_dat <= mac_addr[7:0];
174 pause_dat <= 8'h88; // Type = 8808 = MAC ctrl frame
178 pause_dat <= 8'h00; // Opcode = 0001 = PAUSE
182 pause_dat <= pause_time_held[15:8];
184 pause_dat <= pause_time_held[7:0];
185 endcase // case (tx_state)
187 wire start_ifg = (tx_state == TX_CRC_3);
188 always @(posedge tx_clk)
193 else if(ifg_ctr != 0)
194 ifg_ctr <= ifg_ctr - 1;
196 wire clear_crc = (tx_state == TX_IDLE);
199 (tx_state==TX_IN_FRAME) |
200 (tx_state==TX_IN_FRAME_2) |
204 crc crc(.clk(tx_clk), .reset(reset), .clear(clear_crc),
205 .data(txd_pre), .calc(calc_crc), .crc_out(crc_out));
207 assign tx_ack = (tx_state == TX_FIRSTBYTE);
209 always @(posedge tx_clk)
211 GMII_TX_EN <= tx_en_pre;
212 GMII_TX_ER <= tx_er_pre;
215 GMII_TXD <= crc_out[31:24];
217 GMII_TXD <= crc_out[23:16];
219 GMII_TXD <= crc_out[15:8];
221 GMII_TXD <= crc_out[7:0];
224 endcase // case (tx_state)
227 // report that we are paused only when we get back to IDLE
228 always @(posedge tx_clk)
231 else if(~pause_apply)
233 else if(tx_state == TX_IDLE)
236 endmodule // simple_gemac_tx
242 always @(posedge tx_clk)
243 calc_crc_d1 <= calc_crc;
245 always @(posedge tx_clk)
249 crc_ctr <= crc_ctr+1;
251 $display("CRC COUNT = %d",crc_ctr);