Line 1... |
Line 1... |
`timescale 1ns/1ns
|
`timescale 1ns/1ns
|
|
|
module ptp_parser (
|
module ptp_parser (
|
input clk, rst,
|
input clk, rst,
|
input [31:0] ptp_data,
|
input [31:0] int_data,
|
input ptp_valid,
|
input int_valid,
|
input ptp_sop,
|
input int_sop,
|
input ptp_eop,
|
input int_eop,
|
input [ 1:0] ptp_mod,
|
input [ 1:0] int_mod,
|
input [31:0] ptp_time,
|
input [31:0] sop_time,
|
|
|
output reg ptp_found,
|
output reg ptp_found,
|
output reg [51:0] ptp_infor
|
output reg [51:0] ptp_infor
|
);
|
);
|
|
|
reg [31:0] ptp_data_d1;
|
reg [31:0] int_data_d1;
|
reg ptp_valid_d1;
|
reg int_valid_d1;
|
reg ptp_sop_d1;
|
reg int_sop_d1;
|
reg ptp_eop_d1;
|
reg int_eop_d1;
|
reg [ 1:0] ptp_mod_d1;
|
reg [ 1:0] int_mod_d1;
|
always @(posedge rst or posedge clk) begin
|
always @(posedge rst or posedge clk) begin
|
if (rst) begin
|
if (rst) begin
|
ptp_data_d1 <= 32'h00000000;
|
int_data_d1 <= 32'h00000000;
|
ptp_valid_d1 <= 1'b0;
|
int_valid_d1 <= 1'b0;
|
ptp_sop_d1 <= 1'b0;
|
int_sop_d1 <= 1'b0;
|
ptp_eop_d1 <= 1'b0;
|
int_eop_d1 <= 1'b0;
|
ptp_mod_d1 <= 2'b00;
|
int_mod_d1 <= 2'b00;
|
end
|
end
|
else begin
|
else begin
|
if (ptp_valid) begin
|
if (int_valid) begin
|
ptp_data_d1 <= ptp_data;
|
int_data_d1 <= int_data;
|
ptp_mod_d1 <= ptp_mod;
|
int_mod_d1 <= int_mod;
|
end
|
end
|
ptp_valid_d1 <= ptp_valid;
|
int_valid_d1 <= int_valid;
|
ptp_sop_d1 <= ptp_sop;
|
int_sop_d1 <= int_sop;
|
ptp_eop_d1 <= ptp_eop;
|
int_eop_d1 <= int_eop;
|
end
|
end
|
end
|
end
|
|
|
reg [ 9:0] ptp_cnt;
|
reg [ 9:0] int_cnt, bypass_ipv4_cnt, bypass_ipv6_cnt, bypass_udp_cnt, ptp_cnt;
|
reg ptp_vlan, ptp_ip, ptp_udp, ptp_port, ptp_event;
|
reg bypass_vlan, ptp_l2, bypass_ipv4, bypass_ipv6, found_udp, bypass_udp, ptp_l4, ptp_event;
|
reg [ 3:0] ptp_msgid;
|
reg [ 3:0] ptp_msgid;
|
reg [15:0] ptp_seqid;
|
reg [15:0] ptp_seqid;
|
always @(posedge rst or posedge clk) begin
|
always @(posedge rst or posedge clk) begin
|
if (rst)
|
if (rst) begin
|
ptp_cnt <= 10'd0;
|
int_cnt <= 10'd0;
|
else
|
bypass_ipv4_cnt <= 10'd0;
|
if (ptp_valid && ptp_sop)
|
bypass_udp_cnt <= 10'd0;
|
ptp_cnt <= 10'd0;
|
end
|
else if (ptp_valid)
|
else begin
|
ptp_cnt <= ptp_cnt + 10'd1 - ptp_vlan;
|
if (int_valid_d1 && int_sop_d1)
|
|
int_cnt <= 10'd0;
|
|
else if (int_valid_d1)
|
|
int_cnt <= int_cnt + 10'd1 - bypass_vlan - (bypass_ipv4 || bypass_udp);
|
|
|
|
if (int_valid_d1 && int_sop_d1)
|
|
bypass_ipv4_cnt <= 10'd0;
|
|
else if (int_valid_d1 && bypass_ipv4)
|
|
bypass_ipv4_cnt <= bypass_ipv4_cnt + 10'd1;
|
|
|
|
if (int_valid_d1 && int_sop_d1)
|
|
bypass_udp_cnt <= 10'd0;
|
|
else if (int_valid_d1 && bypass_udp)
|
|
bypass_udp_cnt <= bypass_udp_cnt + 10'd1;
|
|
end
|
end
|
end
|
|
|
always @(posedge rst or posedge clk) begin
|
always @(posedge rst or posedge clk) begin
|
if (rst) begin
|
if (rst) begin
|
ptp_vlan <= 1'b0;
|
bypass_vlan <= 1'b0;
|
ptp_ip <= 1'b0;
|
bypass_ipv4 <= 1'b0;
|
ptp_udp <= 1'b0;
|
found_udp <= 1'b0;
|
ptp_port <= 1'b0;
|
bypass_udp <= 1'b0;
|
|
ptp_l2 <= 1'b0;
|
|
ptp_l4 <= 1'b0;
|
ptp_event <= 1'b0;
|
ptp_event <= 1'b0;
|
|
end
|
|
else if (int_valid_d1 && int_sop_d1) begin
|
|
bypass_vlan <= 1'b0;
|
|
bypass_ipv4 <= 1'b0;
|
|
found_udp <= 1'b0;
|
|
bypass_udp <= 1'b0;
|
|
ptp_l2 <= 1'b0;
|
|
ptp_l4 <= 1'b0;
|
|
ptp_event <= 1'b0;
|
|
end
|
|
else begin
|
|
// bypass vlan
|
|
// ether_type == cvlan
|
|
if (int_valid_d1 && int_cnt==10'd3 && int_data_d1[31:16]==16'h8100)
|
|
bypass_vlan <= 1'b1;
|
|
else
|
|
bypass_vlan <= 1'b0;
|
|
// ether_type == svlan
|
|
// TO BE ADDED HERE
|
|
|
|
// bypass ipv4
|
|
// ether_type == ip, ip_version == 4
|
|
if (int_valid_d1 && int_cnt==10'd3 && bypass_ipv4_cnt==10'd0 &&
|
|
int_data_d1[31:16]==16'h0800 && int_data_d1[15:12]==4'h4)
|
|
bypass_ipv4 <= 1'b1;
|
|
else if (int_valid_d1 && bypass_ipv4_cnt==10'd4)
|
|
bypass_ipv4 <= 1'b0;
|
|
|
|
// bypass ipv6
|
|
// ether_type == ip, ip_version == 6
|
|
// TO BE ADDED HERE
|
|
|
|
// check if it is UDP
|
|
// ipv4_protocol == udp
|
|
if (int_valid_d1 && bypass_ipv4_cnt==10'd1 && int_data_d1[ 7: 0]== 8'h11)
|
|
found_udp <= 1'b1;
|
|
// ipv6_protocol == udp
|
|
// TO BE ADDED HERE
|
|
|
|
// bypass udp
|
|
// ipv4_udp
|
|
if (int_valid_d1 && bypass_ipv4_cnt==10'd4 && bypass_udp_cnt==10'd0 && found_udp)
|
|
bypass_udp <= 1'b1;
|
|
else if (int_valid_d1 && bypass_udp_cnt==10'd2)
|
|
bypass_udp <= 1'b0;
|
|
// ipv6_udp
|
|
// TO BE ADDED HERE
|
|
|
|
// check if it is L2 PTP
|
|
// ether_type == ptp
|
|
if (int_valid_d1 && int_cnt==10'd3 && int_data_d1[31:16]==16'h88F7)
|
|
ptp_l2 <= 1'b1;
|
|
// check if it is L4 PTP
|
|
// ipv4_udp_dest_port == ptp_event
|
|
if (int_valid_d1 && bypass_udp_cnt==10'd0 && bypass_udp && int_data_d1[31:16]==16'h013f)
|
|
ptp_l4 <= 1'b1;
|
|
// ipv6_udp_dest_port == ptp_event
|
|
// TO BE ADDED HERE
|
|
|
|
// check if it is PTP Event message
|
|
if (int_valid_d1 && int_cnt==10'd3 && int_data_d1[31:16]==16'h88F7 && (int_data_d1[11: 8]== 4'h0 || int_data_d1[11:8]==4'h2))
|
|
// ptp_message_id == sync || delay_req
|
|
ptp_event <= 1'b1;
|
|
else if (int_valid_d1 && int_cnt==10'd4 && bypass_udp_cnt==10'd1 && ptp_l4 && (int_data_d1[11: 8]== 4'h0 || int_data_d1[11:8]==4'h2))
|
|
// ptp_message_id == sync || delay_req
|
|
ptp_event <= 1'b1;
|
|
end
|
|
end
|
|
|
|
always @(posedge rst or posedge clk) begin
|
|
if (rst) begin
|
ptp_msgid <= 4'd0;
|
ptp_msgid <= 4'd0;
|
ptp_seqid <= 16'd0;
|
ptp_seqid <= 16'd0;
|
end
|
end
|
else if (ptp_valid_d1 && ptp_sop_d1) begin
|
else if (int_valid_d1 && int_sop_d1) begin
|
ptp_vlan <= 1'b0;
|
|
ptp_ip <= 1'b0;
|
|
ptp_udp <= 1'b0;
|
|
ptp_port <= 1'b0;
|
|
ptp_event <= 1'b0;
|
|
ptp_msgid <= 4'd0;
|
ptp_msgid <= 4'd0;
|
ptp_seqid <= 16'd0;
|
ptp_seqid <= 16'd0;
|
end
|
end
|
else begin
|
else begin
|
if (ptp_valid_d1 && ptp_cnt==10'd4) // ether_type == vlan
|
// get PTP identification information as additional information to Timestamp
|
ptp_vlan <= ( ptp_data_d1[31:16]==16'h8100);
|
// message id
|
else
|
if (int_valid_d1 && int_cnt==10'd3 && int_data_d1[31:16]==16'h88F7)
|
ptp_vlan <= 1'b0;
|
ptp_msgid <= int_data_d1[11: 8];
|
if (ptp_valid_d1 && ptp_cnt==10'd4) // ether_type == ip
|
else if (int_valid_d1 && int_cnt==10'd4 && bypass_udp_cnt==10'd1 && ptp_l4)
|
ptp_ip <= ( ptp_data_d1[31:16]==16'h0800);
|
ptp_msgid <= int_data_d1[11: 8];
|
if (ptp_valid_d1 && ptp_cnt==10'd6) // ip_type == udp
|
// sequence id
|
ptp_udp <= ( ptp_data_d1[ 7: 0]== 8'h11 && ptp_ip);
|
if (int_valid_d1 && int_cnt==10'd11 && ptp_l2)
|
if (ptp_valid_d1 && ptp_cnt==10'd10) // udp_dest_port == ptp_event
|
ptp_seqid <= int_data_d1[31:16];
|
ptp_port <= ( ptp_data_d1[31:16]==16'h013f && ptp_udp);
|
else if (int_valid_d1 && int_cnt==10'd10 && ptp_l4)
|
if (ptp_valid_d1 && ptp_cnt==10'd11) // ptp_message_id == sync || delay_req
|
ptp_seqid <= int_data_d1[31:16];
|
ptp_event <= ((ptp_data_d1[11: 8]== 4'h0 || ptp_data_d1[11:8]==4'h2) && ptp_port);
|
|
|
|
if (ptp_valid_d1 && ptp_cnt==10'd11) // ptp_sequence_id
|
|
ptp_msgid <= ptp_data_d1[11: 8];
|
|
if (ptp_valid_d1 && ptp_cnt==10'd19) // ptp_sequence_id
|
|
ptp_seqid <= ptp_data_d1[31:16];
|
|
end
|
end
|
end
|
end
|
|
|
always @(posedge rst or posedge clk) begin
|
always @(posedge rst or posedge clk) begin
|
if (rst) begin
|
if (rst) begin
|
ptp_found <= 1'b0;
|
ptp_found <= 1'b0;
|
ptp_infor <= 52'd0;
|
ptp_infor <= 52'd0;
|
end
|
end
|
else if (ptp_valid_d1 && ptp_sop_d1) begin
|
else if (int_valid_d1 && int_sop_d1) begin
|
ptp_found <= 1'b0;
|
ptp_found <= 1'b0;
|
ptp_infor <= 52'd0;
|
ptp_infor <= 52'd0;
|
end
|
end
|
else if (ptp_valid_d1 && ptp_eop_d1) begin
|
else if (int_valid_d1 && int_eop_d1) begin
|
ptp_found <= ptp_event;
|
ptp_found <= ptp_event;
|
ptp_infor <= {ptp_seqid, ptp_msgid, ptp_time}; // 16+4+32
|
ptp_infor <= {ptp_seqid, ptp_msgid, sop_time}; // 16+4+32
|
end
|
end
|
else begin
|
else begin
|
ptp_found <= 1'b0;
|
ptp_found <= 1'b0;
|
ptp_infor <= 52'd0;
|
ptp_infor <= 52'd0;
|
end
|
end
|