FPGA 学习小组
直播中

alexdos

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

以太网控制器控制模块数据传输控制代码实现

数据传输控制要保证主机接口和外部 PHY 可以同时发送数据给对方,从而实现全双工的要求。数据传输控制的主要代码如下:

  1. `include "timescale.v"
  2. module eth_transmitcontrol (MTxClk, TxReset, TxUsedDataIn, TxUsedDataOut, TxDoneIn,
  3. TxAbortIn,
  4. TxStartFrmIn, TPauseRq, TxUsedDataOutDetected, TxFlow, DlyCrcEn, TxPauseTV, MAC,
  5. TxCtrlStartFrm,
  6. TxCtrlEndFrm, SendingCtrlFrm, CtrlMux, ControlData, WillSendControlFrame, BlockTxDone);
  7. parameter Tp = 1;
  8. //输入输出信号
  9. input MTxClk;
  10. ……
  11. //寄存器与连线
  12. reg SendingCtrlFrm;
  13. ……
  14. //发送控制帧数据的命令,高有效
  15. always @ (posedge MTxClk or posedge TxReset)
  16. begin
  17. if(TxReset)
  18. WillSendControlFrame <= #Tp 1'b0;
  19. else
  20. if(TxCtrlEndFrm & CtrlMux)
  21. WillSendControlFrame <= #Tp 1'b0;
  22. else
  23. if(TPauseRq & TxFlow)
  24. WillSendControlFrame <= #Tp 1'b1;
  25. end
  26. //产生传输控制数据包的开始帧
  27. always @ (posedge MTxClk or posedge TxReset)
  28. begin
  29. if(TxReset)
  30. TxCtrlStartFrm <= #Tp 1'b0;
  31. else
  32. if(TxUsedDataIn_q & CtrlMux)
  33. TxCtrlStartFrm <= #Tp 1'b0;
  34. else
  35. if(WillSendControlFrame & ~TxUsedDataOut & (TxDoneIn | TxAbortIn | TxStartFrmIn |
  36. (~TxUsedDataOutDetected)))
  37. TxCtrlStartFrm <= #Tp 1'b1;
  38. end
  39. //产生传输控制数据包的结束帧
  40. always @ (posedge MTxClk or posedge TxReset)
  41. begin
  42. if(TxReset)
  43. TxCtrlEndFrm <= #Tp 1'b0;
  44. else
  45. if(ControlEnd | ControlEnd_q)
  46. TxCtrlEndFrm <= #Tp 1'b1;
  47. else
  48. TxCtrlEndFrm <= #Tp 1'b0;
  49. end
  50. //产生乘信号
  51. always @ (posedge MTxClk or posedge TxReset)
  52. begin
  53. if(TxReset)
  54. CtrlMux <= #Tp 1'b0;
  55. else
  56. if(WillSendControlFrame & ~TxUsedDataOut)
  57. CtrlMux <= #Tp 1'b1;
  58. else
  59. if(TxDoneIn)
  60. CtrlMux <= #Tp 1'b0;
  61. end
  62. //产生发送控制帧数据,使能 CRC 校验和 PAD
  63. always @ (posedge MTxClk or posedge TxReset)
  64. begin
  65. if(TxReset)
  66. SendingCtrlFrm <= #Tp 1'b0;
  67. else
  68. if(WillSendControlFrame & TxCtrlStartFrm)
  69. SendingCtrlFrm <= #Tp 1'b1;
  70. else
  71. if(TxDoneIn)
  72. SendingCtrlFrm <= #Tp 1'b0;
  73. end
  74. always @ (posedge MTxClk or posedge TxReset)
  75. begin
  76. if(TxReset)
  77. TxUsedDataIn_q <= #Tp 1'b0;
  78. else
  79. TxUsedDataIn_q <= #Tp TxUsedDataIn;
  80. end
  81. //当发送控制帧数据时,产生信号屏蔽发送结束信号到主机接口
  82. always @ (posedge MTxClk or posedge TxReset)
  83. begin
  84. if(TxReset)
  85. BlockTxDone <= #Tp 1'b0;
  86. else
  87. if(TxCtrlStartFrm)
  88. BlockTxDone <= #Tp 1'b1;
  89. else
  90. if(TxStartFrmIn)
  91. BlockTxDone <= #Tp 1'b0;
  92. end
  93. always @ (posedge MTxClk)
  94. begin
  95. ControlEnd_q <= #Tp ControlEnd;
  96. TxCtrlStartFrm_q <= #Tp TxCtrlStartFrm;
  97. end
  98. assign IncrementDlyCrcCnt = CtrlMux & TxUsedDataIn & ~DlyCrcCnt[2];
  99. // 延迟 CRC 计数器
  100. always @ (posedge MTxClk or posedge TxReset)
  101. begin
  102. if(TxReset)
  103. DlyCrcCnt <= #Tp 4'h0;
  104. else
  105. if(ResetByteCnt)
  106. DlyCrcCnt <= #Tp 4'h0;
  107. else
  108. if(IncrementDlyCrcCnt)
  109. DlyCrcCnt <= #Tp DlyCrcCnt + 1'b1;
  110. end
  111. assign ResetByteCnt = TxReset | (~TxCtrlStartFrm & (TxDoneIn | TxAbortIn));
  112. assign IncrementByteCnt = CtrlMux & (TxCtrlStartFrm & ~TxCtrlStartFrm_q & ~TxUsedDataIn |
  113. TxUsedDataIn & ~ControlEnd);
  114. assign IncrementByteCntBy2 = CtrlMux & TxCtrlStartFrm & (~TxCtrlStartFrm_q) & TxUsedDataIn;
  115. // When TxUsedDataIn and CtrlMux are set at the same time
  116. assign EnableCnt = (~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0]));
  117. //字节计数器
  118. always @ (posedge MTxClk or posedge TxReset)
  119. begin
  120. if(TxReset)
  121. ByteCnt <= #Tp 6'h0;
  122. else
  123. if(ResetByteCnt)
  124. ByteCnt <= #Tp 6'h0;
  125. else
  126. if(IncrementByteCntBy2 & EnableCnt)
  127. ByteCnt <= #Tp (ByteCnt[5:0] ) + 2'h2;
  128. else
  129. if(IncrementByteCnt & EnableCnt)
  130. ByteCnt <= #Tp (ByteCnt[5:0] ) + 1'b1;
  131. end
  132. assign ControlEnd = ByteCnt[5:0] == 6'h22;
  133. // 控制数据产生
  134. always @ (ByteCnt or DlyCrcEn or MAC or TxPauseTV or DlyCrcCnt)
  135. begin
  136. case(ByteCnt)
  137. 6'h0: if(~DlyCrcEn | DlyCrcEn & (&DlyCrcCnt[1:0]))
  138. MuxedCtrlData[7:0] = 8'h01;
  139. else
  140. MuxedCtrlData[7:0] = 8'h0;
  141. 6'h2: MuxedCtrlData[7:0] = 8'h80;
  142. 6'h4: MuxedCtrlData[7:0] = 8'hC2;
  143. 6'h6: MuxedCtrlData[7:0] = 8'h00;
  144. 6'h8: MuxedCtrlData[7:0] = 8'h00;
  145. 6'hA: MuxedCtrlData[7:0] = 8'h01;
  146. 6'hC: MuxedCtrlData[7:0] = MAC[47:40];
  147. 6'hE: MuxedCtrlData[7:0] = MAC[39:32];
  148. 6'h10: MuxedCtrlData[7:0] = MAC[31:24];
  149. 6'h12: MuxedCtrlData[7:0] = MAC[23:16];
  150. 6'h14: MuxedCtrlData[7:0] = MAC[15:8];
  151. 6'h16: MuxedCtrlData[7:0] = MAC[7:0];
  152. 6'h18: MuxedCtrlData[7:0] = 8'h88; // Type/Length
  153. 6'h1A: MuxedCtrlData[7:0] = 8'h08;
  154. 6'h1C: MuxedCtrlData[7:0] = 8'h00; // Opcode
  155. 6'h1E: MuxedCtrlData[7:0] = 8'h01;
  156. 6'h20: MuxedCtrlData[7:0] = TxPauseTV[15:8]; // Pause timer value
  157. 6'h22: MuxedCtrlData[7:0] = TxPauseTV[7:0];
  158. default: MuxedCtrlData[7:0] = 8'h0;
  159. endcase
  160. end
  161. //锁存控制数据
  162. always @ (posedge MTxClk or posedge TxReset)
  163. begin
  164. if(TxReset)
  165. ControlData[7:0] <= #Tp 8'h0;
  166. else
  167. if(~ByteCnt[0])
  168. ControlData[7:0] <= #Tp MuxedCtrlData[7:0];
  169. end
  170. endmodule

更多回帖

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