eth: Add 32-bit support to combined MAC+PCS module

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2025-06-17 21:37:34 -07:00
parent 7b1ae24d95
commit 5b0cae2aac
6 changed files with 337 additions and 138 deletions

View File

@@ -1,5 +1,6 @@
taxi_eth_mac_phy_10g_rx.sv taxi_eth_mac_phy_10g_rx.sv
taxi_eth_phy_10g_rx_if.f taxi_eth_phy_10g_rx_if.f
taxi_axis_baser_rx_32.sv
taxi_axis_baser_rx_64.sv taxi_axis_baser_rx_64.sv
../lib/taxi/src/lfsr/rtl/taxi_lfsr.sv ../lib/taxi/src/lfsr/rtl/taxi_lfsr.sv
../lib/taxi/src/axis/rtl/taxi_axis_if.sv ../lib/taxi/src/axis/rtl/taxi_axis_if.sv

View File

@@ -142,62 +142,127 @@ eth_phy_10g_rx_if_inst (
.cfg_rx_prbs31_enable(cfg_rx_prbs31_enable) .cfg_rx_prbs31_enable(cfg_rx_prbs31_enable)
); );
taxi_axis_baser_rx_64 #( if (DATA_W == 64) begin
.DATA_W(DATA_W),
.HDR_W(HDR_W),
.GBX_IF_EN(GBX_IF_EN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W)
)
axis_baser_rx_inst (
.clk(clk),
.rst(rst),
/* taxi_axis_baser_rx_64 #(
* 10GBASE-R encoded input .DATA_W(DATA_W),
*/ .HDR_W(HDR_W),
.encoded_rx_data(encoded_rx_data), .GBX_IF_EN(GBX_IF_EN),
.encoded_rx_data_valid(encoded_rx_data_valid), .PTP_TS_EN(PTP_TS_EN),
.encoded_rx_hdr(encoded_rx_hdr), .PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.encoded_rx_hdr_valid(encoded_rx_hdr_valid), .PTP_TS_W(PTP_TS_W)
)
axis_baser_rx_inst (
.clk(clk),
.rst(rst),
/* /*
* Receive interface (AXI stream) * 10GBASE-R encoded input
*/ */
.m_axis_rx(m_axis_rx), .encoded_rx_data(encoded_rx_data),
.encoded_rx_data_valid(encoded_rx_data_valid),
.encoded_rx_hdr(encoded_rx_hdr),
.encoded_rx_hdr_valid(encoded_rx_hdr_valid),
/* /*
* PTP * Receive interface (AXI stream)
*/ */
.ptp_ts(ptp_ts), .m_axis_rx(m_axis_rx),
/* /*
* Configuration * PTP
*/ */
.cfg_rx_max_pkt_len(cfg_rx_max_pkt_len), .ptp_ts(ptp_ts),
.cfg_rx_enable(cfg_rx_enable),
/* /*
* Status * Configuration
*/ */
.rx_start_packet(rx_start_packet), .cfg_rx_max_pkt_len(cfg_rx_max_pkt_len),
.stat_rx_byte(stat_rx_byte), .cfg_rx_enable(cfg_rx_enable),
.stat_rx_pkt_len(stat_rx_pkt_len),
.stat_rx_pkt_fragment(stat_rx_pkt_fragment), /*
.stat_rx_pkt_jabber(stat_rx_pkt_jabber), * Status
.stat_rx_pkt_ucast(stat_rx_pkt_ucast), */
.stat_rx_pkt_mcast(stat_rx_pkt_mcast), .rx_start_packet(rx_start_packet),
.stat_rx_pkt_bcast(stat_rx_pkt_bcast), .stat_rx_byte(stat_rx_byte),
.stat_rx_pkt_vlan(stat_rx_pkt_vlan), .stat_rx_pkt_len(stat_rx_pkt_len),
.stat_rx_pkt_good(stat_rx_pkt_good), .stat_rx_pkt_fragment(stat_rx_pkt_fragment),
.stat_rx_pkt_bad(stat_rx_pkt_bad), .stat_rx_pkt_jabber(stat_rx_pkt_jabber),
.stat_rx_err_oversize(stat_rx_err_oversize), .stat_rx_pkt_ucast(stat_rx_pkt_ucast),
.stat_rx_err_bad_fcs(stat_rx_err_bad_fcs), .stat_rx_pkt_mcast(stat_rx_pkt_mcast),
.stat_rx_err_bad_block(stat_rx_err_bad_block), .stat_rx_pkt_bcast(stat_rx_pkt_bcast),
.stat_rx_err_framing(stat_rx_err_framing), .stat_rx_pkt_vlan(stat_rx_pkt_vlan),
.stat_rx_err_preamble(stat_rx_err_preamble) .stat_rx_pkt_good(stat_rx_pkt_good),
); .stat_rx_pkt_bad(stat_rx_pkt_bad),
.stat_rx_err_oversize(stat_rx_err_oversize),
.stat_rx_err_bad_fcs(stat_rx_err_bad_fcs),
.stat_rx_err_bad_block(stat_rx_err_bad_block),
.stat_rx_err_framing(stat_rx_err_framing),
.stat_rx_err_preamble(stat_rx_err_preamble)
);
end else begin
taxi_axis_baser_rx_32 #(
.DATA_W(DATA_W),
.HDR_W(HDR_W),
.GBX_IF_EN(GBX_IF_EN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_W(PTP_TS_W)
)
axis_baser_rx_inst (
.clk(clk),
.rst(rst),
/*
* 10GBASE-R encoded input
*/
.encoded_rx_data(encoded_rx_data),
.encoded_rx_data_valid(encoded_rx_data_valid),
.encoded_rx_hdr(encoded_rx_hdr),
.encoded_rx_hdr_valid(encoded_rx_hdr_valid),
/*
* Receive interface (AXI stream)
*/
.m_axis_rx(m_axis_rx),
/*
* PTP
*/
.ptp_ts(ptp_ts),
/*
* Configuration
*/
.cfg_rx_max_pkt_len(cfg_rx_max_pkt_len),
.cfg_rx_enable(cfg_rx_enable),
/*
* Status
*/
.rx_start_packet(rx_start_packet[0]),
.stat_rx_byte(stat_rx_byte[2:0]),
.stat_rx_pkt_len(stat_rx_pkt_len),
.stat_rx_pkt_fragment(stat_rx_pkt_fragment),
.stat_rx_pkt_jabber(stat_rx_pkt_jabber),
.stat_rx_pkt_ucast(stat_rx_pkt_ucast),
.stat_rx_pkt_mcast(stat_rx_pkt_mcast),
.stat_rx_pkt_bcast(stat_rx_pkt_bcast),
.stat_rx_pkt_vlan(stat_rx_pkt_vlan),
.stat_rx_pkt_good(stat_rx_pkt_good),
.stat_rx_pkt_bad(stat_rx_pkt_bad),
.stat_rx_err_oversize(stat_rx_err_oversize),
.stat_rx_err_bad_fcs(stat_rx_err_bad_fcs),
.stat_rx_err_bad_block(stat_rx_err_bad_block),
.stat_rx_err_framing(stat_rx_err_framing),
.stat_rx_err_preamble(stat_rx_err_preamble)
);
assign rx_start_packet[1] = 1'b0;
assign stat_rx_byte[3] = 1'b0;
end
endmodule endmodule

