mirror of
https://github.com/fpganinja/taxi.git
synced 2025-12-09 17:08:38 -08:00
eth: Add MAC statistics module to 1G MACs
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -36,6 +36,11 @@ export PARAM_PTP_TS_W := 96
|
||||
export PARAM_TX_TAG_W := 16
|
||||
export PARAM_PFC_EN := 1
|
||||
export PARAM_PAUSE_EN := $(PARAM_PFC_EN)
|
||||
export PARAM_STAT_EN := 1
|
||||
export PARAM_STAT_TX_LEVEL := 2
|
||||
export PARAM_STAT_RX_LEVEL := $(PARAM_STAT_TX_LEVEL)
|
||||
export PARAM_STAT_ID_BASE := 0
|
||||
export PARAM_STAT_UPDATE_PERIOD := 1024
|
||||
|
||||
ifeq ($(SIM), icarus)
|
||||
PLUSARGS += -fst
|
||||
|
||||
@@ -43,6 +43,7 @@ class TB:
|
||||
|
||||
cocotb.start_soon(Clock(dut.rx_clk, 8, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.tx_clk, 8, units="ns").start())
|
||||
cocotb.start_soon(Clock(dut.stat_clk, 8, units="ns").start())
|
||||
|
||||
self.gmii_source = GmiiSource(dut.gmii_rxd, dut.gmii_rx_er, dut.gmii_rx_dv,
|
||||
dut.rx_clk, dut.rx_rst, dut.rx_clk_enable, dut.rx_mii_select)
|
||||
@@ -53,6 +54,8 @@ class TB:
|
||||
self.tx_cpl_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_tx_cpl), dut.tx_clk, dut.tx_rst)
|
||||
self.axis_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_rx), dut.rx_clk, dut.rx_rst)
|
||||
|
||||
self.stat_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_stat), dut.stat_clk, dut.stat_rst)
|
||||
|
||||
self.rx_ptp_clock = PtpClockSimTime(ts_tod=dut.rx_ptp_ts, clock=dut.rx_clk)
|
||||
self.tx_ptp_clock = PtpClockSimTime(ts_tod=dut.tx_ptp_ts, clock=dut.tx_clk)
|
||||
|
||||
@@ -74,8 +77,12 @@ class TB:
|
||||
dut.rx_mii_select.setimmediatevalue(0)
|
||||
dut.tx_mii_select.setimmediatevalue(0)
|
||||
|
||||
dut.cfg_ifg.setimmediatevalue(0)
|
||||
dut.stat_rx_fifo_drop.setimmediatevalue(0)
|
||||
|
||||
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
||||
dut.cfg_tx_ifg.setimmediatevalue(0)
|
||||
dut.cfg_tx_enable.setimmediatevalue(0)
|
||||
dut.cfg_rx_max_pkt_len.setimmediatevalue(0)
|
||||
dut.cfg_rx_enable.setimmediatevalue(0)
|
||||
dut.cfg_mcf_rx_eth_dst_mcast.setimmediatevalue(0)
|
||||
dut.cfg_mcf_rx_check_eth_dst_mcast.setimmediatevalue(0)
|
||||
@@ -112,14 +119,17 @@ class TB:
|
||||
async def reset(self):
|
||||
self.dut.rx_rst.setimmediatevalue(0)
|
||||
self.dut.tx_rst.setimmediatevalue(0)
|
||||
self.dut.stat_rst.setimmediatevalue(0)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
self.dut.rx_rst.value = 1
|
||||
self.dut.tx_rst.value = 1
|
||||
self.dut.stat_rst.value = 1
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
self.dut.rx_rst.value = 0
|
||||
self.dut.tx_rst.value = 0
|
||||
self.dut.stat_rst.value = 0
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
await RisingEdge(self.dut.tx_clk)
|
||||
|
||||
@@ -165,7 +175,9 @@ async def run_test_rx(dut, payload_lengths=None, payload_data=None, ifg=12, enab
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_ifg.value = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_rx_enable.value = 1
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
@@ -212,8 +224,10 @@ async def run_test_tx(dut, payload_lengths=None, payload_data=None, ifg=12, enab
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_ifg.value = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_tx_enable.value = 1
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 9218
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
|
||||
@@ -256,8 +270,10 @@ async def run_test_tx_underrun(dut, ifg=12, enable_gen=None, mii_sel=False):
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_ifg.value = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_tx_enable.value = 1
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 9218
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
|
||||
@@ -310,8 +326,10 @@ async def run_test_tx_error(dut, ifg=12, enable_gen=None, mii_sel=False):
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_ifg.value = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_tx_enable.value = 1
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 9218
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
|
||||
@@ -345,13 +363,100 @@ async def run_test_tx_error(dut, ifg=12, enable_gen=None, mii_sel=False):
|
||||
await RisingEdge(dut.tx_clk)
|
||||
|
||||
|
||||
async def run_test_rx_oversize(dut, ifg=12, enable_gen=None, mii_sel=False):
|
||||
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 1518
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 1518
|
||||
tb.dut.cfg_rx_enable.value = 1
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
|
||||
if enable_gen is not None:
|
||||
tb.set_enable_generator_rx(enable_gen())
|
||||
tb.set_enable_generator_tx(enable_gen())
|
||||
|
||||
await tb.reset()
|
||||
|
||||
test_data = bytes(x for x in range(60))
|
||||
|
||||
for k in range(3):
|
||||
test_frame = GmiiFrame.from_payload(test_data)
|
||||
if k == 1:
|
||||
test_frame = GmiiFrame.from_payload(bytes(x % 256 for x in range(1515)))
|
||||
await tb.gmii_source.send(test_frame)
|
||||
|
||||
for k in range(3):
|
||||
rx_frame = await tb.axis_sink.recv()
|
||||
|
||||
if k == 1:
|
||||
frame_error = rx_frame.tuser[-1] & 1
|
||||
assert frame_error
|
||||
else:
|
||||
frame_error = rx_frame.tuser & 1
|
||||
assert rx_frame.tdata == test_data
|
||||
assert frame_error == 0
|
||||
|
||||
assert tb.axis_sink.empty()
|
||||
|
||||
await RisingEdge(dut.rx_clk)
|
||||
await RisingEdge(dut.rx_clk)
|
||||
|
||||
|
||||
async def run_test_tx_oversize(dut, ifg=12, enable_gen=None, mii_sel=False):
|
||||
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 1518
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_tx_enable.value = 1
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 1518
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
|
||||
if enable_gen is not None:
|
||||
tb.set_enable_generator_rx(enable_gen())
|
||||
tb.set_enable_generator_tx(enable_gen())
|
||||
|
||||
await tb.reset()
|
||||
|
||||
test_data = bytes(x for x in range(60))
|
||||
|
||||
for k in range(3):
|
||||
test_frame = AxiStreamFrame(test_data)
|
||||
if k == 1:
|
||||
test_frame = AxiStreamFrame(bytes(x % 256 for x in range(1515)))
|
||||
await tb.axis_source.send(test_frame)
|
||||
|
||||
for k in range(3):
|
||||
rx_frame = await tb.gmii_sink.recv()
|
||||
|
||||
if k == 1:
|
||||
assert rx_frame.error[-1] == 1
|
||||
else:
|
||||
assert rx_frame.get_payload() == test_data
|
||||
assert rx_frame.check_fcs()
|
||||
assert rx_frame.error is None
|
||||
|
||||
assert tb.gmii_sink.empty()
|
||||
|
||||
await RisingEdge(dut.tx_clk)
|
||||
await RisingEdge(dut.tx_clk)
|
||||
|
||||
|
||||
async def run_test_lfc(dut, ifg=12, enable_gen=None, mii_sel=True):
|
||||
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_ifg.value = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_tx_enable.value = 1
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_rx_enable.value = 1
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
@@ -501,8 +606,10 @@ async def run_test_pfc(dut, ifg=12, enable_gen=None, mii_sel=True):
|
||||
tb = TB(dut)
|
||||
|
||||
tb.gmii_source.ifg = ifg
|
||||
tb.dut.cfg_ifg.value = ifg
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
tb.dut.cfg_tx_enable.value = 1
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 9218
|
||||
tb.dut.cfg_rx_enable.value = 1
|
||||
tb.dut.rx_mii_select.value = mii_sel
|
||||
tb.dut.tx_mii_select.value = mii_sel
|
||||
@@ -649,7 +756,10 @@ def cycle_en():
|
||||
|
||||
if cocotb.SIM_NAME:
|
||||
|
||||
for test in [run_test_rx, run_test_tx]:
|
||||
for test in [
|
||||
run_test_rx,
|
||||
run_test_tx,
|
||||
]:
|
||||
|
||||
factory = TestFactory(test)
|
||||
factory.add_option("payload_lengths", [size_list])
|
||||
@@ -659,7 +769,12 @@ if cocotb.SIM_NAME:
|
||||
factory.add_option("mii_sel", [False, True])
|
||||
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,
|
||||
run_test_rx_oversize,
|
||||
run_test_tx_oversize,
|
||||
]:
|
||||
|
||||
factory = TestFactory(test)
|
||||
factory.add_option("ifg", [12])
|
||||
@@ -668,7 +783,11 @@ if cocotb.SIM_NAME:
|
||||
factory.generate_tests()
|
||||
|
||||
if cocotb.top.PFC_EN.value:
|
||||
for test in [run_test_lfc, run_test_pfc]:
|
||||
for test in [
|
||||
run_test_lfc,
|
||||
run_test_pfc,
|
||||
]:
|
||||
|
||||
factory = TestFactory(test)
|
||||
factory.add_option("ifg", [12])
|
||||
factory.add_option("enable_gen", [None, cycle_en])
|
||||
@@ -718,6 +837,11 @@ def test_taxi_eth_mac_1g(request, pfc_en):
|
||||
parameters['TX_TAG_W'] = 16
|
||||
parameters['PFC_EN'] = pfc_en
|
||||
parameters['PAUSE_EN'] = parameters['PFC_EN']
|
||||
parameters['STAT_EN'] = 1
|
||||
parameters['STAT_TX_LEVEL'] = 2
|
||||
parameters['STAT_RX_LEVEL'] = parameters['STAT_TX_LEVEL']
|
||||
parameters['STAT_ID_BASE'] = 0
|
||||
parameters['STAT_UPDATE_PERIOD'] = 1024
|
||||
|
||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||
|
||||
|
||||
@@ -25,7 +25,12 @@ module test_taxi_eth_mac_1g #
|
||||
parameter PTP_TS_W = 96,
|
||||
parameter TX_TAG_W = 16,
|
||||
parameter logic PFC_EN = 1'b0,
|
||||
parameter logic PAUSE_EN = PFC_EN
|
||||
parameter logic PAUSE_EN = PFC_EN,
|
||||
parameter logic STAT_EN = 1'b0,
|
||||
parameter STAT_TX_LEVEL = 1,
|
||||
parameter STAT_RX_LEVEL = STAT_TX_LEVEL,
|
||||
parameter STAT_ID_BASE = 0,
|
||||
parameter STAT_UPDATE_PERIOD = 1024
|
||||
/* verilator lint_on WIDTHTRUNC */
|
||||
)
|
||||
();
|
||||
@@ -73,11 +78,39 @@ logic tx_clk_enable;
|
||||
logic rx_mii_select;
|
||||
logic tx_mii_select;
|
||||
|
||||
logic stat_clk;
|
||||
logic stat_rst;
|
||||
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(8)) m_axis_stat();
|
||||
|
||||
logic tx_start_packet;
|
||||
logic tx_error_underflow;
|
||||
logic stat_tx_byte;
|
||||
logic [15:0] stat_tx_pkt_len;
|
||||
logic stat_tx_pkt_ucast;
|
||||
logic stat_tx_pkt_mcast;
|
||||
logic stat_tx_pkt_bcast;
|
||||
logic stat_tx_pkt_vlan;
|
||||
logic stat_tx_pkt_good;
|
||||
logic stat_tx_pkt_bad;
|
||||
logic stat_tx_err_oversize;
|
||||
logic stat_tx_err_user;
|
||||
logic stat_tx_err_underflow;
|
||||
logic rx_start_packet;
|
||||
logic rx_error_bad_frame;
|
||||
logic rx_error_bad_fcs;
|
||||
logic stat_rx_byte;
|
||||
logic [15:0] stat_rx_pkt_len;
|
||||
logic stat_rx_pkt_fragment;
|
||||
logic stat_rx_pkt_jabber;
|
||||
logic stat_rx_pkt_ucast;
|
||||
logic stat_rx_pkt_mcast;
|
||||
logic stat_rx_pkt_bcast;
|
||||
logic stat_rx_pkt_vlan;
|
||||
logic stat_rx_pkt_good;
|
||||
logic stat_rx_pkt_bad;
|
||||
logic stat_rx_err_oversize;
|
||||
logic stat_rx_err_bad_fcs;
|
||||
logic stat_rx_err_bad_block;
|
||||
logic stat_rx_err_framing;
|
||||
logic stat_rx_err_preamble;
|
||||
logic stat_rx_fifo_drop;
|
||||
logic stat_tx_mcf;
|
||||
logic stat_rx_mcf;
|
||||
logic stat_tx_lfc_pkt;
|
||||
@@ -97,8 +130,10 @@ logic [7:0] stat_rx_pfc_xon;
|
||||
logic [7:0] stat_rx_pfc_xoff;
|
||||
logic [7:0] stat_rx_pfc_paused;
|
||||
|
||||
logic [7:0] cfg_ifg;
|
||||
logic [15:0] cfg_tx_max_pkt_len;
|
||||
logic [7:0] cfg_tx_ifg;
|
||||
logic cfg_tx_enable;
|
||||
logic [15:0] cfg_rx_max_pkt_len;
|
||||
logic cfg_rx_enable;
|
||||
logic [47:0] cfg_mcf_rx_eth_dst_mcast;
|
||||
logic cfg_mcf_rx_check_eth_dst_mcast;
|
||||
@@ -139,7 +174,12 @@ taxi_eth_mac_1g #(
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W),
|
||||
.PFC_EN(PFC_EN),
|
||||
.PAUSE_EN(PAUSE_EN)
|
||||
.PAUSE_EN(PAUSE_EN),
|
||||
.STAT_EN(STAT_EN),
|
||||
.STAT_TX_LEVEL(STAT_TX_LEVEL),
|
||||
.STAT_RX_LEVEL(STAT_RX_LEVEL),
|
||||
.STAT_ID_BASE(STAT_ID_BASE),
|
||||
.STAT_UPDATE_PERIOD(STAT_UPDATE_PERIOD)
|
||||
)
|
||||
uut (
|
||||
.rx_clk(rx_clk),
|
||||
@@ -207,14 +247,45 @@ uut (
|
||||
.rx_mii_select(rx_mii_select),
|
||||
.tx_mii_select(tx_mii_select),
|
||||
|
||||
/*
|
||||
* Statistics
|
||||
*/
|
||||
.stat_clk(stat_clk),
|
||||
.stat_rst(stat_rst),
|
||||
.m_axis_stat(m_axis_stat),
|
||||
|
||||
/*
|
||||
* Status
|
||||
*/
|
||||
.tx_start_packet(tx_start_packet),
|
||||
.tx_error_underflow(tx_error_underflow),
|
||||
.stat_tx_byte(stat_tx_byte),
|
||||
.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),
|
||||
.rx_start_packet(rx_start_packet),
|
||||
.rx_error_bad_frame(rx_error_bad_frame),
|
||||
.rx_error_bad_fcs(rx_error_bad_fcs),
|
||||
.stat_rx_byte(stat_rx_byte),
|
||||
.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),
|
||||
.stat_rx_fifo_drop(stat_rx_fifo_drop),
|
||||
.stat_tx_mcf(stat_tx_mcf),
|
||||
.stat_rx_mcf(stat_rx_mcf),
|
||||
.stat_tx_lfc_pkt(stat_tx_lfc_pkt),
|
||||
@@ -237,8 +308,10 @@ uut (
|
||||
/*
|
||||
* Configuration
|
||||
*/
|
||||
.cfg_ifg(cfg_ifg),
|
||||
.cfg_tx_max_pkt_len(cfg_tx_max_pkt_len),
|
||||
.cfg_tx_ifg(cfg_tx_ifg),
|
||||
.cfg_tx_enable(cfg_tx_enable),
|
||||
.cfg_rx_max_pkt_len(cfg_rx_max_pkt_len),
|
||||
.cfg_rx_enable(cfg_rx_enable),
|
||||
.cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast),
|
||||
.cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast),
|
||||
|
||||
Reference in New Issue
Block a user