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

Subversion Repositories ha1588

[/] [ha1588/] [tags/] [v1p2/] [rtl/] [tsu/] [tsu.v] - Blame information for rev 76

Go to most recent revision | 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 43 edn_walter
 
31
    input [7:0] ptp_msgid_mask,
32 4 ash_riple
 
33
    input        rtc_timer_clk,
34 32 edn_walter
    input [79:0] rtc_timer_in,  // timeStamp1s_48bit + timeStamp1ns_32bit
35 4 ash_riple
 
36
    input         q_rst,
37 5 ash_riple
    input         q_rd_clk,
38 4 ash_riple
    input         q_rd_en,
39 37 edn_walter
    output [  7:0] q_rd_stat,
40
    output [127:0] q_rd_data  // null_16bit + timeStamp1s_48bit + timeStamp1ns_32bit + msgId_4bit + ckSum_12bit + seqId_16bit 
41 4 ash_riple
);
42
 
43
// buffer gmii input
44
reg       int_gmii_ctrl;
45
reg       int_gmii_ctrl_d1, int_gmii_ctrl_d2, int_gmii_ctrl_d3, int_gmii_ctrl_d4, int_gmii_ctrl_d5;
46
reg [7:0] int_gmii_data;
47
reg [7:0] int_gmii_data_d1;
48
always @(posedge rst or posedge gmii_clk) begin
49
  if (rst) begin
50
    int_gmii_ctrl    <= 1'b0;
51
    int_gmii_ctrl_d1 <= 1'b0;
52
    int_gmii_ctrl_d2 <= 1'b0;
53
    int_gmii_ctrl_d3 <= 1'b0;
54
    int_gmii_ctrl_d4 <= 1'b0;
55
    int_gmii_ctrl_d5 <= 1'b0;
56
    int_gmii_data    <= 8'h00;
57
    int_gmii_data_d1 <= 8'h00;
58
  end
59
  else begin
60
    int_gmii_ctrl    <= gmii_ctrl;
61
    int_gmii_ctrl_d1 <= int_gmii_ctrl;
62
    int_gmii_ctrl_d2 <= int_gmii_ctrl_d1;
63
    int_gmii_ctrl_d3 <= int_gmii_ctrl_d2;
64
    int_gmii_ctrl_d4 <= int_gmii_ctrl_d3;
65
    int_gmii_ctrl_d5 <= int_gmii_ctrl_d4;
66
    int_gmii_data    <= gmii_data;
67
    int_gmii_data_d1 <= int_gmii_data;
68
  end
69
end
70
 
71
// ptp CDC time stamping
72 39 edn_walter
wire ts_req = int_gmii_ctrl;  // TODO: check frame start delimiter
73 4 ash_riple
reg  ts_req_d1, ts_req_d2, ts_req_d3;
74
always @(posedge rst or posedge rtc_timer_clk) begin
75
  if (rst) begin
76
    ts_req_d1 <= 1'b0;
77
    ts_req_d2 <= 1'b0;
78
    ts_req_d3 <= 1'b0;
79
  end
80
  else begin
81
    ts_req_d1 <= ts_req;
82
    ts_req_d2 <= ts_req_d1;
83
    ts_req_d3 <= ts_req_d2;
84
  end
85
end
86 37 edn_walter
reg [79:0] rtc_time_stamp;
87 4 ash_riple
always @(posedge rst or posedge rtc_timer_clk) begin
88
  if (rst)
89 37 edn_walter
    rtc_time_stamp <= 80'd0;
90 4 ash_riple
  else
91
    if (ts_req_d2 & !ts_req_d3)
92 37 edn_walter
      rtc_time_stamp <= rtc_timer_in;
93 4 ash_riple
end
94
reg ts_ack, ts_ack_clr;
95
always @(posedge ts_ack_clr or posedge rtc_timer_clk) begin
96
  if (ts_ack_clr)
97
    ts_ack <= 1'b0;
98
  else
99
    if (ts_req_d2 & !ts_req_d3)
100
      ts_ack <= 1'b1;
101
end
102
 
103
reg ts_ack_d1, ts_ack_d2, ts_ack_d3;
104
always @(posedge rst or posedge gmii_clk) begin
105
  if (rst) begin
106
    ts_ack_d1 <= 1'b0;
107
    ts_ack_d2 <= 1'b0;
108
    ts_ack_d3 <= 1'b0;
109
  end
110
  else begin
111
    ts_ack_d1 <= ts_ack;
112
    ts_ack_d2 <= ts_ack_d1;
113
    ts_ack_d3 <= ts_ack_d2;
114
  end
115
end
116 44 edn_walter
reg [79:0] tsu_time_stamp;
117 4 ash_riple
always @(posedge rst or posedge gmii_clk) begin
118
  if (rst) begin
119 44 edn_walter
    tsu_time_stamp <= 80'd0;
120 4 ash_riple
    ts_ack_clr      <= 1'b0;
121
  end
122
  else begin
123
    if (ts_ack_d2 & !ts_ack_d3) begin
124 44 edn_walter
      tsu_time_stamp <= rtc_time_stamp;
125 4 ash_riple
      ts_ack_clr      <= 1'b1;
126
    end
127
    else begin
128 44 edn_walter
      tsu_time_stamp <= tsu_time_stamp;
129 4 ash_riple
      ts_ack_clr      <= 1'b0;
