110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf ·...

54
10 MAC Ethernet RS-485 CAN Internet TCP/IP USB 2.0 IEEE 1394 FPGA FPGA MAC 10.1 IEEE 802.3 LAN Local Area Network CSMA/CD CSMA/CD Carrier sense multiple Access with Collision Detection IEEE 802.3 10.1.1 OSI Open System Interconnect Reference Model 10-1 4 10 Mbit/s 10Base-T 100 Mbit/s 1000 Mbit/s 802.3z 10 IEEE 802.3ae

Transcript of 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf ·...

Page 1: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

1100 MMAACC

EthernetRS-485 CAN

Internet TCP/IPUSB 2.0 IEEE 1394

�����

FPGAFPGA MAC

10.1

IEEE 802.3 LAN Local Area Network CSMA/CD

CSMA/CD Carrier sense multiple Access with Collision Detection

IEEE 802.3

10.1.1OSI Open System Interconnect Reference Model

10-1

4� 10 Mbit/s 10Base-T� 100 Mbit/s� 1000 Mbit/s 802.3z� 10 IEEE 802.3ae

Page 2: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

367

10-1

MAC/

IP TCP HTTPTCP/IP 10-2

10-2

FTP FTP10-3

IP IPTCP UDP ICMP

TCP/IPRJ-45

MAC

Page 3: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

368

MAC

10-3 FTP

10.1.2 MACMAC

IEEE 802.3

1

IEEE 802.3 MAC 10-4

10-4

� Preamble PRE 1 0

� Start-of-frame delimiter SFD 1 01

� Destination Address DA� Source Address SA� Length/Type / MAC

Page 4: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

369

� Data n 46 n 1500� Frame check sequence FCS 32 CRC

2

MACMAC���� 46 46� / CRC

MAChalf duplex full duplex IEEE 802.3 MAC

3

CRC CRCMAC

10.1.3 Media Independent InterfaceIEEE 802.3 Media Independent Interface MII

MAC PHY 10-5

�������

���� �

���

����

� 10-5 ���� �

Page 5: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

370

MACMAC

10Mbit/s 1 / 100Mbit/s4 / 1000Mbit/s

8 /

10.2 MAC

MAC MACIEEE 802.3 IEEE 802.3u 10Mbit/s 100Mbit/s

10-6 PHY

FTP HTTP

10-6

� IEEE 802.3x� CSMA/CD� 32 CRC��� IEEE 802.3 MII

10-7

� Host Interface

Page 6: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

371

Status Module

Transmit Module

Control Module Receive Module

Host Interface Register Module

MAC

Media Independent Module

10-7

� Transmit ModuleCRC

� Receive ModuleCRC

� Control Module� Media Independent Interface

PHY� Status Module� Register Module

10.3 MAC

MAC

10.3.1 ——eth_top

module eth_top ( // wb_clk_i, wb_rst_i, wb_dat_i, wb_dat_o, …. );//input clk_i; // input rst_i; // input [31:0] dat_i; // output [31:0] dat_o; // output err_o; //

Page 7: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

372

……////eth_miim miim1 ( .Clk(wb_clk_i), .Reset(wb_rst_i), .Divider(r_ClkDiv), ……);//eth_registers ethreg1 ( .DataIn(wb_dat_i), .Address(wb_adr_i[9:2]), .Rw(wb_we

_i), …… );//eth_maccontrol maccontrol1 ( .MTxClk(mtx_clk_pad_i), .TPauseRq(TPauseRq), ……);//eth_txethmac txethmac1 ( .MTxClk(mtx_clk_pad_i), .Reset(wb_rst_i), .CarrierSense(TxCarrierS

ense), …… );//eth_rxethmac rxethmac1 ( .MRxClk(mrx_clk_pad_i), .MRxDV(MRxDV_Lb), .MRxD(MRx

D_Lb), ……);

//always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) begin if(wb_rst_i) begin TxPauseRq_sync1 <= #Tp 1'b0; TxPauseRq_sync2 <= #Tp 1'b0; TxPauseRq_sync3 <= #Tp 1'b0; end else begin TxPauseRq_sync1 <= #Tp (r_TxPauseRq & r_TxFlow); TxPauseRq_sync2 <= #Tp TxPauseRq_sync1; TxPauseRq_sync3 <= #Tp TxPauseRq_sync2; end end

Page 8: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

373

always @ (posedge mtx_clk_pad_i or posedge wb_rst_i) begin if(wb_rst_i) TPauseRq <= #Tp 1'b0; else TPauseRq <= #Tp TxPauseRq_sync2 & (~TxPauseRq_sync3); end

//eth_macstatus macstatus1 ( .MRxClk(mrx_clk_pad_i), .Reset(wb_rst_i), ….);endmodule

10.3.2 Media Independent Interface ModulePHY PHY

10-8

10-8

3� MII PHY

� MII PHY

� PHY PHY

�MII

`include "timescale.v" module eth_miim ( Clk, Reset, Divider, NoPre, CtrlData, Rgad, Fiad, WCtrlData, RStat, ScanStat, Mdi,

Page 9: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

374

Mdo, MdoEn, Mdc, Busy, Prsd, LinkFail, Nvalid, WCtrlDataStart, RStatStart, UpdateMIIRX_DATAReg ); //input Clk; //input Reset; // input [7:0] Divider; // input [15:0] CtrlData; // PHYinput [4:0] Rgad; // PHYinput [4:0] Fiad; // PHYinput NoPre; // input WCtrlData; // input RStat; // input ScanStat; // input Mdi; // MIIoutput Mdc; // MIIoutput Mdo; // MIIoutput MdoEn; // MIIoutput Busy; // output LinkFail; // output Nvalid; //

output [15:0] Prsd; // PHY

output WCtrlDataStart; // MII WCTRLDATAoutput RStatStart; // MII RSTAToutput UpdateMIIRX_DATAReg;// MII RX_DATAparameter Tp = 1; //reg Nvalid; ………// MIIalways @ (posedge Clk or posedge Reset) begin if(Reset) begin EndBusy_d <= #Tp 1'b0; EndBusy <= #Tp 1'b0; end else begin EndBusy_d <= #Tp ~InProgress_q2 & InProgress_q3; EndBusy <= #Tp EndBusy_d; end end

// MII RX_DATAalways @ (posedge Clk or posedge Reset) begin if(Reset) UpdateMIIRX_DATAReg <= #Tp 0; else if(EndBusy & ~WCtrlDataStart_q)

Page 10: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

375

UpdateMIIRX_DATAReg <= #Tp 1; else UpdateMIIRX_DATAReg <= #Tp 0; end

//always @ (posedge Clk or posedge Reset) begin if(Reset) begin WCtrlData_q1 <= #Tp 1'b0; WCtrlData_q2 <= #Tp 1'b0; WCtrlData_q3 <= #Tp 1'b0;

RStat_q1 <= #Tp 1'b0; RStat_q2 <= #Tp 1'b0; RStat_q3 <= #Tp 1'b0;

ScanStat_q1 <= #Tp 1'b0; ScanStat_q2 <= #Tp 1'b0; SyncStatMdcEn <= #Tp 1'b0; end else begin WCtrlData_q1 <= #Tp WCtrlData; WCtrlData_q2 <= #Tp WCtrlData_q1; WCtrlData_q3 <= #Tp WCtrlData_q2;

RStat_q1 <= #Tp RStat; RStat_q2 <= #Tp RStat_q1; RStat_q3 <= #Tp RStat_q2;

ScanStat_q1 <= #Tp ScanStat; ScanStat_q2 <= #Tp ScanStat_q1; if(MdcEn) SyncStatMdcEn <= #Tp ScanStat_q2; end end

//always @ (posedge Clk or posedge Reset) begin if(Reset) begin WCtrlDataStart <= #Tp 1'b0; WCtrlDataStart_q <= #Tp 1'b0; RStatStart <= #Tp 1'b0; end else begin if(EndBusy) begin

Page 11: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

376

WCtrlDataStart <= #Tp 1'b0; RStatStart <= #Tp 1'b0; end else begin if(WCtrlData_q2 & ~WCtrlData_q3) WCtrlDataStart <= #Tp 1'b1; if(RStat_q2 & ~RStat_q3) RStatStart <= #Tp 1'b1; WCtrlDataStart_q <= #Tp WCtrlDataStart; end end end

//always @ (posedge Clk or posedge Reset) begin if(Reset) Nvalid <= #Tp 1'b0; else begin if(~InProgress_q2 & InProgress_q3) begin Nvalid <= #Tp 1'b0; end else begin if(ScanStat_q2 & ~SyncStatMdcEn) Nvalid <= #Tp 1'b1; end end end

//always @ (posedge Clk or posedge Reset) begin if(Reset) begin WCtrlDataStart_q1 <= #Tp 1'b0; WCtrlDataStart_q2 <= #Tp 1'b0;

RStatStart_q1 <= #Tp 1'b0; RStatStart_q2 <= #Tp 1'b0;

InProgress_q1 <= #Tp 1'b0; InProgress_q2 <= #Tp 1'b0; InProgress_q3 <= #Tp 1'b0;

LatchByte0_d <= #Tp 1'b0; LatchByte1_d <= #Tp 1'b0;

LatchByte <= #Tp 2'b00;

Page 12: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

377

end else begin if(MdcEn) begin WCtrlDataStart_q1 <= #Tp WCtrlDataStart; WCtrlDataStart_q2 <= #Tp WCtrlDataStart_q1;

RStatStart_q1 <= #Tp RStatStart; RStatStart_q2 <= #Tp RStatStart_q1;

LatchByte[0] <= #Tp LatchByte0_d; LatchByte[1] <= #Tp LatchByte1_d;

LatchByte0_d <= #Tp LatchByte0_d2; LatchByte1_d <= #Tp LatchByte1_d2;

InProgress_q1 <= #Tp InProgress; InProgress_q2 <= #Tp InProgress_q1; InProgress_q3 <= #Tp InProgress_q2; end end end

//assign WriteDataOp = WCtrlDataStart_q1 & ~WCtrlDataStart_q2; assign ReadStatusOp = RStatStart_q1 & ~RStatStart_q2; assign ScanStatusOp = SyncStatMdcEn & ~InProgress & ~InProgress_q1 & ~InProgress_q2; assign StartOp = WriteDataOp | ReadStatusOp | ScanStatusOp;

//assign Busy = WCtrlDataStart | RStatStart | SyncStatMdcEn | EndBusy | InProgress | InProgress_q3 | Nvalid; ////always @ (posedge Clk or posedge Reset) begin if(Reset) begin InProgress <= #Tp 1'b0; WriteOp <= #Tp 1'b0; end else begin if(MdcEn) begin if(StartOp) begin if(~InProgress) WriteOp <= #Tp WriteDataOp; InProgress <= #Tp 1'b1; end else

Page 13: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

378

begin if(EndOp) begin InProgress <= #Tp 1'b0; WriteOp <= #Tp 1'b0; end end end end end

//always @ (posedge Clk or posedge Reset) begin if(Reset) BitCounter[6:0] <= #Tp 7'h0; else begin if(MdcEn) begin if(InProgress) begin if(NoPre & ( BitCounter == 7'h0 )) BitCounter[6:0] <= #Tp 7'h21; else BitCounter[6:0] <= #Tp BitCounter[6:0] + 1'b1; end else BitCounter[6:0] <= #Tp 7'h0; end end end

// 63assign EndOp = BitCounter==63;

assign ByteSelect[0] = InProgress & ((NoPre & (BitCounter == 7'h0)) | (~NoPre & (BitCounter == 7'h20))); assign ByteSelect[1] = InProgress & (BitCounter == 7'h28); assign ByteSelect[2] = InProgress & WriteOp & (BitCounter == 7'h30); assign ByteSelect[3] = InProgress & WriteOp & (BitCounter == 7'h38);

//assign LatchByte1_d2 = InProgress & ~WriteOp & BitCounter == 7'h37; assign LatchByte0_d2 = InProgress & ~WriteOp & BitCounter == 7'h3F;

//eth_clockgen

clkgen(.Clk(Clk), .Reset(Reset), .Divider(Divider[7:0]), .MdcEn(MdcEn), .MdcEn_n(MdcEn_n), .Mdc(Mdc) ); //eth_shiftreg shftrg(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .Mdi(Mdi), .Fiad(Fiad), .Rgad(Rgad),

Page 14: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

379

.CtrlData(CtrlData), .WriteOp(WriteOp), .ByteSelect(ByteSelect), .LatchByte(LatchByte),

.ShiftedBit(ShiftedBit), .Prsd(Prsd), .LinkFail(LinkFail) ); //eth_outputcontrol outctrl(.Clk(Clk), .Reset(Reset), .MdcEn_n(MdcEn_n), .InProgress(InProgress), .ShiftedBit(ShiftedBit), .BitCounter(BitCounter), .WriteOp(WriteOp), .NoPre(

NoPre), .Mdo(Mdo), .MdoEn(MdoEn) ); endmodule

10.3.3

PHYCRC 4 10-9

10-9

4��� CRC 32 CRC�

� TxDone� TxRetry� TxAbort

4`include "timescale.v"

