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

Subversion Repositories ha1588

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

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

Line No. Rev Author Line
1 34 edn_walter
/*
2 38 edn_walter
 * ptp_parser.v
3 34 edn_walter
 *
4 37 edn_walter
 * Copyright (c) 2012, BABY&HW. All rights reserved.
5 34 edn_walter
 *
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 37 edn_walter
  output reg [31: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 4 ash_riple
always @(posedge rst or posedge clk) begin
52 10 edn_walter
  if (rst) begin
53
    int_cnt <= 10'd0;
54
    bypass_ipv4_cnt <= 10'd0;
55 11 edn_walter
    bypass_ipv6_cnt <= 10'd0;
56 10 edn_walter
    bypass_udp_cnt <= 10'd0;
57
  end
58
  else begin
59 29 edn_walter
    if (int_valid && int_sop)
60 10 edn_walter
      int_cnt <= 10'd0;
61 29 edn_walter
    else if (int_valid)
62 35 edn_walter
      int_cnt <= int_cnt + 10'd1 - bypass_vlan - bypass_mpls - (bypass_ipv4 || bypass_ipv6 || bypass_udp);
63 10 edn_walter
 
64 29 edn_walter
    if (int_valid && int_sop)
65 10 edn_walter
      bypass_ipv4_cnt <= 10'd0;
66 29 edn_walter
    else if (int_valid && bypass_ipv4)
67 10 edn_walter
      bypass_ipv4_cnt <= bypass_ipv4_cnt + 10'd1;
68
 
69 29 edn_walter
    if (int_valid && int_sop)
70 11 edn_walter
      bypass_ipv6_cnt <= 10'd0;
71 29 edn_walter
    else if (int_valid && bypass_ipv6)
72 11 edn_walter
      bypass_ipv6_cnt <= bypass_ipv6_cnt + 10'd1;
73
 
74 29 edn_walter
    if (int_valid && int_sop)
75 10 edn_walter
      bypass_udp_cnt <= 10'd0;
76 29 edn_walter
    else if (int_valid && bypass_udp)
77 10 edn_walter
      bypass_udp_cnt <= bypass_udp_cnt + 10'd1;
78 29 edn_walter
 
79
    if (int_valid && int_sop)
80
      ptp_cnt <= 10'd0;
81
    else if (int_valid && (ptp_l2 || (bypass_udp_cnt>=10'd2 && ptp_l4)))
82
      ptp_cnt <= ptp_cnt + 10'd1;
83 10 edn_walter
  end
84 4 ash_riple
end
85
 
86 29 edn_walter
// packet parser: comparator
87 4 ash_riple
always @(posedge rst or posedge clk) begin
88
  if (rst) begin
89 10 edn_walter
    bypass_vlan  <= 1'b0;
90 35 edn_walter
    bypass_mpls  <= 1'b0;
91 10 edn_walter
    bypass_ipv4  <= 1'b0;
92 11 edn_walter
    bypass_ipv6  <= 1'b0;
93 10 edn_walter
    found_udp    <= 1'b0;
94
    bypass_udp   <= 1'b0;
95
    ptp_l2    <= 1'b0;
96
    ptp_l4    <= 1'b0;
97 4 ash_riple
    ptp_event <= 1'b0;
98 10 edn_walter
  end
99 29 edn_walter
  else if (int_valid && int_sop) begin
100 10 edn_walter
    bypass_vlan  <= 1'b0;
101 35 edn_walter
    bypass_mpls  <= 1'b0;
102 10 edn_walter
    bypass_ipv4  <= 1'b0;
103 11 edn_walter
    bypass_ipv6  <= 1'b0;
104 10 edn_walter
    found_udp    <= 1'b0;
105
    bypass_udp   <= 1'b0;
106
    ptp_l2    <= 1'b0;
107
    ptp_l4    <= 1'b0;
108
    ptp_event <= 1'b0;
109
  end
110
  else begin
111
    // bypass vlan
112 29 edn_walter
    if      (int_valid && int_cnt==10'd3 && int_data[31:16]==16'h8100)  // ether_type == cvlan
113 10 edn_walter
      bypass_vlan <= 1'b1;
114 29 edn_walter
    else if (int_valid && int_cnt==10'd3 && int_data[31:16]==16'h9100)  // ether_type == svlan
115 12 edn_walter
      bypass_vlan <= 1'b1;
116 29 edn_walter
    else if (int_valid && int_cnt==10'd4 && int_data[31:16]==16'h8100 && bypass_vlan)  // svlan_type == cvlan
117 12 edn_walter
      bypass_vlan <= 1'b1;
118 29 edn_walter
    else if (int_valid && bypass_vlan)
119 10 edn_walter
      bypass_vlan <= 1'b0;
120
 
121 35 edn_walter
    // bypass mpls
122
    if      (int_valid && (int_cnt==10'd3 || bypass_vlan && int_cnt==10'd4) &&
123
            (int_data[31:16]==16'h8847 || int_data[31:16]==16'h8848))  // ether_type == mpls
124
      bypass_mpls <= 1'b1;
125
    else if (int_valid &&  int_cnt==10'd4 && bypass_mpls &&
126
             int_data[24]==1'b0)  // bottom of label stack == 0
127
      bypass_mpls <= 1'b1;
128
    else if (int_valid && bypass_mpls)
129
      bypass_mpls <= 1'b0;
130
 
131 10 edn_walter
    // bypass ipv4
132 35 edn_walter
    if      (int_valid && (int_cnt==10'd3 || (bypass_vlan || bypass_mpls) && int_cnt==10'd4) && bypass_ipv4_cnt==10'd0 &&
133
            (int_data[31:16]==16'h0800 || bypass_mpls) && int_data[15:12]==4'h4)  // ether_type == ipv4, ip_version == 4
134 10 edn_walter
      bypass_ipv4 <= 1'b1;
135 29 edn_walter
    else if (int_valid && bypass_ipv4_cnt==10'd4)
136 10 edn_walter
      bypass_ipv4 <= 1'b0;
137
 
138
    // bypass ipv6
139 35 edn_walter
    if      (int_valid && (int_cnt==10'd3 || (bypass_vlan || bypass_mpls) && int_cnt==10'd4) && bypass_ipv6_cnt==10'd0 &&
140
            (int_data[31:16]==16'h86dd || bypass_mpls) && int_data[15:12]==4'h6)  // ether_type == ipv6, ip_version == 6
141 11 edn_walter
      bypass_ipv6 <= 1'b1;
142 29 edn_walter
    else if (int_valid && bypass_ipv6_cnt==10'd9)
143 11 edn_walter
      bypass_ipv6 <= 1'b0;
144 10 edn_walter
 
145
    // check if it is UDP
146 29 edn_walter
    if      (int_valid && bypass_ipv4_cnt==10'd1 && int_data[ 7: 0]== 8'h11)  // ipv4_protocol == udp
147 10 edn_walter
      found_udp <= 1'b1;
148 29 edn_walter
    else if (int_valid && bypass_ipv6_cnt==10'd1 && int_data[31:24]== 8'h11)  // ipv6_protocol == udp
149 11 edn_walter
      found_udp <= 1'b1;
150 10 edn_walter
 
151
    // bypass udp
152 29 edn_walter
    if      (int_valid && bypass_ipv4_cnt==10'd4 && bypass_udp_cnt==10'd0 && found_udp)  // ipv4_udp
153 10 edn_walter
      bypass_udp <= 1'b1;
154 29 edn_walter
    else if (int_valid && bypass_ipv6_cnt==10'd9 && bypass_udp_cnt==10'd0 && found_udp)  // ipv6_udp
155 11 edn_walter
      bypass_udp <= 1'b1;
156 29 edn_walter
    else if (int_valid && bypass_udp_cnt==10'd2)
157 11 edn_walter
      bypass_udp <= 1'b0;
158 10 edn_walter
 
159
    // check if it is L2 PTP
160 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
161 10 edn_walter
      ptp_l2 <= 1'b1;
162
    // check if it is L4 PTP
163 29 edn_walter
    if (int_valid && bypass_udp_cnt==10'd0 && bypass_udp &&
164
       (int_data[31:16]==16'h013f || int_data[31:16]==16'h0140))  // udp_dest_port == ptp_event || ptp_general
165 10 edn_walter
      ptp_l4 <= 1'b1;
166
 
167
    // check if it is PTP Event message
168 35 edn_walter
    if      (int_valid && (int_cnt==10'd3 || bypass_vlan && int_cnt==10'd4) && int_data[31:16]==16'h88F7 &&
169 37 edn_walter
            (int_data[11: 8]>= 4'h0 && int_data[11:8]<=4'h7))  // ptp_message_id == ptp_event
170 10 edn_walter
      ptp_event <= 1'b1;
171 35 edn_walter
    else if (int_valid && int_cnt==10'd4 && bypass_udp_cnt==10'd1 && ptp_l4 &&
172 37 edn_walter
            (int_data[11: 8]>= 4'h0 && int_data[11:8]<=4'h7))  // ptp_message_id == ptp_event
173 10 edn_walter
      ptp_event <= 1'b1;
174
  end
175
end
176
 
177 29 edn_walter
// ptp message
178
reg [31:0] ptp_data;
179 37 edn_walter
reg [ 3:0] ptp_msgid;
180
reg [15:0] ptp_seqid;
181
reg [11:0] ptp_cksum;
182 10 edn_walter
always @(posedge rst or posedge clk) begin
183
  if (rst) begin
184 29 edn_walter
    ptp_data  <= 32'd0;
185 7 edn_walter
    ptp_msgid <= 4'd0;
186 8 edn_walter
    ptp_seqid <= 16'd0;
187 37 edn_walter
    ptp_cksum <= 12'd0;
188 4 ash_riple
  end
189 29 edn_walter
  else if (int_valid && int_sop) begin
190
    ptp_data  <= 32'd0;
191 7 edn_walter
    ptp_msgid <= 4'd0;
192 8 edn_walter
    ptp_seqid <= 16'd0;
193 37 edn_walter
    ptp_cksum <= 12'd0;
194 4 ash_riple
  end
195
  else begin
196 10 edn_walter
    // get PTP identification information as additional information to Timestamp
197 29 edn_walter
    // ptp message body
198
    if (int_valid && (ptp_l2 || (bypass_udp_cnt>=10'd2 && ptp_l4)))
199
      ptp_data <= {int_data_d1[15:0], int_data[31:16]};
200 10 edn_walter
    // message id
201 29 edn_walter
    if (int_valid && ptp_cnt==10'd1)
202 37 edn_walter
      ptp_msgid <= ptp_data[27:24];
203 10 edn_walter
    // sequence id
204 29 edn_walter
    if (int_valid && ptp_cnt==10'd8)
205 37 edn_walter
      ptp_seqid <= ptp_data[15:0];
206
    // sum up clock id and source port id
207
    if (int_valid && ptp_cnt==10'd6)
208
      ptp_cksum <= ptp_data[31:24] + ptp_data[23:16] + ptp_data[15: 8] + ptp_data[ 7: 0] + ptp_cksum;
209
    if (int_valid && ptp_cnt==10'd7)
210
      ptp_cksum <= ptp_data[31:24] + ptp_data[23:16] + ptp_data[15: 8] + ptp_data[ 7: 0] + ptp_cksum;
211
    if (int_valid && ptp_cnt==10'd8)
212
      ptp_cksum <= ptp_data[31:24] + ptp_data[23:16]                                     + ptp_cksum;
213 4 ash_riple
  end
214
end
215
 
216 29 edn_walter
// parser output
217 4 ash_riple
always @(posedge rst or posedge clk) begin
218
  if (rst) begin
219
    ptp_found <=  1'b0;
220 37 edn_walter
    ptp_infor <= 32'd0;
221 4 ash_riple
  end
222 29 edn_walter
  else if (int_valid && int_sop) begin
223 4 ash_riple
    ptp_found <=  1'b0;
224 37 edn_walter
    ptp_infor <= 32'd0;
225 4 ash_riple
  end
226 29 edn_walter
  else if (int_valid && ptp_cnt==10'd9) begin
227 4 ash_riple
    ptp_found <=  ptp_event;
228 37 edn_walter
    ptp_infor <= {ptp_msgid, ptp_cksum, ptp_seqid};  // 4+12+16
229 4 ash_riple
  end
230
end
231
 
232
endmodule

powered by: WebSVN 2.1.0

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