130
    end
131
  end
132
end
133
 
134
// 8b-32b datapath gearbox
135
reg        int_valid;
136
reg        int_sop, int_eop;
137
reg [ 1:0] int_bcnt, int_mod;
138
reg [31:0] int_data;
139
always @(posedge rst or posedge gmii_clk) begin
140
  if (rst)
141
    int_bcnt <= 2'd0;
142
  else
143
    if (int_gmii_ctrl_d1 | (int_bcnt!=2'd0))
144
      int_bcnt <= int_bcnt + 2'd1;
145
    else
146
      int_bcnt <= 2'd0;
147
end
148
always @(posedge rst or posedge gmii_clk) begin
149
  if (rst) begin
150
    int_data  <= 32'd0;
151
    int_valid <=  1'b0;
152
    int_mod   <=  2'd0;
153
  end
154
  else begin
155
    if (int_gmii_ctrl_d1) begin
156
      int_data[ 7: 0] <= (int_bcnt==2'd3)? int_gmii_data_d1:int_data[ 7: 0];
157
      int_data[15: 8] <= (int_bcnt==2'd2)? int_gmii_data_d1:int_data[15: 8];
158
      int_data[23:16] <= (int_bcnt==2'd1)? int_gmii_data_d1:int_data[23:16];
159
      int_data[31:24] <= (int_bcnt==2'd0)? int_gmii_data_d1:int_data[31:24];
160
    end
161
 
162
    if (int_bcnt==2'd3)
163
      int_valid <= 1'b1;
164
    else
165
      int_valid <= 1'b0;
166
 
167
    if (int_gmii_ctrl_d1 & !int_gmii_ctrl_d2)
168
      int_mod <= 2'd0;
169
    else if (!int_gmii_ctrl_d1 & int_gmii_ctrl_d2)
170
      int_mod <= int_bcnt;
171
 
172
    if (int_gmii_ctrl & !int_gmii_ctrl_d5 & int_bcnt==2'd3)
173
      int_sop <= 1'b1;
174
    else
175
      int_sop <= 1'b0;
176
 
177
    if (!int_gmii_ctrl & int_bcnt==2'd3)
178
      int_eop <= 1'b1;
179
    else
180
      int_eop <= 1'b0;
181
 
182
  end
183
end
184
 
185 29 edn_walter
reg [31:0] int_data_d1;
186
reg        int_valid_d1;
187
reg        int_sop_d1;
188
reg        int_eop_d1;
189
reg [ 1:0] int_mod_d1;
190
always @(posedge rst or posedge gmii_clk) begin
191
  if (rst) begin
192
    int_data_d1  <= 32'h00000000;
193
    int_valid_d1 <= 1'b0;
194
    int_sop_d1   <= 1'b0;
195
    int_eop_d1   <= 1'b0;
196
    int_mod_d1   <= 2'b00;
197
  end
198
  else begin
199
    if (int_valid) begin
200
      int_data_d1  <= int_data;
201
      int_mod_d1   <= int_mod;
202
    end
203
      int_valid_d1 <= int_valid;
204
      int_sop_d1   <= int_sop;
205
      int_eop_d1   <= int_eop;
206
  end
207
end
208
 
209 4 ash_riple
// ptp packet parser here
210
// works at 1/4 gmii_clk frequency, needs multicycle timing constraint
211
wire        ptp_found;
212 37 edn_walter
wire [31:0] ptp_infor;
213 4 ash_riple
ptp_parser parser(
214
  .clk(gmii_clk),
215
  .rst(rst),
216 29 edn_walter
  .int_data(int_data_d1),
217
  .int_valid(int_valid_d1),
218
  .int_sop(int_sop_d1),
219
  .int_eop(int_eop_d1),
220
  .int_mod(int_mod_d1),
221 43 edn_walter
  .ptp_msgid_mask(ptp_msgid_mask),
222 4 ash_riple
  .ptp_found(ptp_found),
223
  .ptp_infor(ptp_infor)
224
);
225
 
226
// ptp time stamp dcfifo
227 5 ash_riple
wire q_wr_clk = gmii_clk;
228 29 edn_walter
wire q_wr_en = ptp_found && int_eop_d1;
229 44 edn_walter
wire [127:0] q_wr_data = {16'd0, tsu_time_stamp, ptp_infor};  // 16+80+32 bit
230 7 edn_walter
wire [3:0] q_wrusedw;
231
wire [3:0] q_rdusedw;
232 4 ash_riple
 
233 5 ash_riple
ptp_queue queue(
234
  .aclr(q_rst),
235
 
236
  .wrclk(q_wr_clk),
237 37 edn_walter
  .wrreq(q_wr_en && q_wrusedw<15),  // write with overflow protection
238 5 ash_riple
  .data(q_wr_data),
239
  .wrusedw(q_wrusedw),
240
 
241
  .rdclk(q_rd_clk),
242 37 edn_walter
  .rdreq(q_rd_en && q_rdusedw>0 ),  // read with underflow protection
243 5 ash_riple
  .q(q_rd_data),
244
  .rdusedw(q_rdusedw)
245
);
246
 
247 7 edn_walter
assign q_rd_stat = {4'd0, q_rdusedw};
248 5 ash_riple
 
249 4 ash_riple
endmodule

powered by: WebSVN 2.1.0

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