Page 15: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

380

module eth_txethmac (MTxClk, Reset, TxStartFrm, TxEndFrm, TxUnderRun, TxData, CarrierSense, Collision, Pad, CrcEn, FullD, HugEn, DlyCrcEn, MinFL, MaxFL, IPGT, IPGR1, IPGR2, CollValid, MaxRet, NoBckof, ExDfrEn, MTxD, MTxEn, MTxErr, TxDone, TxRetry, TxAbort, TxUsedData, WillTransmit, ResetCollision, RetryCnt, StartTxDone, StartTxAbort, MaxCollisionOccured, LateCollision, DeferIndication, StatePreamble, StateData); parameter Tp = 1;

//input MTxClk; //input Reset; // input TxStartFrm; // input TxEndFrm; // input TxUnderRun; input [7:0] TxData; //…..//reg [3:0] MTxD; …..//assign ResetCollision = ~(StatePreamble | (|StateData) | StatePAD | StateFCS); assign ExcessiveDeferOccured = TxStartFrm & StateDefer & ExcessiveDefer & ~StopExcessiveDeferOccured; assign StartTxDone = ~Collision & (StateFCS & NibCntEq7 | StateData[1] & TxEndFrm & (~Pad | Pad &

NibbleMinFl) & ~CrcEn); assign UnderRun = StateData[0] & TxUnderRun & ~Collision; assign TooBig = ~Collision & MaxFrame & (StateData[0] & ~TxUnderRun | StateFCS); assign StartTxRetry = StartJam & (ColWindow & ~RetryMax) & ~UnderRun; assign LateCollision = StartJam & ~ColWindow & ~UnderRun; assign MaxCollisionOccured = StartJam & ColWindow & RetryMax; assign StateSFD = StatePreamble & NibCntEq15; assign StartTxAbort = TooBig | UnderRun | ExcessiveDeferOccured | LateCollision | MaxCollisionOccured;

//always @ (posedge MTxClk or posedge Reset) begin if(Reset) StopExcessiveDeferOccured <= #Tp 1'b0; else begin if(~TxStartFrm) StopExcessiveDeferOccured <= #Tp 1'b0; else if(ExcessiveDeferOccured) StopExcessiveDeferOccured <= #Tp 1'b1; end end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) ColWindow <= #Tp 1'b1; else begin

Page 16: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

381

if(~Collision & ByteCnt[5:0] == CollValid[5:0] & (StateData[1] | StatePAD & NibCnt[0] | StateFCS & NibCnt[0]))

ColWindow <= #Tp 1'b0; else if(StateIdle | StateIPG) ColWindow <= #Tp 1'b1; end end

//always @ (posedge MTxClk or posedge Reset) begin if(Reset) StatusLatch <= #Tp 1'b0; else begin if(~TxStartFrm) StatusLatch <= #Tp 1'b0; else if(ExcessiveDeferOccured | StateIdle) StatusLatch <= #Tp 1'b1; end end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) TxUsedData <= #Tp 1'b0; else TxUsedData <= #Tp |StartData; end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) TxDone <= #Tp 1'b0; else begin if(TxStartFrm & ~StatusLatch) TxDone <= #Tp 1'b0; else if(StartTxDone) TxDone <= #Tp 1'b1; end end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) TxRetry <= #Tp 1'b0; else begin

Page 17: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

382

if(TxStartFrm & ~StatusLatch) TxRetry <= #Tp 1'b0; else if(StartTxRetry) TxRetry <= #Tp 1'b1; end end //always @ (posedge MTxClk or posedge Reset) begin if(Reset) TxAbort <= #Tp 1'b0; else begin if(TxStartFrm & ~StatusLatch & ~ExcessiveDeferOccured) TxAbort <= #Tp 1'b0; else if(StartTxAbort) TxAbort <= #Tp 1'b1; end end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) RetryCnt[3:0] <= #Tp 4'h0; else begin if(ExcessiveDeferOccured | UnderRun | TooBig | StartTxDone | TxUnderRun | StateJam & NibCntEq7 & (~ColWindow | RetryMax)) RetryCnt[3:0] <= #Tp 4'h0; else if(StateJam & NibCntEq7 & ColWindow & (RandomEq0 | NoBckof) | StateBackOff &

RandomEqByteCnt) RetryCnt[3:0] <= #Tp RetryCnt[3:0] + 1'b1; end endassign RetryMax = RetryCnt[3:0] == MaxRet[3:0]; // 4always @ (StatePreamble or StateData or StateData or StateFCS or StateJam or StateSFD or TxData or Crc or NibCnt or NibCntEq15) begin if(StateData[0]) MTxD_d[3:0] = TxData[3:0]; // else if(StateData[1]) MTxD_d[3:0] = TxData[7:4]; // else if(StateFCS) MTxD_d[3:0] = {~Crc[28], ~Crc[29], ~Crc[30], ~Crc[31]}; // CRC else if(StateJam)

Page 18: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

383

MTxD_d[3:0] = 4'h9; else if(StatePreamble) if(NibCntEq15) MTxD_d[3:0] = 4'hd; // SFD else MTxD_d[3:0] = 4'h5; // else MTxD_d[3:0] = 4'h0; end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) MTxEn <= #Tp 1'b0; else MTxEn <= #Tp StatePreamble | (|StateData) | StatePAD | StateFCS | StateJam; end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) MTxD[3:0] <= #Tp 4'h0; else MTxD[3:0] <= #Tp MTxD_d[3:0]; end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) MTxErr <= #Tp 1'b0; else MTxErr <= #Tp TooBig | UnderRun; end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) WillTransmit <= #Tp 1'b0; else WillTransmit <= #Tp StartPreamble | StatePreamble | (|StateData) | StatePAD | StateFCS | StateJam; end//assign PacketFinished_d = StartTxDone | TooBig | UnderRun | LateCollision | MaxCollisionOccured |

ExcessiveDeferOccured; //always @ (posedge MTxClk or posedge Reset) begin if(Reset) begin PacketFinished <= #Tp 1'b0; PacketFinished_q <= #Tp 1'b0;

Page 19: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

384

