mirror of
https://github.com/fpganinja/taxi.git
synced 2026-07-18 22:21:22 -07:00
eth: Suport AN config reg exchange in AXI stream-BASE-X encode/decode logic
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -20,6 +20,7 @@ module taxi_axis_basex_rx_16 #
|
||||
parameter DATA_W = 16,
|
||||
parameter CTRL_W = (DATA_W/8),
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter logic AN_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||
parameter PTP_TS_W = 96
|
||||
@@ -40,6 +41,15 @@ module taxi_axis_basex_rx_16 #
|
||||
*/
|
||||
taxi_axis_if.src m_axis_rx,
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
output wire logic [15:0] rx_an_cfg,
|
||||
output wire logic rx_an_cfg_valid,
|
||||
output wire logic rx_an_ability_match,
|
||||
output wire logic rx_an_ack_match,
|
||||
output wire logic rx_an_idle_match,
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
@@ -133,6 +143,9 @@ 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;
|
||||
|
||||
logic input_k28p5_d0_reg = 1'b0;
|
||||
logic input_i_d0_reg = 1'b0;
|
||||
logic input_c_d0_reg = 1'b0;
|
||||
logic input_start_d0_reg = 1'b0;
|
||||
|
||||
logic frame_oversize_reg = 1'b0, frame_oversize_next;
|
||||
@@ -152,6 +165,12 @@ logic m_axis_rx_tvalid_reg = 1'b0, m_axis_rx_tvalid_next;
|
||||
logic m_axis_rx_tlast_reg = 1'b0, m_axis_rx_tlast_next;
|
||||
logic m_axis_rx_tuser_reg = 1'b0, m_axis_rx_tuser_next;
|
||||
|
||||
logic [15:0] rx_an_cfg_reg = '0;
|
||||
logic rx_an_cfg_valid_reg = 1'b0;
|
||||
logic [1:0] an_ability_match_cnt_reg = '0;
|
||||
logic [1:0] an_ack_match_cnt_reg = '0;
|
||||
logic [1:0] an_idle_match_cnt_reg = '0;
|
||||
|
||||
logic start_packet_int_reg = 1'b0;
|
||||
logic [1:0] start_packet_reg = '0;
|
||||
logic frame_reg = 1'b0;
|
||||
@@ -202,6 +221,12 @@ if (PTP_TS_EN) begin
|
||||
assign m_axis_rx.tuser[1 +: PTP_TS_W] = ptp_ts_out_reg;
|
||||
end
|
||||
|
||||
assign rx_an_cfg = AN_EN ? rx_an_cfg_reg : '0;
|
||||
assign rx_an_cfg_valid = AN_EN ? rx_an_cfg_valid_reg : 1'b0;
|
||||
assign rx_an_ability_match = AN_EN ? &an_ability_match_cnt_reg : 1'b0;
|
||||
assign rx_an_ack_match = AN_EN ? &an_ack_match_cnt_reg : 1'b0;
|
||||
assign rx_an_idle_match = AN_EN ? &an_idle_match_cnt_reg : 1'b0;
|
||||
|
||||
assign rx_start_packet = start_packet_reg;
|
||||
|
||||
assign stat_rx_byte = stat_rx_byte_reg;
|
||||
@@ -589,6 +614,8 @@ always_ff @(posedge clk) begin
|
||||
m_axis_rx_tlast_reg <= m_axis_rx_tlast_next;
|
||||
m_axis_rx_tuser_reg <= m_axis_rx_tuser_next;
|
||||
|
||||
rx_an_cfg_valid_reg <= 1'b0;
|
||||
|
||||
ptp_ts_out_reg <= ptp_ts_out_next;
|
||||
|
||||
stat_rx_byte_reg <= stat_rx_byte_next;
|
||||
@@ -616,6 +643,9 @@ always_ff @(posedge clk) begin
|
||||
input_data_d1_reg <= input_data_d0_reg;
|
||||
input_data_d2_reg <= input_data_d1_reg;
|
||||
|
||||
input_k28p5_d0_reg <= 1'b0;
|
||||
input_i_d0_reg <= 1'b0;
|
||||
input_c_d0_reg <= 1'b0;
|
||||
input_start_d0_reg <= 1'b0;
|
||||
|
||||
if (PTP_TS_EN && PTP_TS_FMT_TOD) begin
|
||||
@@ -629,6 +659,49 @@ always_ff @(posedge clk) begin
|
||||
/* verilator lint_on SELRANGE */
|
||||
end
|
||||
|
||||
// /K28.5/ control character detection
|
||||
if (encoded_rx_data_k[0] && encoded_rx_data[7:0] == K(28, 5)) begin
|
||||
input_k28p5_d0_reg <= 1'b1;
|
||||
end
|
||||
|
||||
// idle symbol detection
|
||||
if (encoded_rx_data_k == 2'b01 && (encoded_rx_data == CTRL_I1 || encoded_rx_data == CTRL_I2)) begin
|
||||
input_i_d0_reg <= 1'b1;
|
||||
end
|
||||
|
||||
if (AN_EN && input_i_d0_reg) begin
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
if (!(&an_idle_match_cnt_reg)) begin
|
||||
an_idle_match_cnt_reg <= an_idle_match_cnt_reg + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// config symbol detection
|
||||
if (encoded_rx_data_k == 2'b01 && (encoded_rx_data == CTRL_C1 || encoded_rx_data == CTRL_C2)) begin
|
||||
input_c_d0_reg <= 1'b1;
|
||||
end
|
||||
|
||||
if (AN_EN && input_c_d0_reg) begin
|
||||
rx_an_cfg_reg <= encoded_rx_data;
|
||||
rx_an_cfg_valid_reg <= encoded_rx_data_k == 2'b00;
|
||||
if (((rx_an_cfg_reg ^ encoded_rx_data) & 16'h4000) == 0) begin
|
||||
if (!(&an_ability_match_cnt_reg)) begin
|
||||
an_ability_match_cnt_reg <= an_ability_match_cnt_reg + 1;
|
||||
end
|
||||
end else begin
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
end
|
||||
if (rx_an_cfg_reg[14] && rx_an_cfg_reg == encoded_rx_data) begin
|
||||
if (!(&an_ack_match_cnt_reg)) begin
|
||||
an_ack_match_cnt_reg <= an_ack_match_cnt_reg + 1;
|
||||
end
|
||||
end else begin
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
end
|
||||
an_idle_match_cnt_reg <= '0;
|
||||
end
|
||||
|
||||
// start control character detection
|
||||
if (encoded_rx_data_k[0] && encoded_rx_data[7:0] == CTRL_S) begin
|
||||
input_start_d0_reg <= 1'b1;
|
||||
@@ -636,6 +709,12 @@ always_ff @(posedge clk) begin
|
||||
lanes_swapped_reg <= 1'b0;
|
||||
end
|
||||
|
||||
if (AN_EN && input_start_d0_reg) begin
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
an_idle_match_cnt_reg <= '0;
|
||||
end
|
||||
|
||||
// SFD detection
|
||||
start_packet_int_reg <= 1'b0;
|
||||
if (in_pre_reg) begin
|
||||
@@ -684,6 +763,11 @@ always_ff @(posedge clk) begin
|
||||
|
||||
m_axis_rx_tvalid_reg <= 1'b0;
|
||||
|
||||
rx_an_cfg_valid_reg <= 1'b0;
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
an_idle_match_cnt_reg <= '0;
|
||||
|
||||
start_packet_int_reg <= 1'b0;
|
||||
start_packet_reg <= '0;
|
||||
frame_reg <= 1'b0;
|
||||
@@ -704,6 +788,9 @@ always_ff @(posedge clk) begin
|
||||
stat_rx_err_framing_reg <= 1'b0;
|
||||
stat_rx_err_preamble_reg <= 1'b0;
|
||||
|
||||
input_k28p5_d0_reg <= 1'b0;
|
||||
input_i_d0_reg <= 1'b0;
|
||||
input_c_d0_reg <= 1'b0;
|
||||
input_start_d0_reg <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,6 +20,7 @@ module taxi_axis_basex_rx_8 #
|
||||
parameter DATA_W = 8,
|
||||
parameter CTRL_W = (DATA_W/8),
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter logic AN_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter PTP_TS_W = 96
|
||||
)
|
||||
@@ -39,6 +40,15 @@ module taxi_axis_basex_rx_8 #
|
||||
*/
|
||||
taxi_axis_if.src m_axis_rx,
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
output wire logic [15:0] rx_an_cfg,
|
||||
output wire logic rx_an_cfg_valid,
|
||||
output wire logic rx_an_ability_match,
|
||||
output wire logic rx_an_ack_match,
|
||||
output wire logic rx_an_idle_match,
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
@@ -130,6 +140,12 @@ logic [DATA_W-1:0] encoded_rx_data_d4_reg = '0;
|
||||
|
||||
logic encoded_rx_data_k_d0_reg = 1'b0;
|
||||
|
||||
logic input_k28p5_d0_reg = 1'b0;
|
||||
logic input_i_d0_reg = 1'b0;
|
||||
logic input_c_d0_reg = 1'b0;
|
||||
logic input_c_d1_reg = 1'b0;
|
||||
logic input_start_d0_reg = 1'b0;
|
||||
|
||||
logic frame_error_reg = 1'b0, frame_error_next;
|
||||
logic pre_ok_reg = 1'b0, pre_ok_next;
|
||||
logic [3:0] hdr_ptr_reg = '0, hdr_ptr_next;
|
||||
@@ -146,6 +162,13 @@ logic m_axis_rx_tvalid_reg = 1'b0, m_axis_rx_tvalid_next;
|
||||
logic m_axis_rx_tlast_reg = 1'b0, m_axis_rx_tlast_next;
|
||||
logic m_axis_rx_tuser_reg = 1'b0, m_axis_rx_tuser_next;
|
||||
|
||||
logic [15:0] rx_an_cfg_reg = '0;
|
||||
logic rx_an_cfg_valid_reg = 1'b0;
|
||||
logic an_cfg_match_reg = 1'b0;
|
||||
logic [1:0] an_ability_match_cnt_reg = '0;
|
||||
logic [1:0] an_ack_match_cnt_reg = '0;
|
||||
logic [1:0] an_idle_match_cnt_reg = '0;
|
||||
|
||||
logic start_packet_int_reg = 1'b0;
|
||||
logic start_packet_reg = 1'b0;
|
||||
|
||||
@@ -182,6 +205,12 @@ if (PTP_TS_EN) begin
|
||||
assign m_axis_rx.tuser[1 +: PTP_TS_W] = ptp_ts_out_reg;
|
||||
end
|
||||
|
||||
assign rx_an_cfg = AN_EN ? rx_an_cfg_reg : '0;
|
||||
assign rx_an_cfg_valid = AN_EN ? rx_an_cfg_valid_reg : 1'b0;
|
||||
assign rx_an_ability_match = AN_EN ? &an_ability_match_cnt_reg : 1'b0;
|
||||
assign rx_an_ack_match = AN_EN ? &an_ack_match_cnt_reg : 1'b0;
|
||||
assign rx_an_idle_match = AN_EN ? &an_idle_match_cnt_reg : 1'b0;
|
||||
|
||||
assign rx_start_packet = start_packet_reg;
|
||||
|
||||
assign stat_rx_byte = stat_rx_byte_reg;
|
||||
@@ -458,6 +487,8 @@ always_ff @(posedge clk) begin
|
||||
m_axis_rx_tlast_reg <= m_axis_rx_tlast_next;
|
||||
m_axis_rx_tuser_reg <= m_axis_rx_tuser_next;
|
||||
|
||||
rx_an_cfg_valid_reg <= 1'b0;
|
||||
|
||||
start_packet_int_reg <= 1'b0;
|
||||
start_packet_reg <= 1'b0;
|
||||
|
||||
@@ -482,6 +513,73 @@ always_ff @(posedge clk) begin
|
||||
|
||||
encoded_rx_data_k_d0_reg <= encoded_rx_data_k;
|
||||
|
||||
input_k28p5_d0_reg <= 1'b0;
|
||||
input_i_d0_reg <= 1'b0;
|
||||
input_c_d0_reg <= 1'b0;
|
||||
input_c_d1_reg <= input_c_d0_reg;
|
||||
input_start_d0_reg <= 1'b0;
|
||||
|
||||
// /K28.5/ control character detection
|
||||
if (encoded_rx_data_k && encoded_rx_data == K(28, 5)) begin
|
||||
input_k28p5_d0_reg <= 1'b1;
|
||||
end
|
||||
|
||||
// idle symbol detection
|
||||
if (input_k28p5_d0_reg && (encoded_rx_data == D(5,6) || encoded_rx_data == D(16,2))) begin
|
||||
input_i_d0_reg <= 1'b1;
|
||||
end
|
||||
|
||||
if (AN_EN && input_i_d0_reg) begin
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
if (!(&an_idle_match_cnt_reg)) begin
|
||||
an_idle_match_cnt_reg <= an_idle_match_cnt_reg + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// config symbol detection
|
||||
if (input_k28p5_d0_reg && (encoded_rx_data == D(21,5) || encoded_rx_data == D(2,2))) begin
|
||||
input_c_d0_reg <= 1'b1;
|
||||
end
|
||||
|
||||
if (AN_EN && input_c_d0_reg) begin
|
||||
rx_an_cfg_reg[7:0] <= encoded_rx_data;
|
||||
an_cfg_match_reg <= rx_an_cfg_reg[7:0] == encoded_rx_data;
|
||||
input_c_d1_reg <= encoded_rx_data_k == 1'b0;
|
||||
an_idle_match_cnt_reg <= '0;
|
||||
end
|
||||
|
||||
if (AN_EN && input_c_d1_reg) begin
|
||||
rx_an_cfg_reg[15:8] <= encoded_rx_data;
|
||||
rx_an_cfg_valid_reg <= encoded_rx_data_k == 1'b0;
|
||||
if (an_cfg_match_reg && ((rx_an_cfg_reg[15:8] ^ encoded_rx_data) & 8'h40) == 0) begin
|
||||
if (!(&an_ability_match_cnt_reg)) begin
|
||||
an_ability_match_cnt_reg <= an_ability_match_cnt_reg + 1;
|
||||
end
|
||||
end else begin
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
end
|
||||
if (an_cfg_match_reg && rx_an_cfg_reg[14] && rx_an_cfg_reg[15:8] == encoded_rx_data) begin
|
||||
if (!(&an_ack_match_cnt_reg)) begin
|
||||
an_ack_match_cnt_reg <= an_ack_match_cnt_reg + 1;
|
||||
end
|
||||
end else begin
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
end
|
||||
an_idle_match_cnt_reg <= '0;
|
||||
end
|
||||
|
||||
// start control character detection
|
||||
if (encoded_rx_data_k && encoded_rx_data == CTRL_S) begin
|
||||
input_start_d0_reg <= 1'b1;
|
||||
end
|
||||
|
||||
if (AN_EN && input_start_d0_reg) begin
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
an_idle_match_cnt_reg <= '0;
|
||||
end
|
||||
|
||||
if (reset_crc) begin
|
||||
crc_state_reg <= '1;
|
||||
end else if (update_crc) begin
|
||||
@@ -508,8 +606,19 @@ always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
state_reg <= STATE_IDLE;
|
||||
|
||||
input_k28p5_d0_reg <= 1'b0;
|
||||
input_i_d0_reg <= 1'b0;
|
||||
input_c_d0_reg <= 1'b0;
|
||||
input_c_d1_reg <= 1'b0;
|
||||
input_start_d0_reg <= 1'b0;
|
||||
|
||||
m_axis_rx_tvalid_reg <= 1'b0;
|
||||
|
||||
rx_an_cfg_valid_reg <= 1'b0;
|
||||
an_ability_match_cnt_reg <= '0;
|
||||
an_ack_match_cnt_reg <= '0;
|
||||
an_idle_match_cnt_reg <= '0;
|
||||
|
||||
start_packet_int_reg <= 1'b0;
|
||||
start_packet_reg <= 1'b0;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ module taxi_axis_basex_tx_16 #
|
||||
parameter CTRL_W = (DATA_W/8),
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter GBX_CNT = 1,
|
||||
parameter logic AN_EN = 1'b1,
|
||||
parameter logic DIC_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter PTP_TS_W = 96,
|
||||
@@ -48,6 +49,13 @@ module taxi_axis_basex_tx_16 #
|
||||
input wire logic tx_gbx_req_stall = '0,
|
||||
output wire logic [GBX_CNT-1:0] tx_gbx_sync,
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
input wire logic [15:0] tx_an_cfg = '0,
|
||||
input wire logic tx_an_cfg_valid = 1'b0,
|
||||
output wire logic tx_an_cfg_ready,
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
@@ -188,7 +196,8 @@ typedef enum logic [3:0] {
|
||||
STATE_TR,
|
||||
STATE_RR,
|
||||
STATE_ERR,
|
||||
STATE_IFG
|
||||
STATE_IFG,
|
||||
STATE_AN
|
||||
} state_t;
|
||||
|
||||
state_t state_reg = STATE_IDLE, state_next;
|
||||
@@ -214,10 +223,13 @@ logic frame_len_lim_check_reg = '0, frame_len_lim_check_next;
|
||||
logic [1:0] pre_cnt_reg = '0, pre_cnt_next;
|
||||
logic [7:0] ifg_cnt_reg = '0, ifg_cnt_next;
|
||||
logic deficit_idle_cnt_reg = 1'd0, deficit_idle_cnt_next;
|
||||
logic an_phase_reg = 1'b0, an_phase_next;
|
||||
logic rd_reg = 1'b0, rd_next;
|
||||
|
||||
logic s_axis_tx_tready_reg = 1'b0, s_axis_tx_tready_next;
|
||||
|
||||
logic tx_an_cfg_ready_reg = 1'b0, tx_an_cfg_ready_next;
|
||||
|
||||
logic [PTP_TS_W-1:0] m_axis_tx_cpl_ts_reg = '0, m_axis_tx_cpl_ts_next;
|
||||
logic [TX_TAG_W-1:0] m_axis_tx_cpl_tag_reg = '0, m_axis_tx_cpl_tag_next;
|
||||
logic m_axis_tx_cpl_valid_reg = 1'b0, m_axis_tx_cpl_valid_next;
|
||||
@@ -262,6 +274,8 @@ assign m_axis_tx_cpl.tid = m_axis_tx_cpl_tag_reg;
|
||||
assign m_axis_tx_cpl.tdest = '0;
|
||||
assign m_axis_tx_cpl.tuser = '0;
|
||||
|
||||
assign tx_an_cfg_ready = AN_EN ? tx_an_cfg_ready_reg : 1'b0;
|
||||
|
||||
assign tx_start_packet = {1'b0, start_packet_reg};
|
||||
|
||||
assign stat_tx_byte = stat_tx_byte_reg;
|
||||
@@ -362,19 +376,22 @@ always_comb begin
|
||||
pre_cnt_next = pre_cnt_reg;
|
||||
ifg_cnt_next = ifg_cnt_reg;
|
||||
deficit_idle_cnt_next = deficit_idle_cnt_reg;
|
||||
an_phase_next = an_phase_reg;
|
||||
rd_next = rd_reg;
|
||||
|
||||
s_axis_tx_tready_next = 1'b0;
|
||||
|
||||
m_axis_tx_cpl_ts_next = m_axis_tx_cpl_ts_reg;
|
||||
m_axis_tx_cpl_tag_next = m_axis_tx_cpl_tag_reg;
|
||||
m_axis_tx_cpl_valid_next = 1'b0;
|
||||
|
||||
tx_an_cfg_ready_next = 1'b0;
|
||||
|
||||
s_tdata_next = s_tdata_reg;
|
||||
s_empty_next = s_empty_reg;
|
||||
|
||||
crc_data_next = crc_data_reg;
|
||||
|
||||
m_axis_tx_cpl_ts_next = m_axis_tx_cpl_ts_reg;
|
||||
m_axis_tx_cpl_tag_next = m_axis_tx_cpl_tag_reg;
|
||||
m_axis_tx_cpl_valid_next = 1'b0;
|
||||
|
||||
if (start_packet_reg) begin
|
||||
if (PTP_TS_EN) begin
|
||||
m_axis_tx_cpl_ts_next = ptp_ts;
|
||||
@@ -495,6 +512,11 @@ always_comb begin
|
||||
encoded_tx_data_next = {{1{ETH_PRE}}, CTRL_S};
|
||||
encoded_tx_data_k_next = 2'b01;
|
||||
state_next = STATE_PREAMBLE;
|
||||
end else if (AN_EN && tx_an_cfg_valid) begin
|
||||
// Config register
|
||||
encoded_tx_data_next = an_phase_reg ? CTRL_C2 : CTRL_C1;
|
||||
encoded_tx_data_k_next = 2'b01;
|
||||
state_next = STATE_AN;
|
||||
end else begin
|
||||
ifg_cnt_next = 8'd0;
|
||||
deficit_idle_cnt_next = 1'd0;
|
||||
@@ -737,6 +759,19 @@ always_comb begin
|
||||
end
|
||||
end
|
||||
end
|
||||
STATE_AN: begin
|
||||
if (AN_EN) begin
|
||||
// send config register
|
||||
encoded_tx_data_next = tx_an_cfg;
|
||||
encoded_tx_data_k_next = 2'b00;
|
||||
|
||||
tx_an_cfg_ready_next = 1'b1;
|
||||
|
||||
an_phase_next = !an_phase_reg;
|
||||
|
||||
state_next = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
// invalid state, return to idle
|
||||
state_next = STATE_IDLE;
|
||||
@@ -768,6 +803,7 @@ always_ff @(posedge clk) begin
|
||||
pre_cnt_reg <= pre_cnt_next;
|
||||
ifg_cnt_reg <= ifg_cnt_next;
|
||||
deficit_idle_cnt_reg <= deficit_idle_cnt_next;
|
||||
an_phase_reg <= an_phase_next;
|
||||
rd_reg <= rd_next;
|
||||
|
||||
s_tdata_reg <= s_tdata_next;
|
||||
@@ -781,6 +817,8 @@ always_ff @(posedge clk) begin
|
||||
m_axis_tx_cpl_tag_reg <= m_axis_tx_cpl_tag_next;
|
||||
m_axis_tx_cpl_valid_reg <= m_axis_tx_cpl_valid_next;
|
||||
|
||||
tx_an_cfg_ready_reg <= tx_an_cfg_ready_next;
|
||||
|
||||
start_packet_int_reg <= start_packet_int_next;
|
||||
start_packet_reg <= start_packet_next;
|
||||
|
||||
@@ -822,12 +860,15 @@ always_ff @(posedge clk) begin
|
||||
|
||||
frame_reg <= 1'b0;
|
||||
deficit_idle_cnt_reg <= 1'd0;
|
||||
an_phase_reg <= 1'b0;
|
||||
rd_reg <= 1'b0;
|
||||
|
||||
s_axis_tx_tready_reg <= 1'b0;
|
||||
|
||||
m_axis_tx_cpl_valid_reg <= 1'b0;
|
||||
|
||||
tx_an_cfg_ready_reg <= 1'b0;
|
||||
|
||||
encoded_tx_data_reg <= '0;
|
||||
encoded_tx_data_k_reg <= '0;
|
||||
encoded_tx_data_dm_reg <= '0;
|
||||
|
||||
@@ -23,6 +23,7 @@ module taxi_axis_basex_tx_8 #
|
||||
parameter MIN_FRAME_LEN = 64,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter GBX_CNT = 1,
|
||||
parameter logic AN_EN = 1'b1,
|
||||
parameter logic DIC_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter PTP_TS_W = 96,
|
||||
@@ -50,6 +51,13 @@ module taxi_axis_basex_tx_8 #
|
||||
input wire logic tx_gbx_req_stall = '0,
|
||||
output wire logic [GBX_CNT-1:0] tx_gbx_sync,
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
input wire logic [15:0] tx_an_cfg = '0,
|
||||
input wire logic tx_an_cfg_valid = 1'b0,
|
||||
output wire logic tx_an_cfg_ready,
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
@@ -181,7 +189,8 @@ typedef enum logic [3:0] {
|
||||
STATE_FCS,
|
||||
STATE_T,
|
||||
STATE_R,
|
||||
STATE_IFG
|
||||
STATE_IFG,
|
||||
STATE_AN
|
||||
} state_t;
|
||||
|
||||
state_t state_reg = STATE_IDLE, state_next;
|
||||
@@ -206,6 +215,7 @@ logic [2:0] pre_cnt_reg = '0, pre_cnt_next;
|
||||
logic [7:0] ifg_cnt_reg = '0, ifg_cnt_next;
|
||||
logic deficit_idle_cnt_reg = 1'd0, deficit_idle_cnt_next;
|
||||
logic odd_reg = 1'b0, odd_next;
|
||||
logic an_phase_reg = 1'b0, an_phase_next;
|
||||
logic rd_reg = 1'b0, rd_next;
|
||||
|
||||
logic [DATA_W-1:0] encoded_tx_data_reg = '0, encoded_tx_data_next;
|
||||
@@ -221,6 +231,8 @@ logic [PTP_TS_W-1:0] m_axis_tx_cpl_ts_reg = '0, m_axis_tx_cpl_ts_next;
|
||||
logic [TX_TAG_W-1:0] m_axis_tx_cpl_tag_reg = '0, m_axis_tx_cpl_tag_next;
|
||||
logic m_axis_tx_cpl_valid_reg = 1'b0, m_axis_tx_cpl_valid_next;
|
||||
|
||||
logic tx_an_cfg_ready_reg = 1'b0, tx_an_cfg_ready_next;
|
||||
|
||||
logic start_packet_int_reg = 1'b0, start_packet_int_next;
|
||||
logic start_packet_reg = 1'b0, start_packet_next;
|
||||
|
||||
@@ -257,6 +269,8 @@ assign m_axis_tx_cpl.tid = m_axis_tx_cpl_tag_reg;
|
||||
assign m_axis_tx_cpl.tdest = '0;
|
||||
assign m_axis_tx_cpl.tuser = '0;
|
||||
|
||||
assign tx_an_cfg_ready = AN_EN ? tx_an_cfg_ready_reg : 1'b0;
|
||||
|
||||
assign tx_start_packet = start_packet_reg;
|
||||
assign stat_tx_byte = stat_tx_byte_reg;
|
||||
assign stat_tx_pkt_len = stat_tx_pkt_len_reg;
|
||||
@@ -307,10 +321,13 @@ always_comb begin
|
||||
ifg_cnt_next = ifg_cnt_reg;
|
||||
deficit_idle_cnt_next = deficit_idle_cnt_reg;
|
||||
odd_next = odd_reg;
|
||||
an_phase_next = an_phase_reg;
|
||||
rd_next = rd_reg;
|
||||
|
||||
s_axis_tx_tready_next = 1'b0;
|
||||
|
||||
tx_an_cfg_ready_next = 1'b0;
|
||||
|
||||
s_tdata_next = s_tdata_reg;
|
||||
|
||||
m_axis_tx_cpl_ts_next = m_axis_tx_cpl_ts_reg;
|
||||
@@ -438,6 +455,10 @@ always_comb begin
|
||||
encoded_tx_data_next = CTRL_S;
|
||||
encoded_tx_data_k_next = 1'b1;
|
||||
state_next = STATE_PREAMBLE;
|
||||
end else if (AN_EN && odd_reg && tx_an_cfg_valid) begin
|
||||
encoded_tx_data_next = an_phase_reg ? D(2,2) : D(21,5);
|
||||
encoded_tx_data_k_next = 1'b0;
|
||||
state_next = STATE_AN;
|
||||
end else begin
|
||||
state_next = STATE_IDLE;
|
||||
end
|
||||
@@ -643,6 +664,22 @@ always_comb begin
|
||||
end
|
||||
end
|
||||
end
|
||||
STATE_AN: begin
|
||||
if (AN_EN) begin
|
||||
// send config register
|
||||
if (!odd_reg) begin
|
||||
encoded_tx_data_next = tx_an_cfg[7:0];
|
||||
encoded_tx_data_k_next = 1'b0;
|
||||
state_next = STATE_AN;
|
||||
end else begin
|
||||
encoded_tx_data_next = tx_an_cfg[15:8];
|
||||
encoded_tx_data_k_next = 1'b0;
|
||||
tx_an_cfg_ready_next = 1'b1;
|
||||
an_phase_next = !an_phase_reg;
|
||||
state_next = STATE_IDLE;
|
||||
end
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
// invalid state, return to idle
|
||||
state_next = STATE_IDLE;
|
||||
@@ -674,15 +711,18 @@ always_ff @(posedge clk) begin
|
||||
ifg_cnt_reg <= ifg_cnt_next;
|
||||
deficit_idle_cnt_reg <= deficit_idle_cnt_next;
|
||||
odd_reg <= odd_next;
|
||||
an_phase_reg <= an_phase_next;
|
||||
rd_reg <= rd_next;
|
||||
|
||||
s_tdata_reg <= s_tdata_next;
|
||||
|
||||
s_axis_tx_tready_reg <= s_axis_tx_tready_next;
|
||||
|
||||
m_axis_tx_cpl_ts_reg <= m_axis_tx_cpl_ts_next;
|
||||
m_axis_tx_cpl_tag_reg <= m_axis_tx_cpl_tag_next;
|
||||
m_axis_tx_cpl_valid_reg <= m_axis_tx_cpl_valid_next;
|
||||
|
||||
s_tdata_reg <= s_tdata_next;
|
||||
|
||||
s_axis_tx_tready_reg <= s_axis_tx_tready_next;
|
||||
tx_an_cfg_ready_reg <= tx_an_cfg_ready_next;
|
||||
|
||||
start_packet_int_reg <= start_packet_int_next;
|
||||
start_packet_reg <= start_packet_next;
|
||||
@@ -722,12 +762,15 @@ always_ff @(posedge clk) begin
|
||||
|
||||
frame_reg <= 1'b0;
|
||||
odd_reg <= 1'b0;
|
||||
an_phase_reg <= 1'b0;
|
||||
rd_reg <= 1'b0;
|
||||
|
||||
s_axis_tx_tready_reg <= 1'b0;
|
||||
|
||||
m_axis_tx_cpl_valid_reg <= 1'b0;
|
||||
|
||||
tx_an_cfg_ready_reg <= 1'b0;
|
||||
|
||||
encoded_tx_data_valid_reg <= 1'b0;
|
||||
encoded_tx_data_k_reg <= 1'b0;
|
||||
encoded_tx_data_dm_reg <= 1'b0;
|
||||
|
||||
@@ -136,6 +136,7 @@ if (DATA_W == 16) begin
|
||||
.DATA_W(DATA_W),
|
||||
.CTRL_W(CTRL_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.AN_EN(1'b0),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
|
||||
.PTP_TS_W(PTP_TS_W)
|
||||
@@ -156,6 +157,15 @@ if (DATA_W == 16) begin
|
||||
*/
|
||||
.m_axis_rx(m_axis_rx),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.rx_an_cfg(),
|
||||
.rx_an_cfg_valid(),
|
||||
.rx_an_ability_match(),
|
||||
.rx_an_ack_match(),
|
||||
.rx_an_idle_match(),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
@@ -194,6 +204,7 @@ end else begin
|
||||
.DATA_W(DATA_W),
|
||||
.CTRL_W(CTRL_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.AN_EN(1'b0),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W)
|
||||
)
|
||||
@@ -213,6 +224,15 @@ end else begin
|
||||
*/
|
||||
.m_axis_rx(m_axis_rx),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.rx_an_cfg(),
|
||||
.rx_an_cfg_valid(),
|
||||
.rx_an_ability_match(),
|
||||
.rx_an_ack_match(),
|
||||
.rx_an_idle_match(),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
|
||||
@@ -142,6 +142,7 @@ if (DATA_W == 16) begin
|
||||
.CTRL_W(CTRL_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.GBX_CNT(1),
|
||||
.AN_EN(1'b0),
|
||||
.DIC_EN(DIC_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W),
|
||||
@@ -169,6 +170,13 @@ if (DATA_W == 16) begin
|
||||
.tx_gbx_req_stall(tx_gbx_req_stall),
|
||||
.tx_gbx_sync(tx_gbx_sync),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.tx_an_cfg('0),
|
||||
.tx_an_cfg_valid(1'b0),
|
||||
.tx_an_cfg_ready(),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
@@ -205,6 +213,7 @@ end else begin
|
||||
.CTRL_W(CTRL_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.GBX_CNT(1),
|
||||
.AN_EN(1'b0),
|
||||
.DIC_EN(DIC_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W),
|
||||
@@ -232,6 +241,13 @@ end else begin
|
||||
.tx_gbx_req_stall(tx_gbx_req_stall),
|
||||
.tx_gbx_sync(tx_gbx_sync),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.tx_an_cfg('0),
|
||||
.tx_an_cfg_valid(1'b0),
|
||||
.tx_an_cfg_ready(),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,7 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
||||
# module parameters
|
||||
export PARAM_DATA_W := 16
|
||||
export PARAM_GBX_IF_EN := 0
|
||||
export PARAM_AN_EN := 1
|
||||
export PARAM_PTP_TS_EN := 1
|
||||
export PARAM_PTP_TS_FMT_TOD := 1
|
||||
|
||||
|
||||
@@ -265,6 +265,38 @@ async def run_test_oversize(dut, gbx_cfg=None, ifg=12):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_an(dut, gbx_cfg=None):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
|
||||
await tb.reset()
|
||||
|
||||
for k in range(16):
|
||||
an_cfg = 1 << k
|
||||
|
||||
tb.source.set_an_cfg(an_cfg)
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert int(dut.rx_an_cfg.value) == an_cfg
|
||||
assert int(dut.rx_an_ability_match.value)
|
||||
assert int(dut.rx_an_ack_match.value) == bool(an_cfg & 0x4000)
|
||||
assert not int(dut.rx_an_idle_match.value)
|
||||
|
||||
tb.source.set_an_cfg(None)
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert not int(dut.rx_an_ability_match.value)
|
||||
assert not int(dut.rx_an_ack_match.value)
|
||||
assert int(dut.rx_an_idle_match.value)
|
||||
|
||||
for k in range(10):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
def size_list():
|
||||
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
|
||||
|
||||
@@ -287,13 +319,17 @@ 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", list(range(0, 13)))
|
||||
factory.add_option("pre_len", [8, 7])
|
||||
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", list(range(0, 13)))
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
factory = TestFactory(run_test_an)
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
@@ -338,6 +374,7 @@ def test_taxi_axis_basex_rx_16(request, gbx_en):
|
||||
|
||||
parameters['DATA_W'] = 16
|
||||
parameters['GBX_IF_EN'] = gbx_en
|
||||
parameters['AN_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_basex_rx_16 #
|
||||
parameter DATA_W = 16,
|
||||
parameter CTRL_W = DATA_W / 8,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter logic AN_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
|
||||
@@ -39,6 +40,12 @@ logic encoded_rx_data_valid;
|
||||
|
||||
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(USER_W)) m_axis_rx();
|
||||
|
||||
logic [15:0] rx_an_cfg;
|
||||
logic rx_an_cfg_valid;
|
||||
logic rx_an_ability_match;
|
||||
logic rx_an_ack_match;
|
||||
logic rx_an_idle_match;
|
||||
|
||||
logic [PTP_TS_W-1:0] ptp_ts;
|
||||
|
||||
logic [15:0] cfg_rx_max_pkt_len;
|
||||
@@ -65,6 +72,7 @@ taxi_axis_basex_rx_16 #(
|
||||
.DATA_W(DATA_W),
|
||||
.CTRL_W(CTRL_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.AN_EN(AN_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W)
|
||||
)
|
||||
@@ -84,6 +92,15 @@ uut (
|
||||
*/
|
||||
.m_axis_rx(m_axis_rx),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.rx_an_cfg(rx_an_cfg),
|
||||
.rx_an_cfg_valid(rx_an_cfg_valid),
|
||||
.rx_an_ability_match(rx_an_ability_match),
|
||||
.rx_an_ack_match(rx_an_ack_match),
|
||||
.rx_an_idle_match(rx_an_idle_match),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,7 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
||||
# module parameters
|
||||
export PARAM_DATA_W := 8
|
||||
export PARAM_GBX_IF_EN := 0
|
||||
export PARAM_AN_EN := 1
|
||||
export PARAM_PTP_TS_EN := 1
|
||||
export PARAM_PTP_TS_FMT_TOD := 1
|
||||
|
||||
|
||||
@@ -265,6 +265,38 @@ async def run_test_oversize(dut, gbx_cfg=None, ifg=12):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_an(dut, gbx_cfg=None):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
|
||||
await tb.reset()
|
||||
|
||||
for k in range(16):
|
||||
an_cfg = 1 << k
|
||||
|
||||
tb.source.set_an_cfg(an_cfg)
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert int(dut.rx_an_cfg.value) == an_cfg
|
||||
assert int(dut.rx_an_ability_match.value)
|
||||
assert int(dut.rx_an_ack_match.value) == bool(an_cfg & 0x4000)
|
||||
assert not int(dut.rx_an_idle_match.value)
|
||||
|
||||
tb.source.set_an_cfg(None)
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert not int(dut.rx_an_ability_match.value)
|
||||
assert not int(dut.rx_an_ack_match.value)
|
||||
assert int(dut.rx_an_idle_match.value)
|
||||
|
||||
for k in range(10):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
def size_list():
|
||||
return list(range(60, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
|
||||
|
||||
@@ -297,6 +329,10 @@ if getattr(cocotb, 'top', None) is not None:
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
factory = TestFactory(run_test_an)
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
|
||||
# cocotb-test
|
||||
|
||||
@@ -338,6 +374,7 @@ def test_taxi_axis_basex_rx_8(request, gbx_en):
|
||||
|
||||
parameters['DATA_W'] = 8
|
||||
parameters['GBX_IF_EN'] = gbx_en
|
||||
parameters['AN_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_basex_rx_8 #
|
||||
parameter DATA_W = 8,
|
||||
parameter CTRL_W = DATA_W / 8,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter logic AN_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
|
||||
@@ -39,6 +40,12 @@ logic encoded_rx_data_valid;
|
||||
|
||||
taxi_axis_if #(.DATA_W(DATA_W), .USER_EN(1), .USER_W(USER_W)) m_axis_rx();
|
||||
|
||||
logic [15:0] rx_an_cfg;
|
||||
logic rx_an_cfg_valid;
|
||||
logic rx_an_ability_match;
|
||||
logic rx_an_ack_match;
|
||||
logic rx_an_idle_match;
|
||||
|
||||
logic [PTP_TS_W-1:0] ptp_ts;
|
||||
|
||||
logic [15:0] cfg_rx_max_pkt_len;
|
||||
@@ -65,6 +72,7 @@ taxi_axis_basex_rx_8 #(
|
||||
.DATA_W(DATA_W),
|
||||
.CTRL_W(CTRL_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.AN_EN(AN_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W)
|
||||
)
|
||||
@@ -84,6 +92,15 @@ uut (
|
||||
*/
|
||||
.m_axis_rx(m_axis_rx),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.rx_an_cfg(rx_an_cfg),
|
||||
.rx_an_cfg_valid(rx_an_cfg_valid),
|
||||
.rx_an_ability_match(rx_an_ability_match),
|
||||
.rx_an_ack_match(rx_an_ack_match),
|
||||
.rx_an_idle_match(rx_an_idle_match),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,7 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
||||
export PARAM_DATA_W := 16
|
||||
export PARAM_GBX_IF_EN := 0
|
||||
export PARAM_GBX_CNT := 1
|
||||
export PARAM_AN_EN := 1
|
||||
export PARAM_DIC_EN := 1
|
||||
export PARAM_PTP_TS_EN := 1
|
||||
export PARAM_PTP_TS_W := 96
|
||||
|
||||
@@ -67,6 +67,9 @@ class TB:
|
||||
self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts, clock=dut.clk)
|
||||
self.tx_cpl_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_tx_cpl), dut.clk, dut.rst)
|
||||
|
||||
dut.tx_an_cfg.setimmediatevalue(0)
|
||||
dut.tx_an_cfg_valid.setimmediatevalue(0)
|
||||
|
||||
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
||||
dut.cfg_tx_ifg.setimmediatevalue(0)
|
||||
dut.cfg_tx_enable.setimmediatevalue(0)
|
||||
@@ -378,6 +381,39 @@ async def run_test_oversize(dut, gbx_cfg=None, ifg=12):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_an(dut, gbx_cfg=None):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
|
||||
await tb.reset()
|
||||
|
||||
for k in range(16):
|
||||
an_cfg = 1 << k
|
||||
|
||||
dut.tx_an_cfg.value = an_cfg
|
||||
dut.tx_an_cfg_valid.value = 1
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert tb.sink.get_an_cfg() == an_cfg
|
||||
assert tb.sink.get_an_ability_match()
|
||||
assert tb.sink.get_an_ack_match() == bool(an_cfg & 0x4000)
|
||||
assert not tb.sink.get_an_idle_match()
|
||||
|
||||
dut.tx_an_cfg_valid.value = 0
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert not tb.sink.get_an_ability_match()
|
||||
assert not tb.sink.get_an_ack_match()
|
||||
assert tb.sink.get_an_idle_match()
|
||||
|
||||
for k in range(10):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
def size_list():
|
||||
return list(range(16, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
|
||||
|
||||
@@ -415,6 +451,10 @@ if getattr(cocotb, 'top', None) is not None:
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
factory = TestFactory(run_test_an)
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
|
||||
# cocotb-test
|
||||
|
||||
@@ -459,6 +499,7 @@ def test_taxi_axis_basex_tx_16(request, gbx_en, dic_en):
|
||||
parameters['CTRL_W'] = parameters['DATA_W'] // 8
|
||||
parameters['GBX_IF_EN'] = gbx_en
|
||||
parameters['GBX_CNT'] = 1
|
||||
parameters['AN_EN'] = 1
|
||||
parameters['DIC_EN'] = dic_en
|
||||
parameters['PTP_TS_EN'] = 1
|
||||
parameters['PTP_TS_W'] = 96
|
||||
|
||||
@@ -22,6 +22,7 @@ module test_taxi_axis_basex_tx_16 #
|
||||
parameter CTRL_W = DATA_W / 8,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter GBX_CNT = 1,
|
||||
parameter logic AN_EN = 1'b1,
|
||||
parameter logic DIC_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter PTP_TS_W = 96,
|
||||
@@ -48,6 +49,10 @@ logic [GBX_CNT-1:0] tx_gbx_req_sync;
|
||||
logic tx_gbx_req_stall;
|
||||
logic [GBX_CNT-1:0] tx_gbx_sync;
|
||||
|
||||
logic [15:0] tx_an_cfg;
|
||||
logic tx_an_cfg_valid;
|
||||
logic tx_an_cfg_ready;
|
||||
|
||||
logic [PTP_TS_W-1:0] ptp_ts;
|
||||
|
||||
logic [15:0] cfg_tx_max_pkt_len;
|
||||
@@ -72,6 +77,7 @@ taxi_axis_basex_tx_16 #(
|
||||
.CTRL_W(CTRL_W),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.GBX_CNT(GBX_CNT),
|
||||
.AN_EN(AN_EN),
|
||||
.DIC_EN(DIC_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W),
|
||||
@@ -99,6 +105,13 @@ uut (
|
||||
.tx_gbx_req_stall(tx_gbx_req_stall),
|
||||
.tx_gbx_sync(tx_gbx_sync),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.tx_an_cfg(tx_an_cfg),
|
||||
.tx_an_cfg_valid(tx_an_cfg_valid),
|
||||
.tx_an_cfg_ready(tx_an_cfg_ready),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
|
||||
@@ -39,6 +39,7 @@ export PARAM_PADDING_EN := 1
|
||||
export PARAM_MIN_FRAME_LEN := 64
|
||||
export PARAM_GBX_IF_EN := 0
|
||||
export PARAM_GBX_CNT := 1
|
||||
export PARAM_AN_EN := 1
|
||||
export PARAM_DIC_EN := 1
|
||||
export PARAM_PTP_TS_EN := 1
|
||||
export PARAM_PTP_TS_FMT_TOD := 1
|
||||
|
||||
@@ -67,6 +67,9 @@ class TB:
|
||||
self.ptp_clock = PtpClockSimTime(ts_tod=dut.ptp_ts, clock=dut.clk)
|
||||
self.tx_cpl_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_tx_cpl), dut.clk, dut.rst)
|
||||
|
||||
dut.tx_an_cfg.setimmediatevalue(0)
|
||||
dut.tx_an_cfg_valid.setimmediatevalue(0)
|
||||
|
||||
dut.cfg_tx_max_pkt_len.setimmediatevalue(0)
|
||||
dut.cfg_tx_ifg.setimmediatevalue(0)
|
||||
dut.cfg_tx_enable.setimmediatevalue(0)
|
||||
@@ -378,6 +381,39 @@ async def run_test_oversize(dut, gbx_cfg=None, ifg=12):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
async def run_test_an(dut, gbx_cfg=None):
|
||||
|
||||
tb = TB(dut, gbx_cfg)
|
||||
|
||||
await tb.reset()
|
||||
|
||||
for k in range(16):
|
||||
an_cfg = 1 << k
|
||||
|
||||
dut.tx_an_cfg.value = an_cfg
|
||||
dut.tx_an_cfg_valid.value = 1
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert tb.sink.get_an_cfg() == an_cfg
|
||||
assert tb.sink.get_an_ability_match()
|
||||
assert tb.sink.get_an_ack_match() == bool(an_cfg & 0x4000)
|
||||
assert not tb.sink.get_an_idle_match()
|
||||
|
||||
dut.tx_an_cfg_valid.value = 0
|
||||
|
||||
for k in range(20):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
assert not tb.sink.get_an_ability_match()
|
||||
assert not tb.sink.get_an_ack_match()
|
||||
assert tb.sink.get_an_idle_match()
|
||||
|
||||
for k in range(10):
|
||||
await RisingEdge(dut.clk)
|
||||
|
||||
|
||||
def size_list():
|
||||
return list(range(16, 128)) + [512, 1514, 9214] + [60]*10 + [i for i in range(64, 73) for k in range(8)]
|
||||
|
||||
@@ -415,6 +451,10 @@ if getattr(cocotb, 'top', None) is not None:
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
factory = TestFactory(run_test_an)
|
||||
factory.add_option("gbx_cfg", gbx_cfgs)
|
||||
factory.generate_tests()
|
||||
|
||||
|
||||
# cocotb-test
|
||||
|
||||
@@ -461,6 +501,7 @@ def test_taxi_axis_basex_tx_8(request, gbx_en, dic_en):
|
||||
parameters['MIN_FRAME_LEN'] = 64
|
||||
parameters['GBX_IF_EN'] = gbx_en
|
||||
parameters['GBX_CNT'] = 1
|
||||
parameters['AN_EN'] = 1
|
||||
parameters['DIC_EN'] = dic_en
|
||||
parameters['PTP_TS_EN'] = 1
|
||||
parameters['PTP_TS_FMT_TOD'] = 1
|
||||
|
||||
@@ -24,6 +24,7 @@ module test_taxi_axis_basex_tx_8 #
|
||||
parameter MIN_FRAME_LEN = 64,
|
||||
parameter logic GBX_IF_EN = 1'b0,
|
||||
parameter GBX_CNT = 1,
|
||||
parameter logic AN_EN = 1'b1,
|
||||
parameter logic DIC_EN = 1'b1,
|
||||
parameter logic PTP_TS_EN = 1'b0,
|
||||
parameter logic PTP_TS_FMT_TOD = 1'b1,
|
||||
@@ -51,6 +52,10 @@ logic [GBX_CNT-1:0] tx_gbx_req_sync;
|
||||
logic tx_gbx_req_stall;
|
||||
logic [GBX_CNT-1:0] tx_gbx_sync;
|
||||
|
||||
logic [15:0] tx_an_cfg;
|
||||
logic tx_an_cfg_valid;
|
||||
logic tx_an_cfg_ready;
|
||||
|
||||
logic [PTP_TS_W-1:0] ptp_ts;
|
||||
|
||||
logic [15:0] cfg_tx_max_pkt_len;
|
||||
@@ -77,7 +82,8 @@ taxi_axis_basex_tx_8 #(
|
||||
.MIN_FRAME_LEN(MIN_FRAME_LEN),
|
||||
.GBX_IF_EN(GBX_IF_EN),
|
||||
.GBX_CNT(GBX_CNT),
|
||||
// .DIC_EN(DIC_EN),
|
||||
.AN_EN(AN_EN),
|
||||
.DIC_EN(DIC_EN),
|
||||
.PTP_TS_EN(PTP_TS_EN),
|
||||
.PTP_TS_W(PTP_TS_W),
|
||||
.TX_CPL_CTRL_IN_TUSER(TX_CPL_CTRL_IN_TUSER)
|
||||
@@ -104,6 +110,13 @@ uut (
|
||||
.tx_gbx_req_stall(tx_gbx_req_stall),
|
||||
.tx_gbx_sync(tx_gbx_sync),
|
||||
|
||||
/*
|
||||
* AN config register
|
||||
*/
|
||||
.tx_an_cfg(tx_an_cfg),
|
||||
.tx_an_cfg_valid(tx_an_cfg_valid),
|
||||
.tx_an_cfg_ready(tx_an_cfg_ready),
|
||||
|
||||
/*
|
||||
* PTP
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user