Skip to content

Commit 82fe5a6

Browse files
committed
Add PTP timestamp capture logic to MACs
1 parent 659aa67 commit 82fe5a6

37 files changed

+1471
-427
lines changed

rtl/axis_baser_rx_64.v

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,34 +33,44 @@ module axis_baser_rx_64 #
3333
(
3434
parameter DATA_WIDTH = 64,
3535
parameter KEEP_WIDTH = (DATA_WIDTH/8),
36-
parameter HDR_WIDTH = 2
36+
parameter HDR_WIDTH = 2,
37+
parameter PTP_PERIOD_NS = 4'h6,
38+
parameter PTP_PERIOD_FNS = 16'h6666,
39+
parameter PTP_TS_ENABLE = 0,
40+
parameter PTP_TS_WIDTH = 96,
41+
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1
3742
)
3843
(
39-
input wire clk,
40-
input wire rst,
44+
input wire clk,
45+
input wire rst,
4146

4247
/*
4348
* 10GBASE-R encoded input
4449
*/
45-
input wire [DATA_WIDTH-1:0] encoded_rx_data,
46-
input wire [HDR_WIDTH-1:0] encoded_rx_hdr,
50+
input wire [DATA_WIDTH-1:0] encoded_rx_data,
51+
input wire [HDR_WIDTH-1:0] encoded_rx_hdr,
4752

4853
/*
4954
* AXI output
5055
*/
51-
output wire [DATA_WIDTH-1:0] m_axis_tdata,
52-
output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
53-
output wire m_axis_tvalid,
54-
output wire m_axis_tlast,
55-
output wire m_axis_tuser,
56+
output wire [DATA_WIDTH-1:0] m_axis_tdata,
57+
output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
58+
output wire m_axis_tvalid,
59+
output wire m_axis_tlast,
60+
output wire [USER_WIDTH-1:0] m_axis_tuser,
61+
62+
/*
63+
* PTP
64+
*/
65+
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
5666

5767
/*
5868
* Status
5969
*/
60-
output wire [1:0] start_packet,
61-
output wire error_bad_frame,
62-
output wire error_bad_fcs,
63-
output wire rx_bad_block
70+
output wire [1:0] start_packet,
71+
output wire error_bad_frame,
72+
output wire error_bad_fcs,
73+
output wire rx_bad_block
6474
);
6575

6676
// bus width assertions
@@ -177,6 +187,8 @@ reg error_bad_frame_reg = 1'b0, error_bad_frame_next;
177187
reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
178188
reg rx_bad_block_reg = 1'b0;
179189

190+
reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0;
191+
180192
reg [31:0] crc_state = 32'hFFFFFFFF;
181193
reg [31:0] crc_state3 = 32'hFFFFFFFF;
182194

@@ -198,7 +210,7 @@ assign m_axis_tdata = m_axis_tdata_reg;
198210
assign m_axis_tkeep = m_axis_tkeep_reg;
199211
assign m_axis_tvalid = m_axis_tvalid_reg;
200212
assign m_axis_tlast = m_axis_tlast_reg;
201-
assign m_axis_tuser = m_axis_tuser_reg;
213+
assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg;
202214

203215
assign start_packet = start_packet_reg;
204216
assign error_bad_frame = error_bad_frame_reg;
@@ -518,6 +530,28 @@ always @(posedge clk) begin
518530
end
519531
end
520532

533+
if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
534+
// ns field rollover
535+
ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
536+
ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1;
537+
end
538+
539+
if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin
540+
if (PTP_TS_WIDTH == 96) begin
541+
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
542+
ptp_ts_reg[95:48] <= ptp_ts[95:48];
543+
end else begin
544+
ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
545+
end
546+
end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin
547+
if (PTP_TS_WIDTH == 96) begin
548+
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
549+
ptp_ts_reg[95:48] <= ptp_ts[95:48];
550+
end else begin
551+
ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
552+
end
553+
end
554+
521555
m_axis_tdata_reg <= m_axis_tdata_next;
522556
m_axis_tkeep_reg <= m_axis_tkeep_next;
523557
m_axis_tlast_reg <= m_axis_tlast_next;

rtl/axis_baser_tx_64.v

Lines changed: 78 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,38 +36,53 @@ module axis_baser_tx_64 #
3636
parameter HDR_WIDTH = 2,
3737
parameter ENABLE_PADDING = 1,
3838
parameter ENABLE_DIC = 1,
39-
parameter MIN_FRAME_LENGTH = 64
39+
parameter MIN_FRAME_LENGTH = 64,
40+
parameter PTP_PERIOD_NS = 4'h6,
41+
parameter PTP_PERIOD_FNS = 16'h6666,
42+
parameter PTP_TS_ENABLE = 0,
43+
parameter PTP_TS_WIDTH = 96,
44+
parameter PTP_TAG_ENABLE = 0,
45+
parameter PTP_TAG_WIDTH = 16,
46+
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1
4047
)
4148
(
42-
input wire clk,
43-
input wire rst,
49+
input wire clk,
50+
input wire rst,
4451

4552
/*
4653
* AXI input
4754
*/
48-
input wire [DATA_WIDTH-1:0] s_axis_tdata,
49-
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
50-
input wire s_axis_tvalid,
51-
output wire s_axis_tready,
52-
input wire s_axis_tlast,
53-
input wire s_axis_tuser,
55+
input wire [DATA_WIDTH-1:0] s_axis_tdata,
56+
input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
57+
input wire s_axis_tvalid,
58+
output wire s_axis_tready,
59+
input wire s_axis_tlast,
60+
input wire [USER_WIDTH-1:0] s_axis_tuser,
5461

5562
/*
5663
* 10GBASE-R encoded interface
5764
*/
58-
output wire [DATA_WIDTH-1:0] encoded_tx_data,
59-
output wire [HDR_WIDTH-1:0] encoded_tx_hdr,
65+
output wire [DATA_WIDTH-1:0] encoded_tx_data,
66+
output wire [HDR_WIDTH-1:0] encoded_tx_hdr,
67+
68+
/*
69+
* PTP
70+
*/
71+
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
72+
output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts,
73+
output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag,
74+
output wire m_axis_ptp_ts_valid,
6075

6176
/*
6277
* Configuration
6378
*/
64-
input wire [7:0] ifg_delay,
79+
input wire [7:0] ifg_delay,
6580

6681
/*
6782
* Status
6883
*/
69-
output wire [1:0] start_packet,
70-
output wire error_underflow
84+
output wire [1:0] start_packet,
85+
output wire error_underflow
7186
);
7287