end else begin PacketFinished <= #Tp PacketFinished_d; PacketFinished_q <= #Tp PacketFinished; end end//eth_txcounters txcounters1 (.StatePreamble(StatePreamble), .StateIPG(StateIPG), .StateData(StateData), .StatePAD(StatePAD), .StateFCS(StateFCS), .StateJam(StateJam), .StateBackOff(StateBackOff), .StateDefer(StateDefer), .StateIdle(StateIdle), .StartDefer(StartDefer), .StartIPG(StartIPG), .StartFCS(StartFCS), .StartJam(StartJam), .TxStartFrm(TxStartFrm), .MTxClk(MTxClk), .Reset(Reset), .MinFL(MinFL), .MaxFL(MaxFL), .HugEn(HugEn), .ExDfrEn(ExDfrEn), .PacketFinished_q(PacketFinished_q), .DlyCrcEn(DlyCrcEn), .StartBackoff(StartBackoff), .StateSFD(StateSFD), .ByteCnt(ByteCnt), .NibCnt(NibCnt), .ExcessiveDefer(ExcessiveDefer), .NibCntEq7(NibCntEq7), .NibCntEq15(NibCntEq15), .MaxFrame(MaxFrame), .NibbleMinFl(NibbleMinFl), .DlyCrcCnt(DlyCrcCnt)); //eth_txstatem txstatem1 (.MTxClk(MTxClk), .Reset(Reset), .ExcessiveDefer(ExcessiveDefer), .CarrierSense(CarrierSense),.NibCnt(NibCnt[6:0]), .IPGT(IPGT), .IPGR1(IPGR1), .IPGR2(IPGR2), .FullD(Ful

lD), .TxStartFrm(TxStartFrm), .TxEndFrm(TxEndFrm), .TxUnderRun(TxUnderRun), .Collision(Collision), .UnderRun(UnderRun), .StartTxDone(StartTxDone), .TooBig(TooBig), .NibCntEq7(NibCntEq7), .NibCntEq15(NibCntEq15), .MaxFrame(MaxFrame), .Pad(Pad), .CrcEn(CrcEn),.NibbleMinFl(NibbleMinFl), .RandomEq0(RandomEq0), .ColWindow(ColWindow), .RetryMax(RetryMax),.NoBckof(NoBckof), .RandomEqByteCnt(RandomEqByteCnt), .StateIdle(StateIdle),.StateIPG(StateIPG), .StatePreamble(StatePreamble), .StateData(StateData), .StatePAD(StatePAD),.StateFCS(StateFCS), .StateJam(StateJam), .StateJam_q(StateJam_q), .StateBackOff(StateBackOff),.StateDefer(StateDefer), .StartFCS(StartFCS), .StartJam(StartJam), .StartBackoff(StartBackoff),.StartDefer(StartDefer), .DeferIndication(DeferIndication), .StartPreamble(StartPreamble), .StartData(StartData), .StartIPG(StartIPG)); // CRCeth_crc txcrc (.Clk(MTxClk), .Reset(Reset), .Data(Data_Crc), .Enable(Enable_Crc), .Initialize(Initialize_Crc), .Crc(Crc), .CrcError(CrcError) ); //eth_random random1

(.MTxClk(MTxClk), .Reset(Reset), .StateJam(StateJam), .StateJam_q(StateJam_q), .RetryCnt(RetryCnt), .NibCnt(NibCnt), .ByteCnt(ByteCnt[9:0]), .RandomEq0(RandomEq0), .RandomEqByteCnt(RandomEqByteCnt));

endmodule

1

� StateIdle� StatePreamble� StateData0� StateData1� StateFCS� StateDefer� StateIPG� StatePAD 46 0

Page 20: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

10-10

Page 21: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

386

1 StateIdle TxStartFrmStatePreamble

2 StatePreamble PHYSFD StateData0 TxUsedData

4 StateData14 StateData0 StateData1

TxEndFrm3 CRC

StateFCS CRC StateDeferStateIPG StateIdle

CRCStateDefer

4 StateIPG StateIdle

CRC StatePAD46 StateFCS CRC StateDefer

StateIPG StateIdle

5 StateIdleCRC StateFCS

CRC StateDefer StateIPGStateIdle

CRC StateDeferStateIPG StateIdle

