cndm: Add PTP TD leaf clocks to testbenches to provide MAC models with time reference

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-03-12 22:27:53 -07:00
parent 0d48b71c26
commit 0364fce4f9
4 changed files with 242 additions and 6 deletions

View File

@@ -305,9 +305,11 @@ class TB:
rx_clk=dut.mac_rx_clk[k], rx_clk=dut.mac_rx_clk[k],
rx_rst=dut.mac_rx_rst[k], rx_rst=dut.mac_rx_rst[k],
rx_bus=AxiStreamBus.from_entity(dut.mac_axis_rx[k]), rx_bus=AxiStreamBus.from_entity(dut.mac_axis_rx[k]),
tx_ptp_time=dut.mac_axis_tx[k].tid, # TODO rx_ptp_time=dut.rx_ptp_time[k],
tx_ptp_ts=dut.mac_axis_tx_cpl[k].tdata, # TODO tx_ptp_time=dut.tx_ptp_time[k],
tx_ptp_ts_valid=dut.mac_axis_tx_cpl[k].tvalid, # TODO tx_ptp_ts=dut.mac_axis_tx_cpl[k].tdata,
tx_ptp_ts_tag=dut.mac_axis_tx_cpl[k].tid,
tx_ptp_ts_valid=dut.mac_axis_tx_cpl[k].tvalid,
ifg=12, speed=eth_speed ifg=12, speed=eth_speed
) )
self.port_mac.append(mac) self.port_mac.append(mac)

View File

@@ -195,6 +195,122 @@ taxi_axis_if #(
.USER_W(PTP_TS_W+1) .USER_W(PTP_TS_W+1)
) mac_axis_rx[PORTS](); ) mac_axis_rx[PORTS]();
// PTP leaf clocks for MAC timestamping
logic [PTP_TS_W-1:0] tx_ptp_time[PORTS];
logic tx_ptp_step[PORTS];
logic [PTP_TS_W-1:0] rx_ptp_time[PORTS];
logic rx_ptp_step[PORTS];
if (PTP_TS_EN) begin : ptp
for (genvar n = 0; n < PORTS; n = n + 1) begin : ch
// TX
wire [PTP_TS_W-1:0] tx_ptp_ts_rel;
wire tx_ptp_ts_rel_step;
wire [PTP_TS_W-1:0] tx_ptp_ts_tod;
wire tx_ptp_ts_tod_step;
taxi_ptp_td_leaf #(
.TS_REL_EN(!PTP_TS_FMT_TOD),
.TS_TOD_EN(PTP_TS_FMT_TOD),
.TS_FNS_W(16),
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
.TS_REL_W(PTP_TS_W),
.TS_TOD_W(PTP_TS_W),
.TD_SDI_PIPELINE(2)
)
tx_leaf_inst (
.clk(mac_tx_clk[n]),
.rst(mac_tx_rst[n]),
.sample_clk(ptp_sample_clk),
/*
* PTP clock interface
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_td_sdi(ptp_td_sdo),
/*
* Timestamp output
*/
.output_ts_rel(tx_ptp_ts_rel),
.output_ts_rel_step(tx_ptp_ts_rel_step),
.output_ts_tod(tx_ptp_ts_tod),
.output_ts_tod_step(tx_ptp_ts_tod_step),
/*
* PPS output (ToD format only)
*/
.output_pps(),
.output_pps_str(),
/*
* Status
*/
.locked()
);
assign tx_ptp_time[n] = PTP_TS_FMT_TOD ? tx_ptp_ts_tod : tx_ptp_ts_rel;
assign tx_ptp_step[n] = PTP_TS_FMT_TOD ? tx_ptp_ts_tod_step : tx_ptp_ts_rel_step;
// RX
wire [PTP_TS_W-1:0] rx_ptp_ts_rel;
wire rx_ptp_ts_rel_step;
wire [PTP_TS_W-1:0] rx_ptp_ts_tod;
wire rx_ptp_ts_tod_step;
taxi_ptp_td_leaf #(
.TS_REL_EN(!PTP_TS_FMT_TOD),
.TS_TOD_EN(PTP_TS_FMT_TOD),
.TS_FNS_W(16),
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
.TS_REL_W(PTP_TS_W),
.TS_TOD_W(PTP_TS_W),
.TD_SDI_PIPELINE(2)
)
rx_leaf_inst (
.clk(mac_rx_clk[n]),
.rst(mac_rx_rst[n]),
.sample_clk(ptp_sample_clk),
/*
* PTP clock interface
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_td_sdi(ptp_td_sdo),
/*
* Timestamp output
*/
.output_ts_rel(rx_ptp_ts_rel),
.output_ts_rel_step(rx_ptp_ts_rel_step),
.output_ts_tod(rx_ptp_ts_tod),
.output_ts_tod_step(rx_ptp_ts_tod_step),
/*
* PPS output (ToD format only)
*/
.output_pps(),
.output_pps_str(),
/*
* Status
*/
.locked()
);
assign rx_ptp_time[n] = PTP_TS_FMT_TOD ? rx_ptp_ts_tod : rx_ptp_ts_rel;
assign rx_ptp_step[n] = PTP_TS_FMT_TOD ? rx_ptp_ts_tod_step : rx_ptp_ts_rel_step;
end
end
cndm_lite_pcie_us #( cndm_lite_pcie_us #(
.SIM(SIM), .SIM(SIM),
.VENDOR(VENDOR), .VENDOR(VENDOR),

