1 `define ADDR_ETH_STATUS 16'hFF68
2 `define ADDR_ETH 16'hFF69
18 reg [10:0] txlength = 0;
19 reg [10:0] txwraddr = 0;
20 reg [1:0] txstate = 0;
26 wire decode = (addrlatch == `ADDR_ETH_STATUS) || (addrlatch == `ADDR_ETH);
28 assign data = (decode && rdlatch) ? odata : 8'bzzzzzzzz;
43 .wr(wr && state == 2'b10 && addr == `ADDR_ETH),
49 wire [10:0] rxphyaddr;
54 reg [1:0] rxstate = 0;
56 reg [10:0] rxcurlength;
58 reg [10:0] rxcoreaddr = 0;
59 wire [7:0] rxcoredata;
63 .manchester_data_in(~rxp),
80 always @ (posedge clk) begin
84 if (rd && addr == `ADDR_ETH_STATUS)
85 odata <= {state,4'b0,rxpktrdy,txbusy};
86 else if (wr && addr == `ADDR_ETH_STATUS) begin /* Reset the state machines. */
89 end else if (rd && addr == `ADDR_ETH) begin
95 rxcurlength <= rxlength;
96 odata <= rxpktrdy ? {5'b0,rxlength[10:8]} : 8'b0;
100 rxstate <= (rxcurlength == 0) ? 2'b00 : 2'b10;
101 odata <= rxcurlength[7:0];
106 if (rxcoreaddr == (rxcurlength - 1)) begin
110 rxcoreaddr <= rxcoreaddr + 1;
113 end else if (rxstate == 2'b11 || rxclear) begin
116 end else if (wr && addr == `ADDR_ETH) begin
119 txlength[10:8] <= data[2:0];
123 txlength[7:0] <= data[7:0];
128 if(txwraddr == (txlength - 1)) begin
132 txwraddr <= txwraddr + 1;
134 end else if (txstate == 2'b11) begin
149 output reg [7:0] rdata);
151 reg [7:0] mem [1600:0];
153 always @(posedge wrclk) begin
158 always @(posedge rdclk)
162 module EnetTX(input clk20, output reg Ethernet_TDp, output reg Ethernet_TDm, output wire busy, input start, input [11:0] length, output wire [11:0] rdaddress, input [7:0] indata);
163 reg StartSending; always @(posedge clk20) StartSending<=start;
164 reg [11:0] curlen = 0; always @(posedge clk20) if (start) curlen <= length + 8;
166 reg [11:0] internaladdr;
167 assign rdaddress = internaladdr - 8;
168 wire [7:0] pkt_data = (internaladdr < 7) ? 8'h55 :
169 (internaladdr == 7) ? 8'hD5 :
172 //////////////////////////////////////////////////////////////////////
173 // and finally the 10BASE-T's magic
174 reg [3:0] ShiftCount;
176 always @(posedge clk20) if(StartSending) SendingPacket<=1; else if(ShiftCount==14 && internaladdr==(curlen + 4)) SendingPacket<=0;
177 always @(posedge clk20) ShiftCount <= SendingPacket ? ShiftCount+1 : 15;
178 wire readram = (ShiftCount==15);
179 always @(posedge clk20) if(ShiftCount==15) internaladdr <= SendingPacket ? internaladdr+1 : 0;
180 reg [7:0] ShiftData; always @(posedge clk20) if(ShiftCount[0]) ShiftData <= readram ? pkt_data : {1'b0, ShiftData[7:1]};
182 // generate the CRC32
184 reg CRCflush; always @(posedge clk20) if(CRCflush) CRCflush <= SendingPacket; else if(readram) CRCflush <= (internaladdr==curlen);
185 reg CRCinit; always @(posedge clk20) if(readram) CRCinit <= (internaladdr==7);
186 wire CRCinput = CRCflush ? 0 : (ShiftData[0] ^ CRC[31]);
187 always @(posedge clk20) if(ShiftCount[0]) CRC <= CRCinit ? ~0 : ({CRC[30:0],1'b0} ^ ({32{CRCinput}} & 32'h04C11DB7));
190 reg [17:0] LinkPulseCount; always @(posedge clk20) LinkPulseCount <= SendingPacket ? 0 : LinkPulseCount+1;
191 reg LinkPulse; always @(posedge clk20) LinkPulse <= &LinkPulseCount[17:1];
193 // TP_IDL, shift-register and manchester encoder
194 reg SendingPacketData; always @(posedge clk20) SendingPacketData <= SendingPacket;
195 assign busy = SendingPacketData;
196 reg [2:0] idlecount; always @(posedge clk20) if(SendingPacketData) idlecount<=0; else if(~&idlecount) idlecount<=idlecount+1;
197 wire dataout = CRCflush ? ~CRC[31] : ShiftData[0];
198 reg qo; always @(posedge clk20) qo <= SendingPacketData ? ~dataout^ShiftCount[0] : 1;
199 reg qoe; always @(posedge clk20) qoe <= SendingPacketData | LinkPulse | (idlecount<6);
200 always @(posedge clk20) Ethernet_TDp <= (qoe ? qo : 1'b0);
201 always @(posedge clk20) Ethernet_TDm <= (qoe ? ~qo : 1'b0);
206 input manchester_data_in,
208 output reg [10:0] oaddr,
209 output reg [7:0] odata,
210 output reg pktrdy = 0,
211 output reg [10:0] olength = 0,
215 always @(posedge rxclk) in_data <= {in_data[1:0], manchester_data_in};
220 always @(posedge rxclk) if(|cnt || (in_data[2] ^ in_data[1])) cnt<=cnt+1;
223 always @(posedge rxclk) new_bit_avail <= (cnt==3);
224 always @(posedge rxclk) if(cnt==3) data<={in_data[1],data[7:1]};
226 /////////////////////////////////////////////////
227 reg end_of_Ethernet_frame;
230 always @(posedge rxclk)
231 if(end_of_Ethernet_frame)
233 else if(new_bit_avail) begin
234 if(!(data==8'h55 || data==8'hAA)) // not preamble?
237 if(~&sync1) // if all bits of this "sync1" counter are one, we decide that enough of the preamble
238 // has been received, so stop counting and wait for "sync2" to detect the SFD
239 sync1 <= sync1 + 1; // otherwise keep counting
243 always @(posedge rxclk)
244 if(end_of_Ethernet_frame || pktrdy) // i.e., if we're busy, drop it on the floor
247 if(new_bit_avail) begin
248 if(|sync2) // if the SFD has already been detected (Ethernet data is coming in)
249 sync2 <= sync2 + 1; // then count the bits coming in
250 else if(&sync1 && data==8'hD5) // otherwise, let's wait for the SFD (0xD5)
254 wire new_byte_available = new_bit_avail && (sync2[2:0]==3'h0) && (sync2[9:3]!=0);
256 /////////////////////////////////////////////////
257 // if no clock transistion is detected for some time, that's the end of the Ethernet frame
259 reg [2:0] transition_timeout;
260 always @(posedge rxclk) if(in_data[2]^in_data[1]) transition_timeout<=0; else if(~&cnt) transition_timeout<=transition_timeout+1;
261 always @(posedge rxclk) end_of_Ethernet_frame <= &transition_timeout;
264 /////////////////////////////////////////////////
265 always @(posedge rxclk)
266 if (new_byte_available && !pktrdy) begin
271 end else if (end_of_Ethernet_frame && (iaddr > 1)) begin
276 end else if (pktclear) begin