`include "timescale.v" module eth_txstatem (MTxClk, Reset, ExcessiveDefer, CarrierSense, NibCnt, IPGT, IPGR1, IPGR2, FullD, TxStartFrm, TxEndFrm, TxUnderRun, Collision, UnderRun, StartTxDone, TooBig, NibCntEq7, NibCntEq15, MaxFrame, Pad, CrcEn, NibbleMinFl, RandomEq0, ColWindow, RetryMax, NoBckof, RandomEqByteCnt, StateIdle, StateIPG, StatePreamble, StateData, StatePAD, StateFCS, StateJam, StateJam_q, StateBackOff, StateDefer, StartFCS, StartJam, StartBackoff, StartDefer, DeferIndication, StartPreamble, StartData, StartIPG ); parameter Tp = 1; //input MTxClk; input Reset; output StartIPG; //wire StartIdle; // Idlewire StartPAD; // PAD……reg Rule1; //

Page 22: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

387

assign StartIPG = StateDefer & ~ExcessiveDefer & ~CarrierSense; assign StartIdle = StateIPG & (Rule1 & NibCnt[6:0] >= IPGT | ~Rule1 & NibCnt[6:0] >= IPGR2); assign StartPreamble = StateIdle & TxStartFrm & ~CarrierSense; assign StartData[0] = ~Collision & (StatePreamble & NibCntEq15 | StateData[1] & ~TxEndFrm); assign StartData[1] = ~Collision & StateData[0] & ~TxUnderRun & ~MaxFrame; assign StartPAD = ~Collision & StateData[1] & TxEndFrm & Pad & ~NibbleMinFl; assign StartFCS = ~Collision & StateData[1] & TxEndFrm & (~Pad | Pad & NibbleMinFl) & CrcEn | ~Collision & StatePAD & NibbleMinFl & CrcEn; assign StartJam = (Collision | UnderRun) & ((StatePreamble & NibCntEq15) | (|StateData[1:0]) | StatePAD |

StateFCS); assign StartBackoff = StateJam & ~RandomEq0 & ColWindow & ~RetryMax & NibCntEq7 & ~NoBckof; assign StartDefer = StateIPG & ~Rule1 & CarrierSense & NibCnt[6:0] <= IPGR1 & NibCnt[6:0] != IPGR2 | StateIdle & CarrierSense | StateJam & NibCntEq7 & (NoBckof | RandomEq0 | ~ColWindow | RetryMax) | StateBackOff & (TxUnderRun | RandomEqByteCnt) | StartTxDone | TooBig; assign DeferIndication = StateIdle & CarrierSense; //always @ (posedge MTxClk or posedge Reset) begin if(Reset) begin StateIPG <= #Tp 1'b0; StateIdle <= #Tp 1'b0; StatePreamble <= #Tp 1'b0; StateData[1:0] <= #Tp 2'b0; StatePAD <= #Tp 1'b0; StateFCS <= #Tp 1'b0; StateJam <= #Tp 1'b0; StateJam_q <= #Tp 1'b0; StateBackOff <= #Tp 1'b0; StateDefer <= #Tp 1'b1; end else begin StateData[1:0] <= #Tp StartData[1:0]; StateJam_q <= #Tp StateJam; if(StartDefer | StartIdle) StateIPG <= #Tp 1'b0; else if(StartIPG) StateIPG <= #Tp 1'b1; if(StartDefer | StartPreamble) StateIdle <= #Tp 1'b0; else if(StartIdle) StateIdle <= #Tp 1'b1; if(StartData[0] | StartJam) StatePreamble <= #Tp 1'b0; else if(StartPreamble) StatePreamble <= #Tp 1'b1;

Page 23: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

388

if(StartFCS | StartJam) StatePAD <= #Tp 1'b0; else if(StartPAD) StatePAD <= #Tp 1'b1; if(StartJam | StartDefer) StateFCS <= #Tp 1'b0; else if(StartFCS) StateFCS <= #Tp 1'b1; if(StartBackoff | StartDefer) StateJam <= #Tp 1'b0; else if(StartJam) StateJam <= #Tp 1'b1; if(StartDefer) StateBackOff <= #Tp 1'b0; else if(StartBackoff) StateBackOff <= #Tp 1'b1; if(StartIPG) StateDefer <= #Tp 1'b0; else if(StartDefer) StateDefer <= #Tp 1'b1; end end//always @ (posedge MTxClk or posedge Reset) begin if(Reset) Rule1 <= #Tp 1'b0; else begin if(StateIdle | StateBackOff) Rule1 <= #Tp 1'b0; else if(StatePreamble | FullD) Rule1 <= #Tp 1'b1; end endendmodule

2

DlyCrcCnt CRC4 NibCnt ByteCnt

//always @ (posedge MTxClk or posedge Reset) begin if(Reset)

Page 24: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

389

NibCnt <= #Tp 16'h0; else begin if(ResetNibCnt) NibCnt <= #Tp 16'h0; else if(IncrementNibCnt) NibCnt <= #Tp NibCnt + 1'b1; end endassign NibCntEq7 = &NibCnt[2:0]; assign NibCntEq15 = &NibCnt[3:0]; assign NibbleMinFl = NibCnt >= (((MinFL-3'h4)<<1) -1); // FCS should not be included in NibbleMinFl assign ExcessiveDeferCnt = NibCnt[13:0] == 16'h17b7; assign ExcessiveDefer = NibCnt[13:0] == 16'h17b7 & ~ExDfrEn; // 6071 nibbles assign IncrementByteCnt = StateData[1] & ~ByteCntMax & ~|DlyCrcCnt[2:0] | StateBackOff & (&NibCnt[6:0]) | (StatePAD | StateFCS) & NibCnt[0] & ~ByteCntMax; assign ResetByteCnt = StartBackoff | StateIdle & TxStartFrm | PacketFinished_q; //always @ (posedge MTxClk or posedge Reset) begin if(Reset) ByteCnt[15:0] <= #Tp 16'h0; else begin if(ResetByteCnt) ByteCnt[15:0] <= #Tp 16'h0; else if(IncrementByteCnt) ByteCnt[15:0] <= #Tp ByteCnt[15:0] + 1'b1; end endassign MaxFrame = ByteCnt[15:0] == MaxFL[15:0] & ~HugEn; assign ByteCntMax = &ByteCnt[15:0]; //CRCalways @ (posedge MTxClk or posedge Reset) begin if(Reset) DlyCrcCnt <= #Tp 3'h0; else begin if(StateData[1] & DlyCrcCnt == 3'h4 | StartJam | PacketFinished_q) DlyCrcCnt <= #Tp 3'h0; else if(DlyCrcEn & (StateSFD | StateData[1] & (|DlyCrcCnt[2:0]))) DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1; end end

3 CRC

CRC CRC

Page 25: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

390

CRC CRCCRC

include "timescale.v" module eth_crc (Clk, Reset, Data, Enable, Initialize, Crc, CrcError); parameter Tp = 1; //input Clk; input Reset; input [3:0] Data; input Enable; input Initialize; output [31:0] Crc; output CrcError; reg [31:0] Crc; wire [31:0] CrcNext; // CRCassign CrcNext[0] = Enable & (Data[0] ^ Crc[28]); assign CrcNext[1] = Enable & (Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29]); assign CrcNext[2] = Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30]); assign CrcNext[3] = Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31]); assign CrcNext[4] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[0]; assign CrcNext[5] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[1]; assign CrcNext[6] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[ 2]; assign CrcNext[7] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[3]; assign CrcNext[8] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[4]; assign CrcNext[9] = (Enable & (Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30])) ^ Crc[5]; assign CrcNext[10] = (Enable & (Data[3] ^ Data[2] ^ Data[0] ^ Crc[28] ^ Crc[30] ^ Crc[31])) ^ Crc[6]; assign CrcNext[11] = (Enable & (Data[3] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[31])) ^ Crc[7]; assign CrcNext[12] = (Enable & (Data[2] ^ Data[1] ^ Data[0] ^ Crc[28] ^ Crc[29] ^ Crc[30])) ^ Crc[8]; assign CrcNext[13] = (Enable & (Data[3] ^ Data[2] ^ Data[1] ^ Crc[29] ^ Crc[30] ^ Crc[31])) ^ Crc[9]; assign CrcNext[14] = (Enable & (Data[3] ^ Data[2] ^ Crc[30] ^ Crc[31])) ^ Crc[10]; assign CrcNext[15] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[11]; assign CrcNext[16] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[12]; assign CrcNext[17] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[13]; assign CrcNext[18] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[14]; assign CrcNext[19] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[15]; assign CrcNext[20] = Crc[16]; assign CrcNext[21] = Crc[17]; assign CrcNext[22] = (Enable & (Data[0] ^ Crc[28])) ^ Crc[18]; assign CrcNext[23] = (Enable & (Data[1] ^ Data[0] ^ Crc[29] ^ Crc[28])) ^ Crc[19]; assign CrcNext[24] = (Enable & (Data[2] ^ Data[1] ^ Crc[30] ^ Crc[29])) ^ Crc[20]; assign CrcNext[25] = (Enable & (Data[3] ^ Data[2] ^ Crc[31] ^ Crc[30])) ^ Crc[21]; assign CrcNext[26] = (Enable & (Data[3] ^ Data[0] ^ Crc[31] ^ Crc[28])) ^ Crc[22]; assign CrcNext[27] = (Enable & (Data[1] ^ Crc[29])) ^ Crc[23]; assign CrcNext[28] = (Enable & (Data[2] ^ Crc[30])) ^ Crc[24]; assign CrcNext[29] = (Enable & (Data[3] ^ Crc[31])) ^ Crc[25]; assign CrcNext[30] = Crc[26]; assign CrcNext[31] = Crc[27]; // CRCalways @ (posedge Clk or posedge Reset) begin if (Reset)

Page 26: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

391

Crc <= #1 32'hffffffff; else if(Initialize) Crc <= #Tp 32'hffffffff; else Crc <= #Tp CrcNext; end//assign CrcError = Crc[31:0] != 32'hc704dd7b; // CRC not equal to magic number endmodule

4

0x99999999

Binary Exponential algorithm

4

`include "timescale.v" module eth_random (MTxClk, Reset, StateJam, StateJam_q, RetryCnt, NibCnt, ByteCnt, RandomEq0, RandomEqByteCnt); parameter Tp = 1; //input MTxClk; input Reset; input StateJam; input StateJam_q; input [3:0] RetryCnt; input [15:0] NibCnt; input [9:0] ByteCnt; output RandomEq0; output RandomEqByteCnt; //wire Feedback; reg [9:0] x; wire [9:0] Random; reg [9:0] RandomLatched; always @ (posedge MTxClk or posedge Reset) begin if(Reset) x[9:0] <= #Tp 0; else x[9:0] <= #Tp {x[8:0], Feedback}; end

Page 27: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

392

assign Feedback = x[2] ~ ^ x[9]; //assign Random [0] = x[0]; assign Random [1] = (RetryCnt > 1) ? x[1] : 1'b0; assign Random [2] = (RetryCnt > 2) ? x[2] : 1'b0; assign Random [3] = (RetryCnt > 3) ? x[3] : 1'b0; assign Random [4] = (RetryCnt > 4) ? x[4] : 1'b0; assign Random [5] = (RetryCnt > 5) ? x[5] : 1'b0; assign Random [6] = (RetryCnt > 6) ? x[6] : 1'b0; assign Random [7] = (RetryCnt > 7) ? x[7] : 1'b0; assign Random [8] = (RetryCnt > 8) ? x[8] : 1'b0; assign Random [9] = (RetryCnt > 9) ? x[9] : 1'b0; // 0 0x99999999always @ (posedge MTxClk or posedge Reset) begin if(Reset) RandomLatched <= #Tp 10'h000; else begin if(StateJam & StateJam_q) RandomLatched <= #Tp Random; end end// 0assign RandomEq0 = RandomLatched == 10'h0; assign RandomEqByteCnt = ByteCnt[9:0] == RandomLatched & (&NibCnt[6:0]); endmodule

10.3.4PHY

4 8CRC

10-11

10-11

Page 28: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

393

4��� CRC 32 CRC CRC

�4

