mirror of
https://github.com/fpganinja/taxi.git
synced 2026-08-19 05:41:45 -07:00
eth: Add support for USXGMII symbol replication to 32-bit AXIS/BASE-R decode module
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -20,6 +20,7 @@ module taxi_axis_baser_rx_32 #
|
||||
parameter DATA_W = 32,
|
||||
parameter HDR_W = 2,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter logic USXGMII_EN = 1'b0,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter PTP_TS_W = 96
|
||||
)
|
||||
@@ -57,6 +58,9 @@ module taxi_axis_baser_rx_32 #
|
||||
*/
|
||||
input wire logic [15:0] cfg_rx_max_pkt_len = 16'd1518-1,
|
||||
input wire logic cfg_rx_enable,
|
||||
input wire logic cfg_rx_usxgmii_en = 1'b1,
|
||||
input wire logic cfg_rx_usxgmii_5g = 1'b0,
|
||||
input wire logic [2:0] cfg_rx_usxgmii_speed = 3'b011,
|
||||
|
||||
/*
|
||||
* Status
|
||||
@@ -155,6 +159,7 @@ state_t state_reg = STATE_IDLE, state_next;
|
||||
|
||||
// datapath control signals
|
||||
logic reset_crc;
|
||||
logic update_crc;
|
||||
|
||||
logic term_present_alt_reg = 1'b0;
|
||||
logic term_present_reg = 1'b0;
|
||||
@@ -165,6 +170,9 @@ logic [1:0] term_lane_reg = 0;
|
||||
logic [1:0] term_lane_d0_reg = 0;
|
||||
logic framing_error_reg = 1'b0;
|
||||
|
||||
logic [9:0] rep_cnt_reg = '0;
|
||||
logic rep_stall_reg = 1'b0;
|
||||
|
||||
logic [DATA_W-1:0] input_data_d0_reg = '0;
|
||||
logic [DATA_W-1:0] input_data_d1_reg = '0;
|
||||
logic [DATA_W-1:0] input_data_d2_reg = '0;
|
||||
@@ -292,6 +300,7 @@ always_comb begin
|
||||
state_next = STATE_IDLE;
|
||||
|
||||
reset_crc = 1'b0;
|
||||
update_crc = 1'b0;
|
||||
|
||||
frame_oversize_next = frame_oversize_reg;
|
||||
pre_ok_next = pre_ok_reg;
|
||||
@@ -332,6 +341,9 @@ always_comb begin
|
||||
if (GBX_IF_EN && !encoded_rx_data_valid) begin
|
||||
// data from gearbox not valid - hold state
|
||||
state_next = state_reg;
|
||||
end else if (USXGMII_EN && rep_stall_reg) begin
|
||||
// USXGMII stall - hold state
|
||||
state_next = state_reg;
|
||||
end else begin
|
||||
// counter to measure frame length
|
||||
if (&frame_len_reg[15:2] == 0) begin
|
||||
@@ -382,6 +394,7 @@ always_comb begin
|
||||
STATE_IDLE: begin
|
||||
// idle state - wait for packet
|
||||
reset_crc = 1'b1;
|
||||
update_crc = 1'b1;
|
||||
|
||||
frame_oversize_next = 1'b0;
|
||||
frame_len_next = 16'(KEEP_W);
|
||||
@@ -412,6 +425,7 @@ always_comb begin
|
||||
end
|
||||
STATE_PREAMBLE: begin
|
||||
// drop preamble
|
||||
update_crc = 1'b1;
|
||||
|
||||
hdr_ptr_next = 0;
|
||||
|
||||
@@ -429,6 +443,8 @@ always_comb begin
|
||||
end
|
||||
STATE_PAYLOAD: begin
|
||||
// read payload
|
||||
update_crc = 1'b1;
|
||||
|
||||
m_axis_rx_tdata_next = input_data_d2_reg;
|
||||
m_axis_rx_tkeep_next = {KEEP_W{1'b1}};
|
||||
m_axis_rx_tvalid_next = 1'b1;
|
||||
@@ -611,16 +627,20 @@ always_ff @(posedge clk) begin
|
||||
term_first_cycle_reg <= term_first_cycle_alt_reg;
|
||||
term_lane_alt_reg <= 0;
|
||||
term_lane_reg <= term_lane_alt_reg;
|
||||
term_lane_d0_reg <= term_lane_reg;
|
||||
|
||||
input_data_d0_reg <= encoded_rx_data_reg;
|
||||
input_data_d1_reg <= input_data_d0_reg;
|
||||
input_data_d2_reg <= input_data_d1_reg;
|
||||
|
||||
input_start_alt_reg <= 1'b0;
|
||||
input_start_d0_reg <= input_start_alt_reg;
|
||||
input_start_d1_reg <= input_start_d0_reg;
|
||||
input_start_d2_reg <= input_start_d1_reg;
|
||||
|
||||
if (!USXGMII_EN || !rep_stall_reg) begin
|
||||
term_lane_d0_reg <= term_lane_reg;
|
||||
|
||||
input_data_d0_reg <= encoded_rx_data_reg;
|
||||
input_data_d1_reg <= input_data_d0_reg;
|
||||
input_data_d2_reg <= input_data_d1_reg;
|
||||
|
||||
input_start_d0_reg <= input_start_alt_reg;
|
||||
input_start_d1_reg <= input_start_d0_reg;
|
||||
input_start_d2_reg <= input_start_d1_reg;
|
||||
end
|
||||
|
||||
if (encoded_rx_hdr_valid_reg) begin
|
||||
// portion with header
|
||||
@@ -801,16 +821,54 @@ always_ff @(posedge clk) begin
|
||||
|
||||
if (reset_crc) begin
|
||||
crc_state_reg <= '1;
|
||||
end else begin
|
||||
end else if (update_crc) begin
|
||||
crc_state_reg <= crc_state;
|
||||
end
|
||||
|
||||
crc_valid_reg <= crc_valid;
|
||||
if (update_crc) begin
|
||||
crc_valid_reg <= crc_valid;
|
||||
end
|
||||
|
||||
if (USXGMII_EN && cfg_rx_usxgmii_en) begin
|
||||
if (rep_cnt_reg == 0 || (encoded_rx_hdr_valid_reg && encoded_rx_hdr_reg[0]) || input_start_alt_reg) begin
|
||||
if (cfg_rx_usxgmii_5g) begin
|
||||
case (cfg_rx_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_rx_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
|
||||
|
||||
if (rst) begin
|
||||
state_reg <= STATE_IDLE;
|
||||
|
||||
rep_cnt_reg <= '0;
|
||||
rep_stall_reg <= 1'b0;
|
||||
|
||||
m_axis_rx_tvalid_reg <= 1'b0;
|
||||
|
||||
rx_os_0_reg <= 1'b0;
|
||||
|
||||
@@ -37,6 +37,7 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
||||
export PARAM_DATA_W := 32
|
||||
export PARAM_HDR_W := 2
|
||||
export PARAM_GBX_IF_EN := 1
|
||||
export PARAM_USXGMII_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")
|
||||
@@ -66,6 +66,29 @@ class TB:
|
||||
|
||||
dut.cfg_rx_max_pkt_len.setimmediatevalue(0)
|
||||
dut.cfg_rx_enable.setimmediatevalue(0)
|
||||
if usxgmii_speed is not None:
|
||||
dut.cfg_rx_usxgmii_en.setimmediatevalue(1)
|
||||
dut.cfg_rx_usxgmii_5g.setimmediatevalue(0)
|
||||
dut.cfg_rx_usxgmii_speed.setimmediatevalue(usxgmii_speed)
|
||||
if usxgmii_speed == 0:
|
||||
self.source.set_xgmii_rep_count(999) # 10 Mbps
|
||||
elif usxgmii_speed == 1:
|
||||
self.source.set_xgmii_rep_count(99) # 100 Mbps
|
||||
elif usxgmii_speed == 2:
|
||||
self.source.set_xgmii_rep_count(9) # 1 Gbps
|
||||
elif usxgmii_speed == 3:
|
||||
self.source.set_xgmii_rep_count(0) # 10 Gbps
|
||||
elif usxgmii_speed == 4:
|
||||
self.source.set_xgmii_rep_count(3) # 2.5 Gbps
|
||||
elif usxgmii_speed == 5:
|
||||
self.source.set_xgmii_rep_count(1) # 5 Gbps
|
||||
else:
|
||||
self.source.set_xgmii_rep_count(0)
|
||||
else:
|
||||
dut.cfg_rx_usxgmii_en.setimmediatevalue(0)
|
||||
dut.cfg_rx_usxgmii_5g.setimmediatevalue(0)
|
||||
dut.cfg_rx_usxgmii_speed.setimmediatevalue(0b011)
|
||||
self.source.set_xgmii_rep_count(0)
|
||||
|
||||
self.stats = {}
|
||||
self.stats["stat_rx_byte"] = 0
|
||||
@@ -110,9 +133,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.source.ifg = ifg
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 9218-1
|
||||
@@ -176,9 +199,9 @@ async def run_test(dut, gbx_cfg=None, payload_lengths=None, payload_data=None, i
|
||||
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.source.ifg = ifg
|
||||
tb.dut.cfg_rx_max_pkt_len.value = 1518-1
|
||||
@@ -265,9 +288,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()
|
||||
|
||||
@@ -315,16 +338,19 @@ if getattr(cocotb, 'top', None) is not None:
|
||||
factory = TestFactory(run_test)
|
||||
factory.add_option("payload_lengths", [size_list])
|
||||
factory.add_option("payload_data", [incrementing_payload])
|
||||
factory.add_option("ifg", list(range(0, 13)))
|
||||
factory.add_option("ifg", [0, 1, 11, 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_oversize)
|
||||
factory.add_option("ifg", list(range(0, 13)))
|
||||
factory.add_option("ifg", [0, 1, 11, 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()
|
||||
|
||||
@@ -370,6 +396,7 @@ def test_taxi_axis_baser_rx_32(request, gbx_en):
|
||||
parameters['DATA_W'] = 32
|
||||
parameters['HDR_W'] = 2
|
||||
parameters['GBX_IF_EN'] = gbx_en
|
||||
parameters['USXGMII_EN'] = 1
|
||||
parameters['PTP_TS_EN'] = 1
|
||||
parameters['PTP_TS_FMT_TOD'] = 1
|
||||
parameters['PTP_TS_W'] = 96 if parameters['PTP_TS_FMT_TOD'] else 64
|
||||
|
||||
@@ -21,6 +21,7 @@ module test_taxi_axis_baser_rx_32 #
|
||||
parameter DATA_W = 32,
|
||||
parameter HDR_W = 2,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter logic USXGMII_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||
parameter PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 64
|
||||
@@ -48,6 +49,9 @@ logic [PTP_TS_W-1:0] ptp_ts;
|
||||
|
||||
logic [15:0] cfg_rx_max_pkt_len;
|
||||
logic cfg_rx_enable;
|
||||
logic cfg_rx_usxgmii_en;
|
||||
logic cfg_rx_usxgmii_5g;
|
||||
logic [2:0] cfg_rx_usxgmii_speed;
|
||||
|
||||
logic rx_start_packet;
|
||||
logic [2:0] stat_rx_byte;
|
||||
@@ -70,6 +74,7 @@ taxi_axis_baser_rx_32 #(
|
||||
.DATA_W(DATA_W),
|
||||
.HDR_W(HDR_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.USXGMII_EN(USXGMII_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W)
|
||||
)
|
||||
@@ -107,6 +112,9 @@ uut (
|
||||
*/
|
||||
.cfg_rx_max_pkt_len(cfg_rx_max_pkt_len),
|
||||
.cfg_rx_enable(cfg_rx_enable),
|
||||
.cfg_rx_usxgmii_en(cfg_rx_usxgmii_en),
|
||||
.cfg_rx_usxgmii_5g(cfg_rx_usxgmii_5g),
|
||||
.cfg_rx_usxgmii_speed(cfg_rx_usxgmii_speed),
|
||||
|
||||
/*
|
||||
* Status
|
||||
|
||||
Reference in New Issue
Block a user