1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-30 08:32:52 +08:00
corundum/fpga/common/rtl/mqnic_ptp_clock.v
Alex Forencich 2a7d0e0947 Use new PTP time distribution subsystem
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2023-11-07 21:57:07 -08:00

567 lines
21 KiB
Verilog

// SPDX-License-Identifier: BSD-2-Clause-Views
/*
* Copyright (c) 2021-2023 The Regents of the University of California
*/
// Language: Verilog 2001
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* PTP hardware clock
*/
module mqnic_ptp_clock #
(
parameter PTP_CLK_PERIOD_NS_NUM = 4,
parameter PTP_CLK_PERIOD_NS_DENOM = 1,
parameter PTP_CLOCK_CDC_PIPELINE = 0,
parameter REG_ADDR_WIDTH = 7,
parameter REG_DATA_WIDTH = 32,
parameter REG_STRB_WIDTH = (REG_DATA_WIDTH/8),
parameter RB_BASE_ADDR = 0,
parameter RB_NEXT_PTR = 0
)
(
input wire clk,
input wire rst,
/*
* Register interface
*/
input wire [REG_ADDR_WIDTH-1:0] reg_wr_addr,
input wire [REG_DATA_WIDTH-1:0] reg_wr_data,
input wire [REG_STRB_WIDTH-1:0] reg_wr_strb,
input wire reg_wr_en,
output wire reg_wr_wait,
output wire reg_wr_ack,
input wire [REG_ADDR_WIDTH-1:0] reg_rd_addr,
input wire reg_rd_en,
output wire [REG_DATA_WIDTH-1:0] reg_rd_data,
output wire reg_rd_wait,
output wire reg_rd_ack,
/*
* PTP clock
*/
input wire ptp_clk,
input wire ptp_rst,
input wire ptp_sample_clk,
output wire ptp_td_sd,
output wire ptp_pps,
output wire ptp_pps_str,
output wire ptp_sync_locked,
output wire [63:0] ptp_sync_ts_rel,
output wire ptp_sync_ts_rel_step,
output wire [95:0] ptp_sync_ts_tod,
output wire ptp_sync_ts_tod_step,
output wire ptp_sync_pps,
output wire ptp_sync_pps_str
);
parameter PTP_FNS_WIDTH = 32;
parameter PTP_CLK_PERIOD_NS = PTP_CLK_PERIOD_NS_NUM / PTP_CLK_PERIOD_NS_DENOM;
parameter PTP_CLK_PERIOD_NS_REM = PTP_CLK_PERIOD_NS_NUM - PTP_CLK_PERIOD_NS*PTP_CLK_PERIOD_NS_DENOM;
parameter PTP_CLK_PERIOD_FNS = (PTP_CLK_PERIOD_NS_REM * {32'd1, {PTP_FNS_WIDTH{1'b0}}}) / PTP_CLK_PERIOD_NS_DENOM;
parameter PTP_CLK_PERIOD_FNS_REM = (PTP_CLK_PERIOD_NS_REM * {32'd1, {PTP_FNS_WIDTH{1'b0}}}) - PTP_CLK_PERIOD_FNS*PTP_CLK_PERIOD_NS_DENOM;
localparam RBB = RB_BASE_ADDR & {REG_ADDR_WIDTH{1'b1}};
// check configuration
initial begin
if (REG_DATA_WIDTH != 32) begin
$error("Error: Register interface width must be 32 (instance %m)");
$finish;
end
if (REG_STRB_WIDTH * 8 != REG_DATA_WIDTH) begin
$error("Error: Register interface requires byte (8-bit) granularity (instance %m)");
$finish;
end
if (REG_ADDR_WIDTH < 7) begin
$error("Error: Register address width too narrow (instance %m)");
$finish;
end
if (RB_NEXT_PTR >= RB_BASE_ADDR && RB_NEXT_PTR < RB_BASE_ADDR + 7'h60) begin
$error("Error: RB_NEXT_PTR overlaps block (instance %m)");
$finish;
end
end
// control registers
reg reg_wr_ack_reg = 1'b0;
reg [REG_DATA_WIDTH-1:0] reg_rd_data_reg = 0;
reg reg_rd_ack_reg = 1'b0;
reg [95:0] get_ptp_ts_tod_reg = 0;
reg [29:0] set_ptp_ts_tod_ns_reg = 0;
reg [47:0] set_ptp_ts_tod_s_reg = 0;
reg set_ptp_ts_tod_req_reg = 1'b0;
(* shreg_extract = "no" *)
reg set_ptp_ts_tod_req_sync1_reg = 1'b0, set_ptp_ts_tod_req_sync2_reg = 1'b0;
reg set_ptp_ts_tod_ack_reg = 1'b0;
(* shreg_extract = "no" *)
reg set_ptp_ts_tod_ack_sync1_reg = 1'b0, set_ptp_ts_tod_ack_sync2_reg = 1'b0;
reg set_ptp_ts_tod_valid_reg = 0;
wire set_ptp_ts_tod_ready;
reg [29:0] offset_ptp_ts_tod_ns_reg = 0;
reg offset_ptp_ts_tod_req_reg = 1'b0;
(* shreg_extract = "no" *)
reg offset_ptp_ts_tod_req_sync1_reg = 1'b0, offset_ptp_ts_tod_req_sync2_reg = 1'b0;
reg offset_ptp_ts_tod_ack_reg = 1'b0;
(* shreg_extract = "no" *)
reg offset_ptp_ts_tod_ack_sync1_reg = 1'b0, offset_ptp_ts_tod_ack_sync2_reg = 1'b0;
reg offset_ptp_ts_tod_valid_reg = 0;
wire offset_ptp_ts_tod_ready;
reg [63:0] get_ptp_ts_rel_reg = 0;
reg [47:0] set_ptp_ts_rel_ns_reg = 0;
reg set_ptp_ts_rel_req_reg = 1'b0;
(* shreg_extract = "no" *)
reg set_ptp_ts_rel_req_sync1_reg = 1'b0, set_ptp_ts_rel_req_sync2_reg = 1'b0;
reg set_ptp_ts_rel_ack_reg = 1'b0;
(* shreg_extract = "no" *)
reg set_ptp_ts_rel_ack_sync1_reg = 1'b0, set_ptp_ts_rel_ack_sync2_reg = 1'b0;
reg set_ptp_ts_rel_valid_reg = 0;
wire set_ptp_ts_rel_ready;
reg [31:0] offset_ptp_ts_rel_ns_reg = 0;
reg offset_ptp_ts_rel_req_reg = 1'b0;
(* shreg_extract = "no" *)
reg offset_ptp_ts_rel_req_sync1_reg = 1'b0, offset_ptp_ts_rel_req_sync2_reg = 1'b0;
reg offset_ptp_ts_rel_ack_reg = 1'b0;
(* shreg_extract = "no" *)
reg offset_ptp_ts_rel_ack_sync1_reg = 1'b0, offset_ptp_ts_rel_ack_sync2_reg = 1'b0;
reg offset_ptp_ts_rel_valid_reg = 0;
wire offset_ptp_ts_rel_ready;
reg [7:0] set_ptp_period_ns_reg = PTP_CLK_PERIOD_NS;
reg [PTP_FNS_WIDTH-1:0] set_ptp_period_fns_reg = PTP_CLK_PERIOD_FNS;
reg set_ptp_period_req_reg = 1'b0;
(* shreg_extract = "no" *)
reg set_ptp_period_req_sync1_reg = 1'b0, set_ptp_period_req_sync2_reg = 1'b0;
reg set_ptp_period_ack_reg = 1'b0;
(* shreg_extract = "no" *)
reg set_ptp_period_ack_sync1_reg = 1'b0, set_ptp_period_ack_sync2_reg = 1'b0;
reg set_ptp_period_valid_reg = 0;
wire set_ptp_period_ready;
reg [31:0] offset_ptp_ts_fns_reg = 0;
reg offset_ptp_ts_req_reg = 1'b0;
(* shreg_extract = "no" *)
reg offset_ptp_ts_req_sync1_reg = 1'b0, offset_ptp_ts_req_sync2_reg = 1'b0;
reg offset_ptp_ts_ack_reg = 1'b0;
(* shreg_extract = "no" *)
reg offset_ptp_ts_ack_sync1_reg = 1'b0, offset_ptp_ts_ack_sync2_reg = 1'b0;
reg offset_ptp_ts_valid_reg = 0;
wire offset_ptp_ts_ready;
always @(posedge ptp_clk) begin
set_ptp_ts_tod_req_sync1_reg <= set_ptp_ts_tod_req_reg;
set_ptp_ts_tod_req_sync2_reg <= set_ptp_ts_tod_req_sync1_reg;
offset_ptp_ts_tod_req_sync1_reg <= offset_ptp_ts_tod_req_reg;
offset_ptp_ts_tod_req_sync2_reg <= offset_ptp_ts_tod_req_sync1_reg;
set_ptp_ts_rel_req_sync1_reg <= set_ptp_ts_rel_req_reg;
set_ptp_ts_rel_req_sync2_reg <= set_ptp_ts_rel_req_sync1_reg;
offset_ptp_ts_rel_req_sync1_reg <= offset_ptp_ts_rel_req_reg;
offset_ptp_ts_rel_req_sync2_reg <= offset_ptp_ts_rel_req_sync1_reg;
set_ptp_period_req_sync1_reg <= set_ptp_period_req_reg;
set_ptp_period_req_sync2_reg <= set_ptp_period_req_sync1_reg;
offset_ptp_ts_req_sync1_reg <= offset_ptp_ts_req_reg;
offset_ptp_ts_req_sync2_reg <= offset_ptp_ts_req_sync1_reg;
end
always @(posedge clk) begin
set_ptp_ts_tod_ack_sync1_reg <= set_ptp_ts_tod_ack_reg;
set_ptp_ts_tod_ack_sync2_reg <= set_ptp_ts_tod_ack_sync1_reg;
offset_ptp_ts_tod_ack_sync1_reg <= offset_ptp_ts_tod_ack_reg;
offset_ptp_ts_tod_ack_sync2_reg <= offset_ptp_ts_tod_ack_sync1_reg;
set_ptp_ts_rel_ack_sync1_reg <= set_ptp_ts_rel_ack_reg;
set_ptp_ts_rel_ack_sync2_reg <= set_ptp_ts_rel_ack_sync1_reg;
offset_ptp_ts_rel_ack_sync1_reg <= offset_ptp_ts_rel_ack_reg;
offset_ptp_ts_rel_ack_sync2_reg <= offset_ptp_ts_rel_ack_sync1_reg;
set_ptp_period_ack_sync1_reg <= set_ptp_period_ack_reg;
set_ptp_period_ack_sync2_reg <= set_ptp_period_ack_sync1_reg;
offset_ptp_ts_ack_sync1_reg <= offset_ptp_ts_ack_reg;
offset_ptp_ts_ack_sync2_reg <= offset_ptp_ts_ack_sync1_reg;
end
always @(posedge ptp_clk) begin
if (set_ptp_ts_tod_ack_reg) begin
set_ptp_ts_tod_ack_reg <= set_ptp_ts_tod_req_sync2_reg;
end else begin
if (set_ptp_ts_tod_valid_reg && set_ptp_ts_tod_ready) begin
set_ptp_ts_tod_valid_reg <= 1'b0;
set_ptp_ts_tod_ack_reg <= 1'b1;
end else begin
set_ptp_ts_tod_valid_reg <= set_ptp_ts_tod_req_sync2_reg;
end
end
if (offset_ptp_ts_tod_ack_reg) begin
offset_ptp_ts_tod_ack_reg <= offset_ptp_ts_tod_req_sync2_reg;
end else begin
if (offset_ptp_ts_tod_valid_reg && offset_ptp_ts_tod_ready) begin
offset_ptp_ts_tod_valid_reg <= 1'b0;
offset_ptp_ts_tod_ack_reg <= 1'b1;
end else begin
offset_ptp_ts_tod_valid_reg <= offset_ptp_ts_tod_req_sync2_reg;
end
end
if (set_ptp_ts_rel_ack_reg) begin
set_ptp_ts_rel_ack_reg <= set_ptp_ts_rel_req_sync2_reg;
end else begin
if (set_ptp_ts_rel_valid_reg && set_ptp_ts_rel_ready) begin
set_ptp_ts_rel_valid_reg <= 1'b0;
set_ptp_ts_rel_ack_reg <= 1'b1;
end else begin
set_ptp_ts_rel_valid_reg <= set_ptp_ts_rel_req_sync2_reg;
end
end
if (offset_ptp_ts_rel_ack_reg) begin
offset_ptp_ts_rel_ack_reg <= offset_ptp_ts_rel_req_sync2_reg;
end else begin
if (offset_ptp_ts_rel_valid_reg && offset_ptp_ts_rel_ready) begin
offset_ptp_ts_rel_valid_reg <= 1'b0;
offset_ptp_ts_rel_ack_reg <= 1'b1;
end else begin
offset_ptp_ts_rel_valid_reg <= offset_ptp_ts_rel_req_sync2_reg;
end
end
if (set_ptp_period_ack_reg) begin
set_ptp_period_ack_reg <= set_ptp_period_req_sync2_reg;
end else begin
if (set_ptp_period_valid_reg && set_ptp_period_ready) begin
set_ptp_period_valid_reg <= 1'b0;
set_ptp_period_ack_reg <= 1'b1;
end else begin
set_ptp_period_valid_reg <= set_ptp_period_req_sync2_reg;
end
end
if (offset_ptp_ts_ack_reg) begin
offset_ptp_ts_ack_reg <= offset_ptp_ts_req_sync2_reg;
end else begin
if (offset_ptp_ts_valid_reg && offset_ptp_ts_ready) begin
offset_ptp_ts_valid_reg <= 1'b0;
offset_ptp_ts_ack_reg <= 1'b1;
end else begin
offset_ptp_ts_valid_reg <= offset_ptp_ts_req_sync2_reg;
end
end
if (ptp_rst) begin
set_ptp_ts_tod_ack_reg <= 1'b0;
set_ptp_ts_tod_valid_reg <= 1'b0;
offset_ptp_ts_tod_ack_reg <= 1'b0;
offset_ptp_ts_tod_valid_reg <= 1'b0;
set_ptp_ts_rel_ack_reg <= 1'b0;
set_ptp_ts_rel_valid_reg <= 1'b0;
offset_ptp_ts_rel_ack_reg <= 1'b0;
offset_ptp_ts_rel_valid_reg <= 1'b0;
set_ptp_period_ack_reg <= 1'b0;
set_ptp_period_valid_reg <= 1'b0;
offset_ptp_ts_ack_reg <= 1'b0;
offset_ptp_ts_valid_reg <= 1'b0;
end
end
assign reg_wr_wait = 1'b0;
assign reg_wr_ack = reg_wr_ack_reg;
assign reg_rd_data = reg_rd_data_reg;
assign reg_rd_wait = 1'b0;
assign reg_rd_ack = reg_rd_ack_reg;
always @(posedge clk) begin
reg_wr_ack_reg <= 1'b0;
reg_rd_data_reg <= 0;
reg_rd_ack_reg <= 1'b0;
set_ptp_ts_tod_req_reg <= set_ptp_ts_tod_req_reg && !set_ptp_ts_tod_ack_sync2_reg;
offset_ptp_ts_tod_req_reg <= offset_ptp_ts_tod_req_reg && !offset_ptp_ts_tod_ack_sync2_reg;
set_ptp_ts_rel_req_reg <= set_ptp_ts_rel_req_reg && !set_ptp_ts_rel_ack_sync2_reg;
offset_ptp_ts_rel_req_reg <= offset_ptp_ts_rel_req_reg && !offset_ptp_ts_rel_ack_sync2_reg;
offset_ptp_ts_req_reg <= offset_ptp_ts_req_reg && !offset_ptp_ts_ack_sync2_reg;
set_ptp_period_req_reg <= set_ptp_period_req_reg && !set_ptp_period_ack_sync2_reg;
if (reg_wr_en && !reg_wr_ack_reg) begin
// write operation
reg_wr_ack_reg <= 1'b1;
case ({reg_wr_addr >> 2, 2'b00})
// PHC
RBB+7'h50: begin
// PTP offset ToD
if (!offset_ptp_ts_tod_req_reg || offset_ptp_ts_tod_ack_sync2_reg) begin
offset_ptp_ts_tod_ns_reg <= reg_wr_data;
offset_ptp_ts_tod_req_reg <= reg_wr_data != 0;
end
end
RBB+7'h54: begin
// PTP set ToD ns
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
set_ptp_ts_tod_ns_reg <= reg_wr_data;
end
end
RBB+7'h58: begin
// PTP set ToD sec l
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
set_ptp_ts_tod_s_reg[31:0] <= reg_wr_data;
end
end
RBB+7'h5C: begin
// PTP set ToD sec h
if (!set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg) begin
set_ptp_ts_tod_s_reg[47:32] <= reg_wr_data;
set_ptp_ts_tod_req_reg <= 1'b1;
end
end
RBB+7'h60: begin
// PTP set rel ns l
if (!set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg) begin
set_ptp_ts_rel_ns_reg[31:0] <= reg_wr_data;
end
end
RBB+7'h64: begin
// PTP set rel ns h
if (!set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg) begin
set_ptp_ts_rel_ns_reg[47:32] <= reg_wr_data;
set_ptp_ts_rel_req_reg <= 1'b1;
end
end
RBB+7'h68: begin
// PTP offset rel
if (!offset_ptp_ts_rel_req_reg || offset_ptp_ts_rel_ack_sync2_reg) begin
offset_ptp_ts_rel_ns_reg <= reg_wr_data;
offset_ptp_ts_rel_req_reg <= reg_wr_data != 0;
end
end
RBB+7'h6C: begin
// PTP offset FNS
if (!offset_ptp_ts_req_reg || offset_ptp_ts_ack_sync2_reg) begin
offset_ptp_ts_fns_reg <= reg_wr_data;
offset_ptp_ts_req_reg <= reg_wr_data != 0;
end
end
RBB+7'h78: begin
// PTP period fns
if (!set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg) begin
set_ptp_period_fns_reg <= reg_wr_data;
end
end
RBB+7'h7C: begin
// PTP period ns
if (!set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg) begin
set_ptp_period_ns_reg <= reg_wr_data;
set_ptp_period_req_reg <= 1'b1;
end
end
default: reg_wr_ack_reg <= 1'b0;
endcase
end
if (reg_rd_en && !reg_rd_ack_reg) begin
// read operation
reg_rd_ack_reg <= 1'b1;
case ({reg_rd_addr >> 2, 2'b00})
// PHC
RBB+7'h00: reg_rd_data_reg <= 32'h0000C080; // PHC: Type
RBB+7'h04: reg_rd_data_reg <= 32'h00000200; // PHC: Version
RBB+7'h08: reg_rd_data_reg <= RB_NEXT_PTR; // PHC: Next header
RBB+7'h0C: begin
// PHC control
reg_rd_data_reg[8] <= ptp_sync_pps_str; // PPS
reg_rd_data_reg[16] <= ptp_sync_locked; // Locked
reg_rd_data_reg[24] <= set_ptp_ts_tod_req_reg || set_ptp_ts_tod_ack_sync2_reg; // ToD set pending
reg_rd_data_reg[25] <= offset_ptp_ts_tod_req_reg || offset_ptp_ts_tod_ack_sync2_reg; // ToD offset pending
reg_rd_data_reg[26] <= set_ptp_ts_rel_req_reg || set_ptp_ts_rel_ack_sync2_reg; // Relative set pending
reg_rd_data_reg[27] <= offset_ptp_ts_rel_req_reg || offset_ptp_ts_rel_ack_sync2_reg; // Relative offset pending
reg_rd_data_reg[28] <= set_ptp_period_req_reg || set_ptp_period_ack_sync2_reg; // Period set pending
reg_rd_data_reg[29] <= offset_ptp_ts_req_reg || offset_ptp_ts_ack_sync2_reg; // FNS offset pending
end
RBB+7'h10: reg_rd_data_reg <= {ptp_sync_ts_tod[15:0], 16'd0}; // PTP cur fns
RBB+7'h14: reg_rd_data_reg <= ptp_sync_ts_tod[47:16]; // PTP cur ToD ns
RBB+7'h18: reg_rd_data_reg <= ptp_sync_ts_tod[79:48]; // PTP cur ToD sec l
RBB+7'h1C: reg_rd_data_reg <= ptp_sync_ts_tod[95:80]; // PTP cur ToD sec h
RBB+7'h20: reg_rd_data_reg <= ptp_sync_ts_rel[47:16]; // PTP cur rel ns l
RBB+7'h24: reg_rd_data_reg <= ptp_sync_ts_rel[63:48]; // PTP cur rel ns h
RBB+7'h28: reg_rd_data_reg <= 0; // PTP cur PTM l
RBB+7'h2C: reg_rd_data_reg <= 0; // PTP cur PTM h
RBB+7'h30: begin
// PTP snapshot fns
get_ptp_ts_tod_reg <= ptp_sync_ts_tod;
get_ptp_ts_rel_reg <= ptp_sync_ts_rel;
reg_rd_data_reg <= {ptp_sync_ts_tod[15:0], 16'd0};
end
RBB+7'h34: reg_rd_data_reg <= get_ptp_ts_tod_reg[45:16]; // PTP snapshot ToD ns
RBB+7'h38: reg_rd_data_reg <= get_ptp_ts_tod_reg[79:48]; // PTP snapshot ToD sec l
RBB+7'h3C: reg_rd_data_reg <= get_ptp_ts_tod_reg[95:80]; // PTP snapshot ToD sec h
RBB+7'h40: reg_rd_data_reg <= get_ptp_ts_rel_reg[47:16]; // PTP snapshot rel ns l
RBB+7'h44: reg_rd_data_reg <= get_ptp_ts_rel_reg[63:48]; // PTP snapshot rel ns h
RBB+7'h48: reg_rd_data_reg <= 0; // PTP snapshot PTM l
RBB+7'h4C: reg_rd_data_reg <= 0; // PTP snapshot PTM h
RBB+7'h50: reg_rd_data_reg <= offset_ptp_ts_tod_ns_reg; // PTP offset ToD
RBB+7'h54: reg_rd_data_reg <= set_ptp_ts_tod_ns_reg; // PTP set ToD ns
RBB+7'h58: reg_rd_data_reg <= set_ptp_ts_tod_s_reg[31:0]; // PTP set ToD sec l
RBB+7'h5C: reg_rd_data_reg <= set_ptp_ts_tod_s_reg[47:16]; // PTP set ToD sec h
RBB+7'h60: reg_rd_data_reg <= set_ptp_ts_rel_ns_reg[31:0]; // PTP set rel ns l
RBB+7'h64: reg_rd_data_reg <= set_ptp_ts_rel_ns_reg[47:16]; // PTP set rel ns h
RBB+7'h68: reg_rd_data_reg <= offset_ptp_ts_rel_ns_reg; // PTP offset rel
RBB+7'h6C: reg_rd_data_reg <= offset_ptp_ts_fns_reg; // PTP offset FNS
RBB+7'h70: reg_rd_data_reg <= PTP_CLK_PERIOD_FNS; // PTP nom period fns
RBB+7'h74: reg_rd_data_reg <= PTP_CLK_PERIOD_NS; // PTP nom period ns
RBB+7'h78: reg_rd_data_reg <= set_ptp_period_fns_reg; // PTP period fns
RBB+7'h7C: reg_rd_data_reg <= set_ptp_period_ns_reg; // PTP period ns
default: reg_rd_ack_reg <= 1'b0;
endcase
end
if (rst) begin
reg_wr_ack_reg <= 1'b0;
reg_rd_ack_reg <= 1'b0;
set_ptp_period_ns_reg <= PTP_CLK_PERIOD_NS;
set_ptp_period_fns_reg <= PTP_CLK_PERIOD_FNS;
set_ptp_ts_tod_req_reg <= 1'b0;
offset_ptp_ts_tod_req_reg <= 1'b0;
set_ptp_ts_rel_req_reg <= 1'b0;
offset_ptp_ts_rel_req_reg <= 1'b0;
offset_ptp_ts_req_reg <= 1'b0;
set_ptp_period_req_reg <= 1'b0;
end
end
// PTP clock
ptp_td_phc #(
.PERIOD_NS_NUM(PTP_CLK_PERIOD_NS_NUM),
.PERIOD_NS_DENOM(PTP_CLK_PERIOD_NS_DENOM)
)
ptp_td_phc_inst (
.clk(ptp_clk),
.rst(ptp_rst),
/*
* ToD timestamp control
*/
.input_ts_tod_s(set_ptp_ts_tod_s_reg),
.input_ts_tod_ns(set_ptp_ts_tod_ns_reg),
.input_ts_tod_valid(set_ptp_ts_tod_valid_reg),
.input_ts_tod_ready(set_ptp_ts_tod_ready),
.input_ts_tod_offset_ns(offset_ptp_ts_tod_ns_reg),
.input_ts_tod_offset_valid(offset_ptp_ts_tod_valid_reg),
.input_ts_tod_offset_ready(offset_ptp_ts_tod_ready),
/*
* Relative timestamp control
*/
.input_ts_rel_ns(set_ptp_ts_rel_ns_reg),
.input_ts_rel_valid(set_ptp_ts_rel_valid_reg),
.input_ts_rel_ready(set_ptp_ts_rel_ready),
.input_ts_rel_offset_ns(offset_ptp_ts_rel_ns_reg),
.input_ts_rel_offset_valid(offset_ptp_ts_rel_valid_reg),
.input_ts_rel_offset_ready(offset_ptp_ts_rel_ready),
/*
* Fractional ns control
*/
.input_ts_offset_fns(offset_ptp_ts_fns_reg),
.input_ts_offset_valid(offset_ptp_ts_valid_reg),
.input_ts_offset_ready(offset_ptp_ts_ready),
/*
* Period control
*/
.input_period_ns(set_ptp_period_ns_reg),
.input_period_fns(set_ptp_period_fns_reg),
.input_period_valid(set_ptp_period_valid_reg),
.input_period_ready(set_ptp_period_ready),
.input_drift_num(0),
.input_drift_denom(0),
.input_drift_valid(1'b0),
.input_drift_ready(),
/*
* Time distribution serial data output
*/
.ptp_td_sdo(ptp_td_sd),
/*
* PPS output
*/
.output_pps(ptp_pps),
.output_pps_str(ptp_pps_str)
);
// sync to core clock domain
ptp_td_leaf #(
.TS_REL_EN(1),
.TS_TOD_EN(1),
.TS_FNS_W(16),
.TS_REL_NS_W(48),
.TS_TOD_S_W(48),
.TS_REL_W(64),
.TS_TOD_W(96),
.TD_SDI_PIPELINE(PTP_CLOCK_CDC_PIPELINE)
)
ptp_td_leaf_inst (
.clk(clk),
.rst(rst),
.sample_clk(ptp_sample_clk),
/*
* PTP clock interface
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_td_sdi(ptp_td_sd),
/*
* Timestamp output
*/
.output_ts_rel(ptp_sync_ts_rel),
.output_ts_rel_step(ptp_sync_ts_rel_step),
.output_ts_tod(ptp_sync_ts_tod),
.output_ts_tod_step(ptp_sync_ts_tod_step),
/*
* PPS output (ToD format only)
*/
.output_pps(ptp_sync_pps),
.output_pps_str(ptp_sync_pps_str),
/*
* Status
*/
.locked(ptp_sync_locked)
);
endmodule
`resetall