`include "timescale.v" module eth_rxethmac (MRxClk, MRxDV, MRxD, Reset, Transmitting, MaxFL, r_IFG, HugEn, DlyCrcEn, RxData, RxValid, RxStartFrm, RxEndFrm, ByteCnt, ByteCntEq0, ByteCntGreat2, ByteCntMaxFrame, CrcError, StateIdle, StatePreamble, StateSFD, StateData, MAC, r_Pro, r_Bro,r_HASH0, r_HASH1, RxAbort, AddressMiss, PassAll, ControlFrmAddressOK ); parameter Tp = 1;

//input MRxClk; input MRxDV; …..input [47:0] MAC; // input [31:0] r_HASH0; // input [31:0] r_HASH1; // input PassAll; ….

//reg [7:0] RxData; reg RxValid; ….

//eth_rxstatem rxstatem1 (.MRxClk(MRxClk), .Reset(Reset), .MRxDV(MRxDV), .ByteCntEq0(ByteCntEq0), .ByteCntGreat2(ByteCntGreat2), .Transmitting(Transmitting), .MRxDEq5(MRxDEq5), .MRxDEqD(MRxDEqD), .IFGCounterEq24(IFGCounterEq24), .ByteCntMaxFrame(ByteCntMaxFrame), .StateData(StateData), .StateIdle(StateIdle), .StatePreamble(StatePreamble),.StateSFD(StateSFD), .StateDrop(StateDrop));

//eth_rxcounters rxcounters1 (.MRxClk(MRxClk), .Reset(Reset), .MRxDV(MRxDV), .StateIdle(StateIdle), .StateSFD(StateSFD), .StateData(StateData), .StateDrop(StateDrop),.StatePreamble(StatePreamble), .MRxDEqD(MRxDEqD), .DlyCrcEn(DlyCrcEn),.DlyCrcCnt(DlyCrcCnt), .Transmitting(Transmitting), .MaxFL(MaxFL), .r_IFG(r_IFG),.HugEn(HugEn), .IFGCounterEq24(IFGCounterEq24), .ByteCntEq0(ByteCntEq0),.ByteCntEq1(ByteCntEq1), .ByteCntEq2(ByteCntEq2), .ByteCntEq3(ByteCntEq3),.ByteCntEq4(ByteCntEq4), .ByteCntEq5(ByteCntEq5), .ByteCntEq6(ByteCntEq6),.ByteCntEq7(ByteCntEq7), .ByteCntGreat2(ByteCntGreat2), .ByteCntSmall7(ByteCntSmall7), .ByteCntMaxFrame(ByteCntMaxFrame),.ByteCnt(ByteCnt));

//eth_rxaddrcheck rxaddrcheck1 (.MRxClk(MRxClk),.Reset(Reset),.RxData(RxData), .Broadcast (Broadcast),.r_Bro (r_Bro),.r_Pro(r_Pro),.ByteCntEq6(ByteCntEq6),.ByteCntEq7(ByteCntEq7), .ByteCntEq2(ByteCntEq2),.ByteCntEq3(ByteCntEq3),.ByteCntEq4(ByteCntEq4),.ByteCntEq5(ByteCntEq5),

Page 29: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

394

.HASH0(r_HASH0),.HASH1(r_HASH1),.CrcHash(CrcHash[5:0]), .CrcHashGood(CrcHashGood), .StateData(StateData),.Multicast(Multicast),.MAC(MAC),.RxAbort(RxAbort),.RxEndFrm(RxEndFrm), .AddressMiss(AddressMiss),.PassAll(PassAll),.ControlFrmAddressOK(ControlFrmAddressOK));

// CRCassign Enable_Crc = MRxDV & (|StateData & ~ByteCntMaxFrame); assign Initialize_Crc = StateSFD | DlyCrcEn & (|DlyCrcCnt[3:0]) & DlyCrcCnt[3:0] < 4'h9; assign Data_Crc[0] = MRxD[3]; assign Data_Crc[1] = MRxD[2]; assign Data_Crc[2] = MRxD[1]; assign Data_Crc[3] = MRxD[0];

// Crceth_crc crcrx (.Clk(MRxClk), .Reset(Reset), .Data(Data_Crc), .Enable(Enable_Crc), .Initialize(Initialize_Crc), .Crc(Crc), .CrcError(CrcError) );

// CRCalways @ (posedge MRxClk) begin CrcHashGood <= #Tp StateData[0] & ByteCntEq6; end

always @ (posedge MRxClk) begin if(Reset | StateIdle) CrcHash[8:0] <= #Tp 9'h0; else if(StateData[0] & ByteCntEq6) CrcHash[8:0] <= #Tp Crc[31:23]; end

//always @ (posedge MRxClk or posedge Reset) begin if(Reset) begin RxData_d[7:0] <= #Tp 8'h0; DelayData <= #Tp 1'b0; LatchedNibble[3:0] <= #Tp 4'h0; LatchedByte[7:0] <= #Tp 8'h0; RxData[7:0] <= #Tp 8'h0; end else begin LatchedNibble[3:0] <= #Tp MRxD[3:0]; // LatchedByte[7:0] <= #Tp {MRxD[3:0], LatchedNibble[3:0]}; // DelayData <= #Tp StateData[0];

if(GenerateRxValid) RxData_d[7:0] <= #Tp LatchedByte[7:0] & {8{|StateData}}; else

Page 30: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

395

if(~DelayData) RxData_d[7:0] <= #Tp 8'h0; // RxData[7:0] <= #Tp RxData_d[7:0]; // end endalways @ (posedge MRxClk or posedge Reset) begin if(Reset) Broadcast <= #Tp 1'b0; else begin if(StateData[0] & ~(&LatchedByte[7:0]) & ByteCntSmall7) Broadcast <= #Tp 1'b0; else if(StateData[0] & (&LatchedByte[7:0]) & ByteCntEq1) Broadcast <= #Tp 1'b1; else if(RxAbort | RxEndFrm) Broadcast <= #Tp 1'b0; end end

//always @ (posedge MRxClk or posedge Reset) begin if(Reset) Multicast <= #Tp 1'b0; else begin if(Reset) Multicast <= #Tp 1'b0; else if(StateData[0] & ByteCntEq1 & LatchedByte == 8'h01) Multicast <= #Tp 1'b1; else if(RxAbort | RxEndFrm) Multicast <= #Tp 1'b0; end end

assign GenerateRxValid = StateData[0] & (~ByteCntEq0 | DlyCrcCnt >= 4'h3); //always @ (posedge MRxClk or posedge Reset) begin if(Reset) begin RxValid_d <= #Tp 1'b0; RxValid <= #Tp 1'b0; end else begin RxValid_d <= #Tp GenerateRxValid;

Page 31: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

396

RxValid <= #Tp RxValid_d; end end

assign GenerateRxStartFrm = StateData[0] & (ByteCntEq1 & ~DlyCrcEn | DlyCrcCnt == 4'h3 & DlyCrcEn); //always @ (posedge MRxClk or posedge Reset) begin if(Reset) begin RxStartFrm_d <= #Tp 1'b0; RxStartFrm <= #Tp 1'b0; end else begin RxStartFrm_d <= #Tp GenerateRxStartFrm; RxStartFrm <= #Tp RxStartFrm_d; end end

assign GenerateRxEndFrm = StateData[0] & (~MRxDV & ByteCntGreat2 | ByteCntMaxFrame); assign DribbleRxEndFrm = StateData[1] & ~MRxDV & ByteCntGreat2;

//always @ (posedge MRxClk or posedge Reset) begin if(Reset) begin RxEndFrm_d <= #Tp 1'b0; RxEndFrm <= #Tp 1'b0; end else begin RxEndFrm_d <= #Tp GenerateRxEndFrm; RxEndFrm <= #Tp RxEndFrm_d | DribbleRxEndFrm; end endendmodule

1

SFD CRC

2

3 CRC

CRC 32 CRC

Page 32: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

397

CRC CRCCRC

4

`include "timescale.v" module eth_rxaddrcheck(MRxClk, Reset, RxData, Broadcast ,r_Bro ,r_Pro, ByteCntEq2, ByteCntEq3, ByteCntEq4, ByteCntEq5, ByteCntEq6, ByteCntEq7, HASH0, HASH1, CrcHash, CrcHashGood, StateData, RxEndFrm, Multicast, MAC, RxAbort, AddressMiss, PassAll, ControlFrmAddressOK); parameter Tp = 1;

// input MRxClk; ….

// wire BroadcastOK; ….

//assign RxAddressInvalid = ~(UnicastOK | BroadcastOK | MulticastOK | r_Pro);

//assign BroadcastOK = Broadcast & ~r_Bro;

//assign RxCheckEn = | StateData;

// always @ (posedge MRxClk or posedge Reset) begin if(Reset) RxAbort <= #Tp 1'b0; else if(RxAddressInvalid & ByteCntEq7 & RxCheckEn) RxAbort <= #Tp 1'b1; else RxAbort <= #Tp 1'b0; end

// ff BDalways @ (posedge MRxClk or posedge Reset) begin if(Reset) AddressMiss <= #Tp 1'b0; else if(ByteCntEq7 & RxCheckEn) AddressMiss <= #Tp (~(UnicastOK | BroadcastOK | MulticastOK | (PassAll & ControlFrmAddressOK)));end

//

Page 33: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

398

always @ (posedge MRxClk or posedge Reset) begin if(Reset) MulticastOK <= #Tp 1'b0; else if(RxEndFrm | RxAbort) MulticastOK <= #Tp 1'b0; else if(CrcHashGood & Multicast) MulticastOK <= #Tp HashBit; end

//always @ (posedge MRxClk or posedge Reset) begin if(Reset) UnicastOK <= #Tp 1'b0; else if(RxCheckEn & ByteCntEq2) UnicastOK <= #Tp RxData[7:0] == MAC[47:40]; else if(RxCheckEn & ByteCntEq3) UnicastOK <= #Tp ( RxData[7:0] == MAC[39:32]) & UnicastOK; else if(RxCheckEn & ByteCntEq4) UnicastOK <= #Tp ( RxData[7:0] == MAC[31:24]) & UnicastOK; else if(RxCheckEn & ByteCntEq5) UnicastOK <= #Tp ( RxData[7:0] == MAC[23:16]) & UnicastOK; else if(RxCheckEn & ByteCntEq6) UnicastOK <= #Tp ( RxData[7:0] == MAC[15:8]) & UnicastOK; else if(RxCheckEn & ByteCntEq7) UnicastOK <= #Tp ( RxData[7:0] == MAC[7:0]) & UnicastOK; else if(RxEndFrm | RxAbort) UnicastOK <= #Tp 1'b0; endassign IntHash = (CrcHash[5])? HASH1 : HASH0; always@(CrcHash or IntHash) begin case(CrcHash[4:3]) 2'b00: ByteHash = IntHash[7:0]; 2'b01: ByteHash = IntHash[15:8]; 2'b10: ByteHash = IntHash[23:16]; 2'b11: ByteHash = IntHash[31:24]; endcase endassign HashBit = ByteHash[CrcHash[2:0]]; endmodule

Page 34: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

399

10.3.5

100Mbit/s

��

