diff --git a/rtl/ptp_clock.v b/rtl/ptp_clock.v
index b1bebbff375cc66ea3771678b275359483b807b1..ca646c14d04c7f67b0f5178afdceb6b2e53ee622 100644
--- a/rtl/ptp_clock.v
+++ b/rtl/ptp_clock.v
@@ -42,7 +42,8 @@ module ptp_clock #
     parameter DRIFT_ENABLE = 1,
     parameter DRIFT_NS = 4'h0,
     parameter DRIFT_FNS = 16'h0002,
-    parameter DRIFT_RATE = 16'h0005
+    parameter DRIFT_RATE = 16'h0005,
+    parameter PIPELINE_OUTPUT = 0
 )
 (
     input  wire                       clk,
@@ -131,15 +132,78 @@ reg pps_reg = 0;
 
 assign input_adj_active = adj_active_reg;
 
-assign output_ts_96[95:48] = ts_96_s_reg;
-assign output_ts_96[47:46] = 2'b00;
-assign output_ts_96[45:16] = ts_96_ns_reg;
-assign output_ts_96[15:0]  = FNS_WIDTH > 16 ? ts_96_fns_reg >> (FNS_WIDTH-16) : ts_96_fns_reg << (16-FNS_WIDTH);
-assign output_ts_64[63:16] = ts_64_ns_reg;
-assign output_ts_64[15:0]  = FNS_WIDTH > 16 ? ts_64_fns_reg >> (FNS_WIDTH-16) : ts_64_fns_reg << (16-FNS_WIDTH);
-assign output_ts_step = ts_step_reg;
+generate
+
+if (PIPELINE_OUTPUT > 0) begin
+
+    // pipeline
+    (* shreg_extract = "no" *)
+    reg [95:0]  output_ts_96_reg[0:PIPELINE_OUTPUT-1];
+    (* shreg_extract = "no" *)
+    reg [63:0]  output_ts_64_reg[0:PIPELINE_OUTPUT-1];
+    (* shreg_extract = "no" *)
+    reg         output_ts_step_reg[0:PIPELINE_OUTPUT-1];
+    (* shreg_extract = "no" *)
+    reg         output_pps_reg[0:PIPELINE_OUTPUT-1];
+
+    assign output_ts_96 = output_ts_96_reg[PIPELINE_OUTPUT-1];
+    assign output_ts_64 = output_ts_64_reg[PIPELINE_OUTPUT-1];
+    assign output_ts_step = output_ts_step_reg[PIPELINE_OUTPUT-1];
+    assign output_pps = output_pps_reg[PIPELINE_OUTPUT-1];
+
+    integer i;
+
+    initial begin
+        for (i = 0; i < PIPELINE_OUTPUT; i = i + 1) begin
+            output_ts_96_reg[i] = 96'd0;
+            output_ts_64_reg[i] = 64'd0;
+            output_ts_step_reg[i] = 1'b0;
+            output_pps_reg[i] = 1'b0;
+        end
+    end
+
+    always @(posedge clk) begin
+        output_ts_96_reg[0][95:48] <= ts_96_s_reg;
+        output_ts_96_reg[0][47:46] <= 2'b00;
+        output_ts_96_reg[0][45:16] <= ts_96_ns_reg;
+        output_ts_96_reg[0][15:0]  <= {ts_96_fns_reg, 16'd0} >> FNS_WIDTH;
+        output_ts_64_reg[0][63:16] <= ts_64_ns_reg;
+        output_ts_64_reg[0][15:0]  <= {ts_64_fns_reg, 16'd0} >> FNS_WIDTH;
+        output_ts_step_reg[0] <= ts_step_reg;
+        output_pps_reg[0] <= pps_reg;
+
+        for (i = 0; i < PIPELINE_OUTPUT-1; i = i + 1) begin
+            output_ts_96_reg[i+1] <= output_ts_96_reg[i];
+            output_ts_64_reg[i+1] <= output_ts_64_reg[i];
+            output_ts_step_reg[i+1] <= output_ts_step_reg[i];
+            output_pps_reg[i+1] <= output_pps_reg[i];
+        end
+
+        if (rst) begin
+            for (i = 0; i < PIPELINE_OUTPUT; i = i + 1) begin
+                output_ts_96_reg[i] = 96'd0;
+                output_ts_64_reg[i] = 64'd0;
+                output_ts_step_reg[i] = 1'b0;
+                output_pps_reg[i] = 1'b0;
+            end
+        end
+    end
+
+end else begin
+
+    assign output_ts_96[95:48] = ts_96_s_reg;
+    assign output_ts_96[47:46] = 2'b00;
+    assign output_ts_96[45:16] = ts_96_ns_reg;
+    assign output_ts_96[15:0]  = {ts_96_fns_reg, 16'd0} >> FNS_WIDTH;
+    assign output_ts_64[63:16] = ts_64_ns_reg;
+    assign output_ts_64[15:0]  = {ts_64_fns_reg, 16'd0} >> FNS_WIDTH;
+    assign output_ts_step = ts_step_reg;
+
+    assign output_pps = pps_reg;
+
+end
 
-assign output_pps = pps_reg;
+endgenerate
 
 always @(posedge clk) begin
     ts_step_reg <= 0;
diff --git a/tb/ptp_clock/Makefile b/tb/ptp_clock/Makefile
index be710f6de304fe2f06b9fe701842378594488b81..96bd292aa5a2be66d47950f10c67037582940fdb 100644
--- a/tb/ptp_clock/Makefile
+++ b/tb/ptp_clock/Makefile
@@ -42,6 +42,7 @@ export PARAM_DRIFT_ENABLE ?= 1
 export PARAM_DRIFT_NS ?= 0
 export PARAM_DRIFT_FNS ?= 2
 export PARAM_DRIFT_RATE ?= 5
+export PARAM_PIPELINE_OUTPUT ?= 0
 
 ifeq ($(SIM), icarus)
 	PLUSARGS += -fst
@@ -56,6 +57,7 @@ ifeq ($(SIM), icarus)
 	COMPILE_ARGS += -P $(TOPLEVEL).DRIFT_NS=$(PARAM_DRIFT_NS)
 	COMPILE_ARGS += -P $(TOPLEVEL).DRIFT_FNS=$(PARAM_DRIFT_FNS)
 	COMPILE_ARGS += -P $(TOPLEVEL).DRIFT_RATE=$(PARAM_DRIFT_RATE)
+	COMPILE_ARGS += -P $(TOPLEVEL).PIPELINE_OUTPUT=$(PARAM_PIPELINE_OUTPUT)
 
 	ifeq ($(WAVES), 1)
 		VERILOG_SOURCES += iverilog_dump.v
@@ -74,6 +76,7 @@ else ifeq ($(SIM), verilator)
 	COMPILE_ARGS += -GDRIFT_NS=$(PARAM_DRIFT_NS)
 	COMPILE_ARGS += -GDRIFT_FNS=$(PARAM_DRIFT_FNS)
 	COMPILE_ARGS += -GDRIFT_RATE=$(PARAM_DRIFT_RATE)
+	COMPILE_ARGS += -GPIPELINE_OUTPUT=$(PARAM_PIPELINE_OUTPUT)
 
 	ifeq ($(WAVES), 1)
 		COMPILE_ARGS += --trace-fst
diff --git a/tb/ptp_clock/test_ptp_clock.py b/tb/ptp_clock/test_ptp_clock.py
index 1166d182bdaaa2b3dba49b9242527a16d992421d..fb60fdc87711c8df4031bed235a30116c4f71e27 100644
--- a/tb/ptp_clock/test_ptp_clock.py
+++ b/tb/ptp_clock/test_ptp_clock.py
@@ -367,6 +367,7 @@ def test_ptp_clock(request):
     parameters['DRIFT_NS'] = 0x0
     parameters['DRIFT_FNS'] = 0x0002
     parameters['DRIFT_RATE'] = 0x0005
+    parameters['PIPELINE_OUTPUT'] = 0
 
     extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}