]>
Commit | Line | Data |
---|---|---|
1 | ////////////////////////////////////////////////////////////////////// | |
2 | //// //// | |
3 | //// eth_transmitcontrol.v //// | |
4 | //// //// | |
5 | //// This file is part of the Ethernet IP core project //// | |
6 | //// http://www.opencores.org/projects/ethmac/ //// | |
7 | //// //// | |
8 | //// Author(s): //// | |
9 | //// - Igor Mohor (igorM@opencores.org) //// | |
10 | //// //// | |
11 | //// All additional information is avaliable in the Readme.txt //// | |
12 | //// file. //// | |
13 | //// //// | |
14 | ////////////////////////////////////////////////////////////////////// | |
15 | //// //// | |
16 | //// Copyright (C) 2001 Authors //// | |
17 | //// //// | |
18 | //// This source file may be used and distributed without //// | |
19 | //// restriction provided that this copyright statement is not //// | |
20 | //// removed from the file and that any derivative work contains //// | |
21 | //// the original copyright notice and the associated disclaimer. //// | |
22 | //// //// | |
23 | //// This source file is free software; you can redistribute it //// | |
24 | //// and/or modify it under the terms of the GNU Lesser General //// | |
25 | //// Public License as published by the Free Software Foundation; //// | |
26 | //// either version 2.1 of the License, or (at your option) any //// | |
27 | //// later version. //// | |
28 | //// //// | |
29 | //// This source is distributed in the hope that it will be //// | |
30 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// | |
31 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// | |
32 | //// PURPOSE. See the GNU Lesser General Public License for more //// | |
33 | //// details. //// | |
34 | //// //// | |
35 | //// You should have received a copy of the GNU Lesser General //// | |
36 | //// Public License along with this source; if not, download it //// | |
37 | //// from http://www.opencores.org/lgpl.shtml //// | |
38 | //// //// | |
39 | ////////////////////////////////////////////////////////////////////// | |
40 | // | |
41 | // CVS Revision History | |
42 | // | |
43 | // $Log: eth_transmitcontrol.v,v $ | |
44 | // Revision 1.1 2007-03-20 17:50:56 sithglan | |
45 | // add shit | |
46 | // | |
47 | // Revision 1.6 2002/11/21 00:16:14 mohor | |
48 | // When TxUsedData and CtrlMux occur at the same time, byte counter needs | |
49 | // to be incremented by 2. Signal IncrementByteCntBy2 added for that reason. | |
50 | // | |
51 | // Revision 1.5 2002/11/19 17:37:32 mohor | |
52 | // When control frame (PAUSE) was sent, status was written in the | |
53 | // eth_wishbone module and both TXB and TXC interrupts were set. Fixed. | |
54 | // Only TXC interrupt is set. | |
55 | // | |
56 | // Revision 1.4 2002/01/23 10:28:16 mohor | |
57 | // Link in the header changed. | |
58 | // | |
59 | // Revision 1.3 2001/10/19 08:43:51 mohor | |
60 | // eth_timescale.v changed to timescale.v This is done because of the | |
61 | // simulation of the few cores in a one joined project. | |
62 | // | |
63 | // Revision 1.2 2001/09/11 14:17:00 mohor | |
64 | // Few little NCSIM warnings fixed. | |
65 | // | |
66 | // Revision 1.1 2001/08/06 14:44:29 mohor | |
67 | // A define FPGA added to select between Artisan RAM (for ASIC) and Block Ram (For Virtex). | |
68 | // Include files fixed to contain no path. | |
69 | // File names and module names changed ta have a eth_ prologue in the name. | |
70 | // File eth_timescale.v is used to define timescale | |
71 | // All pin names on the top module are changed to contain _I, _O or _OE at the end. | |
72 | // Bidirectional signal MDIO is changed to three signals (Mdc_O, Mdi_I, Mdo_O | |
73 | // and Mdo_OE. The bidirectional signal must be created on the top level. This | |
74 | // is done due to the ASIC tools. | |
75 | // | |
76 | // Revision 1.1 2001/07/30 21:23:42 mohor | |
77 | // Directory structure changed. Files checked and joind together. | |
78 | // | |
79 | // Revision 1.1 2001/07/03 12:51:54 mohor | |
80 | // Initial release of the MAC Control module. | |
81 | // | |
82 | // | |
83 | // | |
84 | // | |
85 | // | |
86 | // | |
87 | ||
88 | ||
89 | `include "timescale.v" | |
90 | ||
91 | ||
92 | module eth_transmitcontrol (MTxClk, TxReset, TxUsedDataIn, TxUsedDataOut, TxDoneIn, TxAbortIn, | |
93 | TxStartFrmIn, TPauseRq, TxUsedDataOutDetected, TxFlow, DlyCrcEn, | |
94 | TxPauseTV, MAC, TxCtrlStartFrm, TxCtrlEndFrm, SendingCtrlFrm, CtrlMux, | |
95 | ControlData, WillSendControlFrame, BlockTxDone | |
96 | ); | |
97 | ||
98 | parameter Tp = 1; | |
99 | ||
100 | ||
101 | input MTxClk; | |
102 | input TxReset; | |
103 | input TxUsedDataIn; | |
104 | input TxUsedDataOut; | |
105 | input TxDoneIn; | |
106 | input TxAbortIn; | |
107 | input TxStartFrmIn; | |
108 | input TPauseRq; | |
109 | input TxUsedDataOutDetected; | |
110 | input TxFlow; | |
111 | input DlyCrcEn; | |
112 | input [15:0] TxPauseTV; | |
113 | input [47:0] MAC; | |
114 | ||
115 | output TxCtrlStartFrm; | |
116 | output TxCtrlEndFrm; | |
117 | output SendingCtrlFrm; | |
118 | output CtrlMux; | |
119 | output [7:0] ControlData; | |
120 | output WillSendControlFrame; | |
121 | output BlockTxDone; | |
122 | ||
123 | reg SendingCtrlFrm; | |
124 | reg CtrlMux; | |
125 | reg WillSendControlFrame; | |
126 | reg [3:0] DlyCrcCnt; | |
127 | reg [5:0] ByteCnt; | |
128 | reg ControlEnd_q; | |
129 | reg [7:0] MuxedCtrlData; | |
130 | reg TxCtrlStartFrm; | |
131 | reg TxCtrlStartFrm_q; | |
132 | reg TxCtrlEndFrm; | |
133 | reg [7:0] ControlData; | |
134 | reg TxUsedDataIn_q; | |
135 | reg BlockTxDone; | |
136 | ||
137 | wire IncrementDlyCrcCnt; | |
138 | wire ResetByteCnt; | |
139 | wire IncrementByteCnt; | |
140 | wire ControlEnd; | |
141 | wire IncrementByteCntBy2; | |
142 | wire EnableCnt; | |
143 | ||
144 | ||
145 | // A command for Sending the control frame is active (latched) | |
146 | always @ (posedge MTxClk or posedge TxReset) | |
147 | begin | |
148 | if(TxReset) | |
149 | WillSendControlFrame <= #Tp 1'b0; | |
150 | else | |
151 | if(TxCtrlEndFrm & CtrlMux) | |
152 | WillSendControlFrame <= #Tp 1'b0; | |
153 | else | |
154 | if(TPauseRq & TxFlow) | |
155 | WillSendControlFrame <= #Tp 1'b1; | |
156 | end | |
157 | ||
158 | ||
159 | // Generation of the transmit control packet start frame | |
160 | always @ (posedge MTxClk or posedge TxReset) | |
161 | begin | |
162 | if(TxReset) | |
163 | TxCtrlStartFrm <= #Tp 1'b0; | |
164 | else | |
165 | if(TxUsedDataIn_q & CtrlMux) | |
166 | TxCtrlStartFrm <= #Tp 1'b0; | |
167 | else | |
168 | if(WillSendControlFrame & ~TxUsedDataOut & (TxDoneIn | TxAbortIn | TxStartFrmIn | (~TxUsedDataOutDetected))) | |
169 | TxCtrlStartFrm <= #Tp 1'b1; | |
170 | end | |
171 | ||
172 | ||
173 | ||
174 | // Generation of the transmit control packet end frame | |
175 | always @ (posedge MTxClk or posedge TxReset) | |
176 | begin | |
177 | if(TxReset) | |
178 | TxCtrlEndFrm <= #Tp 1'b0; | |
179 | else | |
180 | if(ControlEnd | ControlEnd_q) | |
181 | TxCtrlEndFrm <= #Tp 1'b1; | |
182 | else | |
183 | TxCtrlEndFrm <= #Tp 1'b0; | |
184 | end | |
185 | ||
186 | ||
187 | // Generation of the multiplexer signal (controls muxes for switching between | |
188 | // normal and control packets) | |
189 | always @ (posedge MTxClk or posedge TxReset) | |
190 | begin | |
191 | if(TxReset) | |
192 | CtrlMux <= #Tp 1'b0; | |
193 | else | |
194 | if(WillSendControlFrame & ~TxUsedDataOut) | |
195 | CtrlMux <= #Tp 1'b1; | |
196 | else | |
197 | if(TxDoneIn) | |
198 | CtrlMux <= #Tp 1'b0; | |
199 | end | |
200 | ||
201 | ||
202 | ||
203 | // Generation of the Sending Control Frame signal (enables padding and CRC) | |
204 | always @ (posedge MTxClk or posedge TxReset) | |
205 | begin | |
206 | if(TxReset) | |
207 | SendingCtrlFrm <= #Tp 1'b0; | |
208 | else | |
209 | if(WillSendControlFrame & TxCtrlStartFrm) | |
210 | SendingCtrlFrm <= #Tp 1'b1; | |
211 | else | |
212 | if(TxDoneIn) | |
213 | SendingCtrlFrm <= #Tp 1'b0; | |
214 | end | |
215 | ||
216 | ||
217 | always @ (posedge MTxClk or posedge TxReset) | |
218 | begin | |
219 | if(TxReset) | |
220 | TxUsedDataIn_q <= #Tp 1'b0; | |
221 | else | |
222 | TxUsedDataIn_q <= #Tp TxUsedDataIn; | |
223 | end | |
224 | ||
225 | ||
226 | ||
227 | // Generation of the signal that will block sending the Done signal to the eth_wishbone module | |
228 | // While sending the control frame | |
229 | always @ (posedge MTxClk or posedge TxReset) | |
230 | begin | |
231 | if(TxReset) | |
232 | BlockTxDone <= #Tp 1'b0; | |
233 | else | |
234 | if(TxCtrlStartFrm) | |
235 | BlockTxDone <= #Tp 1'b1; | |
236 | else | |
237 | if(TxStartFrmIn) | |
238 | BlockTxDone <= #Tp 1'b0; | |
239 | end | |
240 | ||
241 | ||
242 | always @ (posedge MTxClk) | |
243 | begin | |
244 | ControlEnd_q <= #Tp ControlEnd; | |
245 | TxCtrlStartFrm_q <= #Tp TxCtrlStartFrm; | |
246 | end | |
247 | ||
248 | ||
249 | assign IncrementDlyCrcCnt = CtrlMux & TxUsedDataIn & ~DlyCrcCnt[2]; | |
250 | ||
251 | ||
252 | // Delayed CRC counter | |
253 | always @ (posedge MTxClk or posedge TxReset) | |
254 | begin | |
255 | if(TxReset) | |
256 | DlyCrcCnt <= #Tp 4'h0; | |
257 | else | |
258 | if(ResetByteCnt) | |
259 | DlyCrcCnt <= #Tp 4'h0; | |
260 | else | |
261 | if(IncrementDlyCrcCnt) | |
262 | DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1; | |
263 | end | |
264 | ||
265 | ||
266 | assign ResetByteCnt = TxReset | (~TxCtrlStartFrm & (TxDoneIn | TxAbortIn)); | |
267 | assign IncrementByteCnt = CtrlMux & (TxCtrlStartFrm & ~TxCtrlStartFrm_q & ~TxUsedDataIn | TxUsedDataIn & ~ControlEnd); | |
268 | assign IncrementByteCntBy2 = CtrlMux & TxCtrlStartFrm & (~TxCtrlStartFrm_q) & TxUsedDataIn; // When TxUsedDataIn and CtrlMux are set at the same time | |
269 | ||
270 | assign EnableCnt = (~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0])); | |
271 | // Byte counter | |
272 | always @ (posedge MTxClk or posedge TxReset) | |
273 | begin | |
274 | if(TxReset) | |
275 | ByteCnt <= #Tp 6'h0; | |
276 | else | |
277 | if(ResetByteCnt) | |
278 | ByteCnt <= #Tp 6'h0; | |
279 | else | |
280 | if(IncrementByteCntBy2 & EnableCnt) | |
281 | ByteCnt <= #Tp (ByteCnt[5:0] ) + 2'h2; | |
282 | else | |
283 | if(IncrementByteCnt & EnableCnt) | |
284 | ByteCnt <= #Tp (ByteCnt[5:0] ) + 1'b1; | |
285 | end | |
286 | ||
287 | ||
288 | assign ControlEnd = ByteCnt[5:0] == 6'h22; | |
289 | ||
290 | ||
291 | // Control data generation (goes to the TxEthMAC module) | |
292 | always @ (ByteCnt or DlyCrcEn or MAC or TxPauseTV or DlyCrcCnt) | |
293 | begin | |
294 | case(ByteCnt) | |
295 | 6'h0: if(~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0])) | |
296 | MuxedCtrlData[7:0] = 8'h01; // Reserved Multicast Address | |
297 | else | |
298 | MuxedCtrlData[7:0] = 8'h0; | |
299 | 6'h2: MuxedCtrlData[7:0] = 8'h80; | |
300 | 6'h4: MuxedCtrlData[7:0] = 8'hC2; | |
301 | 6'h6: MuxedCtrlData[7:0] = 8'h00; | |
302 | 6'h8: MuxedCtrlData[7:0] = 8'h00; | |
303 | 6'hA: MuxedCtrlData[7:0] = 8'h01; | |
304 | 6'hC: MuxedCtrlData[7:0] = MAC[47:40]; | |
305 | 6'hE: MuxedCtrlData[7:0] = MAC[39:32]; | |
306 | 6'h10: MuxedCtrlData[7:0] = MAC[31:24]; | |
307 | 6'h12: MuxedCtrlData[7:0] = MAC[23:16]; | |
308 | 6'h14: MuxedCtrlData[7:0] = MAC[15:8]; | |
309 | 6'h16: MuxedCtrlData[7:0] = MAC[7:0]; | |
310 | 6'h18: MuxedCtrlData[7:0] = 8'h88; // Type/Length | |
311 | 6'h1A: MuxedCtrlData[7:0] = 8'h08; | |
312 | 6'h1C: MuxedCtrlData[7:0] = 8'h00; // Opcode | |
313 | 6'h1E: MuxedCtrlData[7:0] = 8'h01; | |
314 | 6'h20: MuxedCtrlData[7:0] = TxPauseTV[15:8]; // Pause timer value | |
315 | 6'h22: MuxedCtrlData[7:0] = TxPauseTV[7:0]; | |
316 | default: MuxedCtrlData[7:0] = 8'h0; | |
317 | endcase | |
318 | end | |
319 | ||
320 | ||
321 | // Latched Control data | |
322 | always @ (posedge MTxClk or posedge TxReset) | |
323 | begin | |
324 | if(TxReset) | |
325 | ControlData[7:0] <= #Tp 8'h0; | |
326 | else | |
327 | if(~ByteCnt[0]) | |
328 | ControlData[7:0] <= #Tp MuxedCtrlData[7:0]; | |
329 | end | |
330 | ||
331 | ||
332 | ||
333 | endmodule |