`include "timescale.v" module eth_maccontrol (MTxClk, MRxClk, TxReset, RxReset, TPauseRq, TxDataIn, TxStartFrmIn, TxUsedDataIn, TxEndFrmIn, TxDoneIn, TxAbortIn, RxData, RxValid, RxStartFrm, RxEndFrm, ReceiveEnd, ReceivedPacketGood, ReceivedLengthOK, TxFlow, RxFlow, DlyCrcEn, TxPauseTV, MAC, PadIn, PadOut, CrcEnIn, CrcEnOut, TxDataOut, TxStartFrmOut, TxEndFrmOut, TxDoneOut, TxAbortOut, TxUsedDataOut, WillSendControlFrame, TxCtrlEndFrm,ReceivedPauseFrm, ControlFrmAddressOK, SetPauseTimer, r_PassAll, RxStatusWriteLatched_sync2 ); parameter Tp = 1; //input MTxClk; //input MRxClk; //……//reg TxUsedDataOutDetected; ……//always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) TxUsedDataOutDetected <= #Tp 1'b0; else if(TxDoneIn | TxAbortIn) TxUsedDataOutDetected <= #Tp 1'b0; else if(TxUsedDataOut) TxUsedDataOutDetected <= #Tp 1'b1; end //always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) begin TxAbortInLatched <= #Tp 1'b0; TxDoneInLatched <= #Tp 1'b0; end else begin TxAbortInLatched <= #Tp TxAbortIn; TxDoneInLatched <= #Tp TxDoneIn; end end//

Page 35: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

400

always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) MuxedAbort <= #Tp 1'b0; else if(TxStartFrmIn) MuxedAbort <= #Tp 1'b0; else if(TxAbortIn & ~TxAbortInLatched & TxUsedDataOutDetected) MuxedAbort <= #Tp 1'b1; end//always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) MuxedDone <= #Tp 1'b0; else if(TxStartFrmIn) MuxedDone <= #Tp 1'b0; else if(TxDoneIn & (~TxDoneInLatched) & TxUsedDataOutDetected) MuxedDone <= #Tp 1'b1; end

//assign TxDoneOut = CtrlMux? ((~TxStartFrmIn) & (~BlockTxDone) & MuxedDone) : ((~TxStartFrmIn) & (~BlockTxDone) & TxDoneIn);

//assign TxAbortOut = CtrlMux? ((~TxStartFrmIn) & (~BlockTxDone) & MuxedAbort) : ((~TxStartFrmIn) & (~BlockTxDone) & TxAbortIn);

//assign TxUsedDataOut = ~CtrlMux & TxUsedDataIn; //assign TxStartFrmOut = CtrlMux? TxCtrlStartFrm : (TxStartFrmIn & ~Pause);

//assign TxEndFrmOut = CtrlMux? TxCtrlEndFrm : TxEndFrmIn;

//assign TxDataOut[7:0] = CtrlMux? ControlData[7:0] : TxDataIn[7:0]; assign PadOut = PadIn | SendingCtrlFrm;

//CRCassign CrcEnOut = CrcEnIn | SendingCtrlFrm;

//eth_receivecontrol receivecontrol1 ( .MTxClk(MTxClk), .MRxClk(MRxClk), .TxReset(TxReset), .RxReset(RxReset), .RxData(RxData), .RxValid(RxValid), .RxStartFrm(RxStartFrm), .RxEndFrm(RxEndFrm), .RxFlow(RxFlow),

Page 36: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

401

.ReceiveEnd(ReceiveEnd), .MAC(MAC), .DlyCrcEn(DlyCrcEn), .TxDoneIn(TxDoneIn), .TxAbortIn(TxAbortIn), .TxStartFrmOut(TxStartFrmOut), .ReceivedLengthOK(ReceivedLengthOK), .ReceivedPacketGood(ReceivedPacketGood), .TxUsedDataOutDetected(TxUsedDataOutDetected), .Pause(Pause), .ReceivedPauseFrm(ReceivedPauseFrm), .AddressOK(ControlFrmAddressOK), .r_PassAll(r_PassAll), .RxStatusWriteLatched_sync2(RxStatusWriteLatched_sync2), .SetPauseTimer(SetPaus

eTimer) );

//eth_transmitcontrol transmitcontrol1 ( .MTxClk(MTxClk), .TxReset(TxReset), .TxUsedDataIn(TxUsedDataIn), .TxUsedDataOut(TxUsedDataOut), .TxDoneIn(TxDoneIn), .TxAbortIn(TxAbortIn), .TxStartFrmIn(TxStartFrmIn), .TPauseRq(TPauseRq), .TxUsedDataOutDetected(TxUsedDataOutDetected), .TxFlow(TxFlow), .DlyCrcEn(DlyCrcEn), .TxPauseTV(

TxPauseTV), .MAC(MAC), .TxCtrlStartFrm(TxCtrlStartFrm), .TxCtrlEndFrm(TxCtrlEndFrm), .SendingCtrlFrm(SendingCt

rlFrm), .CtrlMux(CtrlMux), .ControlData(ControlData), .WillSendControlFrame(WillSendControlFrame), .BlockTxD

one(BlockTxDone) );endmodule

1

PHY

`include "timescale.v" module eth_transmitcontrol (MTxClk, TxReset, TxUsedDataIn, TxUsedDataOut, TxDoneIn, TxAbortIn, TxStartFrmIn, TPauseRq, TxUsedDataOutDetected, TxFlow, DlyCrcEn, TxPauseTV, MAC, TxCtrlStartFrm, TxCtrlEndFrm, SendingCtrlFrm, CtrlMux, ControlData, WillSendControlFrame, BlockTxDone); parameter Tp = 1; //input MTxClk; ……//reg SendingCtrlFrm; ……//always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) WillSendControlFrame <= #Tp 1'b0; else if(TxCtrlEndFrm & CtrlMux) WillSendControlFrame <= #Tp 1'b0; else if(TPauseRq & TxFlow) WillSendControlFrame <= #Tp 1'b1; end

//always @ (posedge MTxClk or posedge TxReset)

Page 37: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

402

begin if(TxReset) TxCtrlStartFrm <= #Tp 1'b0; else if(TxUsedDataIn_q & CtrlMux) TxCtrlStartFrm <= #Tp 1'b0; else if(WillSendControlFrame & ~TxUsedDataOut & (TxDoneIn | TxAbortIn | TxStartFrmIn |

(~TxUsedDataOutDetected))) TxCtrlStartFrm <= #Tp 1'b1; end

//always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) TxCtrlEndFrm <= #Tp 1'b0; else if(ControlEnd | ControlEnd_q) TxCtrlEndFrm <= #Tp 1'b1; else TxCtrlEndFrm <= #Tp 1'b0; end

//always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) CtrlMux <= #Tp 1'b0; else if(WillSendControlFrame & ~TxUsedDataOut) CtrlMux <= #Tp 1'b1; else if(TxDoneIn) CtrlMux <= #Tp 1'b0; end

// CRC PAD always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) SendingCtrlFrm <= #Tp 1'b0; else if(WillSendControlFrame & TxCtrlStartFrm) SendingCtrlFrm <= #Tp 1'b1; else if(TxDoneIn) SendingCtrlFrm <= #Tp 1'b0; end

always @ (posedge MTxClk or posedge TxReset)

Page 38: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

403

begin if(TxReset) TxUsedDataIn_q <= #Tp 1'b0; else TxUsedDataIn_q <= #Tp TxUsedDataIn; end

//always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) BlockTxDone <= #Tp 1'b0; else if(TxCtrlStartFrm) BlockTxDone <= #Tp 1'b1; else if(TxStartFrmIn) BlockTxDone <= #Tp 1'b0; endalways @ (posedge MTxClk) begin ControlEnd_q <= #Tp ControlEnd; TxCtrlStartFrm_q <= #Tp TxCtrlStartFrm; endassign IncrementDlyCrcCnt = CtrlMux & TxUsedDataIn & ~DlyCrcCnt[2];

// CRCalways @ (posedge MTxClk or posedge TxReset) begin if(TxReset) DlyCrcCnt <= #Tp 4'h0; else if(ResetByteCnt) DlyCrcCnt <= #Tp 4'h0; else if(IncrementDlyCrcCnt) DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1; endassign ResetByteCnt = TxReset | (~TxCtrlStartFrm & (TxDoneIn | TxAbortIn)); assign IncrementByteCnt = CtrlMux & (TxCtrlStartFrm & ~TxCtrlStartFrm_q & ~TxUsedDataIn |

TxUsedDataIn & ~ControlEnd); assign IncrementByteCntBy2 = CtrlMux & TxCtrlStartFrm & (~TxCtrlStartFrm_q) & TxUsedDataIn; //

When TxUsedDataIn and CtrlMux are set at the same time

assign EnableCnt = (~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0])); //always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) ByteCnt <= #Tp 6'h0; else if(ResetByteCnt)

Page 39: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

404

ByteCnt <= #Tp 6'h0; else if(IncrementByteCntBy2 & EnableCnt) ByteCnt <= #Tp (ByteCnt[5:0] ) + 2'h2; else if(IncrementByteCnt & EnableCnt) ByteCnt <= #Tp (ByteCnt[5:0] ) + 1'b1; endassign ControlEnd = ByteCnt[5:0] == 6'h22;

//always @ (ByteCnt or DlyCrcEn or MAC or TxPauseTV or DlyCrcCnt) begin case(ByteCnt) 6'h0: if(~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0])) MuxedCtrlData[7:0] = 8'h01; else MuxedCtrlData[7:0] = 8'h0; 6'h2: MuxedCtrlData[7:0] = 8'h80; 6'h4: MuxedCtrlData[7:0] = 8'hC2; 6'h6: MuxedCtrlData[7:0] = 8'h00; 6'h8: MuxedCtrlData[7:0] = 8'h00; 6'hA: MuxedCtrlData[7:0] = 8'h01; 6'hC: MuxedCtrlData[7:0] = MAC[47:40]; 6'hE: MuxedCtrlData[7:0] = MAC[39:32]; 6'h10: MuxedCtrlData[7:0] = MAC[31:24]; 6'h12: MuxedCtrlData[7:0] = MAC[23:16]; 6'h14: MuxedCtrlData[7:0] = MAC[15:8]; 6'h16: MuxedCtrlData[7:0] = MAC[7:0]; 6'h18: MuxedCtrlData[7:0] = 8'h88; // Type/Length 6'h1A: MuxedCtrlData[7:0] = 8'h08; 6'h1C: MuxedCtrlData[7:0] = 8'h00; // Opcode 6'h1E: MuxedCtrlData[7:0] = 8'h01; 6'h20: MuxedCtrlData[7:0] = TxPauseTV[15:8]; // Pause timer value 6'h22: MuxedCtrlData[7:0] = TxPauseTV[7:0]; default: MuxedCtrlData[7:0] = 8'h0; endcase end

