以下进程用于判定给定帧是否是暂停帧:
- 执行检查,确认包属于全局控制包还是优先控制包。仅当C{0..5}_CONFIGURATION_RX_FLOW_CONTROL_REG1的c{0..5}_ctl_rx_forward_control字段设为 1 时,才会转发通过步骤 1 的包。
- 如果通过步骤 1,则会检查该包以判定它是否属于全局暂停包。
- 如果未通过步骤 2,则会检查该包以判定它是否属于优先暂停包。
在以下伪代码中所示,DA 表示目标地址,SA 表示源地址,OPCODE 为操作代码,而 ETYPE 则是从传入的包提取的“ethertype/length”字段。
对于步骤 1,用于检查功能的伪代码是:
assign da_match_gcp = (!ctl_rx_check_mcast_gcp && !ctl_rx_check_ucast_gcp) ||
((DA == ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_gcp) ||
((DA == 48'h0180c2000001) && ctl_rx_check_mcast_gcp);
assign sa_match_gcp = !ctl_rx_check_sa_gcp || (SA == ctl_rx_pause_sa);
assign etype_match_gcp = !ctl_rx_check_etype_gcp || (ETYPE == ctl_rx_etype_gcp);
assign opcode_match_gcp = !ctl_rx_check_opcode_gcp ||
((OPCODE >= ctl_rx_opcode_min_gcp) && (OPCODE <= ctl_rx_opcode_max_gcp));
assign global_control_packet = da_match_gcp && sa_match_gcp &&
etype_match_gcp && opcode_match_gcp && ctl_rx_enable_gcp;
assign da_match_pcp = (!ctl_rx_check_mcast_pcp && !ctl_rx_check_ucast_pcp) ||
((DA == ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_pcp) ||
((DA == ctl_rx_pause_da_mcast) && ctl_rx_check_mcast_pcp);
assign sa_match_pcp = !ctl_rx_check_sa_pcp || (SA == ctl_rx_pause_sa);
assign etype_match_pcp = !ctl_rx_check_etype_pcp || (ETYPE == ctl_rx_etype_pcp);
assign opcode_match_pcp = !ctl_rx_check_opcode_pcp ||
((OPCODE >= ctl_rx_opcode_min_pcp) && (OPCODE <= ctl_rx_opcode_max_pcp));
assign priority_control_packet = da_match_pcp && sa_match_pcp &&
etype_match_pcp && opcode_match_pcp && ctl_rx_enable_pcp;
assign control_packet = global_control_packet || priority_control_packet;
对于步骤 2,以下伪代码显示了检查功能:
assign da_match_gpp = (!ctl_rx_check_mcast_gpp && !ctl_rx_check_ucast_gpp) ||
((DA == ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_gpp) ||
((DA == 48'h0180c2000001) && ctl_rx_check_mcast_gpp);
assign sa_match_gpp = !ctl_rx_check_sa_gpp || (SA == ctl_rx_pause_sa);
assign etype_match_gpp = !ctl_rx_check_etype_gpp || (ETYPE == ctl_rx_etype_gpp);
assign opcode_match_gpp = !ctl_rx_check_opcode_gpp || (OPCODE == ctl_rx_opcode_gpp);
assign global_pause_packet = da_match_gpp && sa_match_gpp && etype_match_gpp &&
opcode_match_gpp && ctl_rx_enable_gpp;
对于步骤 3,以下伪代码显示了检查功能:assign da_match_ppp = (!ctl_rx_check_mcast_ppp && !ctl_rx_check_ucast_ppp) ||
((DA == ctl_rx_pause_da_ucast) && ctl_rx_check_ucast_ppp) ||
((DA == ctl_rx_pause_da_mcast) && ctl_rx_check_mcast_ppp);
assign sa_match_ppp = !ctl_rx_check_sa_ppp || (SA == ctl_rx_pause_sa);
assign etype_match_ppp = !ctl_rx_check_etype_ppp || (ETYPE == ctl_rx_etype_ppp);
assign opcode_match_ppp = !ctl_rx_check_opcode_ppp || (OPCODE == ctl_rx_opcode_ppp);
assign priority_pause_packet = da_match_ppp && sa_match_ppp && etype_match_ppp &&
opcode_match_ppp && ctl_rx_enable_ppp;