FPGA 学习小组
直播中

alexdos

6年用户 804经验值
擅长:可编程逻辑 电源/新能源 嵌入式技术 模拟技术
私信 关注

以太网控制器数据接收模块

数据接收模块负责接收数据的整个过程。外部 PHY 从物理层(具体指双绞线等电缆)接收串行的数据,将其还原成四位字节形式然后发送到数据接收模块。数据接收模块将接收到的 4位字节形式的数据合并成 8 位字节形式的数据,随后通过主机接口发送到上层协议。数据接收模块在接收数据的过程中完成去除报头和 CRC 校验序列的工作。

数据接收模块的结构如图 10-11 所示。
1.png
数据接收模块由 4 部分组成。

• 数据接收状态机:完成数据接收的整体控制。

• 计数器模块:包括数据接收中所有需要的计数器。

• CRC 校验模块:根据接收到的数据产生 32 位的 CRC 校验序列,并与接收到的 CRC 校验数据比较,从而得到数据是否被破坏。

• 地址检查模块:确认接收到的数据地址是否与实际地址相符。

数据发送模块的顶层程序完成 4 个部分的连接和控制,主要代码如下。

  1. `include "timescale.v"
  2. module eth_rxethmac (MRxClk, MRxDV, MRxD, Reset, Transmitting, MaxFL, r_IFG, HugEn, DlyCrcEn,
  3. RxData, RxValid, RxStartFrm, RxEndFrm, ByteCnt, ByteCntEq0, ByteCntGreat2, ByteCntMaxFrame,
  4. CrcError, StateIdle, StatePreamble, StateSFD, StateData, MAC, r_Pro, r_Bro,r_HASH0, r_HASH1,
  5. RxAbort,
  6. AddressMiss, PassAll, ControlFrmAddressOK );
  7. parameter Tp = 1;
  8. //输入输出信号
  9. input MRxClk;
  10. input MRxDV;
  11. …..
  12. input [47:0] MAC; // 地址
  13. input [31:0] r_HASH0; // 低四位哈希表
  14. input [31:0] r_HASH1; // 高四位哈希表
  15. input PassAll;
  16. ….
  17. //寄存器与连线
  18. reg [7:0] RxData;
  19. reg RxValid;
  20. ….
  21. //连接接收数据状态机
  22. eth_rxstatem rxstatem1
  23. (.MRxClk(MRxClk), .Reset(Reset), .MRxDV(MRxDV), .ByteCntEq0(ByteCntEq0),
  24. .ByteCntGreat2(ByteCntGreat2), .Transmitting(Transmitting), .MRxDEq5(MRxDEq5),
  25. .MRxDEqD(MRxDEqD), .IFGCounterEq24(IFGCounterEq24), .ByteCntMaxFrame(ByteCntMaxFrame),
  26. .StateData(StateData), .StateIdle(StateIdle), .StatePreamble(StatePreamble),.StateSFD(Sta
  27. teSFD),
  28. .StateDrop(StateDrop));
  29. // 连接接收数据计数器模块
  30. eth_rxcounters rxcounters1
  31. (.MRxClk(MRxClk), .Reset(Reset), .MRxDV(MRxDV), .StateIdle(StateIdle),
  32. .StateSFD(StateSFD), .StateData(StateData), .StateDrop(StateDrop),.StatePreamble(StatePre
  33. amble),
  34. .MRxDEqD(MRxDEqD), .DlyCrcEn(DlyCrcEn),.DlyCrcCnt(DlyCrcCnt), .Transmitting(Transmitting
  35. ),
  36. .MaxFL(MaxFL), .r_IFG(r_IFG),.HugEn(HugEn), .IFGCounterEq24(IFGCounterEq24),
  37. .ByteCntEq0(ByteCntEq0),.ByteCntEq1(ByteCntEq1), .ByteCntEq2(ByteCntEq2),
  38. .ByteCntEq3(ByteCntEq3),.ByteCntEq4(ByteCntEq4), .ByteCntEq5(ByteCntEq5),
  39. .ByteCntEq6(ByteCntEq6),.ByteCntEq7(ByteCntEq7), .ByteCntGreat2(ByteCntGreat2),
  40. .ByteCntSmall7(ByteCntSmall7), .ByteCntMaxFrame(ByteCntMaxFrame),.ByteCnt(ByteCnt));
  41. // 连接地址检查模块
  42. eth_rxaddrcheck rxaddrcheck1 (.MRxClk(MRxClk),.Reset(Reset),.RxData(RxData),
  43. .Broadcast (Broadcast),.r_Bro
  44. (r_Bro),.r_Pro(r_Pro),.ByteCntEq6(ByteCntEq6),.ByteCntEq7(ByteCntEq7),
  45. .ByteCntEq2(ByteCntEq2),.ByteCntEq3(ByteCntEq3),.ByteCntEq4(ByteCntEq4),.ByteCntEq5(ByteC
  46. ntEq5),
  47. .HASH0(r_HASH0),.HASH1(r_HASH1),.CrcHash(CrcHash[5:0]), .CrcHashGood(CrcHashGood),
  48. .StateData(StateData),.Multicast(Multicast),.MAC(MAC),.RxAbort(RxAbort),.RxEndFrm(RxEndF
  49. rm),
  50. .AddressMiss(AddressMiss),.PassAll(PassAll),.ControlFrmAddressOK(ControlFrmAddressOK));
  51. //设置产生并初始化 CRC 序列
  52. assign Enable_Crc = MRxDV & (|StateData & ~ByteCntMaxFrame);
  53. assign Initialize_Crc = StateSFD | DlyCrcEn & (|DlyCrcCnt[3:0]) & DlyCrcCnt[3:0] < 4'h9;
  54. assign Data_Crc[0] = MRxD[3];
  55. assign Data_Crc[1] = MRxD[2];
  56. assign Data_Crc[2] = MRxD[1];
  57. assign Data_Crc[3] = MRxD[0];
  58. //连接 Crc 校验模块
  59. eth_crc crcrx
  60. (.Clk(MRxClk), .Reset(Reset), .Data(Data_Crc), .Enable(Enable_Crc), .Initialize(Initialize_Crc),
  61. .Crc(Crc), .CrcError(CrcError)
  62. );
  63. //锁存 CRC 序列并用在哈希表中
  64. always @ (posedge MRxClk)
  65. begin
  66. CrcHashGood <= #Tp StateData[0] & ByteCntEq6;
  67. end
  68. always @ (posedge MRxClk)
  69. begin
  70. if(Reset | StateIdle)
  71. CrcHash[8:0] <= #Tp 9'h0;
  72. else
  73. if(StateData[0] & ByteCntEq6)
  74. CrcHash[8:0] <= #Tp Crc[31:23];
  75. end
  76. // 输出按字节保存的数据到上层协议
  77. always @ (posedge MRxClk or posedge Reset)
  78. begin
  79. if(Reset)
  80. begin
  81. RxData_d[7:0] <= #Tp 8'h0;
  82. DelayData <= #Tp 1'b0;
  83. LatchedNibble[3:0] <= #Tp 4'h0;
  84. LatchedByte[7:0] <= #Tp 8'h0;
  85. RxData[7:0] <= #Tp 8'h0;
  86. end
  87. else
  88. begin
  89. LatchedNibble[3:0] <= #Tp MRxD[3:0]; // 锁存四位字节数据
  90. LatchedByte[7:0] <= #Tp {MRxD[3:0], LatchedNibble[3:0]}; // 锁存八位字节数据
  91. DelayData <= #Tp StateData[0];
  92. if(GenerateRxValid)
  93. RxData_d[7:0] <= #Tp LatchedByte[7:0] & {8{|StateData}};
  94. else
  95. if(~DelayData)
  96. RxData_d[7:0] <= #Tp 8'h0; // 延迟数据
  97. RxData[7:0] <= #Tp RxData_d[7:0]; // 输出按字节保存的数据
  98. end
  99. end
  100. always @ (posedge MRxClk or posedge Reset)
  101. begin
  102. if(Reset)
  103. Broadcast <= #Tp 1'b0;
  104. else
  105. begin
  106. if(StateData[0] & ~(&LatchedByte[7:0]) & ByteCntSmall7)
  107. Broadcast <= #Tp 1'b0;
  108. else
  109. if(StateData[0] & (&LatchedByte[7:0]) & ByteCntEq1)
  110. Broadcast <= #Tp 1'b1;
  111. else
  112. if(RxAbort | RxEndFrm)
  113. Broadcast <= #Tp 1'b0;
  114. end
  115. end
  116. //多点传送
  117. always @ (posedge MRxClk or posedge Reset)
  118. begin
  119. if(Reset)
  120. Multicast <= #Tp 1'b0;
  121. else
  122. begin
  123. if(Reset)
  124. Multicast <= #Tp 1'b0;
  125. else
  126. if(StateData[0] & ByteCntEq1 & LatchedByte == 8'h01)
  127. Multicast <= #Tp 1'b1;
  128. else if(RxAbort | RxEndFrm)
  129. Multicast <= #Tp 1'b0;
  130. end
  131. end
  132. assign GenerateRxValid = StateData[0] & (~ByteCntEq0 | DlyCrcCnt >= 4'h3);
  133. //数据有效
  134. always @ (posedge MRxClk or posedge Reset)
  135. begin
  136. if(Reset)
  137. begin
  138. RxValid_d <= #Tp 1'b0;
  139. RxValid <= #Tp 1'b0;
  140. end
  141. else
  142. begin
  143. RxValid_d <= #Tp GenerateRxValid;
  144. RxValid <= #Tp RxValid_d;
  145. end
  146. end
  147. assign GenerateRxStartFrm = StateData[0] & (ByteCntEq1 & ~DlyCrcEn | DlyCrcCnt == 4'h3 &
  148. DlyCrcEn);
  149. //产生帧起始信号
  150. always @ (posedge MRxClk or posedge Reset)
  151. begin
  152. if(Reset)
  153. begin
  154. RxStartFrm_d <= #Tp 1'b0;
  155. RxStartFrm <= #Tp 1'b0;
  156. end
  157. else
  158. begin
  159. RxStartFrm_d <= #Tp GenerateRxStartFrm;
  160. RxStartFrm <= #Tp RxStartFrm_d;
  161. end
  162. end
  163. assign GenerateRxEndFrm = StateData[0] & (~MRxDV & ByteCntGreat2 | ByteCntMaxFrame);
  164. assign DribbleRxEndFrm = StateData[1] & ~MRxDV & ByteCntGreat2;
  165. //产生帧尾信号
  166. always @ (posedge MRxClk or posedge Reset)
  167. begin
  168. if(Reset)
  169. begin
  170. RxEndFrm_d <= #Tp 1'b0;
  171. RxEndFrm <= #Tp 1'b0;
  172. end
  173. else
  174. begin
  175. RxEndFrm_d <= #Tp GenerateRxEndFrm;
  176. RxEndFrm <= #Tp RxEndFrm_d | DribbleRxEndFrm;
  177. end
  178. end
  179. endmodule

更多回帖

发帖
×
20
完善资料,
赚取积分