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

Subversion Repositories ha1588

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

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

powered by: WebSVN 2.1.0

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