@@ -36,38 +36,53 @@ module axis_baser_tx_64 #
36
36
parameter HDR_WIDTH = 2 ,
37
37
parameter ENABLE_PADDING = 1 ,
38
38
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
40
47
)
41
48
(
42
- input wire clk,
43
- input wire rst,
49
+ input wire clk,
50
+ input wire rst,
44
51
45
52
/*
46
53
* AXI input
47
54
*/
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,
54
61
55
62
/*
56
63
* 10GBASE-R encoded interface
57
64
*/
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,
60
75
61
76
/*
62
77
* Configuration
63
78
*/
64
- input wire [7 :0 ] ifg_delay,
79
+ input wire [7 :0 ] ifg_delay,
65
80
66
81
/*
67
82
* Status
68
83
*/
69
- output wire [1 :0 ] start_packet,
70
- output wire error_underflow
84
+ output wire [1 :0 ] start_packet,
85
+ output wire error_underflow
71
86
);
72
87
73
88
// bus width assertions
@@ -192,6 +207,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
192
207
193
208
reg s_axis_tready_reg = 1'b0 , s_axis_tready_next;
194
209
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
+
195
215
reg [31 :0 ] crc_state = 32'hFFFFFFFF ;
196
216
197
217
wire [31 :0 ] crc_next0;
@@ -217,6 +237,10 @@ assign s_axis_tready = s_axis_tready_reg;
217
237
assign encoded_tx_data = encoded_tx_data_reg;
218
238
assign encoded_tx_hdr = encoded_tx_hdr_reg;
219
239
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
+
220
244
assign start_packet = start_packet_reg;
221
245
assign error_underflow = error_underflow_reg;
222
246
@@ -469,12 +493,26 @@ always @* begin
469
493
s_tdata_next = s_tdata_reg;
470
494
s_tkeep_next = s_tkeep_reg;
471
495
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
+
472
501
output_data_next = s_tdata_reg;
473
502
output_type_next = OUTPUT_TYPE_IDLE;
474
503
475
504
start_packet_next = 2'b00 ;
476
505
error_underflow_next = 1'b0 ;
477
506
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
+
478
516
case (state_reg)
479
517
STATE_IDLE: begin
480
518
// idle state - wait for data
@@ -493,10 +531,26 @@ always @* begin
493
531
if (ifg_count_reg > 8'd0 ) begin
494
532
// need to send more idles - swap lanes
495
533
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 ;
496
542
start_packet_next = 2'b10 ;
497
543
end else begin
498
544
// no more idles - unswap
499
545
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 ;
500
554
start_packet_next = 2'b01 ;
501
555
end
502
556
output_data_next = {ETH_SFD, {7 {ETH_PRE}}};
@@ -527,7 +581,7 @@ always @* begin
527
581
if (s_axis_tlast) begin
528
582
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
529
583
s_axis_tready_next = 1'b0 ;
530
- if (s_axis_tuser) begin
584
+ if (s_axis_tuser[ 0 ] ) begin
531
585
output_type_next = OUTPUT_TYPE_ERROR;
532
586
frame_ptr_next = 16'd0 ;
533
587
ifg_count_next = 8'd8 ;
@@ -721,6 +775,9 @@ always @(posedge clk) begin
721
775
722
776
s_axis_tready_reg <= 1'b0 ;
723
777
778
+ m_axis_ptp_ts_valid_reg <= 1'b0 ;
779
+ m_axis_ptp_ts_valid_int_reg <= 1'b0 ;
780
+
724
781
encoded_tx_data_reg <= {{8 {CTRL_IDLE}}, BLOCK_TYPE_CTRL};
725
782
encoded_tx_hdr_reg <= SYNC_CTRL;
726
783
@@ -745,6 +802,9 @@ always @(posedge clk) begin
745
802
deficit_idle_count_reg <= deficit_idle_count_next;
746
803
747
804
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;
748
808
749
809
start_packet_reg <= start_packet_next;
750
810
error_underflow_reg <= error_underflow_next;
@@ -845,6 +905,9 @@ always @(posedge clk) begin
845
905
s_tdata_reg <= s_tdata_next;
846
906
s_tkeep_reg <= s_tkeep_next;
847
907
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
+
848
911
swap_data <= output_data_next[63 :32 ];
849
912
850
913
delay_type <= output_type_next ^ 4'd4 ;
0 commit comments