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

Subversion Repositories ha1588

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 edn_walter
/*
2 38 edn_walter
 * tsu.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 15 edn_walter
module tsu (
25 4 ash_riple
    input       rst,
26
 
27
    input       gmii_clk,
28
    input       gmii_ctrl,
29
    input [7:0] gmii_data,
30 54 edn_walter
    input       giga_mode,
31 43 edn_walter
 
32
    input [7:0] ptp_msgid_mask,
33 4 ash_riple
 
34
    input        rtc_timer_clk,
35 32 edn_walter
    input [79:0] rtc_timer_in,  // timeStamp1s_48bit + timeStamp1ns_32bit
36 4 ash_riple
 
37
    input         q_rst,
38 5 ash_riple
    input         q_rd_clk,
39 4 ash_riple
    input         q_rd_en,
40 37 edn_walter
    output [  7:0] q_rd_stat,
41
    output [127:0] q_rd_data  // null_16bit + timeStamp1s_48bit + timeStamp1ns_32bit + msgId_4bit + ckSum_12bit + seqId_16bit 
42 4 ash_riple
);
43
 
44 54 edn_walter
// mii to gmii converter
45
reg nibble_h;
46
always @(posedge rst or posedge gmii_clk) begin
47
  if (rst)
48
    nibble_h <= 1'b0;
49
  else if (gmii_ctrl)
50
    nibble_h <= !nibble_h;
51
end
52
 
53
reg       gmii_ctrl_conv;
54
reg [7:0] gmii_data_conv;
55
always @(posedge rst or posedge gmii_clk) begin
56
  if (rst) begin
57
    gmii_ctrl_conv <= 1'b0;
58
    gmii_data_conv <= 8'd0;
59
  end
60
  else begin
61
    if (giga_mode) begin
62
      gmii_ctrl_conv      <= gmii_ctrl;
63
      gmii_data_conv[7:0] <= gmii_data[7:0];
64
    end
65
    else begin
66
      // 4b-8b datapath gearbox
67
      if (gmii_ctrl) begin
68
        gmii_ctrl_conv      <= ( nibble_h)? 1'b1:1'b0;
69
        gmii_data_conv[7:4] <= ( nibble_h)? gmii_data[3:0]:gmii_data_conv[7:4];
70
        gmii_data_conv[3:0] <= (!nibble_h)? gmii_data[3:0]:gmii_data_conv[3:0];
71
      end
72
      else begin
73
        gmii_ctrl_conv      <= 1'b0;
74
        gmii_data_conv[7:4] <= gmii_data_conv[7:4];
75
        gmii_data_conv[3:0] <= gmii_data_conv[3:0];
76
      end
77
    end
78
  end
79
end
80
 
81 4 ash_riple
// buffer gmii input
82 54 edn_walter
reg       gmii_ctrl_conv_d1, gmii_ctrl_conv_d2, gmii_ctrl_conv_d3, gmii_ctrl_conv_d4,
83
          gmii_ctrl_conv_d5, gmii_ctrl_conv_d6, gmii_ctrl_conv_d7, gmii_ctrl_conv_d8,
84
          gmii_ctrl_conv_d9, gmii_ctrl_conv_da;
85
reg [7:0] gmii_data_conv_d1, gmii_data_conv_d2, gmii_data_conv_d3, gmii_data_conv_d4,
86
          gmii_data_conv_d5, gmii_data_conv_d6, gmii_data_conv_d7, gmii_data_conv_d8,
87
          gmii_data_conv_d9, gmii_data_conv_da;
88
always @(posedge rst or posedge gmii_clk) begin
89
  if (rst) begin
90
    gmii_ctrl_conv_d1 <= 1'b0;
91
    gmii_ctrl_conv_d2 <= 1'b0;
92
    gmii_ctrl_conv_d3 <= 1'b0;
93
    gmii_ctrl_conv_d4 <= 1'b0;
94
    gmii_ctrl_conv_d5 <= 1'b0;
95
    gmii_ctrl_conv_d6 <= 1'b0;
96
    gmii_ctrl_conv_d7 <= 1'b0;
97
    gmii_ctrl_conv_d8 <= 1'b0;
98
    gmii_ctrl_conv_d9 <= 1'b0;
99
    gmii_ctrl_conv_da <= 1'b0;
100
    gmii_data_conv_d1 <= 8'd0;
101
    gmii_data_conv_d2 <= 8'd0;
102
    gmii_data_conv_d3 <= 8'd0;
103
    gmii_data_conv_d4 <= 8'd0;
104
    gmii_data_conv_d5 <= 8'd0;
105
    gmii_data_conv_d6 <= 8'd0;
106
    gmii_data_conv_d7 <= 8'd0;
107
    gmii_data_conv_d8 <= 8'd0;
108
    gmii_data_conv_d9 <= 8'd0;
109
    gmii_data_conv_da <= 8'd0;
110
  end
111
  else begin
112
    gmii_ctrl_conv_d1 <= gmii_ctrl_conv;
113
    gmii_ctrl_conv_d2 <= gmii_ctrl_conv_d1;
114
    gmii_ctrl_conv_d3 <= gmii_ctrl_conv_d2;
115
    gmii_ctrl_conv_d4 <= gmii_ctrl_conv_d3;
116
    gmii_ctrl_conv_d5 <= gmii_ctrl_conv_d4;
117
    gmii_ctrl_conv_d6 <= gmii_ctrl_conv_d5;
118
    gmii_ctrl_conv_d7 <= gmii_ctrl_conv_d6;
119
    gmii_ctrl_conv_d8 <= gmii_ctrl_conv_d7;
120
    gmii_ctrl_conv_d9 <= gmii_ctrl_conv_d8;
121
    gmii_ctrl_conv_da <= gmii_ctrl_conv_d9;
122
    gmii_data_conv_d1 <= gmii_data_conv;
123
    gmii_data_conv_d2 <= gmii_data_conv_d1;
124
    gmii_data_conv_d3 <= gmii_data_conv_d2;
125
    gmii_data_conv_d4 <= gmii_data_conv_d3;
126
    gmii_data_conv_d5 <= gmii_data_conv_d4;
127
    gmii_data_conv_d6 <= gmii_data_conv_d5;
128
    gmii_data_conv_d7 <= gmii_data_conv_d6;
129
    gmii_data_conv_d8 <= gmii_data_conv_d7;
130
    gmii_data_conv_d9 <= gmii_data_conv_d8;
131
    gmii_data_conv_da <= gmii_data_conv_d9;
132
  end
133
end
134
 
135
// choose buffered gmii input
136 4 ash_riple
reg       int_gmii_ctrl;
137 54 edn_walter
reg       int_gmii_ctrl_d1, int_gmii_ctrl_d2, int_gmii_ctrl_d3, int_gmii_ctrl_d4,
138
          int_gmii_ctrl_d5;
139 4 ash_riple
reg [7:0] int_gmii_data;
140 54 edn_walter
reg [7:0] int_gmii_data_d1, int_gmii_data_d2, int_gmii_data_d3, int_gmii_data_d4,
141
          int_gmii_data_d5;
142 4 ash_riple
always @(posedge rst or posedge gmii_clk) begin
143
  if (rst) begin
144
    int_gmii_ctrl    <= 1'b0;
145 54 edn_walter
    int_gmii_data    <= 8'h00;
146 4 ash_riple
    int_gmii_ctrl_d1 <= 1'b0;
147 54 edn_walter
    int_gmii_data_d1 <= 8'h00;
148 4 ash_riple
    int_gmii_ctrl_d2 <= 1'b0;
149 54 edn_walter
    int_gmii_data_d2 <= 8'h00;
150 4 ash_riple
    int_gmii_ctrl_d3 <= 1'b0;
151 54 edn_walter
    int_gmii_data_d3 <= 8'h00;
152 4 ash_riple
    int_gmii_ctrl_d4 <= 1'b0;
153 54 edn_walter
    int_gmii_data_d4 <= 8'h00;
154 4 ash_riple
    int_gmii_ctrl_d5 <= 1'b0;
155 54 edn_walter
    int_gmii_data_d5 <= 8'h00;
156 4 ash_riple
  end
157
  else begin
158 54 edn_walter
    if (giga_mode) begin
159
      int_gmii_ctrl    <= gmii_ctrl_conv;
160
      int_gmii_data    <= gmii_data_conv;
161
      int_gmii_ctrl_d1 <= gmii_ctrl_conv_d1;
162
      int_gmii_data_d1 <= gmii_data_conv_d1;
163
      int_gmii_ctrl_d2 <= gmii_ctrl_conv_d2;
164
      int_gmii_data_d2 <= gmii_data_conv_d2;
165
      int_gmii_ctrl_d3 <= gmii_ctrl_conv_d3;
166
      int_gmii_data_d3 <= gmii_data_conv_d3;
167
      int_gmii_ctrl_d4 <= gmii_ctrl_conv_d4;
168
      int_gmii_data_d4 <= gmii_data_conv_d4;
169
      int_gmii_ctrl_d5 <= gmii_ctrl_conv_d5;
170
      int_gmii_data_d5 <= gmii_data_conv_d5;
171
    end
172
    else begin
173
      int_gmii_ctrl    <= gmii_ctrl_conv;
174
      int_gmii_data    <= gmii_data_conv;
175
      int_gmii_ctrl_d1 <= gmii_ctrl_conv_d2;
176
      int_gmii_data_d1 <= gmii_data_conv_d2;
177
      int_gmii_ctrl_d2 <= gmii_ctrl_conv_d4;
178
      int_gmii_data_d2 <= gmii_data_conv_d4;
179
      int_gmii_ctrl_d3 <= gmii_ctrl_conv_d6;
180
      int_gmii_data_d3 <= gmii_data_conv_d6;
181
      int_gmii_ctrl_d4 <= gmii_ctrl_conv_d8;
182
      int_gmii_data_d4 <= gmii_data_conv_d8;
183
      int_gmii_ctrl_d5 <= gmii_ctrl_conv_da;
184
      int_gmii_data_d5 <= gmii_data_conv_da;
185
    end
186 4 ash_riple
  end
187
end
188
 
189
// ptp CDC time stamping
190 39 edn_walter
wire ts_req = int_gmii_ctrl;  // TODO: check frame start delimiter
191 4 ash_riple
reg  ts_req_d1, ts_req_d2, ts_req_d3;
192
always @(posedge rst or posedge rtc_timer_clk) begin
193
  if (rst) begin
194
    ts_req_d1 <= 1'b0;
195
    ts_req_d2 <= 1'b0;
196
    ts_req_d3 <= 1'b0;
197
  end
198
  else begin
199
    ts_req_d1 <= ts_req;
200
    ts_req_d2 <= ts_req_d1;
201
    ts_req_d3 <= ts_req_d2;
202
  end
203
end
204 37 edn_walter
reg [79:0] rtc_time_stamp;
205 4 ash_riple
always @(posedge rst or posedge rtc_timer_clk) begin
206
  if (rst)
207 37 edn_walter
    rtc_time_stamp <= 80'd0;
208 4 ash_riple
  else
209
    if (ts_req_d2 & !ts_req_d3)
210 37 edn_walter
      rtc_time_stamp <= rtc_timer_in;
211 4 ash_riple
end
212
reg ts_ack, ts_ack_clr;
213
always @(posedge ts_ack_clr or posedge rtc_timer_clk) begin
214
  if (ts_ack_clr)
215
    ts_ack <= 1'b0;
216
  else
217
    if (ts_req_d2 & !ts_req_d3)
218
      ts_ack <= 1'b1;
219
end
220
 
221
reg ts_ack_d1, ts_ack_d2, ts_ack_d3;
222
always @(posedge rst or posedge gmii_clk) begin
223
  if (rst) begin
224
    ts_ack_d1 <= 1'b0;
225
    ts_ack_d2 <= 1'b0;
226
    ts_ack_d3 <= 1'b0;
227
  end
228
  else begin
229
    ts_ack_d1 <= ts_ack;
230
    ts_ack_d2 <= ts_ack_d1;
231
    ts_ack_d3 <= ts_ack_d2;
232
  end
233
end
234 44 edn_walter
reg [79:0] tsu_time_stamp;
235 4 ash_riple
always @(posedge rst or posedge gmii_clk) begin
236
  if (rst) begin
237 44 edn_walter
    tsu_time_stamp <= 80'd0;
238 4 ash_riple
    ts_ack_clr      <= 1'b0;
239
  end
240
  else begin
241
    if (ts_ack_d2 & !ts_ack_d3) begin
242 44 edn_walter
      tsu_time_stamp <= rtc_time_stamp;
243 4 ash_riple
      ts_ack_clr      <= 1'b1;
244
    end
245
    else begin
246 44 edn_walter
      tsu_time_stamp <= tsu_time_stamp;
247 4 ash_riple
      ts_ack_clr      <= 1'b0;
248
    end
249
  end
250
end
251
 
252
// 8b-32b datapath gearbox
253
reg        int_valid;
254
reg        int_sop, int_eop;
255
reg [ 1:0] int_bcnt, int_mod;
256
reg [31:0] int_data;
257
always @(posedge rst or posedge gmii_clk) begin
258
  if (rst)
259
    int_bcnt <= 2'd0;
260
  else
261 54 edn_walter
    if      ( int_gmii_ctrl & !int_gmii_ctrl_d1)
262
      int_bcnt <= 2'd0;  // clear on sop
263
    else if ( int_gmii_ctrl)
264
      int_bcnt <= int_bcnt + 2'd1;  // increment
265
    else if (!int_gmii_ctrl & int_gmii_ctrl_d3 & (int_bcnt!=2'd0))
266
      int_bcnt <= int_bcnt + 2'd1;  // end on eop with mod
267 4 ash_riple
end
268
always @(posedge rst or posedge gmii_clk) begin
269
  if (rst) begin
270
    int_data  <= 32'd0;
271
    int_valid <=  1'b0;
272
    int_mod   <=  2'd0;
273
  end
274
  else begin
275 54 edn_walter
    if (int_gmii_ctrl) begin
276 4 ash_riple
      int_data[ 7: 0] <= (int_bcnt==2'd3)? int_gmii_data_d1:int_data[ 7: 0];
277
      int_data[15: 8] <= (int_bcnt==2'd2)? int_gmii_data_d1:int_data[15: 8];
278
      int_data[23:16] <= (int_bcnt==2'd1)? int_gmii_data_d1:int_data[23:16];
279
      int_data[31:24] <= (int_bcnt==2'd0)? int_gmii_data_d1:int_data[31:24];
280
    end
281
 
282 54 edn_walter
    if (int_gmii_ctrl & int_bcnt==2'd3)
283 4 ash_riple
      int_valid <= 1'b1;
284
    else
285
      int_valid <= 1'b0;
286
 
287
    if (int_gmii_ctrl_d1 & !int_gmii_ctrl_d2)
288
      int_mod <= 2'd0;
289
    else if (!int_gmii_ctrl_d1 & int_gmii_ctrl_d2)
290
      int_mod <= int_bcnt;
291
 
292 54 edn_walter
    if (int_gmii_ctrl_d4 & !int_gmii_ctrl_d5 & int_bcnt==2'd3)
293 4 ash_riple
      int_sop <= 1'b1;
294
    else
295
      int_sop <= 1'b0;
296
 
297 54 edn_walter
    if (!int_gmii_ctrl   &  int_gmii_ctrl_d3 & int_bcnt==2'd3)
298 4 ash_riple
      int_eop <= 1'b1;
299
    else
300
      int_eop <= 1'b0;
301
 
302
  end
303
end
304
 
305 29 edn_walter
reg [31:0] int_data_d1;
306
reg        int_valid_d1;
307
reg        int_sop_d1;
308
reg        int_eop_d1;
309
reg [ 1:0] int_mod_d1;
310
always @(posedge rst or posedge gmii_clk) begin
311
  if (rst) begin
312
    int_data_d1  <= 32'h00000000;
313
    int_valid_d1 <= 1'b0;
314
    int_sop_d1   <= 1'b0;
315
    int_eop_d1   <= 1'b0;
316
    int_mod_d1   <= 2'b00;
317
  end
318
  else begin
319
    if (int_valid) begin
320
      int_data_d1  <= int_data;
321
      int_mod_d1   <= int_mod;
322
    end
323
      int_valid_d1 <= int_valid;
324
      int_sop_d1   <= int_sop;
325
      int_eop_d1   <= int_eop;
326
  end
327
end
328
 
329 4 ash_riple
// ptp packet parser here
330
// works at 1/4 gmii_clk frequency, needs multicycle timing constraint
331
wire        ptp_found;
332 37 edn_walter
wire [31:0] ptp_infor;
333 4 ash_riple
ptp_parser parser(
334
  .clk(gmii_clk),
335
  .rst(rst),
336 29 edn_walter
  .int_data(int_data_d1),
337
  .int_valid(int_valid_d1),
338
  .int_sop(int_sop_d1),
339
  .int_eop(int_eop_d1),
340
  .int_mod(int_mod_d1),
341 43 edn_walter
  .ptp_msgid_mask(ptp_msgid_mask),
342 4 ash_riple
  .ptp_found(ptp_found),
343
  .ptp_infor(ptp_infor)
344
);
345
 
346
// ptp time stamp dcfifo
347 5 ash_riple
wire q_wr_clk = gmii_clk;
348 29 edn_walter
wire q_wr_en = ptp_found && int_eop_d1;
349 44 edn_walter
wire [127:0] q_wr_data = {16'd0, tsu_time_stamp, ptp_infor};  // 16+80+32 bit
350 7 edn_walter
wire [3:0] q_wrusedw;
351
wire [3:0] q_rdusedw;
352 68 ash_riple
wire q_wr_full;
353
wire q_rd_empty;
354 4 ash_riple
 
355 5 ash_riple
ptp_queue queue(
356
  .aclr(q_rst),
357
 
358
  .wrclk(q_wr_clk),
359 68 ash_riple
  .wrreq(q_wr_en && !q_wr_full),  // write with overflow protection
360 5 ash_riple
  .data(q_wr_data),
361 68 ash_riple
  .wrfull(q_wr_full),
362 5 ash_riple
  .wrusedw(q_wrusedw),
363
 
364
  .rdclk(q_rd_clk),
365 68 ash_riple
  .rdreq(q_rd_en && !q_rd_empty),  // read with underflow protection
366 5 ash_riple
  .q(q_rd_data),
367 68 ash_riple
  .rdempty(q_rd_empty),
368 5 ash_riple
  .rdusedw(q_rdusedw)
369
);
370
 
371 7 edn_walter
assign q_rd_stat = {4'd0, q_rdusedw};
372 5 ash_riple
 
373 4 ash_riple
endmodule

powered by: WebSVN 2.1.0

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