7388
// bus width assertions
@@ -192,6 +207,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
192207

193208
reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
194209

210+
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next;
211+
reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next;
212+
reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
213+
reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next;
214+
195215
reg [31:0] crc_state = 32'hFFFFFFFF;
196216

197217
wire [31:0] crc_next0;
@@ -217,6 +237,10 @@ assign s_axis_tready = s_axis_tready_reg;
217237
assign encoded_tx_data = encoded_tx_data_reg;
218238
assign encoded_tx_hdr = encoded_tx_hdr_reg;
219239

240+
assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0;
241+
assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0;
242+
assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0;
243+
220244
assign start_packet = start_packet_reg;
221245
assign error_underflow = error_underflow_reg;
222246

@@ -469,12 +493,26 @@ always @* begin
469493
s_tdata_next = s_tdata_reg;
470494
s_tkeep_next = s_tkeep_reg;
471495

496+
m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
497+
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
498+
m_axis_ptp_ts_valid_next = 1'b0;
499+
m_axis_ptp_ts_valid_int_next = 1'b0;
500+
472501
output_data_next = s_tdata_reg;
473502
output_type_next = OUTPUT_TYPE_IDLE;
474503

475504
start_packet_next = 2'b00;
476505
error_underflow_next = 1'b0;
477506

507+
if (m_axis_ptp_ts_valid_int_reg) begin
508+
m_axis_ptp_ts_valid_next = 1'b1;
509+
if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
510+
// ns field rollover
511+
m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
512+
m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1;
513+
end
514+
end
515+
478516
case (state_reg)
479517
STATE_IDLE: begin
480518
// idle state - wait for data
@@ -493,10 +531,26 @@ always @* begin
493531
if (ifg_count_reg > 8'd0) begin
494532
// need to send more idles - swap lanes
495533
swap_lanes = 1'b1;
534+
if (PTP_TS_WIDTH == 96) begin
535+
m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
536+
m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48];
537+
end else begin
538+
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
539+
end
540+
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
541+
m_axis_ptp_ts_valid_int_next = 1'b1;
496542
start_packet_next = 2'b10;
497543
end else begin
498544
// no more idles - unswap
499545
unswap_lanes = 1'b1;
546+
if (PTP_TS_WIDTH == 96) begin
547+
m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
548+
m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48];
549+
end else begin
550+
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
551+
end
552+
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
553+
m_axis_ptp_ts_valid_int_next = 1'b1;
500554
start_packet_next = 2'b01;
501555
end
502556
output_data_next = {ETH_SFD, {7{ETH_PRE}}};
@@ -527,7 +581,7 @@ always @* begin
527581
if (s_axis_tlast) begin
528582
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
529583
s_axis_tready_next = 1'b0;
530-
if (s_axis_tuser) begin
584+
if (s_axis_tuser[0]) begin
531585
output_type_next = OUTPUT_TYPE_ERROR;
532586
frame_ptr_next = 16'd0;
533587
ifg_count_next = 8'd8;
@@ -721,6 +775,9 @@ always @(posedge clk) begin
721775

722776
s_axis_tready_reg <= 1'b0;
723777

778+
m_axis_ptp_ts_valid_reg <= 1'b0;
779+
m_axis_ptp_ts_valid_int_reg <= 1'b0;
780+
724781
encoded_tx_data_reg <= {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL};
725782
encoded_tx_hdr_reg <= SYNC_CTRL;
726783

@@ -745,6 +802,9 @@ always @(posedge clk) begin
745802
deficit_idle_count_reg <= deficit_idle_count_next;
746803

747804
s_axis_tready_reg <= s_axis_tready_next;
805+
806+
m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next;
807+
m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next;
748808

749809
start_packet_reg <= start_packet_next;
750810
error_underflow_reg <= error_underflow_next;
@@ -845,6 +905,9 @@ always @(posedge clk) begin
845905
s_tdata_reg <= s_tdata_next;
846906
s_tkeep_reg <= s_tkeep_next;
847907

908+
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
909+
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
910+
848911
swap_data <= output_data_next[63:32];
849912

850913
delay_type <= output_type_next ^ 4'd4;

0 commit comments

Comments
 (0)