//always @ (posedge MTxClk or posedge TxReset) begin if(TxReset) ControlData[7:0] <= #Tp 8'h0; else if(~ByteCnt[0]) ControlData[7:0] <= #Tp MuxedCtrlData[7:0]; endendmodule

2

Page 40: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

405

10.4

TestbenchPHY 10-12

10-12 Testbench

10-12 PHY

10.4.1PHY

`include "eth_phy_defines.v" `include "wb_model_defines.v" `include "tb_eth_defines.v" `include "eth_defines.v" `include "timescale.v" module tb_ethernet(); //reg wb_clk; ……//eth_top eth_top ( .wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_adr_i(eth_sl_wb_adr_i[11:2]), .wb_sel_i(eth_sl_wb_sel_i), .wb_we_i(eth_sl_wb_we_i), .wb_cyc_i(eth_sl_wb_cyc_i), .wb_stb_i(eth_sl_wb_stb_i), .wb_ack_o(eth_sl_wb_ack_o), .wb_err_o(eth_sl_wb_err_o), .wb_dat_i(eth_sl_wb_dat_i), .wb_dat_o(eth_sl_wb_dat_o), .m_wb_adr_o(eth_ma_wb_adr_o), .m_wb_sel_o(eth_ma_wb_sel_o), .m_wb_we_o(eth_ma_wb_we_o),

.m_wb_dat_i(eth_ma_wb_dat_i), .m_wb_dat_o(eth_ma_wb_dat_o), .m_wb_cyc_o(eth_ma_wb_cyc_o),

Page 41: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

406

.m_wb_stb_o(eth_ma_wb_stb_o), .m_wb_ack_i(eth_ma_wb_ack_i), .m_wb_err_i(eth_ma_wb_err_i), // .mtx_clk_pad_i(mtx_clk), .mtxd_pad_o(MTxD), .mtxen_pad_o(MTxEn), .mtxerr_pad_o(MTxErr), // .mrx_clk_pad_i(mrx_clk), .mrxd_pad_i(MRxD), .mrxdv_pad_i(MRxDV), .mrxerr_pad_i(MRxErr), .mcoll_pad_i(MColl), .mcrs_pad_i(MCrs), // .mdc_pad_o(Mdc_O), .md_pad_i(Mdi_I), .md_pad_o(Mdo_O), .md_padoe_o(Mdo_OE),

.int_o(wb_int) );// PHYassign Mdio_IO = Mdo_OE ? Mdo_O : 1'bz ; assign Mdi_I = Mdio_IO; integer phy_log_file_desc;

eth_phy eth_phy ( .m_rst_n_i(!wb_rst), // MAC .mtx_clk_o(mtx_clk), .mtxd_i(MTxD), .mtxen_i(MTxEn), .mtxerr_i(MTxErr), // MAC .mrx_clk_o(mrx_clk), .mrxd_o(MRxD), .mrxdv_o(MRxDV), .mrxerr_o(MRxErr), .mcoll_o(MColl), .mcrs_o(MCrs), // .mdc_i(Mdc_O), .md_io(Mdio_IO), .phy_log(phy_log_file_desc) );

//integer host_log_file_desc; WB_MASTER_BEHAVIORAL wb_master ( .CLK_I(wb_clk), .RST_I(wb_rst), .TAG_I({`WB_TAG_WIDTH{1'b0}}), .TAG_O(), .ACK_I(eth_sl_wb_ack_o), .ADR_O(eth_sl_wb_adr), // only eth_sl_wb_adr_i[11:2] used .CYC_O(eth_sl_wb_cyc_i), .DAT_I(eth_sl_wb_dat_o), .DAT_O(eth_sl_wb_dat_i), .ERR_I(eth_sl_wb_err_o), .RTY_I(1'b0), // inactive (1'b0) .SEL_O(eth_sl_wb_sel_i), .STB_O(eth_sl_wb_stb_i), .WE_O (eth_sl_wb_we_i), .CAB_O() // NOT USED for now! );assign eth_sl_wb_adr_i = {20'h0, eth_sl_wb_adr[11:2], 2'h0}; ……//

Page 42: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

407

initial begin // wb_rst = 1'b1; #423 wb_rst = 1'b0;

// clear_memories; clear_buffer_descriptors; #423 StartTB = 1'b1; end

//initial begin wb_clk=0; forever #15 wb_clk = ~wb_clk; // 2*10 ns -> 33.3 MHz endinteger tests_successfull; integer tests_failed; reg [799:0] test_name; // used for tb_log_file

reg [3:0] wbm_init_waits; // initial wait cycles between CYC_O and STB_O of WB Master reg [3:0] wbm_subseq_waits; // subsequent wait cycles between STB_Os of WB Master reg [2:0] wbs_waits; // wait cycles befor WB Slave responds reg [7:0] wbs_retries; // if RTY response, then this is the number of retries before ACK

reg wbm_working; // tasks wbm_write and wbm_read set signal when working and reset it when stop working

//initial begin wait(StartTB); //

// tests_successfull = 0; tests_failed = 0; wbm_working = 0;

