1.数据接收状态机
数据接收的整个过程由一个状态机控制完成。数据的接收与发送是相反的过程:首先去除报头,然后去除 SFD(帧起始分隔符),随后接收数据,最后进行 CRC 校验判断数据在传输过程中是否受损。流程与数据发送的流程相反,这里不再赘述,请参考源代码。
2.计数器模块
数据接收的计数器模块包括接收数据过程中的所有计数器。内容与数据发送模块中的计数器模块类似,请参考源代码。
3.CRC 校验模块
数据接收模块的 CRC 校验首先根据接收到的数据计算产生 32 位 CRC 校验序列,然后跟接收到的 CRC 校验序列比较,判断数据在传输过程中是否损坏。数据接收模块的 CRC 校验的源代码和数据发送模块的 CRC 校验代码一样。
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 到 BD 状态寄存器中,表示“地址丢失”
- always @ (posedge MRxClk or posedge Reset)
- begin
- if(Reset)
- AddressMiss <= #Tp 1'b0;
- else if(ByteCntEq7 & RxCheckEn)
- AddressMiss <= #Tp (~(UnicastOK | BroadcastOK | MulticastOK | (PassAll &
- ControlFrmAddressOK)));
- end
- //哈希地址检查,多点发送
- 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;
- end
- assign 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
- end
- assign HashBit = ByteHash[CrcHash[2:0]];
- endmodule