View File

@@ -305,9 +305,11 @@ class TB:
rx_clk=dut.mac_rx_clk[k], rx_clk=dut.mac_rx_clk[k],
rx_rst=dut.mac_rx_rst[k], rx_rst=dut.mac_rx_rst[k],
rx_bus=AxiStreamBus.from_entity(dut.mac_axis_rx[k]), rx_bus=AxiStreamBus.from_entity(dut.mac_axis_rx[k]),
tx_ptp_time=dut.mac_axis_tx[k].tid, # TODO rx_ptp_time=dut.rx_ptp_time[k],
tx_ptp_ts=dut.mac_axis_tx_cpl[k].tdata, # TODO tx_ptp_time=dut.tx_ptp_time[k],
tx_ptp_ts_valid=dut.mac_axis_tx_cpl[k].tvalid, # TODO tx_ptp_ts=dut.mac_axis_tx_cpl[k].tdata,
tx_ptp_ts_tag=dut.mac_axis_tx_cpl[k].tid,
tx_ptp_ts_valid=dut.mac_axis_tx_cpl[k].tvalid,
ifg=12, speed=eth_speed ifg=12, speed=eth_speed
) )
self.port_mac.append(mac) self.port_mac.append(mac)

View File

@@ -195,6 +195,122 @@ taxi_axis_if #(
.USER_W(PTP_TS_W+1) .USER_W(PTP_TS_W+1)
) mac_axis_rx[PORTS](); ) mac_axis_rx[PORTS]();
// PTP leaf clocks for MAC timestamping
logic [PTP_TS_W-1:0] tx_ptp_time[PORTS];
logic tx_ptp_step[PORTS];
logic [PTP_TS_W-1:0] rx_ptp_time[PORTS];
logic rx_ptp_step[PORTS];
if (PTP_TS_EN) begin : ptp
for (genvar n = 0; n < PORTS; n = n + 1) begin : ch
// TX
wire [PTP_TS_W-1:0] tx_ptp_ts_rel;
wire tx_ptp_ts_rel_step;
wire [PTP_TS_W-1:0] tx_ptp_ts_tod;
wire tx_ptp_ts_tod_step;
taxi_ptp_td_leaf #(
.TS_REL_EN(!PTP_TS_FMT_TOD),
.TS_TOD_EN(PTP_TS_FMT_TOD),
.TS_FNS_W(16),
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
.TS_REL_W(PTP_TS_W),
.TS_TOD_W(PTP_TS_W),
.TD_SDI_PIPELINE(2)
)
tx_leaf_inst (
.clk(mac_tx_clk[n]),
.rst(mac_tx_rst[n]),
.sample_clk(ptp_sample_clk),
/*
* PTP clock interface
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_td_sdi(ptp_td_sdo),
/*
* Timestamp output
*/
.output_ts_rel(tx_ptp_ts_rel),
.output_ts_rel_step(tx_ptp_ts_rel_step),
.output_ts_tod(tx_ptp_ts_tod),
.output_ts_tod_step(tx_ptp_ts_tod_step),
/*
* PPS output (ToD format only)
*/
.output_pps(),
.output_pps_str(),
/*
* Status
*/
.locked()
);
assign tx_ptp_time[n] = PTP_TS_FMT_TOD ? tx_ptp_ts_tod : tx_ptp_ts_rel;
assign tx_ptp_step[n] = PTP_TS_FMT_TOD ? tx_ptp_ts_tod_step : tx_ptp_ts_rel_step;
// RX
wire [PTP_TS_W-1:0] rx_ptp_ts_rel;
wire rx_ptp_ts_rel_step;
wire [PTP_TS_W-1:0] rx_ptp_ts_tod;
wire rx_ptp_ts_tod_step;
taxi_ptp_td_leaf #(
.TS_REL_EN(!PTP_TS_FMT_TOD),
.TS_TOD_EN(PTP_TS_FMT_TOD),
.TS_FNS_W(16),
.TS_REL_NS_W(PTP_TS_FMT_TOD ? 48 : PTP_TS_W-16),
.TS_TOD_S_W(PTP_TS_FMT_TOD ? PTP_TS_W-32-16 : 48),
.TS_REL_W(PTP_TS_W),
.TS_TOD_W(PTP_TS_W),
.TD_SDI_PIPELINE(2)
)
rx_leaf_inst (
.clk(mac_rx_clk[n]),
.rst(mac_rx_rst[n]),
.sample_clk(ptp_sample_clk),
/*
* PTP clock interface
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_td_sdi(ptp_td_sdo),
/*
* Timestamp output
*/
.output_ts_rel(rx_ptp_ts_rel),
.output_ts_rel_step(rx_ptp_ts_rel_step),
.output_ts_tod(rx_ptp_ts_tod),
.output_ts_tod_step(rx_ptp_ts_tod_step),
/*
* PPS output (ToD format only)
*/
.output_pps(),
.output_pps_str(),
/*
* Status
*/
.locked()
);
assign rx_ptp_time[n] = PTP_TS_FMT_TOD ? rx_ptp_ts_tod : rx_ptp_ts_rel;
assign rx_ptp_step[n] = PTP_TS_FMT_TOD ? rx_ptp_ts_tod_step : rx_ptp_ts_rel_step;
end
end
cndm_micro_pcie_us #( cndm_micro_pcie_us #(
.SIM(SIM), .SIM(SIM),
.VENDOR(VENDOR), .VENDOR(VENDOR),