FPGA 学习小组
直播中

alexdos

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

以太网控制器数据发送模块实现代码

数据发送模块负责发送数据,通过主机接口从上层协议获得要发送的数据,同时获得数据帧的起始和结束信号;还要设置信号通知上层协议和外部 PHY 芯片。数据发送模块主要由计数器模块、数据发送状态机、错误处理模块和 CRC 校验模块等 4 部分组成,如图 10-9 所示。
1.png
这 4 部分的功能描述如下。

• 数据发送状态机:完成数据发送的整体控制。

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

• CRC 校验模块:产生 32 位的 CRC 校验序列,添加在发送数据的后面。

• 错误处理模块:当发送数据冲突后,在重新发送数据前产生一个随机的延迟,从而减少发送数据冲突的次数。

当发生如下情况时,数据发送过程结束。

• 数据发送成功结束,设置 TxDone 信号。

• 数据发送过程需要重复,设置 TxRetry 信号,一般发生在数据冲突后。

• 退出数据发送过程,设置 TxAbort 信号。

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

  1. `include "timescale.v"
  2. module eth_txethmac (MTxClk, Reset, TxStartFrm, TxEndFrm, TxUnderRun, TxData, CarrierSense,
  3. Collision, Pad, CrcEn, FullD, HugEn, DlyCrcEn, MinFL, MaxFL, IPGT, IPGR1, IPGR2, CollValid,
  4. MaxRet, NoBckof, ExDfrEn, MTxD, MTxEn, MTxErr, TxDone, TxRetry, TxAbort,
  5. TxUsedData, WillTransmit, ResetCollision, RetryCnt, StartTxDone, StartTxAbort,MaxCollisionOccured,
  6. LateCollision, DeferIndication, StatePreamble, StateData);
  7. parameter Tp = 1;
  8. //输入、输出信号
  9. input MTxClk; //传输时钟
  10. input Reset; // 复位
  11. input TxStartFrm; // 数据包的起始帧
  12. input TxEndFrm; // 数据包的结束帧
  13. input TxUnderRun;
  14. input [7:0] TxData; //数据内容
  15. …..
  16. //寄存器
  17. reg [3:0] MTxD;
  18. …..
  19. //各个信号
  20. assign ResetCollision = ~(StatePreamble | (|StateData) | StatePAD | StateFCS);
  21. assign ExcessiveDeferOccured = TxStartFrm & StateDefer & ExcessiveDefer &~StopExcessiveDeferOccured;
  22. assign StartTxDone = ~Collision & (StateFCS & NibCntEq7 | StateData[1] & TxEndFrm & (~Pad |Pad & NibbleMinFl) & ~CrcEn);
  23. assign UnderRun = StateData[0] & TxUnderRun & ~Collision;
  24. assign TooBig = ~Collision & MaxFrame & (StateData[0] & ~TxUnderRun | StateFCS);
  25. assign StartTxRetry = StartJam & (ColWindow & ~RetryMax) & ~UnderRun;
  26. assign LateCollision = StartJam & ~ColWindow & ~UnderRun;
  27. assign MaxCollisionOccured = StartJam & ColWindow & RetryMax;
  28. assign StateSFD = StatePreamble & NibCntEq15;
  29. assign StartTxAbort = TooBig | UnderRun | ExcessiveDeferOccured | LateCollision |MaxCollisionOccured;
  30. // 停止额外的延迟
  31. always @ (posedge MTxClk or posedge Reset)
  32. begin
  33. if(Reset)
  34. StopExcessiveDeferOccured <= #Tp 1'b0;
  35. else
  36. begin
  37. if(~TxStartFrm)
  38. StopExcessiveDeferOccured <= #Tp 1'b0;
  39. else
  40. if(ExcessiveDeferOccured)
  41. StopExcessiveDeferOccured <= #Tp 1'b1;
  42. end
  43. end
  44. //数据冲突
  45. always @ (posedge MTxClk or posedge Reset)
  46. begin
  47. if(Reset)
  48. ColWindow <= #Tp 1'b1;
  49. else
  50. begin
  51. if(~Collision & ByteCnt[5:0] == CollValid[5:0] & (StateData[1] | StatePAD & NibCnt[0]| StateFCS & NibCnt[0]))
  52. ColWindow <= #Tp 1'b0;
  53. else
  54. if(StateIdle | StateIPG)
  55. ColWindow <= #Tp 1'b1;
  56. end
  57. end
  58. // 开始
  59. always @ (posedge MTxClk or posedge Reset)
  60. begin
  61. if(Reset)
  62. StatusLatch <= #Tp 1'b0;
  63. else
  64. begin
  65. if(~TxStartFrm)
  66. StatusLatch <= #Tp 1'b0;
  67. else
  68. if(ExcessiveDeferOccured | StateIdle)
  69. StatusLatch <= #Tp 1'b1;
  70. end
  71. end
  72. //发送用过的数据包
  73. always @ (posedge MTxClk or posedge Reset)
  74. begin
  75. if(Reset)
  76. TxUsedData <= #Tp 1'b0;
  77. else
  78. TxUsedData <= #Tp |StartData;
  79. end
  80. //发送数据包结束
  81. always @ (posedge MTxClk or posedge Reset)
  82. begin
  83. if(Reset)
  84. TxDone <= #Tp 1'b0;
  85. else
  86. begin
  87. if(TxStartFrm & ~StatusLatch)
  88. TxDone <= #Tp 1'b0;
  89. else
  90. if(StartTxDone)
  91. TxDone <= #Tp 1'b1;
  92. end
  93. end
  94. // 重新发送数据包
  95. always @ (posedge MTxClk or posedge Reset)
  96. begin
  97. if(Reset)
  98. TxRetry <= #Tp 1'b0;
  99. else
  100. begin
  101. if(TxStartFrm & ~StatusLatch)
  102. TxRetry <= #Tp 1'b0;
  103. else
  104. if(StartTxRetry)
  105. TxRetry <= #Tp 1'b1;
  106. end
  107. end
  108. // 退出数据包发送
  109. always @ (posedge MTxClk or posedge Reset)
  110. begin
  111. if(Reset)
  112. TxAbort <= #Tp 1'b0;
  113. else
  114. begin
  115. if(TxStartFrm & ~StatusLatch & ~ExcessiveDeferOccured)
  116. TxAbort <= #Tp 1'b0;
  117. else
  118. if(StartTxAbort)
  119. TxAbort <= #Tp 1'b1;
  120. end
  121. end
  122. //重新计数
  123. always @ (posedge MTxClk or posedge Reset)
  124. begin
  125. if(Reset)
  126. RetryCnt[3:0] <= #Tp 4'h0;
  127. else
  128. begin
  129. if(ExcessiveDeferOccured | UnderRun | TooBig | StartTxDone | TxUnderRun| StateJam & NibCntEq7 & (~ColWindow | RetryMax))
  130. RetryCnt[3:0] <= #Tp 4'h0;
  131. else
  132. if(StateJam & NibCntEq7 & ColWindow & (RandomEq0 | NoBckof) | StateBackOff &RandomEqByteCnt)
  133. RetryCnt[3:0] <= #Tp RetryCnt[3:0] + 1'b1;
  134. end
  135. end
  136. assign RetryMax = RetryCnt[3:0] == MaxRet[3:0];
  137. // 同时传输 4 位数据
  138. always @ (StatePreamble or StateData or StateData or StateFCS or StateJam or StateSFD or TxDataor
  139. Crc or NibCnt or NibCntEq15)
  140. begin
  141. if(StateData[0])
  142. MTxD_d[3:0] = TxData[3:0]; // 低四位
  143. else
  144. if(StateData[1])
  145. MTxD_d[3:0] = TxData[7:4]; //高四位
  146. else
  147. if(StateFCS)
  148. MTxD_d[3:0] = {~Crc[28], ~Crc[29], ~Crc[30], ~Crc[31]}; // CRC 校验序列
  149. else
  150. if(StateJam)
  151. MTxD_d[3:0] = 4'h9;
  152. else
  153. if(StatePreamble)
  154. if(NibCntEq15)
  155. MTxD_d[3:0] = 4'hd; // 帧起始分隔符,SFD
  156. else
  157. MTxD_d[3:0] = 4'h5; // 报头
  158. else
  159. MTxD_d[3:0] = 4'h0;
  160. end
  161. // 传输使能
  162. always @ (posedge MTxClk or posedge Reset)
  163. begin
  164. if(Reset)
  165. MTxEn <= #Tp 1'b0;
  166. else
  167. MTxEn <= #Tp StatePreamble | (|StateData) | StatePAD | StateFCS | StateJam;
  168. end
  169. // 传输四位字节
  170. always @ (posedge MTxClk or posedge Reset)
  171. begin
  172. if(Reset)
  173. MTxD[3:0] <= #Tp 4'h0;
  174. else
  175. MTxD[3:0] <= #Tp MTxD_d[3:0];
  176. end
  177. // 传输错误
  178. always @ (posedge MTxClk or posedge Reset)
  179. begin
  180. if(Reset)
  181. MTxErr <= #Tp 1'b0;
  182. else
  183. MTxErr <= #Tp TooBig | UnderRun;
  184. end
  185. // 即将传输
  186. always @ (posedge MTxClk or posedge Reset)
  187. begin
  188. if(Reset)
  189. WillTransmit <= #Tp 1'b0;
  190. else
  191. WillTransmit <= #Tp StartPreamble | StatePreamble | (|StateData) | StatePAD | StateFCS
  192. | StateJam;
  193. end
  194. //数据包完成标志
  195. assign PacketFinished_d = StartTxDone | TooBig | UnderRun | LateCollision | MaxCollisionOccured
  196. | ExcessiveDeferOccured;
  197. // 数据包结束
  198. always @ (posedge MTxClk or posedge Reset)
  199. begin
  200. if(Reset)
  201. begin
  202. PacketFinished <= #Tp 1'b0;
  203. PacketFinished_q <= #Tp 1'b0;
  204. end
  205. else
  206. begin
  207. PacketFinished <= #Tp PacketFinished_d;
  208. PacketFinished_q <= #Tp PacketFinished;
  209. end
  210. end
  211. // 连接计数器模块
  212. eth_txcounters txcounters1
  213. (.StatePreamble(StatePreamble), .StateIPG(StateIPG), .StateData(StateData),
  214. .StatePAD(StatePAD), .StateFCS(StateFCS), .StateJam(StateJam), .StateBackOff(StateBackOff),
  215. .StateDefer(StateDefer), .StateIdle(StateIdle), .StartDefer(StartDefer), .StartIPG(StartIPG),
  216. .StartFCS(StartFCS), .StartJam(StartJam), .TxStartFrm(TxStartFrm), .MTxClk(MTxClk),
  217. .Reset(Reset), .MinFL(MinFL), .MaxFL(MaxFL), .HugEn(HugEn), .ExDfrEn(ExDfrEn),
  218. .PacketFinished_q(PacketFinished_q), .DlyCrcEn(DlyCrcEn), .StartBackoff(StartBackoff),
  219. .StateSFD(StateSFD), .ByteCnt(ByteCnt), .NibCnt(NibCnt), .ExcessiveDefer(ExcessiveDefer),
  220. .NibCntEq7(NibCntEq7), .NibCntEq15(NibCntEq15), .MaxFrame(MaxFrame), .NibbleMinFl(NibbleMinFl),
  221. .DlyCrcCnt(DlyCrcCnt));
  222. // 连接状态机模块
  223. eth_txstatem txstatem1 (.MTxClk(MTxClk), .Reset(Reset), .ExcessiveDefer(ExcessiveDefer),
  224. .CarrierSense(CarrierSense),.NibCnt(NibCnt[6:0]), .IPGT(IPGT), .IPGR1(IPGR1), .IPGR2(IPGR2), .FullD(FullD), .TxStartFrm(TxStartFrm), .TxEndFrm(TxEndFrm), .TxUnderRun(TxUnderRun), .Collision(Collision),
  225. .UnderRun(UnderRun), .StartTxDone(StartTxDone), .TooBig(TooBig), .NibCntEq7(NibCntEq7),
  226. .NibCntEq15(NibCntEq15), .MaxFrame(MaxFrame), .Pad(Pad), .CrcEn(CrcEn),.NibbleMinFl(NibbleMinFl),
  227. .RandomEq0(RandomEq0), .ColWindow(ColWindow), .RetryMax(RetryMax),.NoBckof(NoBckof),
  228. .RandomEqByteCnt(RandomEqByteCnt), .StateIdle(StateIdle),.StateIPG(StateIPG),
  229. .StatePreamble(StatePreamble), .StateData(StateData), .StatePAD(StatePAD),.StateFCS(StateFCS),
  230. .StateJam(StateJam), .StateJam_q(StateJam_q), .StateBackOff(StateBackOff),.StateDefer(StateDefer),
  231. .StartFCS(StartFCS), .StartJam(StartJam), .StartBackoff(StartBackoff),.StartDefer(StartDefer),
  232. .DeferIndication(DeferIndication), .StartPreamble(StartPreamble), .StartData(StartData),
  233. .StartIPG(StartIPG));
  234. // 连接 CRC 模块
  235. eth_crc txcrc
  236. (.Clk(MTxClk), .Reset(Reset), .Data(Data_Crc), .Enable(Enable_Crc), .Initialize(Initialize_Crc),
  237. .Crc(Crc), .CrcError(CrcError)
  238. );
  239. //连接随机延迟模块
  240. eth_random random1
  241. (.MTxClk(MTxClk), .Reset(Reset), .StateJam(StateJam), .StateJam_q(StateJam_q), .RetryCnt(RetryCnt),
  242. .NibCnt(NibCnt), .ByteCnt(ByteCnt[9:0]), .RandomEq0(RandomEq0), .RandomEqByteCnt(RandomEqByteCnt));
  243. endmodule

更多回帖

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