View File

@@ -1,5 +1,6 @@
taxi_eth_mac_phy_10g_tx.sv taxi_eth_mac_phy_10g_tx.sv
taxi_eth_phy_10g_tx_if.f taxi_eth_phy_10g_tx_if.f
taxi_axis_baser_tx_32.sv
taxi_axis_baser_tx_64.sv taxi_axis_baser_tx_64.sv
../lib/taxi/src/lfsr/rtl/taxi_lfsr.sv ../lib/taxi/src/lfsr/rtl/taxi_lfsr.sv
../lib/taxi/src/axis/rtl/taxi_axis_if.sv ../lib/taxi/src/axis/rtl/taxi_axis_if.sv

View File

@@ -92,68 +92,139 @@ wire tx_gbx_req_sync;
wire tx_gbx_req_stall; wire tx_gbx_req_stall;
wire tx_gbx_sync; wire tx_gbx_sync;
taxi_axis_baser_tx_64 #( if (DATA_W == 64) begin
.DATA_W(DATA_W),
.HDR_W(HDR_W),
.GBX_IF_EN(GBX_IF_EN),
.GBX_CNT(1),
.PADDING_EN(PADDING_EN),
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
)
axis_baser_tx_inst (
.clk(clk),
.rst(rst),
/* taxi_axis_baser_tx_64 #(
* Transmit interface (AXI stream) .DATA_W(DATA_W),
*/ .HDR_W(HDR_W),
.s_axis_tx(s_axis_tx), .GBX_IF_EN(GBX_IF_EN),
.m_axis_tx_cpl(m_axis_tx_cpl), .GBX_CNT(1),
.PADDING_EN(PADDING_EN),
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
)
axis_baser_tx_inst (
.clk(clk),
.rst(rst),
/* /*
* 10GBASE-R encoded interface * Transmit interface (AXI stream)
*/ */
.encoded_tx_data(encoded_tx_data), .s_axis_tx(s_axis_tx),
.encoded_tx_data_valid(encoded_tx_data_valid), .m_axis_tx_cpl(m_axis_tx_cpl),
.encoded_tx_hdr(encoded_tx_hdr),
.encoded_tx_hdr_valid(encoded_tx_hdr_valid),
.tx_gbx_req_sync(tx_gbx_req_sync),
.tx_gbx_req_stall(tx_gbx_req_stall),
.tx_gbx_sync(tx_gbx_sync),
/* /*
* PTP * 10GBASE-R encoded interface
*/ */
.ptp_ts(ptp_ts), .encoded_tx_data(encoded_tx_data),
.encoded_tx_data_valid(encoded_tx_data_valid),
.encoded_tx_hdr(encoded_tx_hdr),
.encoded_tx_hdr_valid(encoded_tx_hdr_valid),
.tx_gbx_req_sync(tx_gbx_req_sync),
.tx_gbx_req_stall(tx_gbx_req_stall),
.tx_gbx_sync(tx_gbx_sync),
/* /*
* Configuration * PTP
*/ */
.cfg_tx_max_pkt_len(cfg_tx_max_pkt_len), .ptp_ts(ptp_ts),
.cfg_tx_ifg(cfg_tx_ifg),
.cfg_tx_enable(cfg_tx_enable),
/* /*
* Status * Configuration
*/ */
.tx_start_packet(tx_start_packet), .cfg_tx_max_pkt_len(cfg_tx_max_pkt_len),
.stat_tx_byte(stat_tx_byte), .cfg_tx_ifg(cfg_tx_ifg),
.stat_tx_pkt_len(stat_tx_pkt_len), .cfg_tx_enable(cfg_tx_enable),
.stat_tx_pkt_ucast(stat_tx_pkt_ucast),
.stat_tx_pkt_mcast(stat_tx_pkt_mcast), /*
.stat_tx_pkt_bcast(stat_tx_pkt_bcast), * Status
.stat_tx_pkt_vlan(stat_tx_pkt_vlan), */
.stat_tx_pkt_good(stat_tx_pkt_good), .tx_start_packet(tx_start_packet),
.stat_tx_pkt_bad(stat_tx_pkt_bad), .stat_tx_byte(stat_tx_byte),
.stat_tx_err_oversize(stat_tx_err_oversize), .stat_tx_pkt_len(stat_tx_pkt_len),
.stat_tx_err_user(stat_tx_err_user), .stat_tx_pkt_ucast(stat_tx_pkt_ucast),
.stat_tx_err_underflow(stat_tx_err_underflow) .stat_tx_pkt_mcast(stat_tx_pkt_mcast),
); .stat_tx_pkt_bcast(stat_tx_pkt_bcast),
.stat_tx_pkt_vlan(stat_tx_pkt_vlan),
.stat_tx_pkt_good(stat_tx_pkt_good),
.stat_tx_pkt_bad(stat_tx_pkt_bad),
.stat_tx_err_oversize(stat_tx_err_oversize),
.stat_tx_err_user(stat_tx_err_user),
.stat_tx_err_underflow(stat_tx_err_underflow)
);
end else begin
taxi_axis_baser_tx_32 #(
.DATA_W(DATA_W),
.HDR_W(HDR_W),
.GBX_IF_EN(GBX_IF_EN),
.GBX_CNT(1),
.PADDING_EN(PADDING_EN),
.DIC_EN(DIC_EN),
.MIN_FRAME_LEN(MIN_FRAME_LEN),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_W(PTP_TS_W),
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
)
axis_baser_tx_inst (
.clk(clk),
.rst(rst),
/*
* Transmit interface (AXI stream)
*/
.s_axis_tx(s_axis_tx),
.m_axis_tx_cpl(m_axis_tx_cpl),
/*
* 10GBASE-R encoded interface
*/
.encoded_tx_data(encoded_tx_data),
.encoded_tx_data_valid(encoded_tx_data_valid),
.encoded_tx_hdr(encoded_tx_hdr),
.encoded_tx_hdr_valid(encoded_tx_hdr_valid),
.tx_gbx_req_sync(tx_gbx_req_sync),
.tx_gbx_req_stall(tx_gbx_req_stall),
.tx_gbx_sync(tx_gbx_sync),
/*
* PTP
*/
.ptp_ts(ptp_ts),
/*
* Configuration
*/
.cfg_tx_max_pkt_len(cfg_tx_max_pkt_len),
.cfg_tx_ifg(cfg_tx_ifg),
.cfg_tx_enable(cfg_tx_enable),
/*
* Status
*/
.tx_start_packet(tx_start_packet[0]),
.stat_tx_byte(stat_tx_byte[2:0]),
.stat_tx_pkt_len(stat_tx_pkt_len),
.stat_tx_pkt_ucast(stat_tx_pkt_ucast),
.stat_tx_pkt_mcast(stat_tx_pkt_mcast),
.stat_tx_pkt_bcast(stat_tx_pkt_bcast),
.stat_tx_pkt_vlan(stat_tx_pkt_vlan),
.stat_tx_pkt_good(stat_tx_pkt_good),
.stat_tx_pkt_bad(stat_tx_pkt_bad),
.stat_tx_err_oversize(stat_tx_err_oversize),
.stat_tx_err_user(stat_tx_err_user),
.stat_tx_err_underflow(stat_tx_err_underflow)
);
assign tx_start_packet[1] = 1'b0;
assign stat_tx_byte[3] = 1'b0;
end
taxi_eth_phy_10g_tx_if #( taxi_eth_phy_10g_tx_if #(
.DATA_W(DATA_W), .DATA_W(DATA_W),

