OpenCores
URL https://opencores.org/ocsvn/ha1588/ha1588/trunk

Subversion Repositories ha1588

[/] [ha1588/] [trunk/] [rtl/] [tsu/] [ptp_parser.v] - Blame information for rev 36

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 edn_walter
/*
2
 * $ptp_parser.v
3
 *
4
 * Copyright (c) 2012, BBY&HW. All rights reserved.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA 02110-1301  USA
20
 */
21
 
22 4 ash_riple
`timescale 1ns/1ns
23
 
24
module ptp_parser (
25
  input        clk, rst,
26 10 edn_walter
  input [31:0] int_data,
27
  input        int_valid,
28
  input        int_sop,
29
  input        int_eop,
30
  input [ 1:0] int_mod,
31 4 ash_riple
 
32
  output reg        ptp_found,
33 27 edn_walter
  output reg [19:0] ptp_infor
34 4 ash_riple
);
35
 
36 10 edn_walter
reg [31:0] int_data_d1;
37 4 ash_riple
always @(posedge rst or posedge clk) begin
38
  if (rst) begin
39 10 edn_walter
    int_data_d1  <= 32'h00000000;
40 4 ash_riple
  end
41
  else begin
42 10 edn_walter
    if (int_valid) begin
43
      int_data_d1  <= int_data;
44 4 ash_riple
    end
45
  end
46
end
47
 
48 29 edn_walter
// packet parser: counter
49 10 edn_walter
reg [ 9:0] int_cnt, bypass_ipv4_cnt, bypass_ipv6_cnt, bypass_udp_cnt, ptp_cnt;
50 35 edn_walter
reg bypass_vlan, ptp_l2, bypass_mpls, bypass_ipv4, bypass_ipv6, found_udp, bypass_udp, ptp_l4, ptp_event;
51 8 edn_walter
reg [ 3:0] ptp_msgid;
52
reg [15:0] ptp_seqid;
53 4 ash_riple
always @(posedge rst or posedge clk) begin
54 10 edn_walter
  if (rst) begin
55
    int_cnt <= 10'd0;
56
    bypass_ipv4_cnt <= 10'd0;
57 11 edn_walter
    bypass_ipv6_cnt <= 10'd0;
58 10 edn_walter
    bypass_udp_cnt <= 10'd0;
59
  end
60
  else begin
61 29 edn_walter
    if (int_valid && int_sop)
62 10 edn_walter
      int_cnt <= 10'd0;
63 29 edn_walter
    else if (int_valid)
64 35 edn_walter
      int_cnt <= int_cnt + 10'd1 - bypass_vlan - bypass_mpls - (bypass_ipv4 || bypass_ipv6 || bypass_udp);
65 10 edn_walter
 
66 29 edn_walter
    if (int_valid && int_sop)
67 10 edn_walter
      bypass_ipv4_cnt <= 10'd0;
68 29 edn_walter
    else if (int_valid && bypass_ipv4)
69 10 edn_walter
      bypass_ipv4_cnt <= bypass_ipv4_cnt + 10'd1;
70
 
71 29 edn_walter
    if (int_valid && int_sop)
72 11 edn_walter
      bypass_ipv6_cnt <= 10'd0;
73 29 edn_walter
    else if (int_valid && bypass_ipv6)
74 11 edn_walter
      bypass_ipv6_cnt <= bypass_ipv6_cnt + 10'd1;
75
 
76 29 edn_walter
    if (int_valid && int_sop)
77 10 edn_walter
      bypass_udp_cnt <= 10'd0;
78 29 edn_walter
    else if (int_valid && bypass_udp)
79 10 edn_walter
      bypass_udp_cnt <= bypass_udp_cnt + 10'd1;
80 29 edn_walter
 
81
    if (int_valid && int_sop)
82
      ptp_cnt <= 10'd0;
83
    else if (int_valid && (ptp_l2 || (bypass_udp_cnt>=10'd2 && ptp_l4)))
84
      ptp_cnt <= ptp_cnt + 10'd1;
85 10 edn_walter
  end
86 4 ash_riple
end
87
 
88 29 edn_walter
// packet parser: comparator
89 4 ash_riple
always @(posedge rst or posedge clk) begin
90
  if (rst) begin
91 10 edn_walter
    bypass_vlan  <= 1'b0;
92 35 edn_walter
    bypass_mpls  <= 1'b0;
93 10 edn_walter
    bypass_ipv4  <= 1'b0;
94 11 edn_walter
    bypass_ipv6  <= 1'b0;
95 10 edn_walter
    found_udp    <= 1'b0;
96
    bypass_udp   <= 1'b0;
97
    ptp_l2    <= 1'b0;
98
    ptp_l4    <= 1'b0;
99 4 ash_riple
    ptp_event <= 1'b0;
100 10 edn_walter
  end
101 29 edn_walter
  else if (int_valid && int_sop) begin
102 10 edn_walter
    bypass_vlan  <= 1'b0;
103 35 edn_walter
    bypass_mpls  <= 1'b0;
104 10 edn_walter
    bypass_ipv4  <= 1'b0;
105 11 edn_walter
    bypass_ipv6  <= 1'b0;
106 10 edn_walter
    found_udp    <= 1'b0;
107
    bypass_udp   <= 1'b0;
108
    ptp_l2    <= 1'b0;
109
    ptp_l4    <= 1'b0;
110
    ptp_event <= 1'b0;
111
  end
112
  else begin
113
    // bypass vlan
114 29 edn_walter
    if      (int_valid && int_cnt==10'd3 && int_data[31:16]==16'h8100)  // ether_type == cvlan
115 10 edn_walter
      bypass_vlan <= 1'b1;
116 29 edn_walter
    else if (int_valid && int_cnt==10'd3 && int_data[31:16]==16'h9100)  // ether_type == svlan
117 12 edn_walter
      bypass_vlan <= 1'b1;
118 29 edn_walter
    else if (int_valid && int_cnt==10'd4 && int_data[31:16]==16'h8100 && bypass_vlan)  // svlan_type == cvlan
119 12 edn_walter
      bypass_vlan <= 1'b1;
120 29 edn_walter
    else if (int_valid && bypass_vlan)
121 10 edn_walter
      bypass_vlan <= 1'b0;
122
 
123 35 edn_walter
    // bypass mpls
124
    if      (int_valid && (int_cnt==10'd3 || bypass_vlan && int_cnt==10'd4) &&
125
            (int_data[31:16]==16'h8847 || int_data[31:16]==16'h8848))  // ether_type == mpls
126
      bypass_mpls <= 1'b1;
127
    else if (int_valid &&  int_cnt==10'd4 && bypass_mpls &&
128
             int_data[24]==1'b0)  // bottom of label stack == 0
129
      bypass_mpls <= 1'b1;
130
    else if (int_valid && bypass_mpls)
131
      bypass_mpls <= 1'b0;
132
 
133 10 edn_walter
    // bypass ipv4
134 35 edn_walter
    if      (int_valid && (int_cnt==10'd3 || (bypass_vlan || bypass_mpls) && int_cnt==10'd4) && bypass_ipv4_cnt==10'd0 &&
135
            (int_data[31:16]==16'h0800 || bypass_mpls) && int_data[15:12]==4'h4)  // ether_type == ipv4, ip_version == 4
136 10 edn_walter
      bypass_ipv4 <= 1'b1;
137 29 edn_walter
    else if (int_valid && bypass_ipv4_cnt==10'd4)
138 10 edn_walter
      bypass_ipv4 <= 1'b0;
139
 
140
    // bypass ipv6
141 35 edn_walter
    if      (int_valid && (int_cnt==10'd3 || (bypass_vlan || bypass_mpls) && int_cnt==10'd4) && bypass_ipv6_cnt==10'd0 &&
142
            (int_data[31:16]==16'h86dd || bypass_mpls) && int_data[15:12]==4'h6)  // ether_type == ipv6, ip_version == 6
143 11 edn_walter
      bypass_ipv6 <= 1'b1;
144 29 edn_walter
    else if (int_valid && bypass_ipv6_cnt==10'd9)
145 11 edn_walter
      bypass_ipv6 <= 1'b0;
146 10 edn_walter
 
147
    // check if it is UDP
148 29 edn_walter
    if      (int_valid && bypass_ipv4_cnt==10'd1 && int_data[ 7: 0]== 8'h11)  // ipv4_protocol == udp
149 10 edn_walter
      found_udp <= 1'b1;
150 29 edn_walter
    else if (int_valid && bypass_ipv6_cnt==10'd1 && int_data[31:24]== 8'h11)  // ipv6_protocol == udp
151 11 edn_walter
      found_udp <= 1'b1;
152 10 edn_walter
 
153
    // bypass udp
154 29 edn_walter
    if      (int_valid && bypass_ipv4_cnt==10'd4 && bypass_udp_cnt==10'd0 && found_udp)  // ipv4_udp
155 10 edn_walter
      bypass_udp <= 1'b1;
156 29 edn_walter
    else if (int_valid && bypass_ipv6_cnt==10'd9 && bypass_udp_cnt==10'd0 && found_udp)  // ipv6_udp
157 11 edn_walter
      bypass_udp <= 1'b1;
158 29 edn_walter
    else if (int_valid && bypass_udp_cnt==10'd2)
159 11 edn_walter
      bypass_udp <= 1'b0;
160 10 edn_walter
 
161
    // check if it is L2 PTP
162 29 edn_walter
    if (int_valid && (int_cnt==10'd3 || bypass_vlan && int_cnt==10'd4) && int_data[31:16]==16'h88F7)  // ether_type == ptp
163 10 edn_walter
      ptp_l2 <= 1'b1;
164
    // check if it is L4 PTP
165 29 edn_walter
    if (int_valid && bypass_udp_cnt==10'd0 && bypass_udp &&
166
       (int_data[31:16]==16'h013f || int_data[31:16]==16'h0140))  // udp_dest_port == ptp_event || ptp_general
167 10 edn_walter
      ptp_l4 <= 1'b1;
168
 
169
    // check if it is PTP Event message
170 35 edn_walter
    if      (int_valid && (int_cnt==10'd3 || bypass_vlan && int_cnt==10'd4) && int_data[31:16]==16'h88F7 &&
171 29 edn_walter
            (int_data[11: 8]== 4'h0 || int_data[11:8]==4'h2))  // ptp_message_id == sync || delay_req
172 10 edn_walter
      ptp_event <= 1'b1;
173 35 edn_walter
    else if (int_valid && int_cnt==10'd4 && bypass_udp_cnt==10'd1 && ptp_l4 &&
174 29 edn_walter
            (int_data[11: 8]== 4'h0 || int_data[11:8]==4'h2))  // ptp_message_id == sync || delay_req
175 10 edn_walter
      ptp_event <= 1'b1;
176
  end
177
end
178
 
179 29 edn_walter
// ptp message
180
reg [31:0] ptp_data;
181 10 edn_walter
always @(posedge rst or posedge clk) begin
182
  if (rst) begin
183 29 edn_walter
    ptp_data  <= 32'd0;
184 7 edn_walter
    ptp_msgid <= 4'd0;
185 8 edn_walter
    ptp_seqid <= 16'd0;
186 4 ash_riple
  end
187 29 edn_walter
  else if (int_valid && int_sop) begin
188
    ptp_data  <= 32'd0;
189 7 edn_walter
    ptp_msgid <= 4'd0;
190 8 edn_walter
    ptp_seqid <= 16'd0;
191 4 ash_riple
  end
192
  else begin
193 10 edn_walter
    // get PTP identification information as additional information to Timestamp
194 29 edn_walter
    // ptp message body
195
    if (int_valid && (ptp_l2 || (bypass_udp_cnt>=10'd2 && ptp_l4)))
196
      ptp_data <= {int_data_d1[15:0], int_data[31:16]};
197 10 edn_walter
    // message id
198 29 edn_walter
    if (int_valid && ptp_cnt==10'd1)
199
      ptp_msgid <=   ptp_data[27:24];
200 10 edn_walter
    // sequence id
201 29 edn_walter
    if (int_valid && ptp_cnt==10'd8)
202
      ptp_seqid <=   ptp_data[15:0];
203 4 ash_riple
  end
204
end
205
 
206 29 edn_walter
// parser output
207 4 ash_riple
always @(posedge rst or posedge clk) begin
208
  if (rst) begin
209
    ptp_found <=  1'b0;
210 27 edn_walter
    ptp_infor <= 20'd0;
211 4 ash_riple
  end
212 29 edn_walter
  else if (int_valid && int_sop) begin
213 4 ash_riple
    ptp_found <=  1'b0;
214 27 edn_walter
    ptp_infor <= 20'd0;
215 4 ash_riple
  end
216 29 edn_walter
  else if (int_valid && ptp_cnt==10'd9) begin
217 4 ash_riple
    ptp_found <=  ptp_event;
218 29 edn_walter
    ptp_infor <= {ptp_msgid, ptp_seqid};  // 4+16
219 4 ash_riple
  end
220
end
221
 
222
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.