mirror of
https://github.com/fpganinja/taxi.git
synced 2026-07-19 06:31:16 -07:00
eth: Add support for USXGMII symbol replication to 32-bit AXIS/BASE-R encode module
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -21,6 +21,7 @@ module taxi_axis_baser_tx_32 #
|
||||
parameter HDR_W = 2,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter GBX_CNT = 1,
|
||||
parameter logic USXGMII_EN = 1'b0,
|
||||
parameter logic DIC_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter PTP_TS_W = 96,
|
||||
@@ -66,6 +67,9 @@ module taxi_axis_baser_tx_32 #
|
||||
input wire logic [15:0] cfg_tx_max_pkt_len = 16'd1518-1,
|
||||
input wire logic [7:0] cfg_tx_ifg = 8'd12,
|
||||
input wire logic cfg_tx_enable,
|
||||
input wire logic cfg_tx_usxgmii_en = 1'b1,
|
||||
input wire logic cfg_tx_usxgmii_5g = 1'b0,
|
||||
input wire logic [2:0] cfg_tx_usxgmii_speed = 3'b011,
|
||||
|
||||
/*
|
||||
* Status
|
||||
@@ -201,6 +205,9 @@ logic frame_len_lim_check_reg = '0, frame_len_lim_check_next;
|
||||
logic [7:0] ifg_cnt_reg = '0, ifg_cnt_next;
|
||||
logic [1:0] deficit_idle_cnt_reg = 2'd0, deficit_idle_cnt_next;
|
||||
|
||||
logic [9:0] rep_cnt_reg = '0;
|
||||
logic rep_stall_reg = 1'b0;
|
||||
|
||||
logic s_axis_tx_tready_reg = 1'b0, s_axis_tx_tready_next;
|
||||
|
||||
logic [PTP_TS_W-1:0] m_axis_tx_cpl_ts_reg = '0, m_axis_tx_cpl_ts_next;
|
||||
@@ -220,6 +227,7 @@ logic [DATA_W-1:0] output_data_reg = '0, output_data_next;
|
||||
logic [DATA_W-1:0] output_data_d1_reg = '0;
|
||||
out_type_t output_type_reg = OUTPUT_TYPE_IDLE, output_type_next;
|
||||
|
||||
logic start_packet_int_reg = 1'b0, start_packet_int_next;
|
||||
logic start_packet_reg = 1'b0, start_packet_next;
|
||||
|
||||
logic [2:0] stat_tx_byte_reg = '0, stat_tx_byte_next;
|
||||
@@ -234,7 +242,7 @@ logic stat_tx_err_oversize_reg = 1'b0, stat_tx_err_oversize_next;
|
||||
logic stat_tx_err_user_reg = 1'b0, stat_tx_err_user_next;
|
||||
logic stat_tx_err_underflow_reg = 1'b0, stat_tx_err_underflow_next;
|
||||
|
||||
assign s_axis_tx.tready = s_axis_tx_tready_reg && (!GBX_IF_EN || !tx_gbx_req_stall);
|
||||
assign s_axis_tx.tready = s_axis_tx_tready_reg && (!GBX_IF_EN || !tx_gbx_req_stall) && (!USXGMII_EN || !rep_stall_reg);
|
||||
|
||||
assign encoded_tx_data = encoded_tx_data_reg;
|
||||
assign encoded_tx_data_valid = GBX_IF_EN ? encoded_tx_data_valid_reg : 1'b1;
|
||||
@@ -375,9 +383,10 @@ always_comb begin
|
||||
end
|
||||
end
|
||||
|
||||
output_data_next = s_tdata_reg;
|
||||
output_type_next = OUTPUT_TYPE_IDLE;
|
||||
output_data_next = output_data_reg;
|
||||
output_type_next = output_type_reg;
|
||||
|
||||
start_packet_int_next = start_packet_int_reg;
|
||||
start_packet_next = 1'b0;
|
||||
|
||||
stat_tx_byte_next = '0;
|
||||
@@ -400,6 +409,32 @@ always_comb begin
|
||||
// gearbox stall - hold state
|
||||
state_next = state_reg;
|
||||
s_axis_tx_tready_next = s_axis_tx_tready_reg;
|
||||
|
||||
output_data_next = output_data_reg;
|
||||
output_type_next = output_type_reg;
|
||||
end else if (USXGMII_EN && rep_stall_reg) begin
|
||||
// USXGMII stall - replicate XGMII symbol
|
||||
state_next = state_reg;
|
||||
s_axis_tx_tready_next = s_axis_tx_tready_reg;
|
||||
|
||||
output_data_next = output_data_reg;
|
||||
output_type_next = output_type_reg;
|
||||
|
||||
// SOP/EOP are not replicated
|
||||
case (output_type_reg)
|
||||
OUTPUT_TYPE_START: begin
|
||||
// replace start character with 0xAA in replications
|
||||
output_data_next[7:0] = 8'hAA;
|
||||
output_type_next = OUTPUT_TYPE_DATA;
|
||||
end
|
||||
OUTPUT_TYPE_TERM_0, OUTPUT_TYPE_TERM_1, OUTPUT_TYPE_TERM_2, OUTPUT_TYPE_TERM_3: begin
|
||||
// EOP is sent once followed by idles
|
||||
output_type_next = OUTPUT_TYPE_IDLE;
|
||||
end
|
||||
default: begin
|
||||
output_type_next = output_type_reg;
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
// counter to measure frame length
|
||||
if (&frame_len_reg[15:2] == 0) begin
|
||||
@@ -495,7 +530,7 @@ always_comb begin
|
||||
output_type_next = OUTPUT_TYPE_DATA;
|
||||
|
||||
s_axis_tx_tready_next = 1'b1;
|
||||
start_packet_next = 1'b1;
|
||||
start_packet_int_next = 1'b1;
|
||||
state_next = STATE_PAYLOAD;
|
||||
end
|
||||
STATE_PAYLOAD: begin
|
||||
@@ -509,6 +544,8 @@ always_comb begin
|
||||
s_empty_next = keep2empty(s_axis_tx.tkeep);
|
||||
|
||||
stat_tx_byte_next = 3'(KEEP_W);
|
||||
start_packet_next = start_packet_int_reg;
|
||||
start_packet_int_next = 1'b0;
|
||||
|
||||
if (s_axis_tx.tvalid && s_axis_tx.tlast) begin
|
||||
if (frame_len_lim_check_reg) begin
|
||||
@@ -691,6 +728,7 @@ always_ff @(posedge clk) begin
|
||||
|
||||
tx_os_ready_reg <= 1'b0;
|
||||
|
||||
start_packet_int_reg <= start_packet_int_next;
|
||||
start_packet_reg <= start_packet_next;
|
||||
|
||||
stat_tx_byte_reg <= stat_tx_byte_next;
|
||||
@@ -829,7 +867,42 @@ always_ff @(posedge clk) begin
|
||||
phase_reg <= 1'b1;
|
||||
end
|
||||
|
||||
crc_state_reg <= crc_state;
|
||||
if (!USXGMII_EN || !rep_stall_reg) begin
|
||||
crc_state_reg <= crc_state;
|
||||
end
|
||||
|
||||
if (USXGMII_EN && cfg_tx_usxgmii_en) begin
|
||||
if (rep_cnt_reg == 0) begin
|
||||
if (cfg_tx_usxgmii_5g) begin
|
||||
case (cfg_tx_usxgmii_speed)
|
||||
3'b000: rep_cnt_reg <= 499; // 10 Mbps
|
||||
3'b001: rep_cnt_reg <= 49; // 100 Mbps
|
||||
3'b010: rep_cnt_reg <= 4; // 1 Gbps
|
||||
3'b100: rep_cnt_reg <= 1; // 2.5 Gbps
|
||||
3'b101: rep_cnt_reg <= 0; // 5 Gbps
|
||||
default: rep_cnt_reg <= 0;
|
||||
endcase
|
||||
end else begin
|
||||
case (cfg_tx_usxgmii_speed)
|
||||
3'b000: rep_cnt_reg <= 999; // 10 Mbps
|
||||
3'b001: rep_cnt_reg <= 99; // 100 Mbps
|
||||
3'b010: rep_cnt_reg <= 9; // 1 Gbps
|
||||
3'b011: rep_cnt_reg <= 0; // 10 Gbps
|
||||
3'b100: rep_cnt_reg <= 3; // 2.5 Gbps
|
||||
3'b101: rep_cnt_reg <= 1; // 5 Gbps
|
||||
default: rep_cnt_reg <= 0;
|
||||
endcase
|
||||
end
|
||||
|
||||
rep_stall_reg <= 1'b0;
|
||||
end else begin
|
||||
rep_cnt_reg <= rep_cnt_reg-1;
|
||||
rep_stall_reg <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
rep_cnt_reg <= '0;
|
||||
rep_stall_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
tx_gbx_sync_reg <= tx_gbx_req_sync;
|
||||
@@ -840,6 +913,9 @@ always_ff @(posedge clk) begin
|
||||
frame_reg <= 1'b0;
|
||||
deficit_idle_cnt_reg <= 2'd0;
|
||||
|
||||
rep_cnt_reg <= '0;
|
||||
rep_stall_reg <= 1'b0;
|
||||
|
||||
s_axis_tx_tready_reg <= 1'b0;
|
||||
|
||||
m_axis_tx_cpl_valid_reg <= 1'b0;
|
||||
|
||||
@@ -38,6 +38,7 @@ export PARAM_DATA_W := 32
|
||||
export PARAM_HDR_W := 2
|
||||
export PARAM_GBX_IF_EN := 1
|
||||
export PARAM_GBX_CNT := 1
|
||||
export PARAM_USXGMII_EN := 1
|
||||
export PARAM_DIC_EN := 1
|
||||
export PARAM_PTP_TS_EN := 1
|
||||
export PARAM_PTP_TS_FMT_TOD := 1
|
||||
|
||||
@@ -38,7 +38,7 @@ except ImportError:
|
||||
|
||||
|
||||
class TB:
|
||||
def __init__(self, dut, gbx_cfg=None):
|
||||
def __init__(self, dut, gbx_cfg=None, usxgmii_speed=None):
|
||||
self.dut = dut
|
||||
|
||||
self.log = logging.getLogger("cocotb.tb")
|
||||
@@ -75,6 +75,29 @@ class TB:
|
||||
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
||||
dut.cfg_tx_ifg.setimmediatevalue(0)
|
||||
dut.cfg_tx_enable.setimmediatevalue(0)
|
||||
if usxgmii_speed is not None:
|
||||
dut.cfg_tx_usxgmii_en.setimmediatevalue(1)
|
||||
dut.cfg_tx_usxgmii_5g.setimmediatevalue(0)
|
||||
dut.cfg_tx_usxgmii_speed.setimmediatevalue(usxgmii_speed)
|
||||
if usxgmii_speed == 0:
|
||||
self.sink.set_xgmii_rep_count(999) # 10 Mbps
|
||||
elif usxgmii_speed == 1:
|
||||
self.sink.set_xgmii_rep_count(99) # 100 Mbps
|
||||
elif usxgmii_speed == 2:
|
||||
self.sink.set_xgmii_rep_count(9) # 1 Gbps
|
||||
elif usxgmii_speed == 3:
|
||||
self.sink.set_xgmii_rep_count(0) # 10 Gbps
|
||||
elif usxgmii_speed == 4:
|
||||
self.sink.set_xgmii_rep_count(3) # 2.5 Gbps
|
||||
elif usxgmii_speed == 5:
|
||||
self.sink.set_xgmii_rep_count(1) # 5 Gbps
|
||||
else:
|
||||
self.sink.set_xgmii_rep_count(0)
|
||||
else:
|
||||
dut.cfg_tx_usxgmii_en.setimmediatevalue(0)
|
||||
dut.cfg_tx_usxgmii_5g.setimmediatevalue(0)
|
||||
dut.cfg_tx_usxgmii_speed.setimmediatevalue(0b011)
|
||||
self.sink.set_xgmii_rep_count(0)
|
||||
|
||||
self.stats = {}
|
||||
self.stats["stat_tx_byte"] = 0
|
||||
@@ -115,9 +138,9 @@ class TB:
|
||||
self.stats[stat] += int(getattr(self.dut, stat).value)
|
||||
|
||||
|
||||
async def run_test(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, ifg=12):
|
||||
async def run_test(dut, gbx_cfg=None, usxgmii_speed=None, payload_lengths=None, payload_data=None, ifg=12):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
tb = TB(dut, gbx_cfg, usxgmii_speed)
|
||||
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218-1
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
@@ -155,7 +178,7 @@ async def run_test(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, i
|
||||
assert rx_frame.check_fcs()
|
||||
assert rx_frame.ctrl is None
|
||||
if gbx_cfg is None:
|
||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*3) < 0.01
|
||||
assert abs(rx_frame_sfd_ns - ptp_ts_ns - tb.clk_period*2) < 0.01
|
||||
|
||||
assert tb.sink.empty()
|
||||
|
||||
@@ -178,9 +201,9 @@ async def run_test(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, i
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_underrun(dut, gbx_cfg=None, ifg=12):
|
||||
async def run_test_underrun(dut, gbx_cfg=None, usxgmii_speed=None, ifg=12):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
tb = TB(dut, gbx_cfg, usxgmii_speed)
|
||||
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218-1
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
@@ -198,12 +221,12 @@ async def run_test_underrun(dut, gbx_cfg=None, ifg=12):
|
||||
test_frame = AxiStreamFrame(test_data)
|
||||
await tb.source.send(test_frame)
|
||||
|
||||
for k in range(32):
|
||||
for k in range(32*(tb.sink.get_xgmii_rep_count()+1)):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
tb.source.pause = True
|
||||
|
||||
for k in range(4):
|
||||
for k in range(4*(tb.sink.get_xgmii_rep_count()+1)):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
tb.source.pause = False
|
||||
@@ -240,9 +263,9 @@ async def run_test_underrun(dut, gbx_cfg=None, ifg=12):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_error(dut, gbx_cfg=None, ifg=12):
|
||||
async def run_test_error(dut, gbx_cfg=None, usxgmii_speed=None, ifg=12):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
tb = TB(dut, gbx_cfg, usxgmii_speed)
|
||||
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 9218-1
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
@@ -294,9 +317,9 @@ async def run_test_error(dut, gbx_cfg=None, ifg=12):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_oversize(dut, gbx_cfg=None, ifg=12):
|
||||
async def run_test_oversize(dut, gbx_cfg=None, usxgmii_speed=None, ifg=12):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
tb = TB(dut, gbx_cfg, usxgmii_speed)
|
||||
|
||||
tb.dut.cfg_tx_max_pkt_len.value = 1518-1
|
||||
tb.dut.cfg_tx_ifg.value = ifg
|
||||
@@ -383,9 +406,9 @@ async def run_test_oversize(dut, gbx_cfg=None, ifg=12):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_os(dut, gbx_cfg=None):
|
||||
async def run_test_os(dut, gbx_cfg=None, usxgmii_speed=None):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
tb = TB(dut, gbx_cfg, usxgmii_speed)
|
||||
|
||||
await tb.reset()
|
||||
|
||||
@@ -435,6 +458,7 @@ if getattr(cocotb, 'top', None) is not None:
|
||||
factory.add_option("payload_lengths", [size_list])
|
||||
factory.add_option("payload_data", [incrementing_payload])
|
||||
factory.add_option("ifg", [12])
|
||||
factory.add_option("usxgmii_speed", [None, 2, 4, 5, 3])
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
@@ -446,10 +470,12 @@ if getattr(cocotb, 'top', None) is not None:
|
||||
|
||||
factory = TestFactory(test)
|
||||
factory.add_option("ifg", [12])
|
||||
factory.add_option("usxgmii_speed", [None, 2, 4, 5, 3])
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
factory = TestFactory(run_test_os)
|
||||
factory.add_option("usxgmii_speed", [None, 2, 4, 5, 3])
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
@@ -497,6 +523,7 @@ def test_taxi_axis_baser_tx_32(request, gbx_en, dic_en):
|
||||
parameters['HDR_W'] = 2
|
||||
parameters['GBX_IF_EN'] = gbx_en
|
||||
parameters['GBX_CNT'] = 1
|
||||
parameters['USXGMII_EN'] = 1
|
||||
parameters['DIC_EN'] = dic_en
|
||||
parameters['PTP_TS_EN'] = 1
|
||||
parameters['PTP_TS_FMT_TOD'] = 1
|
||||
|
||||
@@ -22,6 +22,7 @@ module test_taxi_axis_baser_tx_32 #
|
||||
parameter HDR_W = 2,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter GBX_CNT = 1,
|
||||
parameter logic USXGMII_EN = 1'b1,
|
||||
parameter logic DIC_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||
@@ -58,6 +59,9 @@ logic [PTP_TS_W-1:0] ptp_ts;
|
||||
logic [15:0] cfg_tx_max_pkt_len;
|
||||
logic [7:0] cfg_tx_ifg;
|
||||
logic cfg_tx_enable;
|
||||
logic cfg_tx_usxgmii_en;
|
||||
logic cfg_tx_usxgmii_5g;
|
||||
logic [2:0] cfg_tx_usxgmii_speed;
|
||||
|
||||
logic tx_start_packet;
|
||||
logic [2:0] stat_tx_byte;
|
||||
@@ -77,6 +81,7 @@ taxi_axis_baser_tx_32 #(
|
||||
.HDR_W(HDR_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.GBX_CNT(GBX_CNT),
|
||||
.USXGMII_EN(USXGMII_EN),
|
||||
.DIC_EN(DIC_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W),
|
||||
@@ -122,6 +127,9 @@ uut (
|
||||
.cfg_tx_max_pkt_len(cfg_tx_max_pkt_len),
|
||||
.cfg_tx_ifg(cfg_tx_ifg),
|
||||
.cfg_tx_enable(cfg_tx_enable),
|
||||
.cfg_tx_usxgmii_en(cfg_tx_usxgmii_en),
|
||||
.cfg_tx_usxgmii_5g(cfg_tx_usxgmii_5g),
|
||||
.cfg_tx_usxgmii_speed(cfg_tx_usxgmii_speed),
|
||||
|
||||
/*
|
||||
* Status
|
||||
|
||||
@@ -308,7 +308,7 @@ async def run_test_tx(dut, port=0, payload_lengths=None, payload_data=None, ifg=
|
||||
pipe_delay = 6
|
||||
else:
|
||||
if dut.COMBINED_MAC_PCS.value:
|
||||
pipe_delay = 7
|
||||
pipe_delay = 6
|
||||
else:
|
||||
pipe_delay = 8
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
||||
if len(dut.serdes_tx_data) == 64:
|
||||
pipe_delay = 5
|
||||
else:
|
||||
pipe_delay = 6
|
||||
pipe_delay = 5
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ async def run_test_tx(dut, gbx_cfg=None, payload_lengths=None, payload_data=None
|
||||
if len(dut.serdes_tx_data) == 64:
|
||||
pipe_delay = 5
|
||||
else:
|
||||
pipe_delay = 6
|
||||
pipe_delay = 5
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user