ZHCSYD5 June 2025 DAC39RF20
ADVANCE INFORMATION
initial begin
int tries;
int arrival [];
// 根据启动程序启动链路。RBD 的任何值都正常。
// 请注意,不能设置 LINK_UP,因为 RBD 可能无效。
startup_link();
// 等待 LANE_ARR_RDY 变为高电平
// 1000 次尝试后放弃。
tries = 0;
while(read_reg(LANE_ARR_RDY)==0 && tries<1000)
tries++;
// 对所有通道读取 LANE_ARR
arrival = new [L];
foreach(arrival[i]) arrival[i] = read_reg(LANE_ARR[i]);
RBD = determine_RBD(arrival, K*F/8);
// 使用此 RBD 值重新启动链路
end
// 此函数根据到达时间数组计算 RBD
function determine_RBD(
int arrival [], // 来自 LANE_ARR 的到达时间动态数组
int oneMF // 每个多帧/EMB 的八字节数
);
int spacing, max_spacing;
int latest, earliest;
int L, early_overwrite;
int AM, EB_size;
// 缓冲区大小最多为 16 个八字节,但不能超过 oneMF
EB_size = oneMF > 16 ? 16 : oneMF;
// LANE_ARR 的模值
AM = JENC ? 32*E : 32;
// 通道数目是到达数组的大小
L = arrival.size;
// 按数字升序对到达列表进行排序
arrival.sort;
// 找到到达时间之间的最大间距(在圆上)
max_spacing = 0;
for(int i = 0; i<L; i++) begin
spacing = arrival[(i+1)%L] – arrival[i] + (i==L-1)*AM;
if(spacing>max_spacing) begin
max_spacing = spacing;
latest = arrival[i];
earliest = arrival[(i+1)%L];
end
end
// 检查通道偏斜,确认其对于弹性缓冲器不会过大
if ( (latest-earliest+AM)%AM >= EB_size ) begin
$display(“ERROR: Lane skew too large for elastic buffer”);
$display(“ Earliest=%0d Latest=%0d”);
return 0;
end
// 选择让 RBD 位于最新到达通道 (+1) 和时刻之间的中间位置
// 最早的通道开始覆盖弹性缓冲器。
early_overwrite = (earliest+EB_size)%AM;
if(early_overwrite < latest+1) early_overwrite += AM;
return (latest+1+early_overwrite)/2 % oneMF;
endfunction