View File

@@ -153,6 +153,11 @@ class TB:
async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12): async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
if len(dut.serdes_tx_data) == 64:
pipe_delay = 4
else:
pipe_delay = 6
tb = TB(dut, gbx_cfg) tb = TB(dut, gbx_cfg)
tb.serdes_source.ifg = ifg tb.serdes_source.ifg = ifg
@@ -190,17 +195,20 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
if tx_frame.start_lane == 4: if tx_frame.start_lane == 4:
# start in lane 4 reports 1 full cycle delay, so subtract half clock period # start in lane 4 reports 1 full cycle delay, so subtract half clock period
tx_frame_sfd_ns -= tb.clk_period/2 if len(dut.serdes_tx_data) == 64:
tx_frame_sfd_ns -= tb.clk_period/2
else:
tx_frame_sfd_ns -= tb.clk_period
tb.log.info("RX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("RX frame PTP TS: %f ns", ptp_ts_ns)
tb.log.info("TX frame SFD sim time: %f ns", tx_frame_sfd_ns) tb.log.info("TX frame SFD sim time: %f ns", tx_frame_sfd_ns)
tb.log.info("Difference: %f ns", abs(ptp_ts_ns - tx_frame_sfd_ns)) tb.log.info("Difference: %f ns", abs(ptp_ts_ns - tx_frame_sfd_ns))
tb.log.info("Error: %f ns", abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*4)) tb.log.info("Error: %f ns", abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay))
assert rx_frame.tdata == test_data assert rx_frame.tdata == test_data
assert frame_error == 0 assert frame_error == 0
if gbx_cfg is None: if gbx_cfg is None:
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*4) < 0.01 assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < 0.01
assert tb.axis_sink.empty() assert tb.axis_sink.empty()
@@ -210,6 +218,11 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12): async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
if len(dut.serdes_tx_data) == 64:
pipe_delay = 5
else:
pipe_delay = 5
tb = TB(dut, gbx_cfg) tb = TB(dut, gbx_cfg)
tb.serdes_source.ifg = ifg tb.serdes_source.ifg = ifg
@@ -222,6 +235,7 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
await RisingEdge(dut.tx_clk) await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1 tb.dut.cfg_tx_enable.value = 1
tb.serdes_sink.clear()
test_frames = [payload_data(x) for x in payload_lengths()] test_frames = [payload_data(x) for x in payload_lengths()]
@@ -238,18 +252,21 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
if rx_frame.start_lane == 4: if rx_frame.start_lane == 4:
# start in lane 4 reports 1 full cycle delay, so subtract half clock period # start in lane 4 reports 1 full cycle delay, so subtract half clock period
rx_frame_sfd_ns -= tb.clk_period/2 if len(dut.serdes_tx_data) == 64:
rx_frame_sfd_ns -= tb.clk_period/2
else:
rx_frame_sfd_ns -= tb.clk_period
tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns)
tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns) tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns)
tb.log.info("Difference: %f ns", abs(rx_frame_sfd_ns - ptp_ts_ns)) tb.log.info("Difference: %f ns", abs(rx_frame_sfd_ns - ptp_ts_ns))
tb.log.info("Error: %f ns", abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*5)) tb.log.info("Error: %f ns", abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay))
assert rx_frame.get_payload() == test_data assert rx_frame.get_payload() == test_data
assert rx_frame.check_fcs() assert rx_frame.check_fcs()
assert rx_frame.ctrl is None assert rx_frame.ctrl is None
if gbx_cfg is None: if gbx_cfg is None:
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*5) < 0.01 assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01
assert tb.serdes_sink.empty() assert tb.serdes_sink.empty()
@@ -259,6 +276,11 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12): async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
if len(dut.serdes_tx_data) == 64:
pipe_delay = 5
else:
pipe_delay = 5
dic_en = int(cocotb.top.DIC_EN.value) dic_en = int(cocotb.top.DIC_EN.value)
tb = TB(dut, gbx_cfg) tb = TB(dut, gbx_cfg)
@@ -275,6 +297,7 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
await RisingEdge(dut.tx_clk) await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1 tb.dut.cfg_tx_enable.value = 1
tb.serdes_sink.clear()
for length in range(60, 92): for length in range(60, 92):
@@ -297,7 +320,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
if rx_frame.start_lane == 4: if rx_frame.start_lane == 4:
# start in lane 4 reports 1 full cycle delay, so subtract half clock period # start in lane 4 reports 1 full cycle delay, so subtract half clock period
rx_frame_sfd_ns -= tb.clk_period/2 if len(dut.serdes_tx_data) == 64:
rx_frame_sfd_ns -= tb.clk_period/2
else:
rx_frame_sfd_ns -= tb.clk_period
tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns)
tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns) tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns)
@@ -307,7 +333,7 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
assert rx_frame.check_fcs() assert rx_frame.check_fcs()
assert rx_frame.ctrl is None assert rx_frame.ctrl is None
if gbx_cfg is None: if gbx_cfg is None:
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*5) < 0.01 assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < 0.01
start_lane.append(rx_frame.start_lane) start_lane.append(rx_frame.start_lane)
@@ -365,6 +391,7 @@ async def run_test_tx_underrun(dut, gbx_cfg=None, ifg=12):
await RisingEdge(dut.tx_clk) await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1 tb.dut.cfg_tx_enable.value = 1
tb.serdes_sink.clear()
test_data = bytes(x for x in range(60)) test_data = bytes(x for x in range(60))
@@ -413,6 +440,7 @@ async def run_test_tx_error(dut, gbx_cfg=None, ifg=12):
await RisingEdge(dut.tx_clk) await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1 tb.dut.cfg_tx_enable.value = 1
tb.serdes_sink.clear()
test_data = bytes(x for x in range(60)) test_data = bytes(x for x in range(60))
@@ -461,7 +489,7 @@ async def run_test_rx_frame_sync(dut, gbx_cfg=None):
assert not int(dut.rx_block_lock.value) assert not int(dut.rx_block_lock.value)
assert int(dut.rx_high_ber.value) assert int(dut.rx_high_ber.value)
for k in range(500): for k in range(800):
await RisingEdge(dut.rx_clk) await RisingEdge(dut.rx_clk)
tb.log.info("Check for block lock") tb.log.info("Check for block lock")
@@ -497,6 +525,7 @@ async def run_test_lfc(dut, gbx_cfg=None, ifg=12):
tb.dut.cfg_tx_enable.value = 1 tb.dut.cfg_tx_enable.value = 1
tb.dut.cfg_rx_enable.value = 1 tb.dut.cfg_rx_enable.value = 1
tb.serdes_sink.clear()
dut.tx_lfc_req.value = 0 dut.tx_lfc_req.value = 0
dut.tx_lfc_resend.value = 0 dut.tx_lfc_resend.value = 0
@@ -652,6 +681,7 @@ async def run_test_pfc(dut, gbx_cfg=None, ifg=12):
tb.dut.cfg_tx_enable.value = 1 tb.dut.cfg_tx_enable.value = 1
tb.dut.cfg_rx_enable.value = 1 tb.dut.cfg_rx_enable.value = 1
tb.serdes_sink.clear()
dut.tx_pfc_req.value = 0x00 dut.tx_pfc_req.value = 0x00
dut.tx_pfc_resend.value = 0 dut.tx_pfc_resend.value = 0
@@ -806,11 +836,12 @@ if cocotb.SIM_NAME:
factory.add_option("gbx_cfg", gbx_cfgs) factory.add_option("gbx_cfg", gbx_cfgs)
factory.generate_tests() factory.generate_tests()
factory = TestFactory(run_test_tx_alignment) if len(cocotb.top.serdes_tx_data) == 64:
factory.add_option("payload_data", [incrementing_payload]) factory = TestFactory(run_test_tx_alignment)
factory.add_option("ifg", [12]) factory.add_option("payload_data", [incrementing_payload])
factory.add_option("gbx_cfg", gbx_cfgs) factory.add_option("ifg", [12])
factory.generate_tests() factory.add_option("gbx_cfg", gbx_cfgs)
factory.generate_tests()
for test in [run_test_tx_underrun, run_test_tx_error]: for test in [run_test_tx_underrun, run_test_tx_error]:
@@ -820,6 +851,7 @@ if cocotb.SIM_NAME:
factory.generate_tests() factory.generate_tests()
factory = TestFactory(run_test_rx_frame_sync) factory = TestFactory(run_test_rx_frame_sync)
factory.add_option("gbx_cfg", gbx_cfgs)
factory.generate_tests() factory.generate_tests()
if cocotb.top.PFC_EN.value: if cocotb.top.PFC_EN.value:
@@ -853,7 +885,7 @@ def process_f_files(files):
@pytest.mark.parametrize(("dic_en", "pfc_en"), [(1, 1), (1, 0), (0, 0)]) @pytest.mark.parametrize(("dic_en", "pfc_en"), [(1, 1), (1, 0), (0, 0)])
@pytest.mark.parametrize("gbx_en", [1, 0]) @pytest.mark.parametrize("gbx_en", [1, 0])
@pytest.mark.parametrize("data_w", [64]) @pytest.mark.parametrize("data_w", [32, 64])
def test_taxi_eth_mac_phy_10g(request, data_w, gbx_en, dic_en, pfc_en): def test_taxi_eth_mac_phy_10g(request, data_w, gbx_en, dic_en, pfc_en):
dut = "taxi_eth_mac_phy_10g" dut = "taxi_eth_mac_phy_10g"
module = os.path.splitext(os.path.basename(__file__))[0] module = os.path.splitext(os.path.basename(__file__))[0]