wbm_init_waits = 4'h1; wbm_subseq_waits = 4'h3; wbs_waits = 4'h1; wbs_retries = 8'h2; wb_slave.cycle_response(`ACK_RESPONSE, wbs_waits, wbs_retries); // test_note("PHY generates ideal Carrier sense and Collision signals for following tests"); eth_phy.carrier_sense_real_delay(0); test_mac_full_duplex_transmit(0, 21); // test_mac_full_duplex_receive(0, 13); // test_mac_full_duplex_flow_control(0, 4); // test_note("PHY generates 'real delayed' Carrier sense and Collision signals for following tests");

Page 43: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

408

eth_phy.carrier_sense_real_delay(1);

// test_summary; $stop; end

10.4.2 PHYLXT971A Inter PHY PHY MIIM

� PHY PHY

� PHY PHY

PHY`include "timescale.v" `include "eth_phy_defines.v" `include "tb_eth_defines.v" module eth_phy (m_rst_n_i, mtx_clk_o, mtxd_i, mtxen_i, mtxerr_i, mrx_clk_o, mrxd_o, mrxdv_o, mrxerr_o, mcoll_o, mcrs_o,mdc_i, md_io, phy_log); //input m_rst_n_i; ……//reg control_bit15; // self clearing bit ……

// PHY MIIM……//initial begin md_io_enable = 1'b0; respond_to_all_phy_addr = 1'b0; no_preamble = 1'b0; end

//assign #1 md_io = (m_rst_n_i && md_io_enable) ? md_io_output : 1'bz ;

//always@(posedge mdc_i or negedge m_rst_n_i) begin if (!m_rst_n_i) md_io_reg <= #1 0; else md_io_reg <= #1 md_io; end

Page 44: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

409

// PHY// putting Data out and shifting always@(posedge mdc_i or negedge m_rst_n_i) begin if (!m_rst_n_i) begin phy_address <= 0; reg_address <= 0; reg_data_in <= 0; reg_data_out <= 0; md_io_output <= 0; end else begin if (md_get_phy_address) begin phy_address[4:1] <= phy_address[3:0]; // correct address is `ETH_PHY_ADDR phy_address[0] <= md_io; end if (md_get_reg_address) begin reg_address[4:1] <= reg_address[3:0]; reg_address[0] <= md_io; end if (md_get_reg_data_in) begin reg_data_in[15:1] <= reg_data_in[14:0]; reg_data_in[0] <= md_io; end if (md_put_reg_data_out) begin reg_data_out <= register_bus_out; end if (md_io_enable) begin md_io_output <= reg_data_out[15]; reg_data_out[15:1] <= reg_data_out[14:0]; reg_data_out[0] <= 1'b0; end end end

assign #1 register_bus_in = reg_data_in; // md_put_reg_data_in - allows writing to a selected register

// MIIMalways@(posedge mdc_i or negedge m_rst_n_i) begin if (!m_rst_n_i) begin if (no_preamble) md_transfer_cnt <= 33;

Page 45: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

410

else md_transfer_cnt <= 1; end else begin if (md_transfer_cnt_reset) begin if (no_preamble) md_transfer_cnt <= 33; else md_transfer_cnt <= 1; end else if (md_transfer_cnt < 64) begin md_transfer_cnt <= md_transfer_cnt + 1'b1; end else begin if (no_preamble) md_transfer_cnt <= 33; else md_transfer_cnt <= 1; end end end

// MIIMalways@(m_rst_n_i or md_transfer_cnt or md_io_reg or md_io_rd_wr or phy_address or respond_to_all_phy_addr or no_preamble) begin #1; while ((m_rst_n_i) && (md_transfer_cnt <= 64)) begin // // if (md_transfer_cnt < 33) begin #4 md_put_reg_data_in = 1'b0; if (md_io_reg !== 1'b1) begin #1 md_transfer_cnt_reset = 1'b1; end else begin #1 md_transfer_cnt_reset = 1'b0; end end

// else if (md_transfer_cnt == 33) begin if (no_preamble)

Page 46: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

411

begin #4 md_put_reg_data_in = 1'b0; if (md_io_reg === 1'b0) begin #1 md_transfer_cnt_reset = 1'b0; end else begin #1 md_transfer_cnt_reset = 1'b1; //if ((md_io_reg !== 1'bz) && (md_io_reg !== 1'b1)) if (md_io_reg !== 1'bz) begin // `ifdef VERBOSE $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong first start bit (without preamble)", $time); `endif #10 $stop; end end end else // with preamble begin #4 ; `ifdef VERBOSE $fdisplay(phy_log, " (%0t)(%m)MIIM - 32-bit preamble received", $time); `endif // check start bit only if md_transfer_cnt_reset is inactive, because if // preamble suppression was changed start bit should not be checked if ((md_io_reg !== 1'b0) && (md_transfer_cnt_reset == 1'b0)) begin // `ifdef VERBOSE $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong first start bit", $time); `endif #10 $stop; end end end

else if (md_transfer_cnt == 34) begin #4; if (md_io_reg !== 1'b1) begin // #1; `ifdef VERBOSE if (no_preamble) $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong second start bit (without preamble)", $time); else $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong second start bit", $time); `endif

Page 47: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

412

#10 $stop; end else begin `ifdef VERBOSE if (no_preamble) #1 $fdisplay(phy_log, " (%0t)(%m)MIIM - 2 start bits received (without preamble)", $time); else #1 $fdisplay(phy_log, " (%0t)(%m)MIIM - 2 start bits received", $time); `endif end end

// op-code else if (md_transfer_cnt == 35) begin #4; if (md_io_reg === 1'b1) begin #1 md_io_rd_wr = 1'b1; end else begin #1 md_io_rd_wr = 1'b0; end end

else if (md_transfer_cnt == 36) begin #4; if ((md_io_reg === 1'b0) && (md_io_rd_wr == 1'b1)) begin #1 md_io_rd_wr = 1'b1; // reading from PHY registers `ifdef VERBOSE $fdisplay(phy_log, " (%0t)(%m)MIIM - op-code for READING from registers", $time); `endif end else if ((md_io_reg === 1'b1) && (md_io_rd_wr == 1'b0)) begin #1 md_io_rd_wr = 1'b0; // writing to PHY registers `ifdef VERBOSE $fdisplay(phy_log, " (%0t)(%m)MIIM - op-code for WRITING to registers", $time); `endif end else begin // `ifdef VERBOSE #1 $fdisplay(phy_log, "*E (%0t)(%m)MIIM - wrong OP-CODE", $time); `endif #10 $stop; end

Page 48: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

413

// PHY begin #1 md_get_phy_address = 1'b1; end end

else if (md_transfer_cnt == 41) begin #4 md_get_phy_address = 1'b0; // set the signal - get register address #1 md_get_reg_address = 1'b1; end

// else if (md_transfer_cnt == 46) begin #4 md_get_reg_address = 1'b0; #1 md_put_reg_data_out = 1'b1; end

……// PHY//reg mcoll_o; ……//initial begin mcrs_rx = 0; mcrs_tx = 0; task_mcoll = 0; task_mcrs = 0; task_mcrs_lost = 0; no_collision_in_half_duplex = 0; collision_in_full_duplex = 0; no_carrier_sense_in_tx_half_duplex = 0; no_carrier_sense_in_rx_half_duplex = 0; carrier_sense_in_tx_full_duplex = 0; no_carrier_sense_in_rx_full_duplex = 0; real_carrier_sense = 0; end

//always@(m_rst_n_i or control_bit8_0 or collision_in_full_duplex or mcrs_rx or mcrs_tx or task_mcoll or no_collision_in_half_duplex ) begin if (!m_rst_n_i) mcoll_o = 0; else begin if (control_bit8_0[8]) // full duplex

Page 49: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

414

begin if (collision_in_full_duplex) // collision is usually not asserted in full duplex begin mcoll_o = ((mcrs_rx && mcrs_tx) || task_mcoll); `ifdef VERBOSE if (mcrs_rx && mcrs_tx) $fdisplay(phy_log, " (%0t)(%m) Collision set in FullDuplex!", $time); if (task_mcoll) $fdisplay(phy_log, " (%0t)(%m) Collision set in FullDuplex from TASK!", $time); `endif end else begin mcoll_o = task_mcoll; `ifdef VERBOSE if (task_mcoll) $fdisplay(phy_log, " (%0t)(%m) Collision set in FullDuplex from TASK!", $time); `endif end end else // half duplex begin mcoll_o = ((mcrs_rx && mcrs_tx && !no_collision_in_half_duplex) || task_mcoll); `ifdef VERBOSE if (mcrs_rx && mcrs_tx) $fdisplay(phy_log, " (%0t)(%m) Collision set in HalfDuplex!", $time); if (task_mcoll) $fdisplay(phy_log, " (%0t)(%m) Collision set in HalfDuplex from TASK!", $time); `endif end end end

//always@(m_rst_n_i or control_bit8_0 or carrier_sense_in_tx_full_duplex or no_carrier_sense_in_rx_full_duplex or no_carrier_sense_in_tx_half_duplex or no_carrier_sense_in_rx_half_duplex or mcrs_rx or mcrs_tx or task_mcrs or task_mcrs_lost ) begin if (!m_rst_n_i) mcrs_o = 0; else begin if (control_bit8_0[8]) // full duplex begin if (carrier_sense_in_tx_full_duplex) // carrier sense is usually not asserted during TX in full duplex mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) || mcrs_tx || task_mcrs) && !task_mcrs_lost; else

Page 50: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

415

mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_full_duplex) || task_mcrs) && !task_mcrs_lost; end else // half duplex begin mcrs_o = ((mcrs_rx && !no_carrier_sense_in_rx_half_duplex) || (mcrs_tx && !no_carrier_sense_in_tx_half_duplex) || task_mcrs) && !task_mcrs_lost; end end end

// PHY//reg [7:0] tx_mem [0:4194303]; // 4194304 22 8……//always@(posedge mtx_clk_o) begin // if (!m_rst_n_i) begin tx_cnt <= 0; tx_preamble_ok <= 0; tx_sfd_ok <= 0; tx_len <= 0; tx_len_err <= 0; end else begin if (!mtxen_i) begin tx_cnt <= 0; end else begin // tx_cnt <= tx_cnt + 1; // if (tx_cnt == 0) begin `ifdef VERBOSE $fdisplay(phy_log, " (%0t)(%m) TX frame started with tx_en set!", $time); `endif if (mtxd_i == 4'h5) tx_preamble_ok <= 1; else tx_preamble_ok <= 0; tx_sfd_ok <= 0; tx_byte_aligned_ok <= 0; tx_len <= 0; tx_len_err <= 0;

Page 51: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

416

end // if ((tx_cnt > 0) && (tx_cnt <= 13)) begin if ((tx_preamble_ok != 1) || (mtxd_i != 4'h5)) tx_preamble_ok <= 0; end // SFD if (tx_cnt == 14) begin `ifdef VERBOSE if (tx_preamble_ok == 1) $fdisplay(phy_log, " (%0t)(%m) TX frame preamble OK!", $time); else $fdisplay(phy_log, "*E (%0t)(%m) TX frame preamble NOT OK!", $time); `endif if (mtxd_i == 4'h5) tx_sfd_ok <= 1; else tx_sfd_ok <= 0; end if (tx_cnt == 15) begin if ((tx_sfd_ok != 1) || (mtxd_i != 4'hD)) tx_sfd_ok <= 0; end

// / FCS if (tx_cnt > 15) begin if (tx_cnt == 16) begin `ifdef VERBOSE if (tx_sfd_ok == 1) $fdisplay(phy_log, " (%0t)(%m) TX frame SFD OK!", $time); else $fdisplay(phy_log, "*E (%0t)(%m) TX frame SFD NOT OK!", $time); `endif end

if (tx_cnt[0] == 0) begin tx_mem_data_in[3:0] <= mtxd_i; // storing LSB nibble tx_byte_aligned_ok <= 0; // if transfer will stop after this, then there was drible nibble end else begin tx_mem[tx_mem_addr_in[21:0]] <= {mtxd_i, tx_mem_data_in[3:0]}; // storing data into tx

memory tx_len <= tx_len + 1; // enlarge byte length counter tx_byte_aligned_ok <= 1; // if transfer will stop after this, then transfer is byte alligned tx_mem_addr_in <= tx_mem_addr_in + 1'b1;

Page 52: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

417

end

if (mtxerr_i) tx_len_err <= tx_len; end end end

// if (!m_rst_n_i) begin mcrs_tx <= 0; mtxen_d1 <= 0; mtxen_d2 <= 0; mtxen_d3 <= 0; mtxen_d4 <= 0; mtxen_d5 <= 0; mtxen_d6 <= 0; end else begin mtxen_d1 <= mtxen_i; mtxen_d2 <= mtxen_d1; mtxen_d3 <= mtxen_d2; mtxen_d4 <= mtxen_d3; mtxen_d5 <= mtxen_d4; mtxen_d6 <= mtxen_d5; if (real_carrier_sense) mcrs_tx <= mtxen_d6; else mcrs_tx <= mtxen_i; end end

`ifdef VERBOSE reg frame_started;

initial begin frame_started = 0; endalways@(posedge mtxen_i) begin frame_started <= 1; endalways@(negedge mtxen_i) begin if (frame_started) begin $fdisplay(phy_log, " (%0t)(%m) TX frame ended with tx_en reset!", $time); frame_started <= 0; end

Page 53: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

FPGA

418

endalways@(posedge mrxerr_o) begin $fdisplay(phy_log, " (%0t)(%m) RX frame ERROR signal was set!", $time); end`endif……endmodule

10.4.310-13 MTxD

10-13

10-14 MRxD

10-14

Page 54: 110 0´ ¹ þ5% { < Ä MAC Åread.pudn.com/.../sourcecode/embedded/2204973/ethernet-verilog.pdf · 110 0´ ¹ þ5% { < ÄMAC Å g369g + ød Data ! ô l ¾ ¢ ¦n 46 n 1500 É yd Frame

10 MAC

419

10-15MTxD MRxD

10-15

10-16

10-16

10.5

MAC