@@ -37,7 +37,8 @@ module ptp_clock_cdc #
3737 parameter NS_WIDTH = 4 ,
3838 parameter FNS_WIDTH = 16 ,
3939 parameter USE_SAMPLE_CLOCK = 1 ,
40- parameter LOG_RATE = 3
40+ parameter LOG_RATE = 3 ,
41+ parameter PIPELINE_OUTPUT = 0
4142)
4243(
4344 input wire input_clk,
@@ -115,7 +116,13 @@ reg [FNS_WIDTH-1:0] ts_fns_ovf_reg = {FNS_WIDTH{1'b1}}, ts_fns_ovf_next;
115116
116117reg ts_step_reg = 1'b0 , ts_step_next;
117118
118- reg pps_reg = 0 ;
119+ reg pps_reg = 1'b0 ;
120+
121+ reg [47 :0 ] ts_s_pipe_reg[0 :PIPELINE_OUTPUT- 1 ];
122+ reg [TS_NS_WIDTH- 1 :0 ] ts_ns_pipe_reg[0 :PIPELINE_OUTPUT- 1 ];
123+ reg [FNS_WIDTH- 1 :0 ] ts_fns_pipe_reg[0 :PIPELINE_OUTPUT- 1 ];
124+ reg ts_step_pipe_reg[0 :PIPELINE_OUTPUT- 1 ];
125+ reg pps_pipe_reg[0 :PIPELINE_OUTPUT- 1 ];
119126
120127reg [PHASE_CNT_WIDTH- 1 :0 ] src_phase_reg = {PHASE_CNT_WIDTH{1'b0 }};
121128reg [PHASE_ACC_WIDTH- 1 :0 ] dest_phase_reg = {PHASE_ACC_WIDTH{1'b0 }}, dest_phase_next;
@@ -150,21 +157,90 @@ reg sample_update_sync3_reg = 1'b0;
150157
151158generate
152159
153- if (TS_WIDTH == 96 ) begin
154- assign output_ts[95 :48 ] = ts_s_reg;
155- assign output_ts[47 :46 ] = 2'b00 ;
156- assign output_ts[45 :16 ] = ts_ns_reg;
157- assign output_ts[15 :0 ] = FNS_WIDTH > 16 ? ts_fns_reg >> (FNS_WIDTH- 16 ) : ts_fns_reg << (16 - FNS_WIDTH);
158- end else if (TS_WIDTH == 64 ) begin
159- assign output_ts[63 :16 ] = ts_ns_reg;
160- assign output_ts[15 :0 ] = FNS_WIDTH > 16 ? ts_fns_reg >> (FNS_WIDTH- 16 ) : ts_fns_reg << (16 - FNS_WIDTH);
160+ if (PIPELINE_OUTPUT > 0 ) begin
161+
162+ // pipeline
163+ (* shreg_extract = "no" * )
164+ reg [TS_WIDTH- 1 :0 ] output_ts_reg[0 :PIPELINE_OUTPUT- 1 ];
165+ (* shreg_extract = "no" * )
166+ reg output_ts_step_reg[0 :PIPELINE_OUTPUT- 1 ];
167+ (* shreg_extract = "no" * )
168+ reg output_pps_reg[0 :PIPELINE_OUTPUT- 1 ];
169+
170+ assign output_ts = output_ts_reg[PIPELINE_OUTPUT- 1 ];
171+ assign output_ts_step = output_ts_step_reg[PIPELINE_OUTPUT- 1 ];
172+ assign output_pps = output_pps_reg[PIPELINE_OUTPUT- 1 ];
173+
174+ integer i;
175+
176+ initial begin
177+ for (i = 0 ; i < PIPELINE_OUTPUT; i = i + 1 ) begin
178+ output_ts_reg[i] = 0 ;
179+ output_ts_step_reg[i] = 1'b0 ;
180+ output_pps_reg[i] = 1'b0 ;
181+ end
182+ end
183+
184+ always @(posedge output_clk) begin
185+ if (TS_WIDTH == 96 ) begin
186+ output_ts_reg[0 ][95 :48 ] <= ts_s_reg;
187+ output_ts_reg[0 ][47 :46 ] <= 2'b00 ;
188+ output_ts_reg[0 ][45 :16 ] <= ts_ns_reg;
189+ output_ts_reg[0 ][15 :0 ] <= {ts_fns_reg, 16'd0 } >> FNS_WIDTH;
190+ end else if (TS_WIDTH == 64 ) begin
191+ output_ts_reg[0 ][63 :16 ] <= ts_ns_reg;
192+ output_ts_reg[0 ][15 :0 ] <= {ts_fns_reg, 16'd0 } >> FNS_WIDTH;
193+ end
194+
195+ output_ts_step_reg[0 ] <= ts_step_reg;
196+ output_pps_reg[0 ] <= pps_reg;
197+
198+ for (i = 0 ; i < PIPELINE_OUTPUT- 1 ; i = i + 1 ) begin
199+ output_ts_reg[i+ 1 ] <= output_ts_reg[i];
200+ output_ts_step_reg[i+ 1 ] <= output_ts_step_reg[i];
201+ output_pps_reg[i+ 1 ] <= output_pps_reg[i];
202+ end
203+
204+ if (output_rst) begin
205+ for (i = 0 ; i < PIPELINE_OUTPUT; i = i + 1 ) begin
206+ output_ts_reg[i] = 0 ;
207+ output_ts_step_reg[i] = 1'b0 ;
208+ output_pps_reg[i] = 1'b0 ;
209+ end
210+ end
211+ end
212+
213+ end else begin
214+
215+ if (TS_WIDTH == 96 ) begin
216+ assign output_ts[95 :48 ] = ts_s_reg;
217+ assign output_ts[47 :46 ] = 2'b00 ;
218+ assign output_ts[45 :16 ] = ts_ns_reg;
219+ assign output_ts[15 :0 ] = {ts_fns_reg, 16'd0 } >> FNS_WIDTH;
220+ end else if (TS_WIDTH == 64 ) begin
221+ assign output_ts[63 :16 ] = ts_ns_reg;
222+ assign output_ts[15 :0 ] = {ts_fns_reg, 16'd0 } >> FNS_WIDTH;
223+ end
224+
225+ assign output_ts_step = ts_step_reg;
226+
227+ assign output_pps = pps_reg;
228+
161229end
162230
163231endgenerate
164232
165- assign output_ts_step = ts_step_reg ;
233+ integer i ;
166234
167- assign output_pps = pps_reg;
235+ initial begin
236+ for (i = 0 ; i < PIPELINE_OUTPUT; i = i + 1 ) begin
237+ ts_s_pipe_reg[i] = 0 ;
238+ ts_ns_pipe_reg[i] = 0 ;
239+ ts_fns_pipe_reg[i] = 0 ;
240+ ts_step_pipe_reg[i] = 1'b0 ;
241+ pps_pipe_reg[i] = 1'b0 ;
242+ end
243+ end
168244
169245// source PTP clock capture and sync logic
170246reg input_ts_step_reg = 1'b0 ;
@@ -381,9 +457,15 @@ always @(posedge output_clk) begin
381457
382458 if (dest_update_reg) begin
383459 // capture local TS
384- dest_ts_s_capt_reg <= ts_s_reg;
385- dest_ts_ns_capt_reg <= ts_ns_reg;
386- dest_ts_fns_capt_reg <= ts_fns_reg;
460+ if (PIPELINE_OUTPUT > 0 ) begin
461+ dest_ts_s_capt_reg <= ts_s_pipe_reg[PIPELINE_OUTPUT- 1 ];
462+ dest_ts_ns_capt_reg <= ts_ns_pipe_reg[PIPELINE_OUTPUT- 1 ];
463+ dest_ts_fns_capt_reg <= ts_fns_pipe_reg[PIPELINE_OUTPUT- 1 ];
464+ end else begin
465+ dest_ts_s_capt_reg <= ts_s_reg;
466+ dest_ts_ns_capt_reg <= ts_ns_reg;
467+ dest_ts_fns_capt_reg <= ts_fns_reg;
468+ end
387469
388470 dest_sync_reg <= ! dest_sync_reg;
389471 ts_capt_valid_reg <= 1'b1 ;
@@ -668,6 +750,23 @@ always @(posedge output_clk) begin
668750 pps_reg <= 1'b0 ; // not currently implemented for 64 bit timestamp format
669751 end
670752
753+ // pipeline
754+ if (PIPELINE_OUTPUT > 0 ) begin
755+ ts_s_pipe_reg[0 ] <= ts_s_reg;
756+ ts_ns_pipe_reg[0 ] <= ts_ns_reg;
757+ ts_fns_pipe_reg[0 ] <= ts_fns_reg;
758+ ts_step_pipe_reg[0 ] <= ts_step_reg;
759+ pps_pipe_reg[0 ] <= pps_reg;
760+
761+ for (i = 0 ; i < PIPELINE_OUTPUT- 1 ; i = i + 1 ) begin
762+ ts_s_pipe_reg[i+ 1 ] <= ts_s_pipe_reg[i];
763+ ts_ns_pipe_reg[i+ 1 ] <= ts_ns_pipe_reg[i];
764+ ts_fns_pipe_reg[i+ 1 ] <= ts_fns_pipe_reg[i];
765+ ts_step_pipe_reg[i+ 1 ] <= ts_step_pipe_reg[i];
766+ pps_pipe_reg[i+ 1 ] <= pps_pipe_reg[i];
767+ end
768+ end
769+
671770 if (output_rst) begin
672771 period_ns_reg <= 0 ;
673772 period_fns_reg <= 0 ;
@@ -689,6 +788,14 @@ always @(posedge output_clk) begin
689788
690789 ptp_lock_count_reg <= 0 ;
691790 ptp_locked_reg <= 1'b0 ;
791+
792+ for (i = 0 ; i < PIPELINE_OUTPUT; i = i + 1 ) begin
793+ ts_s_pipe_reg[i] = 0 ;
794+ ts_ns_pipe_reg[i] = 0 ;
795+ ts_fns_pipe_reg[i] = 0 ;
796+ ts_step_pipe_reg[i] = 1'b0 ;
797+ pps_pipe_reg[i] = 1'b0 ;
798+ end
692799 end
693800end
694801
0 commit comments