@@ -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
193208reg 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+
195215reg [31 :0 ] crc_state = 32'hFFFFFFFF ;
196216
197217wire [31 :0 ] crc_next0;
@@ -217,6 +237,10 @@ assign s_axis_tready = s_axis_tready_reg;
217237assign encoded_tx_data = encoded_tx_data_reg;
218238assign 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+
220244assign start_packet = start_packet_reg;
221245assign 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