View File

@@ -123,6 +123,11 @@ class TB:
async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12): async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
if len(dut.serdes_tx_data) == 64:
pipe_delay = 4
else:
pipe_delay = 6
tb = TB(dut, gbx_cfg) tb = TB(dut, gbx_cfg)
tb.serdes_source.ifg = ifg tb.serdes_source.ifg = ifg
@@ -164,7 +169,10 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
if tx_frame.start_lane == 4: if tx_frame.start_lane == 4:
# start in lane 4 reports 1 full cycle delay, so subtract half clock period # start in lane 4 reports 1 full cycle delay, so subtract half clock period
tx_frame_sfd_ns -= tb.clk_period/2 if len(dut.serdes_tx_data) == 64:
tx_frame_sfd_ns -= tb.clk_period/2
else:
tx_frame_sfd_ns -= tb.clk_period
tb.log.info("RX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("RX frame PTP TS: %f ns", ptp_ts_ns)
tb.log.info("TX frame SFD sim time: %f ns", tx_frame_sfd_ns) tb.log.info("TX frame SFD sim time: %f ns", tx_frame_sfd_ns)
@@ -173,7 +181,7 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
assert rx_frame.tdata == test_data assert rx_frame.tdata == test_data
assert frame_error == 0 assert frame_error == 0
if gbx_cfg is None: if gbx_cfg is None:
assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*4) < tb.clk_period*2 assert abs(ptp_ts_ns - tx_frame_sfd_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
assert tb.axis_sink.empty() assert tb.axis_sink.empty()
@@ -183,12 +191,16 @@ async def run_test_rx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12): async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
if len(dut.serdes_tx_data) == 64:
pipe_delay = 5
else:
pipe_delay = 5
tb = TB(dut, gbx_cfg) tb = TB(dut, gbx_cfg)
tb.serdes_source.ifg = ifg tb.serdes_source.ifg = ifg
tb.dut.cfg_tx_max_pkt_len.value = 9218 tb.dut.cfg_tx_max_pkt_len.value = 9218
tb.dut.cfg_tx_ifg.value = ifg tb.dut.cfg_tx_ifg.value = ifg
tb.dut.cfg_tx_enable.value = 1
await tb.reset() await tb.reset()
@@ -198,6 +210,9 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
for k in range(1000): for k in range(1000):
await RisingEdge(dut.tx_clk) await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1
tb.serdes_sink.clear()
test_frames = [payload_data(x) for x in payload_lengths()] test_frames = [payload_data(x) for x in payload_lengths()]
for test_data in test_frames: for test_data in test_frames:
@@ -213,7 +228,10 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
if rx_frame.start_lane == 4: if rx_frame.start_lane == 4:
# start in lane 4 reports 1 full cycle delay, so subtract half clock period # start in lane 4 reports 1 full cycle delay, so subtract half clock period
rx_frame_sfd_ns -= tb.clk_period/2 if len(dut.serdes_tx_data) == 64:
rx_frame_sfd_ns -= tb.clk_period/2
else:
rx_frame_sfd_ns -= tb.clk_period
tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns)
tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns) tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns)
@@ -223,7 +241,7 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
assert rx_frame.check_fcs() assert rx_frame.check_fcs()
assert rx_frame.ctrl is None assert rx_frame.ctrl is None
if gbx_cfg is None: if gbx_cfg is None:
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*5) < tb.clk_period*2 assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
assert tb.serdes_sink.empty() assert tb.serdes_sink.empty()
@@ -233,6 +251,11 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12): async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
if len(dut.serdes_tx_data) == 64:
pipe_delay = 5
else:
pipe_delay = 5
dic_en = int(cocotb.top.DIC_EN.value) dic_en = int(cocotb.top.DIC_EN.value)
tb = TB(dut, gbx_cfg) tb = TB(dut, gbx_cfg)
@@ -242,7 +265,6 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
tb.serdes_source.ifg = ifg tb.serdes_source.ifg = ifg
tb.dut.cfg_tx_max_pkt_len.value = 9218 tb.dut.cfg_tx_max_pkt_len.value = 9218
tb.dut.cfg_tx_ifg.value = ifg tb.dut.cfg_tx_ifg.value = ifg
tb.dut.cfg_tx_enable.value = 1
await tb.reset() await tb.reset()
@@ -252,6 +274,9 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
for k in range(1000): for k in range(1000):
await RisingEdge(dut.tx_clk) await RisingEdge(dut.tx_clk)
tb.dut.cfg_tx_enable.value = 1
tb.serdes_sink.clear()
for length in range(60, 92): for length in range(60, 92):
for k in range(10): for k in range(10):
@@ -273,7 +298,10 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
if rx_frame.start_lane == 4: if rx_frame.start_lane == 4:
# start in lane 4 reports 1 full cycle delay, so subtract half clock period # start in lane 4 reports 1 full cycle delay, so subtract half clock period
rx_frame_sfd_ns -= tb.clk_period/2 if len(dut.serdes_tx_data) == 64:
rx_frame_sfd_ns -= tb.clk_period/2
else:
rx_frame_sfd_ns -= tb.clk_period
tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns) tb.log.info("TX frame PTP TS: %f ns", ptp_ts_ns)
tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns) tb.log.info("RX frame SFD sim time: %f ns", rx_frame_sfd_ns)
@@ -283,7 +311,7 @@ async def run_test_tx_alignment(dut, gbx_cfg=None, payload_data=None, ifg=12):
assert rx_frame.check_fcs() assert rx_frame.check_fcs()
assert rx_frame.ctrl is None assert rx_frame.ctrl is None
if gbx_cfg is None: if gbx_cfg is None:
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*5) < tb.clk_period*2 assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*pipe_delay) < tb.clk_period*2
start_lane.append(rx_frame.start_lane) start_lane.append(rx_frame.start_lane)
@@ -349,7 +377,7 @@ async def run_test_rx_frame_sync(dut, gbx_cfg=None):
assert not dut.rx_block_lock.value.integer assert not dut.rx_block_lock.value.integer
assert dut.rx_high_ber.value.integer assert dut.rx_high_ber.value.integer
for k in range(500): for k in range(800):
await RisingEdge(dut.rx_clk) await RisingEdge(dut.rx_clk)
tb.log.info("Check for block lock") tb.log.info("Check for block lock")
@@ -394,11 +422,12 @@ if cocotb.SIM_NAME:
factory.add_option("gbx_cfg", gbx_cfgs) factory.add_option("gbx_cfg", gbx_cfgs)
factory.generate_tests() factory.generate_tests()
factory = TestFactory(run_test_tx_alignment) if len(cocotb.top.serdes_tx_data) == 64:
factory.add_option("payload_data", [incrementing_payload]) factory = TestFactory(run_test_tx_alignment)
factory.add_option("ifg", [12]) factory.add_option("payload_data", [incrementing_payload])
factory.add_option("gbx_cfg", gbx_cfgs) factory.add_option("ifg", [12])
factory.generate_tests() factory.add_option("gbx_cfg", gbx_cfgs)
factory.generate_tests()
factory = TestFactory(run_test_rx_frame_sync) factory = TestFactory(run_test_rx_frame_sync)
factory.add_option("gbx_cfg", gbx_cfgs) factory.add_option("gbx_cfg", gbx_cfgs)
@@ -428,7 +457,7 @@ def process_f_files(files):
@pytest.mark.parametrize("dic_en", [1, 0]) @pytest.mark.parametrize("dic_en", [1, 0])
@pytest.mark.parametrize("gbx_en", [1, 0]) @pytest.mark.parametrize("gbx_en", [1, 0])
@pytest.mark.parametrize("data_w", [64]) @pytest.mark.parametrize("data_w", [32, 64])
def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en): def test_taxi_eth_mac_phy_10g_fifo(request, data_w, gbx_en, dic_en):
dut = "taxi_eth_mac_phy_10g_fifo" dut = "taxi_eth_mac_phy_10g_fifo"
module = os.path.splitext(os.path.basename(__file__))[0] module = os.path.splitext(os.path.basename(__file__))[0]