在数据传输过程中发生冲突时,数据发送模块首先发送“0x99999999”,然后结束传输。在传输重新开始以前,数据发送模块会做一些补偿。即在重新传输数据以前进行一定时间延迟,延迟时间的长短由错误处理模块产生的随机数决定。这样可以减少再次发生数据冲突的次数。这种随机数采用一种叫做二进制指数补偿算法(Binary Exponen
tial 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
- 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,发送“0x99999999”后锁存产生的随机数
- always @ (posedge MTxClk or posedge Reset)
- begin
- if(Reset)
- RandomLatched <= #Tp 10'h000;
- else
- begin
- if(StateJam & StateJam_q)
- RandomLatched <= #Tp Random;
- end
- end
- // 随机数为 0
- assign RandomEq0 = RandomLatched == 10'h0;
- assign RandomEqByteCnt = ByteCnt[9:0] == RandomLatched & (&NibCnt[6:0]);
- endmodule