Add PTP timestamp capture logic to MACs

This commit is contained in:
Alex Forencich 2019-06-07 16:38:36 -07:00
parent 659aa67481
commit 82fe5a6bdd
37 changed files with 1471 additions and 427 deletions

View File

@ -33,34 +33,44 @@ module axis_baser_rx_64 #
( (
parameter DATA_WIDTH = 64, parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8), parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter HDR_WIDTH = 2 parameter HDR_WIDTH = 2,
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1
) )
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
/* /*
* 10GBASE-R encoded input * 10GBASE-R encoded input
*/ */
input wire [DATA_WIDTH-1:0] encoded_rx_data, input wire [DATA_WIDTH-1:0] encoded_rx_data,
input wire [HDR_WIDTH-1:0] encoded_rx_hdr, input wire [HDR_WIDTH-1:0] encoded_rx_hdr,
/* /*
* AXI output * AXI output
*/ */
output wire [DATA_WIDTH-1:0] m_axis_tdata, output wire [DATA_WIDTH-1:0] m_axis_tdata,
output wire [KEEP_WIDTH-1:0] m_axis_tkeep, output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
output wire m_axis_tvalid, output wire m_axis_tvalid,
output wire m_axis_tlast, output wire m_axis_tlast,
output wire m_axis_tuser, output wire [USER_WIDTH-1:0] m_axis_tuser,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
/* /*
* Status * Status
*/ */
output wire [1:0] start_packet, output wire [1:0] start_packet,
output wire error_bad_frame, output wire error_bad_frame,
output wire error_bad_fcs, output wire error_bad_fcs,
output wire rx_bad_block output wire rx_bad_block
); );
// bus width assertions // bus width assertions
@ -177,6 +187,8 @@ reg error_bad_frame_reg = 1'b0, error_bad_frame_next;
reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
reg rx_bad_block_reg = 1'b0; reg rx_bad_block_reg = 1'b0;
reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0;
reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state = 32'hFFFFFFFF;
reg [31:0] crc_state3 = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF;
@ -198,7 +210,7 @@ assign m_axis_tdata = m_axis_tdata_reg;
assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tkeep = m_axis_tkeep_reg;
assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tvalid = m_axis_tvalid_reg;
assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tlast = m_axis_tlast_reg;
assign m_axis_tuser = m_axis_tuser_reg; assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_bad_frame = error_bad_frame_reg; assign error_bad_frame = error_bad_frame_reg;
@ -518,6 +530,28 @@ always @(posedge clk) begin
end end
end end
if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
// ns field rollover
ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1;
end
if (encoded_rx_hdr == SYNC_CTRL && encoded_rx_data[7:0] == BLOCK_TYPE_START_0) begin
if (PTP_TS_WIDTH == 96) begin
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
ptp_ts_reg[95:48] <= ptp_ts[95:48];
end else begin
ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
end
end else if (encoded_rx_hdr == SYNC_CTRL && (encoded_rx_data[7:0] == BLOCK_TYPE_START_4 || encoded_rx_data[7:0] == BLOCK_TYPE_OS_START)) begin
if (PTP_TS_WIDTH == 96) begin
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
ptp_ts_reg[95:48] <= ptp_ts[95:48];
end else begin
ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
end
end
m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tdata_reg <= m_axis_tdata_next;
m_axis_tkeep_reg <= m_axis_tkeep_next; m_axis_tkeep_reg <= m_axis_tkeep_next;
m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tlast_reg <= m_axis_tlast_next;

View File

@ -36,38 +36,53 @@ module axis_baser_tx_64 #
parameter HDR_WIDTH = 2, parameter HDR_WIDTH = 2,
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter ENABLE_DIC = 1, parameter ENABLE_DIC = 1,
parameter MIN_FRAME_LENGTH = 64 parameter MIN_FRAME_LENGTH = 64,
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter PTP_TAG_ENABLE = 0,
parameter PTP_TAG_WIDTH = 16,
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1
) )
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
/* /*
* AXI input * AXI input
*/ */
input wire [DATA_WIDTH-1:0] s_axis_tdata, input wire [DATA_WIDTH-1:0] s_axis_tdata,
input wire [KEEP_WIDTH-1:0] s_axis_tkeep, input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
input wire s_axis_tvalid, input wire s_axis_tvalid,
output wire s_axis_tready, output wire s_axis_tready,
input wire s_axis_tlast, input wire s_axis_tlast,
input wire s_axis_tuser, input wire [USER_WIDTH-1:0] s_axis_tuser,
/* /*
* 10GBASE-R encoded interface * 10GBASE-R encoded interface
*/ */
output wire [DATA_WIDTH-1:0] encoded_tx_data, output wire [DATA_WIDTH-1:0] encoded_tx_data,
output wire [HDR_WIDTH-1:0] encoded_tx_hdr, output wire [HDR_WIDTH-1:0] encoded_tx_hdr,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts,
output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag,
output wire m_axis_ptp_ts_valid,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay, input wire [7:0] ifg_delay,
/* /*
* Status * Status
*/ */
output wire [1:0] start_packet, output wire [1:0] start_packet,
output wire error_underflow output wire error_underflow
); );
// bus width assertions // bus width assertions
@ -192,6 +207,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next;
reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next;
reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next;
reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0; wire [31:0] crc_next0;
@ -217,6 +237,10 @@ assign s_axis_tready = s_axis_tready_reg;
assign encoded_tx_data = encoded_tx_data_reg; assign encoded_tx_data = encoded_tx_data_reg;
assign encoded_tx_hdr = encoded_tx_hdr_reg; assign encoded_tx_hdr = encoded_tx_hdr_reg;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0;
assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0;
assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_underflow = error_underflow_reg; assign error_underflow = error_underflow_reg;
@ -469,12 +493,26 @@ always @* begin
s_tdata_next = s_tdata_reg; s_tdata_next = s_tdata_reg;
s_tkeep_next = s_tkeep_reg; s_tkeep_next = s_tkeep_reg;
m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
m_axis_ptp_ts_valid_next = 1'b0;
m_axis_ptp_ts_valid_int_next = 1'b0;
output_data_next = s_tdata_reg; output_data_next = s_tdata_reg;
output_type_next = OUTPUT_TYPE_IDLE; output_type_next = OUTPUT_TYPE_IDLE;
start_packet_next = 2'b00; start_packet_next = 2'b00;
error_underflow_next = 1'b0; error_underflow_next = 1'b0;
if (m_axis_ptp_ts_valid_int_reg) begin
m_axis_ptp_ts_valid_next = 1'b1;
if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
// ns field rollover
m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1;
end
end
case (state_reg) case (state_reg)
STATE_IDLE: begin STATE_IDLE: begin
// idle state - wait for data // idle state - wait for data
@ -493,10 +531,26 @@ always @* begin
if (ifg_count_reg > 8'd0) begin if (ifg_count_reg > 8'd0) begin
// need to send more idles - swap lanes // need to send more idles - swap lanes
swap_lanes = 1'b1; swap_lanes = 1'b1;
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48];
end else begin
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b10; start_packet_next = 2'b10;
end else begin end else begin
// no more idles - unswap // no more idles - unswap
unswap_lanes = 1'b1; unswap_lanes = 1'b1;
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48];
end else begin
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b01; start_packet_next = 2'b01;
end end
output_data_next = {ETH_SFD, {7{ETH_PRE}}}; output_data_next = {ETH_SFD, {7{ETH_PRE}}};
@ -527,7 +581,7 @@ always @* begin
if (s_axis_tlast) begin if (s_axis_tlast) begin
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
s_axis_tready_next = 1'b0; s_axis_tready_next = 1'b0;
if (s_axis_tuser) begin if (s_axis_tuser[0]) begin
output_type_next = OUTPUT_TYPE_ERROR; output_type_next = OUTPUT_TYPE_ERROR;
frame_ptr_next = 16'd0; frame_ptr_next = 16'd0;
ifg_count_next = 8'd8; ifg_count_next = 8'd8;
@ -721,6 +775,9 @@ always @(posedge clk) begin
s_axis_tready_reg <= 1'b0; s_axis_tready_reg <= 1'b0;
m_axis_ptp_ts_valid_reg <= 1'b0;
m_axis_ptp_ts_valid_int_reg <= 1'b0;
encoded_tx_data_reg <= {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL}; encoded_tx_data_reg <= {{8{CTRL_IDLE}}, BLOCK_TYPE_CTRL};
encoded_tx_hdr_reg <= SYNC_CTRL; encoded_tx_hdr_reg <= SYNC_CTRL;
@ -745,6 +802,9 @@ always @(posedge clk) begin
deficit_idle_count_reg <= deficit_idle_count_next; deficit_idle_count_reg <= deficit_idle_count_next;
s_axis_tready_reg <= s_axis_tready_next; s_axis_tready_reg <= s_axis_tready_next;
m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next;
m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next;
start_packet_reg <= start_packet_next; start_packet_reg <= start_packet_next;
error_underflow_reg <= error_underflow_next; error_underflow_reg <= error_underflow_next;
@ -845,6 +905,9 @@ always @(posedge clk) begin
s_tdata_reg <= s_tdata_next; s_tdata_reg <= s_tdata_next;
s_tkeep_reg <= s_tkeep_next; s_tkeep_reg <= s_tkeep_next;
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
swap_data <= output_data_next[63:32]; swap_data <= output_data_next[63:32];
delay_type <= output_type_next ^ 4'd4; delay_type <= output_type_next ^ 4'd4;

View File

@ -29,40 +29,59 @@ THE SOFTWARE.
/* /*
* AXI4-Stream GMII frame receiver (GMII in, AXI out) * AXI4-Stream GMII frame receiver (GMII in, AXI out)
*/ */
module axis_gmii_rx module axis_gmii_rx #
( (
input wire clk, parameter DATA_WIDTH = 8,
input wire rst, parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1
)
(
input wire clk,
input wire rst,
/* /*
* GMII input * GMII input
*/ */
input wire [7:0] gmii_rxd, input wire [DATA_WIDTH-1:0] gmii_rxd,
input wire gmii_rx_dv, input wire gmii_rx_dv,
input wire gmii_rx_er, input wire gmii_rx_er,
/* /*
* AXI output * AXI output
*/ */
output wire [7:0] m_axis_tdata, output wire [DATA_WIDTH-1:0] m_axis_tdata,
output wire m_axis_tvalid, output wire m_axis_tvalid,
output wire m_axis_tlast, output wire m_axis_tlast,
output wire m_axis_tuser, output wire [USER_WIDTH-1:0] m_axis_tuser,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
/* /*
* Control * Control
*/ */
input wire clk_enable, input wire clk_enable,
input wire mii_select, input wire mii_select,
/* /*
* Status * Status
*/ */
output wire start_packet, output wire start_packet,
output wire error_bad_frame, output wire error_bad_frame,
output wire error_bad_fcs output wire error_bad_fcs
); );
// bus width assertions
initial begin
if (DATA_WIDTH != 8) begin
$error("Error: Interface width must be 8");
$finish;
end
end
localparam [7:0] localparam [7:0]
ETH_PRE = 8'h55, ETH_PRE = 8'h55,
ETH_SFD = 8'hD5; ETH_SFD = 8'hD5;
@ -81,11 +100,11 @@ reg update_crc;
reg mii_odd = 1'b0; reg mii_odd = 1'b0;
reg mii_locked = 1'b0; reg mii_locked = 1'b0;
reg [7:0] gmii_rxd_d0 = 8'd0; reg [DATA_WIDTH-1:0] gmii_rxd_d0 = {DATA_WIDTH{1'b0}};
reg [7:0] gmii_rxd_d1 = 8'd0; reg [DATA_WIDTH-1:0] gmii_rxd_d1 = {DATA_WIDTH{1'b0}};
reg [7:0] gmii_rxd_d2 = 8'd0; reg [DATA_WIDTH-1:0] gmii_rxd_d2 = {DATA_WIDTH{1'b0}};
reg [7:0] gmii_rxd_d3 = 8'd0; reg [DATA_WIDTH-1:0] gmii_rxd_d3 = {DATA_WIDTH{1'b0}};
reg [7:0] gmii_rxd_d4 = 8'd0; reg [DATA_WIDTH-1:0] gmii_rxd_d4 = {DATA_WIDTH{1'b0}};
reg gmii_rx_dv_d0 = 1'b0; reg gmii_rx_dv_d0 = 1'b0;
reg gmii_rx_dv_d1 = 1'b0; reg gmii_rx_dv_d1 = 1'b0;
@ -99,7 +118,7 @@ reg gmii_rx_er_d2 = 1'b0;
reg gmii_rx_er_d3 = 1'b0; reg gmii_rx_er_d3 = 1'b0;
reg gmii_rx_er_d4 = 1'b0; reg gmii_rx_er_d4 = 1'b0;
reg [7:0] m_axis_tdata_reg = 8'd0, m_axis_tdata_next; reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next;
reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next;
reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next;
@ -108,13 +127,15 @@ reg start_packet_reg = 1'b0, start_packet_next;
reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next;
reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0, ptp_ts_next;
reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next; wire [31:0] crc_next;
assign m_axis_tdata = m_axis_tdata_reg; assign m_axis_tdata = m_axis_tdata_reg;
assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tvalid = m_axis_tvalid_reg;
assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tlast = m_axis_tlast_reg;
assign m_axis_tuser = m_axis_tuser_reg; assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_bad_frame = error_bad_frame_reg; assign error_bad_frame = error_bad_frame_reg;
@ -142,7 +163,7 @@ always @* begin
reset_crc = 1'b0; reset_crc = 1'b0;
update_crc = 1'b0; update_crc = 1'b0;
m_axis_tdata_next = 8'd0; m_axis_tdata_next = {DATA_WIDTH{1'b0}};
m_axis_tvalid_next = 1'b0; m_axis_tvalid_next = 1'b0;
m_axis_tlast_next = 1'b0; m_axis_tlast_next = 1'b0;
m_axis_tuser_next = 1'b0; m_axis_tuser_next = 1'b0;
@ -151,6 +172,8 @@ always @* begin
error_bad_frame_next = 1'b0; error_bad_frame_next = 1'b0;
error_bad_fcs_next = 1'b0; error_bad_fcs_next = 1'b0;
ptp_ts_next = ptp_ts_reg;
if (!clk_enable) begin if (!clk_enable) begin
// clock disabled - hold state // clock disabled - hold state
state_next = state_reg; state_next = state_reg;
@ -164,6 +187,7 @@ always @* begin
reset_crc = 1'b1; reset_crc = 1'b1;
if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD) begin if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD) begin
ptp_ts_next = ptp_ts;
start_packet_next = 1'b1; start_packet_next = 1'b1;
state_next = STATE_PAYLOAD; state_next = STATE_PAYLOAD;
end else begin end else begin
@ -283,6 +307,8 @@ always @(posedge clk) begin
end end
end end
ptp_ts_reg <= ptp_ts_next;
m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tdata_reg <= m_axis_tdata_next;
m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tlast_reg <= m_axis_tlast_next;
m_axis_tuser_reg <= m_axis_tuser_next; m_axis_tuser_reg <= m_axis_tuser_next;

View File

@ -31,47 +31,69 @@ THE SOFTWARE.
*/ */
module axis_gmii_tx # module axis_gmii_tx #
( (
parameter DATA_WIDTH = 8,
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter MIN_FRAME_LENGTH = 64 parameter MIN_FRAME_LENGTH = 64,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter PTP_TAG_ENABLE = 0,
parameter PTP_TAG_WIDTH = 16,
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1
) )
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
/* /*
* AXI input * AXI input
*/ */
input wire [7:0] s_axis_tdata, input wire [DATA_WIDTH-1:0] s_axis_tdata,
input wire s_axis_tvalid, input wire s_axis_tvalid,
output wire s_axis_tready, output wire s_axis_tready,
input wire s_axis_tlast, input wire s_axis_tlast,
input wire s_axis_tuser, input wire [USER_WIDTH-1:0] s_axis_tuser,
/* /*
* GMII output * GMII output
*/ */
output wire [7:0] gmii_txd, output wire [DATA_WIDTH-1:0] gmii_txd,
output wire gmii_tx_en, output wire gmii_tx_en,
output wire gmii_tx_er, output wire gmii_tx_er,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts,
output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag,
output wire m_axis_ptp_ts_valid,
/* /*
* Control * Control
*/ */
input wire clk_enable, input wire clk_enable,
input wire mii_select, input wire mii_select,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay, input wire [7:0] ifg_delay,
/* /*
* Status * Status
*/ */
output wire start_packet, output wire start_packet,
output wire error_underflow output wire error_underflow
); );
// bus width assertions
initial begin
if (DATA_WIDTH != 8) begin
$error("Error: Interface width must be 8");
$finish;
end
end
localparam [7:0] localparam [7:0]
ETH_PRE = 8'h55, ETH_PRE = 8'h55,
ETH_SFD = 8'hD5; ETH_SFD = 8'hD5;
@ -105,6 +127,10 @@ reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next;
reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next;
reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next;
reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
reg start_packet_reg = 1'b0, start_packet_next; reg start_packet_reg = 1'b0, start_packet_next;
reg error_underflow_reg = 1'b0, error_underflow_next; reg error_underflow_reg = 1'b0, error_underflow_next;
@ -117,6 +143,10 @@ assign gmii_txd = gmii_txd_reg;
assign gmii_tx_en = gmii_tx_en_reg; assign gmii_tx_en = gmii_tx_en_reg;
assign gmii_tx_er = gmii_tx_er_reg; assign gmii_tx_er = gmii_tx_er_reg;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0;
assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0;
assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_underflow = error_underflow_reg; assign error_underflow = error_underflow_reg;
@ -151,7 +181,11 @@ always @* begin
s_tdata_next = s_tdata_reg; s_tdata_next = s_tdata_reg;
gmii_txd_next = 8'd0; m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
m_axis_ptp_ts_valid_next = 1'b0;
gmii_txd_next = {DATA_WIDTH{1'b0}};
gmii_tx_en_next = 1'b0; gmii_tx_en_next = 1'b0;
gmii_tx_er_next = 1'b0; gmii_tx_er_next = 1'b0;
@ -210,6 +244,9 @@ always @* begin
s_tdata_next = s_axis_tdata; s_tdata_next = s_axis_tdata;
end end
gmii_txd_next = ETH_SFD; gmii_txd_next = ETH_SFD;
m_axis_ptp_ts_next = ptp_ts;
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_next = 1'b1;
start_packet_next = 1'b1; start_packet_next = 1'b1;
state_next = STATE_PAYLOAD; state_next = STATE_PAYLOAD;
end else begin end else begin
@ -233,7 +270,7 @@ always @* begin
if (s_axis_tvalid) begin if (s_axis_tvalid) begin
if (s_axis_tlast) begin if (s_axis_tlast) begin
s_axis_tready_next = !s_axis_tready_reg; s_axis_tready_next = !s_axis_tready_reg;
if (s_axis_tuser) begin if (s_axis_tuser[0]) begin
gmii_tx_er_next = 1'b1; gmii_tx_er_next = 1'b1;
frame_ptr_next = 1'b0; frame_ptr_next = 1'b0;
state_next = STATE_IFG; state_next = STATE_IFG;
@ -365,6 +402,8 @@ always @(posedge clk) begin
s_axis_tready_reg <= 1'b0; s_axis_tready_reg <= 1'b0;
m_axis_ptp_ts_valid_reg <= 1'b0;
gmii_tx_en_reg <= 1'b0; gmii_tx_en_reg <= 1'b0;
gmii_tx_er_reg <= 1'b0; gmii_tx_er_reg <= 1'b0;
@ -378,6 +417,8 @@ always @(posedge clk) begin
frame_ptr_reg <= frame_ptr_next; frame_ptr_reg <= frame_ptr_next;
s_axis_tready_reg <= s_axis_tready_next; s_axis_tready_reg <= s_axis_tready_next;
m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next;
gmii_tx_en_reg <= gmii_tx_en_next; gmii_tx_en_reg <= gmii_tx_en_next;
gmii_tx_er_reg <= gmii_tx_er_next; gmii_tx_er_reg <= gmii_tx_er_next;
@ -393,6 +434,9 @@ always @(posedge clk) begin
end end
end end
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
mii_odd_reg <= mii_odd_next; mii_odd_reg <= mii_odd_next;
mii_msn_reg <= mii_msn_next; mii_msn_reg <= mii_msn_next;

View File

@ -29,34 +29,60 @@ THE SOFTWARE.
/* /*
* AXI4-Stream XGMII frame receiver (XGMII in, AXI out) * AXI4-Stream XGMII frame receiver (XGMII in, AXI out)
*/ */
module axis_xgmii_rx_32 module axis_xgmii_rx_32 #
( (
input wire clk, parameter DATA_WIDTH = 32,
input wire rst, parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter CTRL_WIDTH = (DATA_WIDTH/8),
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1
)
(
input wire clk,
input wire rst,
/* /*
* XGMII input * XGMII input
*/ */
input wire [31:0] xgmii_rxd, input wire [DATA_WIDTH-1:0] xgmii_rxd,
input wire [3:0] xgmii_rxc, input wire [CTRL_WIDTH-1:0] xgmii_rxc,
/* /*
* AXI output * AXI output
*/ */
output wire [31:0] m_axis_tdata, output wire [DATA_WIDTH-1:0] m_axis_tdata,
output wire [3:0] m_axis_tkeep, output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
output wire m_axis_tvalid, output wire m_axis_tvalid,
output wire m_axis_tlast, output wire m_axis_tlast,
output wire m_axis_tuser, output wire [USER_WIDTH-1:0] m_axis_tuser,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
/* /*
* Status * Status
*/ */
output wire start_packet, output wire start_packet,
output wire error_bad_frame, output wire error_bad_frame,
output wire error_bad_fcs output wire error_bad_fcs
); );
// bus width assertions
initial begin
if (DATA_WIDTH != 32) begin
$error("Error: Interface width must be 32");
$finish;
end
if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin
$error("Error: Interface requires byte (8-bit) granularity");
$finish;
end
end
localparam [7:0] localparam [7:0]
ETH_PRE = 8'h55, ETH_PRE = 8'h55,
ETH_SFD = 8'hD5; ETH_SFD = 8'hD5;
@ -81,16 +107,16 @@ reg update_crc;
reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next; reg [3:0] last_cycle_tkeep_reg = 4'd0, last_cycle_tkeep_next;
reg [31:0] xgmii_rxd_d0 = 32'd0; reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}};
reg [31:0] xgmii_rxd_d1 = 32'd0; reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}};
reg [31:0] xgmii_rxd_d2 = 32'd0; reg [DATA_WIDTH-1:0] xgmii_rxd_d2 = {DATA_WIDTH{1'b0}};
reg [3:0] xgmii_rxc_d0 = 4'd0; reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}};
reg [3:0] xgmii_rxc_d1 = 4'd0; reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}};
reg [3:0] xgmii_rxc_d2 = 4'd0; reg [CTRL_WIDTH-1:0] xgmii_rxc_d2 = {CTRL_WIDTH{1'b0}};
reg [31:0] m_axis_tdata_reg = 32'd0, m_axis_tdata_next; reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next;
reg [3:0] m_axis_tkeep_reg = 4'd0, m_axis_tkeep_next; reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next;
reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next;
reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next;
@ -99,6 +125,8 @@ reg start_packet_reg = 1'b0, start_packet_next;
reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next;
reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0, ptp_ts_next;
reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0; wire [31:0] crc_next0;
@ -120,7 +148,7 @@ assign m_axis_tdata = m_axis_tdata_reg;
assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tkeep = m_axis_tkeep_reg;
assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tvalid = m_axis_tvalid_reg;
assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tlast = m_axis_tlast_reg;
assign m_axis_tuser = m_axis_tuser_reg; assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_bad_frame = error_bad_frame_reg; assign error_bad_frame = error_bad_frame_reg;
@ -257,8 +285,8 @@ always @* begin
last_cycle_tkeep_next = last_cycle_tkeep_reg; last_cycle_tkeep_next = last_cycle_tkeep_reg;
m_axis_tdata_next = 32'd0; m_axis_tdata_next = {DATA_WIDTH{1'b0}};
m_axis_tkeep_next = 4'd0; m_axis_tkeep_next = {KEEP_WIDTH{1'b0}};
m_axis_tvalid_next = 1'b0; m_axis_tvalid_next = 1'b0;
m_axis_tlast_next = 1'b0; m_axis_tlast_next = 1'b0;
m_axis_tuser_next = 1'b0; m_axis_tuser_next = 1'b0;
@ -267,6 +295,8 @@ always @* begin
error_bad_frame_next = 1'b0; error_bad_frame_next = 1'b0;
error_bad_fcs_next = 1'b0; error_bad_fcs_next = 1'b0;
ptp_ts_next = ptp_ts_reg;
case (state_reg) case (state_reg)
STATE_IDLE: begin STATE_IDLE: begin
// idle state - wait for packet // idle state - wait for packet
@ -276,7 +306,7 @@ always @* begin
// start condition // start condition
if (control_masked) begin if (control_masked) begin
// control or error characters in first data word // control or error characters in first data word
m_axis_tdata_next = 32'd0; m_axis_tdata_next = {DATA_WIDTH{1'b0}};
m_axis_tkeep_next = 4'h1; m_axis_tkeep_next = 4'h1;
m_axis_tvalid_next = 1'b1; m_axis_tvalid_next = 1'b1;
m_axis_tlast_next = 1'b1; m_axis_tlast_next = 1'b1;
@ -295,6 +325,7 @@ always @* begin
STATE_PREAMBLE: begin STATE_PREAMBLE: begin
// drop preamble // drop preamble
update_crc = 1'b1; update_crc = 1'b1;
ptp_ts_next = ptp_ts;
start_packet_next = 1'b1; start_packet_next = 1'b1;
state_next = STATE_PAYLOAD; state_next = STATE_PAYLOAD;
end end
@ -379,8 +410,8 @@ always @(posedge clk) begin
crc_valid2_save <= 1'b0; crc_valid2_save <= 1'b0;
crc_valid3_save <= 1'b0; crc_valid3_save <= 1'b0;
xgmii_rxc_d0 <= 4'd0; xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}};
xgmii_rxc_d1 <= 4'd0; xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}};
end else begin end else begin
state_reg <= state_next; state_reg <= state_next;
@ -415,6 +446,8 @@ always @(posedge clk) begin
m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tlast_reg <= m_axis_tlast_next;
m_axis_tuser_reg <= m_axis_tuser_next; m_axis_tuser_reg <= m_axis_tuser_next;
ptp_ts_reg <= ptp_ts_next;
last_cycle_tkeep_reg <= last_cycle_tkeep_next; last_cycle_tkeep_reg <= last_cycle_tkeep_next;
detect_term_save <= detect_term; detect_term_save <= detect_term;

View File

@ -29,34 +29,62 @@ THE SOFTWARE.
/* /*
* AXI4-Stream XGMII frame receiver (XGMII in, AXI out) * AXI4-Stream XGMII frame receiver (XGMII in, AXI out)
*/ */
module axis_xgmii_rx_64 module axis_xgmii_rx_64 #
( (
input wire clk, parameter DATA_WIDTH = 64,
input wire rst, parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter CTRL_WIDTH = (DATA_WIDTH/8),
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1
)
(
input wire clk,
input wire rst,
/* /*
* XGMII input * XGMII input
*/ */
input wire [63:0] xgmii_rxd, input wire [DATA_WIDTH-1:0] xgmii_rxd,
input wire [7:0] xgmii_rxc, input wire [CTRL_WIDTH-1:0] xgmii_rxc,
/* /*
* AXI output * AXI output
*/ */
output wire [63:0] m_axis_tdata, output wire [DATA_WIDTH-1:0] m_axis_tdata,
output wire [7:0] m_axis_tkeep, output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
output wire m_axis_tvalid, output wire m_axis_tvalid,
output wire m_axis_tlast, output wire m_axis_tlast,
output wire m_axis_tuser, output wire [USER_WIDTH-1:0] m_axis_tuser,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
/* /*
* Status * Status
*/ */
output wire [1:0] start_packet, output wire [1:0] start_packet,
output wire error_bad_frame, output wire error_bad_frame,
output wire error_bad_fcs output wire error_bad_fcs
); );
// bus width assertions
initial begin
if (DATA_WIDTH != 64) begin
$error("Error: Interface width must be 64");
$finish;
end
if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin
$error("Error: Interface requires byte (8-bit) granularity");
$finish;
end
end
localparam [7:0] localparam [7:0]
ETH_PRE = 8'h55, ETH_PRE = 8'h55,
ETH_SFD = 8'hD5; ETH_SFD = 8'hD5;
@ -84,15 +112,15 @@ reg lanes_swapped = 1'b0;
reg [31:0] swap_rxd = 32'd0; reg [31:0] swap_rxd = 32'd0;
reg [3:0] swap_rxc = 4'd0; reg [3:0] swap_rxc = 4'd0;
reg [63:0] xgmii_rxd_d0 = 32'd0; reg [DATA_WIDTH-1:0] xgmii_rxd_d0 = {DATA_WIDTH{1'b0}};
reg [63:0] xgmii_rxd_d1 = 32'd0; reg [DATA_WIDTH-1:0] xgmii_rxd_d1 = {DATA_WIDTH{1'b0}};
reg [63:0] xgmii_rxd_crc = 32'd0; reg [DATA_WIDTH-1:0] xgmii_rxd_crc = {DATA_WIDTH{1'b0}};
reg [7:0] xgmii_rxc_d0 = 8'd0; reg [CTRL_WIDTH-1:0] xgmii_rxc_d0 = {CTRL_WIDTH{1'b0}};
reg [7:0] xgmii_rxc_d1 = 8'd0; reg [CTRL_WIDTH-1:0] xgmii_rxc_d1 = {CTRL_WIDTH{1'b0}};
reg [63:0] m_axis_tdata_reg = 64'd0, m_axis_tdata_next; reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next;
reg [7:0] m_axis_tkeep_reg = 8'd0, m_axis_tkeep_next; reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}, m_axis_tkeep_next;
reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next;
reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next;
reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next;
@ -101,6 +129,8 @@ reg [1:0] start_packet_reg = 2'b00;
reg error_bad_frame_reg = 1'b0, error_bad_frame_next; reg error_bad_frame_reg = 1'b0, error_bad_frame_next;
reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next;
reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0;
reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state = 32'hFFFFFFFF;
reg [31:0] crc_state3 = 32'hFFFFFFFF; reg [31:0] crc_state3 = 32'hFFFFFFFF;
@ -122,7 +152,7 @@ assign m_axis_tdata = m_axis_tdata_reg;
assign m_axis_tkeep = m_axis_tkeep_reg; assign m_axis_tkeep = m_axis_tkeep_reg;
assign m_axis_tvalid = m_axis_tvalid_reg; assign m_axis_tvalid = m_axis_tvalid_reg;
assign m_axis_tlast = m_axis_tlast_reg; assign m_axis_tlast = m_axis_tlast_reg;
assign m_axis_tuser = m_axis_tuser_reg; assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_bad_frame = error_bad_frame_reg; assign error_bad_frame = error_bad_frame_reg;
@ -295,8 +325,8 @@ always @* begin
last_cycle_tkeep_next = last_cycle_tkeep_reg; last_cycle_tkeep_next = last_cycle_tkeep_reg;
m_axis_tdata_next = 64'd0; m_axis_tdata_next = {DATA_WIDTH{1'b0}};
m_axis_tkeep_next = 8'd0; m_axis_tkeep_next = {KEEP_WIDTH{1'b0}};
m_axis_tvalid_next = 1'b0; m_axis_tvalid_next = 1'b0;
m_axis_tlast_next = 1'b0; m_axis_tlast_next = 1'b0;
m_axis_tuser_next = 1'b0; m_axis_tuser_next = 1'b0;
@ -313,7 +343,7 @@ always @* begin
// start condition // start condition
if (control_masked) begin if (control_masked) begin
// control or error characters in first data word // control or error characters in first data word
m_axis_tdata_next = 64'd0; m_axis_tdata_next = {DATA_WIDTH{1'b0}};
m_axis_tkeep_next = 8'h01; m_axis_tkeep_next = 8'h01;
m_axis_tvalid_next = 1'b1; m_axis_tvalid_next = 1'b1;
m_axis_tlast_next = 1'b1; m_axis_tlast_next = 1'b1;
@ -397,7 +427,7 @@ always @* begin
// start condition // start condition
if (control_masked) begin if (control_masked) begin
// control or error characters in first data word // control or error characters in first data word
m_axis_tdata_next = 64'd0; m_axis_tdata_next = {DATA_WIDTH{1'b0}};
m_axis_tkeep_next = 8'h01; m_axis_tkeep_next = 8'h01;
m_axis_tvalid_next = 1'b1; m_axis_tvalid_next = 1'b1;
m_axis_tlast_next = 1'b1; m_axis_tlast_next = 1'b1;
@ -430,8 +460,8 @@ always @(posedge clk) begin
crc_state3 <= 32'hFFFFFFFF; crc_state3 <= 32'hFFFFFFFF;
crc_valid7_save <= 1'b0; crc_valid7_save <= 1'b0;
xgmii_rxc_d0 <= 8'd0; xgmii_rxc_d0 <= {CTRL_WIDTH{1'b0}};
xgmii_rxc_d1 <= 8'd0; xgmii_rxc_d1 <= {CTRL_WIDTH{1'b0}};
lanes_swapped <= 1'b0; lanes_swapped <= 1'b0;
end else begin end else begin
@ -471,6 +501,28 @@ always @(posedge clk) begin
end end
end end
if (PTP_TS_WIDTH == 96 && $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
// ns field rollover
ptp_ts_reg[45:16] <= $signed({1'b0, ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
ptp_ts_reg[95:48] <= ptp_ts_reg[95:48] + 1;
end
if (xgmii_rxc[0] && xgmii_rxd[7:0] == XGMII_START) begin
if (PTP_TS_WIDTH == 96) begin
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
ptp_ts_reg[95:48] <= ptp_ts[95:48];
end else begin
ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
end
end else if (xgmii_rxc[4] && xgmii_rxd[39:32] == XGMII_START) begin
if (PTP_TS_WIDTH == 96) begin
ptp_ts_reg[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
ptp_ts_reg[95:48] <= ptp_ts[95:48];
end else begin
ptp_ts_reg <= ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
end
end
m_axis_tdata_reg <= m_axis_tdata_next; m_axis_tdata_reg <= m_axis_tdata_next;
m_axis_tkeep_reg <= m_axis_tkeep_next; m_axis_tkeep_reg <= m_axis_tkeep_next;
m_axis_tlast_reg <= m_axis_tlast_next; m_axis_tlast_reg <= m_axis_tlast_next;

View File

@ -31,42 +31,71 @@ THE SOFTWARE.
*/ */
module axis_xgmii_tx_32 # module axis_xgmii_tx_32 #
( (
parameter DATA_WIDTH = 32,
parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter CTRL_WIDTH = (DATA_WIDTH/8),
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter ENABLE_DIC = 1, parameter ENABLE_DIC = 1,
parameter MIN_FRAME_LENGTH = 64 parameter MIN_FRAME_LENGTH = 64,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter PTP_TAG_ENABLE = 0,
parameter PTP_TAG_WIDTH = 16,
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1
) )
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
/* /*
* AXI input * AXI input
*/ */
input wire [31:0] s_axis_tdata, input wire [DATA_WIDTH-1:0] s_axis_tdata,
input wire [3:0] s_axis_tkeep, input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
input wire s_axis_tvalid, input wire s_axis_tvalid,
output wire s_axis_tready, output wire s_axis_tready,
input wire s_axis_tlast, input wire s_axis_tlast,
input wire s_axis_tuser, input wire [USER_WIDTH-1:0] s_axis_tuser,
/* /*
* XGMII output * XGMII output
*/ */
output wire [31:0] xgmii_txd, output wire [DATA_WIDTH-1:0] xgmii_txd,
output wire [3:0] xgmii_txc, output wire [CTRL_WIDTH-1:0] xgmii_txc,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts,
output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag,
output wire m_axis_ptp_ts_valid,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay, input wire [7:0] ifg_delay,
/* /*
* Status * Status
*/ */
output wire start_packet, output wire start_packet,
output wire error_underflow output wire error_underflow
); );
// bus width assertions
initial begin
if (DATA_WIDTH != 32) begin
$error("Error: Interface width must be 32");
$finish;
end
if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin
$error("Error: Interface requires byte (8-bit) granularity");
$finish;
end
end
localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4;
localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfffc; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfffc;
localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0003; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0003;
@ -98,15 +127,15 @@ reg [2:0] state_reg = STATE_IDLE, state_next;
reg reset_crc; reg reset_crc;
reg update_crc; reg update_crc;
reg [31:0] s_axis_tdata_masked; reg [DATA_WIDTH-1:0] s_axis_tdata_masked;
reg [31:0] s_tdata_reg = 64'd0, s_tdata_next; reg [DATA_WIDTH-1:0] s_tdata_reg ={DATA_WIDTH{1'b0}}, s_tdata_next;
reg [3:0] s_tkeep_reg = 8'd0, s_tkeep_next; reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next;
reg [31:0] fcs_output_txd_0; reg [DATA_WIDTH-1:0] fcs_output_txd_0;
reg [31:0] fcs_output_txd_1; reg [DATA_WIDTH-1:0] fcs_output_txd_1;
reg [3:0] fcs_output_txc_0; reg [CTRL_WIDTH-1:0] fcs_output_txc_0;
reg [3:0] fcs_output_txc_1; reg [CTRL_WIDTH-1:0] fcs_output_txc_1;
reg [7:0] ifg_offset; reg [7:0] ifg_offset;
@ -119,6 +148,10 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next;
reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next;
reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0; wire [31:0] crc_next0;
@ -126,8 +159,8 @@ wire [31:0] crc_next1;
wire [31:0] crc_next2; wire [31:0] crc_next2;
wire [31:0] crc_next3; wire [31:0] crc_next3;
reg [31:0] xgmii_txd_reg = {4{XGMII_IDLE}}, xgmii_txd_next; reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next;
reg [3:0] xgmii_txc_reg = 4'b1111, xgmii_txc_next; reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next;
reg start_packet_reg = 1'b0, start_packet_next; reg start_packet_reg = 1'b0, start_packet_next;
reg error_underflow_reg = 1'b0, error_underflow_next; reg error_underflow_reg = 1'b0, error_underflow_next;
@ -137,6 +170,10 @@ assign s_axis_tready = s_axis_tready_reg;
assign xgmii_txd = xgmii_txd_reg; assign xgmii_txd = xgmii_txd_reg;
assign xgmii_txc = xgmii_txc_reg; assign xgmii_txc = xgmii_txc_reg;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0;
assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0;
assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_underflow = error_underflow_reg; assign error_underflow = error_underflow_reg;
@ -260,10 +297,10 @@ always @* begin
extra_cycle = 1'b1; extra_cycle = 1'b1;
end end
default: begin default: begin
fcs_output_txd_0 = {4{XGMII_ERROR}}; fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txd_1 = {4{XGMII_ERROR}}; fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txc_0 = 4'b1111; fcs_output_txc_0 = {CTRL_WIDTH{1'b1}};
fcs_output_txc_1 = 4'b1111; fcs_output_txc_1 = {CTRL_WIDTH{1'b1}};
ifg_offset = 8'd0; ifg_offset = 8'd0;
extra_cycle = 1'b0; extra_cycle = 1'b0;
end end
@ -286,9 +323,13 @@ always @* begin
s_tdata_next = s_tdata_reg; s_tdata_next = s_tdata_reg;
s_tkeep_next = s_tkeep_reg; s_tkeep_next = s_tkeep_reg;
m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
m_axis_ptp_ts_valid_next = 1'b0;
// XGMII idle // XGMII idle
xgmii_txd_next = {4{XGMII_IDLE}}; xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}};
xgmii_txc_next = 4'b1111; xgmii_txc_next = {CTRL_WIDTH{1'b1}};
start_packet_next = 1'b0; start_packet_next = 1'b0;
error_underflow_next = 1'b0; error_underflow_next = 1'b0;
@ -300,8 +341,8 @@ always @* begin
reset_crc = 1'b1; reset_crc = 1'b1;
// XGMII idle // XGMII idle
xgmii_txd_next = {4{XGMII_IDLE}}; xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}};
xgmii_txc_next = 4'b1111; xgmii_txc_next = {CTRL_WIDTH{1'b1}};
s_tdata_next = s_axis_tdata_masked; s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep; s_tkeep_next = s_axis_tkeep;
@ -327,6 +368,9 @@ always @* begin
xgmii_txd_next = {ETH_SFD, {3{ETH_PRE}}}; xgmii_txd_next = {ETH_SFD, {3{ETH_PRE}}};
xgmii_txc_next = 4'b0000; xgmii_txc_next = 4'b0000;
s_axis_tready_next = 1'b1; s_axis_tready_next = 1'b1;
m_axis_ptp_ts_next = ptp_ts;
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_next = 1'b1;
start_packet_next = 1'b1; start_packet_next = 1'b1;
state_next = STATE_PAYLOAD; state_next = STATE_PAYLOAD;
end end
@ -347,7 +391,7 @@ always @* begin
if (s_axis_tlast) begin if (s_axis_tlast) begin
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
s_axis_tready_next = 1'b0; s_axis_tready_next = 1'b0;
if (s_axis_tuser) begin if (s_axis_tuser[0]) begin
xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}}; xgmii_txd_next = {XGMII_TERM, {3{XGMII_ERROR}}};
xgmii_txc_next = 4'b1111; xgmii_txc_next = 4'b1111;
frame_ptr_next = 16'd0; frame_ptr_next = 16'd0;
@ -389,7 +433,7 @@ always @* begin
s_axis_tready_next = 1'b0; s_axis_tready_next = 1'b0;
xgmii_txd_next = s_tdata_reg; xgmii_txd_next = s_tdata_reg;
xgmii_txc_next = 4'b0000; xgmii_txc_next = {CTRL_WIDTH{1'b0}};
s_tdata_next = 32'd0; s_tdata_next = 32'd0;
s_tkeep_next = 4'hf; s_tkeep_next = 4'hf;
@ -537,8 +581,10 @@ always @(posedge clk) begin
s_axis_tready_reg <= 1'b0; s_axis_tready_reg <= 1'b0;
xgmii_txd_reg <= {4{XGMII_IDLE}}; m_axis_ptp_ts_valid_reg <= 1'b0;
xgmii_txc_reg <= 4'b1111;
xgmii_txd_reg <= {CTRL_WIDTH{XGMII_IDLE}};
xgmii_txc_reg <= {CTRL_WIDTH{1'b1}};
start_packet_reg <= 1'b0; start_packet_reg <= 1'b0;
error_underflow_reg <= 1'b0; error_underflow_reg <= 1'b0;
@ -553,6 +599,8 @@ always @(posedge clk) begin
deficit_idle_count_reg <= deficit_idle_count_next; deficit_idle_count_reg <= deficit_idle_count_next;
s_axis_tready_reg <= s_axis_tready_next; s_axis_tready_reg <= s_axis_tready_next;
m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next;
xgmii_txd_reg <= xgmii_txd_next; xgmii_txd_reg <= xgmii_txd_next;
xgmii_txc_reg <= xgmii_txc_next; xgmii_txc_reg <= xgmii_txc_next;
@ -570,6 +618,9 @@ always @(posedge clk) begin
s_tdata_reg <= s_tdata_next; s_tdata_reg <= s_tdata_next;
s_tkeep_reg <= s_tkeep_next; s_tkeep_reg <= s_tkeep_next;
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
end end
endmodule endmodule

View File

@ -31,42 +31,73 @@ THE SOFTWARE.
*/ */
module axis_xgmii_tx_64 # module axis_xgmii_tx_64 #
( (
parameter DATA_WIDTH = 64,
parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter CTRL_WIDTH = (DATA_WIDTH/8),
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter ENABLE_DIC = 1, parameter ENABLE_DIC = 1,
parameter MIN_FRAME_LENGTH = 64 parameter MIN_FRAME_LENGTH = 64,
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter PTP_TAG_ENABLE = 0,
parameter PTP_TAG_WIDTH = 16,
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1
) )
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
/* /*
* AXI input * AXI input
*/ */
input wire [63:0] s_axis_tdata, input wire [DATA_WIDTH-1:0] s_axis_tdata,
input wire [7:0] s_axis_tkeep, input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
input wire s_axis_tvalid, input wire s_axis_tvalid,
output wire s_axis_tready, output wire s_axis_tready,
input wire s_axis_tlast, input wire s_axis_tlast,
input wire s_axis_tuser, input wire [USER_WIDTH-1:0] s_axis_tuser,
/* /*
* XGMII output * XGMII output
*/ */
output wire [63:0] xgmii_txd, output wire [DATA_WIDTH-1:0] xgmii_txd,
output wire [7:0] xgmii_txc, output wire [CTRL_WIDTH-1:0] xgmii_txc,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts,
output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag,
output wire m_axis_ptp_ts_valid,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay, input wire [7:0] ifg_delay,
/* /*
* Status * Status
*/ */
output wire [1:0] start_packet, output wire [1:0] start_packet,
output wire error_underflow output wire error_underflow
); );
// bus width assertions
initial begin
if (DATA_WIDTH != 64) begin
$error("Error: Interface width must be 64");
$finish;
end
if (KEEP_WIDTH * 8 != DATA_WIDTH || CTRL_WIDTH * 8 != DATA_WIDTH) begin
$error("Error: Interface requires byte (8-bit) granularity");
$finish;
end
end
localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4; localparam MIN_FL_NOCRC = MIN_FRAME_LENGTH-4;
localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8; localparam MIN_FL_NOCRC_MS = MIN_FL_NOCRC & 16'hfff8;
localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007; localparam MIN_FL_NOCRC_LS = MIN_FL_NOCRC & 16'h0007;
@ -103,15 +134,15 @@ reg lanes_swapped = 1'b0;
reg [31:0] swap_txd = 32'd0; reg [31:0] swap_txd = 32'd0;
reg [3:0] swap_txc = 4'd0; reg [3:0] swap_txc = 4'd0;
reg [63:0] s_axis_tdata_masked; reg [DATA_WIDTH-1:0] s_axis_tdata_masked;
reg [63:0] s_tdata_reg = 64'd0, s_tdata_next; reg [DATA_WIDTH-1:0] s_tdata_reg = {DATA_WIDTH{1'b0}}, s_tdata_next;
reg [7:0] s_tkeep_reg = 8'd0, s_tkeep_next; reg [KEEP_WIDTH-1:0] s_tkeep_reg = {KEEP_WIDTH{1'b0}}, s_tkeep_next;
reg [63:0] fcs_output_txd_0; reg [DATA_WIDTH-1:0] fcs_output_txd_0;
reg [63:0] fcs_output_txd_1; reg [DATA_WIDTH-1:0] fcs_output_txd_1;
reg [7:0] fcs_output_txc_0; reg [CTRL_WIDTH-1:0] fcs_output_txc_0;
reg [7:0] fcs_output_txc_1; reg [CTRL_WIDTH-1:0] fcs_output_txc_1;
reg [7:0] ifg_offset; reg [7:0] ifg_offset;
@ -124,6 +155,11 @@ reg [1:0] deficit_idle_count_reg = 2'd0, deficit_idle_count_next;
reg s_axis_tready_reg = 1'b0, s_axis_tready_next; reg s_axis_tready_reg = 1'b0, s_axis_tready_next;
reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next;
reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next;
reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next;
reg m_axis_ptp_ts_valid_int_reg = 1'b0, m_axis_ptp_ts_valid_int_next;
reg [31:0] crc_state = 32'hFFFFFFFF; reg [31:0] crc_state = 32'hFFFFFFFF;
wire [31:0] crc_next0; wire [31:0] crc_next0;
@ -135,8 +171,8 @@ wire [31:0] crc_next5;
wire [31:0] crc_next6; wire [31:0] crc_next6;
wire [31:0] crc_next7; wire [31:0] crc_next7;
reg [63:0] xgmii_txd_reg = {8{XGMII_IDLE}}, xgmii_txd_next; reg [DATA_WIDTH-1:0] xgmii_txd_reg = {CTRL_WIDTH{XGMII_IDLE}}, xgmii_txd_next;
reg [7:0] xgmii_txc_reg = 8'b11111111, xgmii_txc_next; reg [CTRL_WIDTH-1:0] xgmii_txc_reg = {CTRL_WIDTH{1'b1}}, xgmii_txc_next;
reg start_packet_reg = 2'b00, start_packet_next; reg start_packet_reg = 2'b00, start_packet_next;
reg error_underflow_reg = 1'b0, error_underflow_next; reg error_underflow_reg = 1'b0, error_underflow_next;
@ -146,6 +182,10 @@ assign s_axis_tready = s_axis_tready_reg;
assign xgmii_txd = xgmii_txd_reg; assign xgmii_txd = xgmii_txd_reg;
assign xgmii_txc = xgmii_txc_reg; assign xgmii_txc = xgmii_txc_reg;
assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0;
assign m_axis_ptp_ts_tag = PTP_TS_ENABLE && PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0;
assign m_axis_ptp_ts_valid = PTP_TS_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0;
assign start_packet = start_packet_reg; assign start_packet = start_packet_reg;
assign error_underflow = error_underflow_reg; assign error_underflow = error_underflow_reg;
@ -369,10 +409,10 @@ always @* begin
extra_cycle = 1'b1; extra_cycle = 1'b1;
end end
default: begin default: begin
fcs_output_txd_0 = {8{XGMII_ERROR}}; fcs_output_txd_0 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txd_1 = {8{XGMII_ERROR}}; fcs_output_txd_1 = {CTRL_WIDTH{XGMII_ERROR}};
fcs_output_txc_0 = 8'b11111111; fcs_output_txc_0 = {CTRL_WIDTH{1'b1}};
fcs_output_txc_1 = 8'b11111111; fcs_output_txc_1 = {CTRL_WIDTH{1'b1}};
ifg_offset = 8'd0; ifg_offset = 8'd0;
extra_cycle = 1'b1; extra_cycle = 1'b1;
end end
@ -398,13 +438,27 @@ always @* begin
s_tdata_next = s_tdata_reg; s_tdata_next = s_tdata_reg;
s_tkeep_next = s_tkeep_reg; s_tkeep_next = s_tkeep_reg;
m_axis_ptp_ts_next = m_axis_ptp_ts_reg;
m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg;
m_axis_ptp_ts_valid_next = 1'b0;
m_axis_ptp_ts_valid_int_next = 1'b0;
// XGMII idle // XGMII idle
xgmii_txd_next = {8{XGMII_IDLE}}; xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}};
xgmii_txc_next = 8'b11111111; xgmii_txc_next = {CTRL_WIDTH{1'b1}};
start_packet_next = 2'b00; start_packet_next = 2'b00;
error_underflow_next = 1'b0; error_underflow_next = 1'b0;
if (m_axis_ptp_ts_valid_int_reg) begin
m_axis_ptp_ts_valid_next = 1'b1;
if (PTP_TS_WIDTH == 96 && $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000) > 0) begin
// ns field rollover
m_axis_ptp_ts_next[45:16] <= $signed({1'b0, m_axis_ptp_ts_reg[45:16]}) - $signed(31'd1000000000);
m_axis_ptp_ts_next[95:48] <= m_axis_ptp_ts_reg[95:48] + 1;
end
end
case (state_reg) case (state_reg)
STATE_IDLE: begin STATE_IDLE: begin
// idle state - wait for data // idle state - wait for data
@ -413,8 +467,8 @@ always @* begin
s_axis_tready_next = 1'b1; s_axis_tready_next = 1'b1;
// XGMII idle // XGMII idle
xgmii_txd_next = {8{XGMII_IDLE}}; xgmii_txd_next = {CTRL_WIDTH{XGMII_IDLE}};
xgmii_txc_next = 8'b11111111; xgmii_txc_next = {CTRL_WIDTH{1'b1}};
s_tdata_next = s_axis_tdata_masked; s_tdata_next = s_axis_tdata_masked;
s_tkeep_next = s_axis_tkeep; s_tkeep_next = s_axis_tkeep;
@ -424,10 +478,26 @@ always @* begin
if (ifg_count_reg > 8'd0) begin if (ifg_count_reg > 8'd0) begin
// need to send more idles - swap lanes // need to send more idles - swap lanes
swap_lanes = 1'b1; swap_lanes = 1'b1;
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48];
end else begin
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS) * 1.5;
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b10; start_packet_next = 2'b10;
end else begin end else begin
// no more idles - unswap // no more idles - unswap
unswap_lanes = 1'b1; unswap_lanes = 1'b1;
if (PTP_TS_WIDTH == 96) begin
m_axis_ptp_ts_next[45:0] <= ptp_ts[45:0] + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
m_axis_ptp_ts_next[95:48] <= ptp_ts[95:48];
end else begin
m_axis_ptp_ts_next = ptp_ts + (PTP_PERIOD_NS * 2**16 + PTP_PERIOD_FNS);
end
m_axis_ptp_ts_tag_next = s_axis_tuser >> 1;
m_axis_ptp_ts_valid_int_next = 1'b1;
start_packet_next = 2'b01; start_packet_next = 2'b01;
end end
xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START}; xgmii_txd_next = {ETH_SFD, {6{ETH_PRE}}, XGMII_START};
@ -458,7 +528,7 @@ always @* begin
if (s_axis_tlast) begin if (s_axis_tlast) begin
frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep); frame_ptr_next = frame_ptr_reg + keep2count(s_axis_tkeep);
s_axis_tready_next = 1'b0; s_axis_tready_next = 1'b0;
if (s_axis_tuser) begin if (s_axis_tuser[0]) begin
xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}}; xgmii_txd_next = {{3{XGMII_IDLE}}, XGMII_TERM, {4{XGMII_ERROR}}};
xgmii_txc_next = 8'b11111111; xgmii_txc_next = 8'b11111111;
frame_ptr_next = 16'd0; frame_ptr_next = 16'd0;
@ -500,7 +570,7 @@ always @* begin
s_axis_tready_next = 1'b0; s_axis_tready_next = 1'b0;
xgmii_txd_next = s_tdata_reg; xgmii_txd_next = s_tdata_reg;
xgmii_txc_next = 8'b00000000; xgmii_txc_next = {CTRL_WIDTH{1'b0}};
s_tdata_next = 64'd0; s_tdata_next = 64'd0;
s_tkeep_next = 8'hff; s_tkeep_next = 8'hff;
@ -654,8 +724,11 @@ always @(posedge clk) begin
s_axis_tready_reg <= 1'b0; s_axis_tready_reg <= 1'b0;
xgmii_txd_reg <= {8{XGMII_IDLE}}; m_axis_ptp_ts_valid_reg <= 1'b0;
xgmii_txc_reg <= 8'b11111111; m_axis_ptp_ts_valid_int_reg <= 1'b0;
xgmii_txd_reg <= {CTRL_WIDTH{XGMII_IDLE}};
xgmii_txc_reg <= {CTRL_WIDTH{1'b1}};
start_packet_reg <= 2'b00; start_packet_reg <= 2'b00;
error_underflow_reg <= 1'b0; error_underflow_reg <= 1'b0;
@ -672,6 +745,9 @@ always @(posedge clk) begin
deficit_idle_count_reg <= deficit_idle_count_next; deficit_idle_count_reg <= deficit_idle_count_next;
s_axis_tready_reg <= s_axis_tready_next; s_axis_tready_reg <= s_axis_tready_next;
m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next;
m_axis_ptp_ts_valid_int_reg <= m_axis_ptp_ts_valid_int_next;
start_packet_reg <= start_packet_next; start_packet_reg <= start_packet_next;
error_underflow_reg <= error_underflow_next; error_underflow_reg <= error_underflow_next;
@ -697,6 +773,9 @@ always @(posedge clk) begin
s_tdata_reg <= s_tdata_next; s_tdata_reg <= s_tdata_next;
s_tkeep_reg <= s_tkeep_next; s_tkeep_reg <= s_tkeep_next;
m_axis_ptp_ts_reg <= m_axis_ptp_ts_next;
m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next;
swap_txd <= xgmii_txd_next[63:32]; swap_txd <= xgmii_txd_next[63:32];
swap_txc <= xgmii_txc_next[7:4]; swap_txc <= xgmii_txc_next[7:4];
end end

View File

@ -36,54 +36,73 @@ module eth_mac_10g #
parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter CTRL_WIDTH = (DATA_WIDTH/8),
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter ENABLE_DIC = 1, parameter ENABLE_DIC = 1,
parameter MIN_FRAME_LENGTH = 64 parameter MIN_FRAME_LENGTH = 64,
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter TX_PTP_TS_ENABLE = 0,
parameter TX_PTP_TS_WIDTH = 96,
parameter TX_PTP_TAG_ENABLE = 0,
parameter TX_PTP_TAG_WIDTH = 16,
parameter RX_PTP_TS_ENABLE = 0,
parameter RX_PTP_TS_WIDTH = 96,
parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1,
parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1
) )
( (
input wire rx_clk, input wire rx_clk,
input wire rx_rst, input wire rx_rst,
input wire tx_clk, input wire tx_clk,
input wire tx_rst, input wire tx_rst,
/* /*
* AXI input * AXI input
*/ */
input wire [DATA_WIDTH-1:0] tx_axis_tdata, input wire [DATA_WIDTH-1:0] tx_axis_tdata,
input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, input wire [KEEP_WIDTH-1:0] tx_axis_tkeep,
input wire tx_axis_tvalid, input wire tx_axis_tvalid,
output wire tx_axis_tready, output wire tx_axis_tready,
input wire tx_axis_tlast, input wire tx_axis_tlast,
input wire tx_axis_tuser, input wire [TX_USER_WIDTH-1:0] tx_axis_tuser,
/* /*
* AXI output * AXI output
*/ */
output wire [DATA_WIDTH-1:0] rx_axis_tdata, output wire [DATA_WIDTH-1:0] rx_axis_tdata,
output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, output wire [KEEP_WIDTH-1:0] rx_axis_tkeep,
output wire rx_axis_tvalid, output wire rx_axis_tvalid,
output wire rx_axis_tlast, output wire rx_axis_tlast,
output wire rx_axis_tuser, output wire [RX_USER_WIDTH-1:0] rx_axis_tuser,
/* /*
* XGMII interface * XGMII interface
*/ */
input wire [DATA_WIDTH-1:0] xgmii_rxd, input wire [DATA_WIDTH-1:0] xgmii_rxd,
input wire [CTRL_WIDTH-1:0] xgmii_rxc, input wire [CTRL_WIDTH-1:0] xgmii_rxc,
output wire [DATA_WIDTH-1:0] xgmii_txd, output wire [DATA_WIDTH-1:0] xgmii_txd,
output wire [CTRL_WIDTH-1:0] xgmii_txc, output wire [CTRL_WIDTH-1:0] xgmii_txc,
/*
* PTP
*/
input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts,
input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts,
output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts,
output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag,
output wire tx_axis_ptp_ts_valid,
/* /*
* Status * Status
*/ */
output wire [1:0] tx_start_packet, output wire [1:0] tx_start_packet,
output wire tx_error_underflow, output wire tx_error_underflow,
output wire [1:0] rx_start_packet, output wire [1:0] rx_start_packet,
output wire rx_error_bad_frame, output wire rx_error_bad_frame,
output wire rx_error_bad_fcs, output wire rx_error_bad_fcs,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay input wire [7:0] ifg_delay
); );
// bus width assertions // bus width assertions
@ -103,7 +122,16 @@ generate
if (DATA_WIDTH == 64) begin if (DATA_WIDTH == 64) begin
axis_xgmii_rx_64 axis_xgmii_rx_64 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.USER_WIDTH(RX_USER_WIDTH)
)
axis_xgmii_rx_inst ( axis_xgmii_rx_inst (
.clk(rx_clk), .clk(rx_clk),
.rst(rx_rst), .rst(rx_rst),
@ -114,15 +142,26 @@ axis_xgmii_rx_inst (
.m_axis_tvalid(rx_axis_tvalid), .m_axis_tvalid(rx_axis_tvalid),
.m_axis_tlast(rx_axis_tlast), .m_axis_tlast(rx_axis_tlast),
.m_axis_tuser(rx_axis_tuser), .m_axis_tuser(rx_axis_tuser),
.ptp_ts(rx_ptp_ts),
.start_packet(rx_start_packet), .start_packet(rx_start_packet),
.error_bad_frame(rx_error_bad_frame), .error_bad_frame(rx_error_bad_frame),
.error_bad_fcs(rx_error_bad_fcs) .error_bad_fcs(rx_error_bad_fcs)
); );
axis_xgmii_tx_64 #( axis_xgmii_tx_64 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.USER_WIDTH(TX_USER_WIDTH)
) )
axis_xgmii_tx_inst ( axis_xgmii_tx_inst (
.clk(tx_clk), .clk(tx_clk),
@ -135,6 +174,10 @@ axis_xgmii_tx_inst (
.s_axis_tuser(tx_axis_tuser), .s_axis_tuser(tx_axis_tuser),
.xgmii_txd(xgmii_txd), .xgmii_txd(xgmii_txd),
.xgmii_txc(xgmii_txc), .xgmii_txc(xgmii_txc),
.ptp_ts(tx_ptp_ts),
.m_axis_ptp_ts(tx_axis_ptp_ts),
.m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),
.start_packet(tx_start_packet), .start_packet(tx_start_packet),
.error_underflow(tx_error_underflow) .error_underflow(tx_error_underflow)
@ -142,7 +185,14 @@ axis_xgmii_tx_inst (
end else begin end else begin
axis_xgmii_rx_32 axis_xgmii_rx_32 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.USER_WIDTH(RX_USER_WIDTH)
)
axis_xgmii_rx_inst ( axis_xgmii_rx_inst (
.clk(rx_clk), .clk(rx_clk),
.rst(rx_rst), .rst(rx_rst),
@ -153,7 +203,8 @@ axis_xgmii_rx_inst (
.m_axis_tvalid(rx_axis_tvalid), .m_axis_tvalid(rx_axis_tvalid),
.m_axis_tlast(rx_axis_tlast), .m_axis_tlast(rx_axis_tlast),
.m_axis_tuser(rx_axis_tuser), .m_axis_tuser(rx_axis_tuser),
.start_packet(rx_start_packet), .ptp_ts(rx_ptp_ts),
.start_packet(rx_start_packet[0]),
.error_bad_frame(rx_error_bad_frame), .error_bad_frame(rx_error_bad_frame),
.error_bad_fcs(rx_error_bad_fcs) .error_bad_fcs(rx_error_bad_fcs)
); );
@ -161,9 +212,17 @@ axis_xgmii_rx_inst (
assign rx_start_packet[1] = 1'b0; assign rx_start_packet[1] = 1'b0;
axis_xgmii_tx_32 #( axis_xgmii_tx_32 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.USER_WIDTH(TX_USER_WIDTH)
) )
axis_xgmii_tx_inst ( axis_xgmii_tx_inst (
.clk(tx_clk), .clk(tx_clk),
@ -176,8 +235,12 @@ axis_xgmii_tx_inst (
.s_axis_tuser(tx_axis_tuser), .s_axis_tuser(tx_axis_tuser),
.xgmii_txd(xgmii_txd), .xgmii_txd(xgmii_txd),
.xgmii_txc(xgmii_txc), .xgmii_txc(xgmii_txc),
.ptp_ts(tx_ptp_ts),
.m_axis_ptp_ts(tx_axis_ptp_ts),
.m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),
.start_packet(tx_start_packet) .start_packet(tx_start_packet[0])
); );
assign tx_start_packet[1] = 1'b0; assign tx_start_packet[1] = 1'b0;

View File

@ -31,66 +31,89 @@ THE SOFTWARE.
*/ */
module eth_mac_1g # module eth_mac_1g #
( (
parameter DATA_WIDTH = 8,
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter MIN_FRAME_LENGTH = 64 parameter MIN_FRAME_LENGTH = 64,
parameter TX_PTP_TS_ENABLE = 0,
parameter TX_PTP_TS_WIDTH = 96,
parameter TX_PTP_TAG_ENABLE = 0,
parameter TX_PTP_TAG_WIDTH = 16,
parameter RX_PTP_TS_ENABLE = 0,
parameter RX_PTP_TS_WIDTH = 96,
parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1,
parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1
) )
( (
input wire rx_clk, input wire rx_clk,
input wire rx_rst, input wire rx_rst,
input wire tx_clk, input wire tx_clk,
input wire tx_rst, input wire tx_rst,
/* /*
* AXI input * AXI input
*/ */
input wire [7:0] tx_axis_tdata, input wire [DATA_WIDTH-1:0] tx_axis_tdata,
input wire tx_axis_tvalid, input wire tx_axis_tvalid,
output wire tx_axis_tready, output wire tx_axis_tready,
input wire tx_axis_tlast, input wire tx_axis_tlast,
input wire tx_axis_tuser, input wire [TX_USER_WIDTH-1:0] tx_axis_tuser,
/* /*
* AXI output * AXI output
*/ */
output wire [7:0] rx_axis_tdata, output wire [DATA_WIDTH-1:0] rx_axis_tdata,
output wire rx_axis_tvalid, output wire rx_axis_tvalid,
output wire rx_axis_tlast, output wire rx_axis_tlast,
output wire rx_axis_tuser, output wire [RX_USER_WIDTH-1:0] rx_axis_tuser,
/* /*
* GMII interface * GMII interface
*/ */
input wire [7:0] gmii_rxd, input wire [DATA_WIDTH-1:0] gmii_rxd,
input wire gmii_rx_dv, input wire gmii_rx_dv,
input wire gmii_rx_er, input wire gmii_rx_er,
output wire [7:0] gmii_txd, output wire [DATA_WIDTH-1:0] gmii_txd,
output wire gmii_tx_en, output wire gmii_tx_en,
output wire gmii_tx_er, output wire gmii_tx_er,
/*
* PTP
*/
input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts,
input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts,
output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts,
output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag,
output wire tx_axis_ptp_ts_valid,
/* /*
* Control * Control
*/ */
input wire rx_clk_enable, input wire rx_clk_enable,
input wire tx_clk_enable, input wire tx_clk_enable,
input wire rx_mii_select, input wire rx_mii_select,
input wire tx_mii_select, input wire tx_mii_select,
/* /*
* Status * Status
*/ */
output wire tx_start_packet, output wire tx_start_packet,
output wire tx_error_underflow, output wire tx_error_underflow,
output wire rx_start_packet, output wire rx_start_packet,
output wire rx_error_bad_frame, output wire rx_error_bad_frame,
output wire rx_error_bad_fcs, output wire rx_error_bad_fcs,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay input wire [7:0] ifg_delay
); );
axis_gmii_rx axis_gmii_rx #(
.DATA_WIDTH(DATA_WIDTH),
.PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.USER_WIDTH(RX_USER_WIDTH)
)
axis_gmii_rx_inst ( axis_gmii_rx_inst (
.clk(rx_clk), .clk(rx_clk),
.rst(rx_rst), .rst(rx_rst),
@ -101,6 +124,7 @@ axis_gmii_rx_inst (
.m_axis_tvalid(rx_axis_tvalid), .m_axis_tvalid(rx_axis_tvalid),
.m_axis_tlast(rx_axis_tlast), .m_axis_tlast(rx_axis_tlast),
.m_axis_tuser(rx_axis_tuser), .m_axis_tuser(rx_axis_tuser),
.ptp_ts(rx_ptp_ts),
.clk_enable(rx_clk_enable), .clk_enable(rx_clk_enable),
.mii_select(rx_mii_select), .mii_select(rx_mii_select),
.start_packet(rx_start_packet), .start_packet(rx_start_packet),
@ -109,8 +133,14 @@ axis_gmii_rx_inst (
); );
axis_gmii_tx #( axis_gmii_tx #(
.DATA_WIDTH(DATA_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.USER_WIDTH(TX_USER_WIDTH)
) )
axis_gmii_tx_inst ( axis_gmii_tx_inst (
.clk(tx_clk), .clk(tx_clk),
@ -123,6 +153,10 @@ axis_gmii_tx_inst (
.gmii_txd(gmii_txd), .gmii_txd(gmii_txd),
.gmii_tx_en(gmii_tx_en), .gmii_tx_en(gmii_tx_en),
.gmii_tx_er(gmii_tx_er), .gmii_tx_er(gmii_tx_er),
.ptp_ts(tx_ptp_ts),
.m_axis_ptp_ts(tx_axis_ptp_ts),
.m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.clk_enable(tx_clk_enable), .clk_enable(tx_clk_enable),
.mii_select(tx_mii_select), .mii_select(tx_mii_select),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),

View File

@ -38,6 +38,16 @@ module eth_mac_phy_10g #
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter ENABLE_DIC = 1, parameter ENABLE_DIC = 1,
parameter MIN_FRAME_LENGTH = 64, parameter MIN_FRAME_LENGTH = 64,
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter TX_PTP_TS_ENABLE = 0,
parameter TX_PTP_TS_WIDTH = 96,
parameter TX_PTP_TAG_ENABLE = 0,
parameter TX_PTP_TAG_WIDTH = 16,
parameter RX_PTP_TS_ENABLE = 0,
parameter RX_PTP_TS_WIDTH = 96,
parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1,
parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1,
parameter BIT_REVERSE = 0, parameter BIT_REVERSE = 0,
parameter SCRAMBLER_DISABLE = 0, parameter SCRAMBLER_DISABLE = 0,
parameter PRBS31_ENABLE = 0, parameter PRBS31_ENABLE = 0,
@ -45,58 +55,67 @@ module eth_mac_phy_10g #
parameter COUNT_125US = 125000/6.4 parameter COUNT_125US = 125000/6.4
) )
( (
input wire rx_clk, input wire rx_clk,
input wire rx_rst, input wire rx_rst,
input wire tx_clk, input wire tx_clk,
input wire tx_rst, input wire tx_rst,
/* /*
* AXI input * AXI input
*/ */
input wire [DATA_WIDTH-1:0] tx_axis_tdata, input wire [DATA_WIDTH-1:0] tx_axis_tdata,
input wire [KEEP_WIDTH-1:0] tx_axis_tkeep, input wire [KEEP_WIDTH-1:0] tx_axis_tkeep,
input wire tx_axis_tvalid, input wire tx_axis_tvalid,
output wire tx_axis_tready, output wire tx_axis_tready,
input wire tx_axis_tlast, input wire tx_axis_tlast,
input wire tx_axis_tuser, input wire [TX_USER_WIDTH-1:0] tx_axis_tuser,
/* /*
* AXI output * AXI output
*/ */
output wire [DATA_WIDTH-1:0] rx_axis_tdata, output wire [DATA_WIDTH-1:0] rx_axis_tdata,
output wire [KEEP_WIDTH-1:0] rx_axis_tkeep, output wire [KEEP_WIDTH-1:0] rx_axis_tkeep,
output wire rx_axis_tvalid, output wire rx_axis_tvalid,
output wire rx_axis_tlast, output wire rx_axis_tlast,
output wire rx_axis_tuser, output wire [RX_USER_WIDTH-1:0] rx_axis_tuser,
/* /*
* SERDES interface * SERDES interface
*/ */
output wire [DATA_WIDTH-1:0] serdes_tx_data, output wire [DATA_WIDTH-1:0] serdes_tx_data,
output wire [HDR_WIDTH-1:0] serdes_tx_hdr, output wire [HDR_WIDTH-1:0] serdes_tx_hdr,
input wire [DATA_WIDTH-1:0] serdes_rx_data, input wire [DATA_WIDTH-1:0] serdes_rx_data,
input wire [HDR_WIDTH-1:0] serdes_rx_hdr, input wire [HDR_WIDTH-1:0] serdes_rx_hdr,
output wire serdes_rx_bitslip, output wire serdes_rx_bitslip,
/*
* PTP
*/
input wire [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts,
input wire [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts,
output wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts,
output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag,
output wire tx_axis_ptp_ts_valid,
/* /*
* Status * Status
*/ */
output wire [1:0] tx_start_packet, output wire [1:0] tx_start_packet,
output wire tx_error_underflow, output wire tx_error_underflow,
output wire [1:0] rx_start_packet, output wire [1:0] rx_start_packet,
output wire [6:0] rx_error_count, output wire [6:0] rx_error_count,
output wire rx_error_bad_frame, output wire rx_error_bad_frame,
output wire rx_error_bad_fcs, output wire rx_error_bad_fcs,
output wire rx_bad_block, output wire rx_bad_block,
output wire rx_block_lock, output wire rx_block_lock,
output wire rx_high_ber, output wire rx_high_ber,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay, input wire [7:0] ifg_delay,
input wire tx_prbs31_enable, input wire tx_prbs31_enable,
input wire rx_prbs31_enable input wire rx_prbs31_enable
); );
eth_mac_phy_10g_rx #( eth_mac_phy_10g_rx #(
@ -104,6 +123,11 @@ eth_mac_phy_10g_rx #(
.KEEP_WIDTH(KEEP_WIDTH), .KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH), .CTRL_WIDTH(CTRL_WIDTH),
.HDR_WIDTH(HDR_WIDTH), .HDR_WIDTH(HDR_WIDTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.USER_WIDTH(RX_USER_WIDTH),
.BIT_REVERSE(BIT_REVERSE), .BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
.PRBS31_ENABLE(PRBS31_ENABLE), .PRBS31_ENABLE(PRBS31_ENABLE),
@ -121,6 +145,7 @@ eth_mac_phy_10g_rx_inst (
.serdes_rx_data(serdes_rx_data), .serdes_rx_data(serdes_rx_data),
.serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr(serdes_rx_hdr),
.serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_bitslip(serdes_rx_bitslip),
.ptp_ts(rx_ptp_ts),
.rx_start_packet(rx_start_packet), .rx_start_packet(rx_start_packet),
.rx_error_count(rx_error_count), .rx_error_count(rx_error_count),
.rx_error_bad_frame(rx_error_bad_frame), .rx_error_bad_frame(rx_error_bad_frame),
@ -139,6 +164,13 @@ eth_mac_phy_10g_tx #(
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.USER_WIDTH(TX_USER_WIDTH),
.BIT_REVERSE(BIT_REVERSE), .BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
.PRBS31_ENABLE(PRBS31_ENABLE) .PRBS31_ENABLE(PRBS31_ENABLE)
@ -154,6 +186,10 @@ eth_mac_phy_10g_tx_inst (
.s_axis_tuser(tx_axis_tuser), .s_axis_tuser(tx_axis_tuser),
.serdes_tx_data(serdes_tx_data), .serdes_tx_data(serdes_tx_data),
.serdes_tx_hdr(serdes_tx_hdr), .serdes_tx_hdr(serdes_tx_hdr),
.ptp_ts(tx_ptp_ts),
.m_axis_ptp_ts(tx_axis_ptp_ts),
.m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.tx_start_packet(tx_start_packet), .tx_start_packet(tx_start_packet),
.tx_error_underflow(tx_error_underflow), .tx_error_underflow(tx_error_underflow),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),

View File

@ -35,6 +35,11 @@ module eth_mac_phy_10g_rx #
parameter KEEP_WIDTH = (DATA_WIDTH/8), parameter KEEP_WIDTH = (DATA_WIDTH/8),
parameter CTRL_WIDTH = (DATA_WIDTH/8), parameter CTRL_WIDTH = (DATA_WIDTH/8),
parameter HDR_WIDTH = (DATA_WIDTH/32), parameter HDR_WIDTH = (DATA_WIDTH/32),
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1,
parameter BIT_REVERSE = 0, parameter BIT_REVERSE = 0,
parameter SCRAMBLER_DISABLE = 0, parameter SCRAMBLER_DISABLE = 0,
parameter PRBS31_ENABLE = 0, parameter PRBS31_ENABLE = 0,
@ -42,40 +47,45 @@ module eth_mac_phy_10g_rx #
parameter COUNT_125US = 125000/6.4 parameter COUNT_125US = 125000/6.4
) )
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
/* /*
* AXI output * AXI output
*/ */
output wire [DATA_WIDTH-1:0] m_axis_tdata, output wire [DATA_WIDTH-1:0] m_axis_tdata,
output wire [KEEP_WIDTH-1:0] m_axis_tkeep, output wire [KEEP_WIDTH-1:0] m_axis_tkeep,
output wire m_axis_tvalid, output wire m_axis_tvalid,
output wire m_axis_tlast, output wire m_axis_tlast,
output wire m_axis_tuser, output wire [USER_WIDTH-1:0] m_axis_tuser,
/* /*
* SERDES interface * SERDES interface
*/ */
input wire [DATA_WIDTH-1:0] serdes_rx_data, input wire [DATA_WIDTH-1:0] serdes_rx_data,
input wire [HDR_WIDTH-1:0] serdes_rx_hdr, input wire [HDR_WIDTH-1:0] serdes_rx_hdr,
output wire serdes_rx_bitslip, output wire serdes_rx_bitslip,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
/* /*
* Status * Status
*/ */
output wire [1:0] rx_start_packet, output wire [1:0] rx_start_packet,
output wire [6:0] rx_error_count, output wire [6:0] rx_error_count,
output wire rx_error_bad_frame, output wire rx_error_bad_frame,
output wire rx_error_bad_fcs, output wire rx_error_bad_fcs,
output wire rx_bad_block, output wire rx_bad_block,
output wire rx_block_lock, output wire rx_block_lock,
output wire rx_high_ber, output wire rx_high_ber,
/* /*
* Configuration * Configuration
*/ */
input wire rx_prbs31_enable input wire rx_prbs31_enable
); );
// bus width assertions // bus width assertions
@ -126,7 +136,12 @@ eth_phy_10g_rx_if_inst (
axis_baser_rx_64 #( axis_baser_rx_64 #(
.DATA_WIDTH(DATA_WIDTH), .DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH), .KEEP_WIDTH(KEEP_WIDTH),
.HDR_WIDTH(HDR_WIDTH) .HDR_WIDTH(HDR_WIDTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.USER_WIDTH(USER_WIDTH)
) )
axis_baser_rx_inst ( axis_baser_rx_inst (
.clk(clk), .clk(clk),
@ -138,6 +153,7 @@ axis_baser_rx_inst (
.m_axis_tvalid(m_axis_tvalid), .m_axis_tvalid(m_axis_tvalid),
.m_axis_tlast(m_axis_tlast), .m_axis_tlast(m_axis_tlast),
.m_axis_tuser(m_axis_tuser), .m_axis_tuser(m_axis_tuser),
.ptp_ts(ptp_ts),
.start_packet(rx_start_packet), .start_packet(rx_start_packet),
.error_bad_frame(rx_error_bad_frame), .error_bad_frame(rx_error_bad_frame),
.error_bad_fcs(rx_error_bad_fcs), .error_bad_fcs(rx_error_bad_fcs),

View File

@ -38,41 +38,56 @@ module eth_mac_phy_10g_tx #
parameter ENABLE_PADDING = 1, parameter ENABLE_PADDING = 1,
parameter ENABLE_DIC = 1, parameter ENABLE_DIC = 1,
parameter MIN_FRAME_LENGTH = 64, parameter MIN_FRAME_LENGTH = 64,
parameter PTP_PERIOD_NS = 4'h6,
parameter PTP_PERIOD_FNS = 16'h6666,
parameter PTP_TS_ENABLE = 0,
parameter PTP_TS_WIDTH = 96,
parameter PTP_TAG_ENABLE = 0,
parameter PTP_TAG_WIDTH = 16,
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1,
parameter BIT_REVERSE = 0, parameter BIT_REVERSE = 0,
parameter SCRAMBLER_DISABLE = 0, parameter SCRAMBLER_DISABLE = 0,
parameter PRBS31_ENABLE = 0 parameter PRBS31_ENABLE = 0
) )
( (
input wire clk, input wire clk,
input wire rst, input wire rst,
/* /*
* AXI input * AXI input
*/ */
input wire [DATA_WIDTH-1:0] s_axis_tdata, input wire [DATA_WIDTH-1:0] s_axis_tdata,
input wire [KEEP_WIDTH-1:0] s_axis_tkeep, input wire [KEEP_WIDTH-1:0] s_axis_tkeep,
input wire s_axis_tvalid, input wire s_axis_tvalid,
output wire s_axis_tready, output wire s_axis_tready,
input wire s_axis_tlast, input wire s_axis_tlast,
input wire s_axis_tuser, input wire [USER_WIDTH-1:0] s_axis_tuser,
/* /*
* SERDES interface * SERDES interface
*/ */
output wire [DATA_WIDTH-1:0] serdes_tx_data, output wire [DATA_WIDTH-1:0] serdes_tx_data,
output wire [HDR_WIDTH-1:0] serdes_tx_hdr, output wire [HDR_WIDTH-1:0] serdes_tx_hdr,
/*
* PTP
*/
input wire [PTP_TS_WIDTH-1:0] ptp_ts,
output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts,
output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag,
output wire m_axis_ptp_ts_valid,
/* /*
* Status * Status
*/ */
output wire [1:0] tx_start_packet, output wire [1:0] tx_start_packet,
output wire tx_error_underflow, output wire tx_error_underflow,
/* /*
* Configuration * Configuration
*/ */
input wire [7:0] ifg_delay, input wire [7:0] ifg_delay,
input wire tx_prbs31_enable input wire tx_prbs31_enable
); );
// bus width assertions // bus width assertions
@ -102,7 +117,14 @@ axis_baser_tx_64 #(
.HDR_WIDTH(HDR_WIDTH), .HDR_WIDTH(HDR_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.PTP_TAG_ENABLE(PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(PTP_TAG_WIDTH),
.USER_WIDTH(USER_WIDTH)
) )
axis_baser_tx_inst ( axis_baser_tx_inst (
.clk(clk), .clk(clk),
@ -115,6 +137,10 @@ axis_baser_tx_inst (
.s_axis_tuser(s_axis_tuser), .s_axis_tuser(s_axis_tuser),
.encoded_tx_data(encoded_tx_data), .encoded_tx_data(encoded_tx_data),
.encoded_tx_hdr(encoded_tx_hdr), .encoded_tx_hdr(encoded_tx_hdr),
.ptp_ts(ptp_ts),
.m_axis_ptp_ts(m_axis_ptp_ts),
.m_axis_ptp_ts_tag(m_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(m_axis_ptp_ts_valid),
.start_packet(tx_start_packet), .start_packet(tx_start_packet),
.error_underflow(tx_error_underflow), .error_underflow(tx_error_underflow),
.ifg_delay(ifg_delay) .ifg_delay(ifg_delay)

View File

@ -50,6 +50,11 @@ def bench():
DATA_WIDTH = 64 DATA_WIDTH = 64
KEEP_WIDTH = (DATA_WIDTH/8) KEEP_WIDTH = (DATA_WIDTH/8)
HDR_WIDTH = 2 HDR_WIDTH = 2
PTP_PERIOD_NS = 0x6
PTP_PERIOD_FNS = 0x6666
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
@ -58,13 +63,14 @@ def bench():
encoded_rx_data = Signal(intbv(0)[DATA_WIDTH:]) encoded_rx_data = Signal(intbv(0)[DATA_WIDTH:])
encoded_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) encoded_rx_hdr = Signal(intbv(1)[HDR_WIDTH:])
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
# Outputs # Outputs
m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:]) m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
m_axis_tvalid = Signal(bool(0)) m_axis_tvalid = Signal(bool(0))
m_axis_tlast = Signal(bool(0)) m_axis_tlast = Signal(bool(0))
m_axis_tuser = Signal(bool(0)) m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
start_packet = Signal(intbv(0)[2:]) start_packet = Signal(intbv(0)[2:])
error_bad_frame = Signal(bool(0)) error_bad_frame = Signal(bool(0))
error_bad_fcs = Signal(bool(0)) error_bad_fcs = Signal(bool(0))
@ -110,6 +116,7 @@ def bench():
m_axis_tvalid=m_axis_tvalid, m_axis_tvalid=m_axis_tvalid,
m_axis_tlast=m_axis_tlast, m_axis_tlast=m_axis_tlast,
m_axis_tuser=m_axis_tuser, m_axis_tuser=m_axis_tuser,
ptp_ts=ptp_ts,
start_packet=start_packet, start_packet=start_packet,
error_bad_frame=error_bad_frame, error_bad_frame=error_bad_frame,
error_bad_fcs=error_bad_fcs, error_bad_fcs=error_bad_fcs,

View File

@ -35,6 +35,11 @@ module test_axis_baser_rx_64;
parameter DATA_WIDTH = 64; parameter DATA_WIDTH = 64;
parameter KEEP_WIDTH = (DATA_WIDTH/8); parameter KEEP_WIDTH = (DATA_WIDTH/8);
parameter HDR_WIDTH = 2; parameter HDR_WIDTH = 2;
parameter PTP_PERIOD_NS = 4'h6;
parameter PTP_PERIOD_FNS = 16'h6666;
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
@ -43,13 +48,14 @@ reg [7:0] current_test = 0;
reg [DATA_WIDTH-1:0] encoded_rx_data = 0; reg [DATA_WIDTH-1:0] encoded_rx_data = 0;
reg [HDR_WIDTH-1:0] encoded_rx_hdr = 1; reg [HDR_WIDTH-1:0] encoded_rx_hdr = 1;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
// Outputs // Outputs
wire [DATA_WIDTH-1:0] m_axis_tdata; wire [DATA_WIDTH-1:0] m_axis_tdata;
wire [KEEP_WIDTH-1:0] m_axis_tkeep; wire [KEEP_WIDTH-1:0] m_axis_tkeep;
wire m_axis_tvalid; wire m_axis_tvalid;
wire m_axis_tlast; wire m_axis_tlast;
wire m_axis_tuser; wire [USER_WIDTH-1:0] m_axis_tuser;
wire [1:0] start_packet; wire [1:0] start_packet;
wire error_bad_frame; wire error_bad_frame;
wire error_bad_fcs; wire error_bad_fcs;
@ -62,7 +68,8 @@ initial begin
rst, rst,
current_test, current_test,
encoded_rx_data, encoded_rx_data,
encoded_rx_hdr encoded_rx_hdr,
ptp_ts
); );
$to_myhdl( $to_myhdl(
m_axis_tdata, m_axis_tdata,
@ -84,7 +91,12 @@ end
axis_baser_rx_64 #( axis_baser_rx_64 #(
.DATA_WIDTH(DATA_WIDTH), .DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH), .KEEP_WIDTH(KEEP_WIDTH),
.HDR_WIDTH(HDR_WIDTH) .HDR_WIDTH(HDR_WIDTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.USER_WIDTH(USER_WIDTH)
) )
UUT ( UUT (
.clk(clk), .clk(clk),
@ -96,6 +108,7 @@ UUT (
.m_axis_tvalid(m_axis_tvalid), .m_axis_tvalid(m_axis_tvalid),
.m_axis_tlast(m_axis_tlast), .m_axis_tlast(m_axis_tlast),
.m_axis_tuser(m_axis_tuser), .m_axis_tuser(m_axis_tuser),
.ptp_ts(ptp_ts),
.start_packet(start_packet), .start_packet(start_packet),
.error_bad_frame(error_bad_frame), .error_bad_frame(error_bad_frame),
.error_bad_fcs(error_bad_fcs), .error_bad_fcs(error_bad_fcs),

View File

@ -52,6 +52,13 @@ def bench():
ENABLE_PADDING = 1 ENABLE_PADDING = 1
ENABLE_DIC = 1 ENABLE_DIC = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
PTP_PERIOD_NS = 0x6
PTP_PERIOD_FNS = 0x6666
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
PTP_TAG_ENABLE = 0
PTP_TAG_WIDTH = 16
USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
@ -62,13 +69,17 @@ def bench():
s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
s_axis_tvalid = Signal(bool(0)) s_axis_tvalid = Signal(bool(0))
s_axis_tlast = Signal(bool(0)) s_axis_tlast = Signal(bool(0))
s_axis_tuser = Signal(bool(0)) s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
ifg_delay = Signal(intbv(0)[8:]) ifg_delay = Signal(intbv(0)[8:])
# Outputs # Outputs
s_axis_tready = Signal(bool(0)) s_axis_tready = Signal(bool(0))
encoded_tx_data = Signal(intbv(0)[DATA_WIDTH:]) encoded_tx_data = Signal(intbv(0)[DATA_WIDTH:])
encoded_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) encoded_tx_hdr = Signal(intbv(1)[HDR_WIDTH:])
m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
m_axis_ptp_ts_valid = Signal(bool(0))
start_packet = Signal(intbv(0)[2:]) start_packet = Signal(intbv(0)[2:])
error_underflow = Signal(bool(0)) error_underflow = Signal(bool(0))
@ -117,6 +128,10 @@ def bench():
s_axis_tuser=s_axis_tuser, s_axis_tuser=s_axis_tuser,
encoded_tx_data=encoded_tx_data, encoded_tx_data=encoded_tx_data,
encoded_tx_hdr=encoded_tx_hdr, encoded_tx_hdr=encoded_tx_hdr,
ptp_ts=ptp_ts,
m_axis_ptp_ts=m_axis_ptp_ts,
m_axis_ptp_ts_tag=m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid=m_axis_ptp_ts_valid,
ifg_delay=ifg_delay, ifg_delay=ifg_delay,
start_packet=start_packet, start_packet=start_packet,
error_underflow=error_underflow error_underflow=error_underflow

View File

@ -38,6 +38,13 @@ parameter HDR_WIDTH = 2;
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter ENABLE_DIC = 1; parameter ENABLE_DIC = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter PTP_PERIOD_NS = 4'h6;
parameter PTP_PERIOD_FNS = 16'h6666;
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter PTP_TAG_ENABLE = 0;
parameter PTP_TAG_WIDTH = 16;
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
@ -48,13 +55,17 @@ reg [DATA_WIDTH-1:0] s_axis_tdata = 0;
reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0; reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0;
reg s_axis_tvalid = 0; reg s_axis_tvalid = 0;
reg s_axis_tlast = 0; reg s_axis_tlast = 0;
reg s_axis_tuser = 0; reg [USER_WIDTH-1:0] s_axis_tuser = 0;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
reg [7:0] ifg_delay = 0; reg [7:0] ifg_delay = 0;
// Outputs // Outputs
wire s_axis_tready; wire s_axis_tready;
wire [DATA_WIDTH-1:0] encoded_tx_data; wire [DATA_WIDTH-1:0] encoded_tx_data;
wire [HDR_WIDTH-1:0] encoded_tx_hdr; wire [HDR_WIDTH-1:0] encoded_tx_hdr;
wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts;
wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag;
wire m_axis_ptp_ts_valid;
wire [1:0] start_packet; wire [1:0] start_packet;
wire error_underflow; wire error_underflow;
@ -69,12 +80,16 @@ initial begin
s_axis_tvalid, s_axis_tvalid,
s_axis_tlast, s_axis_tlast,
s_axis_tuser, s_axis_tuser,
ptp_ts,
ifg_delay ifg_delay
); );
$to_myhdl( $to_myhdl(
s_axis_tready, s_axis_tready,
encoded_tx_data, encoded_tx_data,
encoded_tx_hdr, encoded_tx_hdr,
m_axis_ptp_ts,
m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid,
start_packet, start_packet,
error_underflow error_underflow
); );
@ -90,7 +105,14 @@ axis_baser_tx_64 #(
.HDR_WIDTH(HDR_WIDTH), .HDR_WIDTH(HDR_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.PTP_TAG_ENABLE(PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(PTP_TAG_WIDTH),
.USER_WIDTH(USER_WIDTH)
) )
UUT ( UUT (
.clk(clk), .clk(clk),
@ -103,6 +125,10 @@ UUT (
.s_axis_tuser(s_axis_tuser), .s_axis_tuser(s_axis_tuser),
.encoded_tx_data(encoded_tx_data), .encoded_tx_data(encoded_tx_data),
.encoded_tx_hdr(encoded_tx_hdr), .encoded_tx_hdr(encoded_tx_hdr),
.ptp_ts(ptp_ts),
.m_axis_ptp_ts(m_axis_ptp_ts),
.m_axis_ptp_ts_tag(m_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(m_axis_ptp_ts_valid),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),
.start_packet(start_packet), .start_packet(start_packet),
.error_underflow(error_underflow) .error_underflow(error_underflow)

View File

@ -46,24 +46,28 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench(): def bench():
# Parameters # Parameters
DATA_WIDTH = 8
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
rst = Signal(bool(0)) rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:]) current_test = Signal(intbv(0)[8:])
gmii_rxd = Signal(intbv(0)[8:]) gmii_rxd = Signal(intbv(0)[DATA_WIDTH:])
gmii_rx_dv = Signal(bool(0)) gmii_rx_dv = Signal(bool(0))
gmii_rx_er = Signal(bool(0)) gmii_rx_er = Signal(bool(0))
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
clk_enable = Signal(bool(1)) clk_enable = Signal(bool(1))
mii_select = Signal(bool(0)) mii_select = Signal(bool(0))
# Outputs # Outputs
m_axis_tdata = Signal(intbv(0)[8:]) m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
m_axis_tvalid = Signal(bool(0)) m_axis_tvalid = Signal(bool(0))
m_axis_tlast = Signal(bool(0)) m_axis_tlast = Signal(bool(0))
m_axis_tuser = Signal(bool(0)) m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
start_packet = Signal(bool(0)) start_packet = Signal(bool(0))
error_bad_frame = Signal(bool(0)) error_bad_frame = Signal(bool(0))
error_bad_fcs = Signal(bool(0)) error_bad_fcs = Signal(bool(0))
@ -113,6 +117,8 @@ def bench():
m_axis_tlast=m_axis_tlast, m_axis_tlast=m_axis_tlast,
m_axis_tuser=m_axis_tuser, m_axis_tuser=m_axis_tuser,
ptp_ts=ptp_ts,
clk_enable=clk_enable, clk_enable=clk_enable,
mii_select=mii_select, mii_select=mii_select,

View File

@ -32,24 +32,28 @@ THE SOFTWARE.
module test_axis_gmii_rx; module test_axis_gmii_rx;
// Parameters // Parameters
parameter DATA_WIDTH = 8;
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
reg rst = 0; reg rst = 0;
reg [7:0] current_test = 0; reg [7:0] current_test = 0;
reg [7:0] gmii_rxd = 0; reg [DATA_WIDTH-1:0] gmii_rxd = 0;
reg gmii_rx_dv = 0; reg gmii_rx_dv = 0;
reg gmii_rx_er = 0; reg gmii_rx_er = 0;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
reg clk_enable = 1; reg clk_enable = 1;
reg mii_select = 0; reg mii_select = 0;
// Outputs // Outputs
wire [7:0] m_axis_tdata; wire [DATA_WIDTH-1:0] m_axis_tdata;
wire m_axis_tvalid; wire m_axis_tvalid;
wire m_axis_tlast; wire m_axis_tlast;
wire m_axis_tuser; wire [USER_WIDTH-1:0] m_axis_tuser;
wire start_packet; wire start_packet;
wire error_bad_frame; wire error_bad_frame;
wire error_bad_fcs; wire error_bad_fcs;
@ -63,6 +67,7 @@ initial begin
gmii_rxd, gmii_rxd,
gmii_rx_dv, gmii_rx_dv,
gmii_rx_er, gmii_rx_er,
ptp_ts,
clk_enable, clk_enable,
mii_select mii_select
); );
@ -81,7 +86,12 @@ initial begin
$dumpvars(0, test_axis_gmii_rx); $dumpvars(0, test_axis_gmii_rx);
end end
axis_gmii_rx axis_gmii_rx #(
.DATA_WIDTH(DATA_WIDTH),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.USER_WIDTH(USER_WIDTH)
)
UUT ( UUT (
.clk(clk), .clk(clk),
.rst(rst), .rst(rst),
@ -92,6 +102,7 @@ UUT (
.m_axis_tvalid(m_axis_tvalid), .m_axis_tvalid(m_axis_tvalid),
.m_axis_tlast(m_axis_tlast), .m_axis_tlast(m_axis_tlast),
.m_axis_tuser(m_axis_tuser), .m_axis_tuser(m_axis_tuser),
.ptp_ts(ptp_ts),
.clk_enable(clk_enable), .clk_enable(clk_enable),
.mii_select(mii_select), .mii_select(mii_select),
.start_packet(start_packet), .start_packet(start_packet),

View File

@ -46,27 +46,37 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench(): def bench():
# Parameters # Parameters
DATA_WIDTH = 8
ENABLE_PADDING = 1 ENABLE_PADDING = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
PTP_TAG_ENABLE = 0
PTP_TAG_WIDTH = 16
USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
rst = Signal(bool(0)) rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:]) current_test = Signal(intbv(0)[8:])
s_axis_tdata = Signal(intbv(0)[8:]) s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
s_axis_tvalid = Signal(bool(0)) s_axis_tvalid = Signal(bool(0))
s_axis_tlast = Signal(bool(0)) s_axis_tlast = Signal(bool(0))
s_axis_tuser = Signal(bool(0)) s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
clk_enable = Signal(bool(1)) clk_enable = Signal(bool(1))
mii_select = Signal(bool(0)) mii_select = Signal(bool(0))
ifg_delay = Signal(intbv(0)[8:]) ifg_delay = Signal(intbv(0)[8:])
# Outputs # Outputs
s_axis_tready = Signal(bool(0)) s_axis_tready = Signal(bool(0))
gmii_txd = Signal(intbv(0)[8:]) gmii_txd = Signal(intbv(0)[DATA_WIDTH:])
gmii_tx_en = Signal(bool(0)) gmii_tx_en = Signal(bool(0))
gmii_tx_er = Signal(bool(0)) gmii_tx_er = Signal(bool(0))
m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
m_axis_ptp_ts_valid = Signal(bool(0))
start_packet = Signal(bool(0)) start_packet = Signal(bool(0))
error_underflow = Signal(bool(0)) error_underflow = Signal(bool(0))
@ -120,6 +130,11 @@ def bench():
gmii_tx_en=gmii_tx_en, gmii_tx_en=gmii_tx_en,
gmii_tx_er=gmii_tx_er, gmii_tx_er=gmii_tx_er,
ptp_ts=ptp_ts,
m_axis_ptp_ts=m_axis_ptp_ts,
m_axis_ptp_ts_tag=m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid=m_axis_ptp_ts_valid,
clk_enable=clk_enable, clk_enable=clk_enable,
mii_select=mii_select, mii_select=mii_select,

View File

@ -32,27 +32,37 @@ THE SOFTWARE.
module test_axis_gmii_tx; module test_axis_gmii_tx;
// Parameters // Parameters
parameter DATA_WIDTH = 8;
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter PTP_TAG_ENABLE = 0;
parameter PTP_TAG_WIDTH = 16;
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
reg rst = 0; reg rst = 0;
reg [7:0] current_test = 0; reg [7:0] current_test = 0;
reg [7:0] s_axis_tdata = 0; reg [DATA_WIDTH-1:0] s_axis_tdata = 0;
reg s_axis_tvalid = 0; reg s_axis_tvalid = 0;
reg s_axis_tlast = 0; reg s_axis_tlast = 0;
reg s_axis_tuser = 0; reg [USER_WIDTH-1:0] s_axis_tuser = 0;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
reg clk_enable = 1; reg clk_enable = 1;
reg mii_select = 0; reg mii_select = 0;
reg [7:0] ifg_delay = 0; reg [7:0] ifg_delay = 0;
// Outputs // Outputs
wire s_axis_tready; wire s_axis_tready;
wire [7:0] gmii_txd; wire [DATA_WIDTH-1:0] gmii_txd;
wire gmii_tx_en; wire gmii_tx_en;
wire gmii_tx_er; wire gmii_tx_er;
wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts;
wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag;
wire m_axis_ptp_ts_valid;
wire start_packet; wire start_packet;
wire error_underflow; wire error_underflow;
@ -66,6 +76,7 @@ initial begin
s_axis_tvalid, s_axis_tvalid,
s_axis_tlast, s_axis_tlast,
s_axis_tuser, s_axis_tuser,
ptp_ts,
clk_enable, clk_enable,
mii_select, mii_select,
ifg_delay ifg_delay
@ -75,6 +86,9 @@ initial begin
gmii_txd, gmii_txd,
gmii_tx_en, gmii_tx_en,
gmii_tx_er, gmii_tx_er,
m_axis_ptp_ts,
m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid,
start_packet, start_packet,
error_underflow error_underflow
); );
@ -85,8 +99,14 @@ initial begin
end end
axis_gmii_tx #( axis_gmii_tx #(
.DATA_WIDTH(DATA_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.PTP_TAG_ENABLE(PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(PTP_TAG_WIDTH),
.USER_WIDTH(USER_WIDTH)
) )
UUT ( UUT (
.clk(clk), .clk(clk),
@ -99,6 +119,10 @@ UUT (
.gmii_txd(gmii_txd), .gmii_txd(gmii_txd),
.gmii_tx_en(gmii_tx_en), .gmii_tx_en(gmii_tx_en),
.gmii_tx_er(gmii_tx_er), .gmii_tx_er(gmii_tx_er),
.ptp_ts(ptp_ts),
.m_axis_ptp_ts(m_axis_ptp_ts),
.m_axis_ptp_ts_tag(m_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(m_axis_ptp_ts_valid),
.clk_enable(clk_enable), .clk_enable(clk_enable),
.mii_select(mii_select), .mii_select(mii_select),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),

View File

@ -46,22 +46,28 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench(): def bench():
# Parameters # Parameters
DATA_WIDTH = 32
KEEP_WIDTH = (DATA_WIDTH/8)
CTRL_WIDTH = (DATA_WIDTH/8)
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
rst = Signal(bool(0)) rst = Signal(bool(0))
current_test = Signal(intbv(0)[4:]) current_test = Signal(intbv(0)[8:])
xgmii_rxd = Signal(intbv(0x07070707)[32:]) xgmii_rxd = Signal(intbv(0x07070707)[DATA_WIDTH:])
xgmii_rxc = Signal(intbv(0xf)[4:]) xgmii_rxc = Signal(intbv(0xf)[CTRL_WIDTH:])
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
# Outputs # Outputs
m_axis_tdata = Signal(intbv(0)[32:]) m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
m_axis_tkeep = Signal(intbv(0)[4:]) m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
m_axis_tvalid = Signal(bool(0)) m_axis_tvalid = Signal(bool(0))
m_axis_tlast = Signal(bool(0)) m_axis_tlast = Signal(bool(0))
m_axis_tuser = Signal(bool(0)) m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
start_packet = Signal(bool(0)) start_packet = Signal(bool(0))
error_bad_frame = Signal(bool(0)) error_bad_frame = Signal(bool(0))
error_bad_fcs = Signal(bool(0)) error_bad_fcs = Signal(bool(0))
@ -109,6 +115,8 @@ def bench():
m_axis_tlast=m_axis_tlast, m_axis_tlast=m_axis_tlast,
m_axis_tuser=m_axis_tuser, m_axis_tuser=m_axis_tuser,
ptp_ts=ptp_ts,
start_packet=start_packet, start_packet=start_packet,
error_bad_frame=error_bad_frame, error_bad_frame=error_bad_frame,
error_bad_fcs=error_bad_fcs error_bad_fcs=error_bad_fcs

View File

@ -32,21 +32,28 @@ THE SOFTWARE.
module test_axis_xgmii_rx_32; module test_axis_xgmii_rx_32;
// Parameters // Parameters
parameter DATA_WIDTH = 32;
parameter KEEP_WIDTH = (DATA_WIDTH/8);
parameter CTRL_WIDTH = (DATA_WIDTH/8);
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
reg rst = 0; reg rst = 0;
reg [3:0] current_test = 0; reg [7:0] current_test = 0;
reg [31:0] xgmii_rxd = 32'h07070707; reg [DATA_WIDTH-1:0] xgmii_rxd = 32'h07070707;
reg [3:0] xgmii_rxc = 4'hf; reg [CTRL_WIDTH-1:0] xgmii_rxc = 4'hf;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
// Outputs // Outputs
wire [31:0] m_axis_tdata; wire [DATA_WIDTH-1:0] m_axis_tdata;
wire [3:0] m_axis_tkeep; wire [KEEP_WIDTH-1:0] m_axis_tkeep;
wire m_axis_tvalid; wire m_axis_tvalid;
wire m_axis_tlast; wire m_axis_tlast;
wire m_axis_tuser; wire [USER_WIDTH-1:0] m_axis_tuser;
wire start_packet; wire start_packet;
wire error_bad_frame; wire error_bad_frame;
wire error_bad_fcs; wire error_bad_fcs;
@ -58,7 +65,8 @@ initial begin
rst, rst,
current_test, current_test,
xgmii_rxd, xgmii_rxd,
xgmii_rxc xgmii_rxc,
ptp_ts
); );
$to_myhdl( $to_myhdl(
m_axis_tdata, m_axis_tdata,
@ -76,7 +84,14 @@ initial begin
$dumpvars(0, test_axis_xgmii_rx_32); $dumpvars(0, test_axis_xgmii_rx_32);
end end
axis_xgmii_rx_32 axis_xgmii_rx_32 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.USER_WIDTH(USER_WIDTH)
)
UUT ( UUT (
.clk(clk), .clk(clk),
.rst(rst), .rst(rst),
@ -87,6 +102,7 @@ UUT (
.m_axis_tvalid(m_axis_tvalid), .m_axis_tvalid(m_axis_tvalid),
.m_axis_tlast(m_axis_tlast), .m_axis_tlast(m_axis_tlast),
.m_axis_tuser(m_axis_tuser), .m_axis_tuser(m_axis_tuser),
.ptp_ts(ptp_ts),
.start_packet(start_packet), .start_packet(start_packet),
.error_bad_frame(error_bad_frame), .error_bad_frame(error_bad_frame),
.error_bad_fcs(error_bad_fcs) .error_bad_fcs(error_bad_fcs)

View File

@ -46,22 +46,30 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench(): def bench():
# Parameters # Parameters
DATA_WIDTH = 64
KEEP_WIDTH = (DATA_WIDTH/8)
CTRL_WIDTH = (DATA_WIDTH/8)
PTP_PERIOD_NS = 0x6
PTP_PERIOD_FNS = 0x6666
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
USER_WIDTH = (PTP_TS_WIDTH if PTP_TS_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
rst = Signal(bool(0)) rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:]) current_test = Signal(intbv(0)[8:])
xgmii_rxd = Signal(intbv(0x0707070707070707)[64:]) xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
xgmii_rxc = Signal(intbv(0xff)[8:]) xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:])
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
# Outputs # Outputs
m_axis_tdata = Signal(intbv(0)[64:]) m_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
m_axis_tkeep = Signal(intbv(0)[8:]) m_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
m_axis_tvalid = Signal(bool(0)) m_axis_tvalid = Signal(bool(0))
m_axis_tlast = Signal(bool(0)) m_axis_tlast = Signal(bool(0))
m_axis_tuser = Signal(bool(0)) m_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
start_packet = Signal(intbv(0)[2:]) start_packet = Signal(intbv(0)[2:])
error_bad_frame = Signal(bool(0)) error_bad_frame = Signal(bool(0))
error_bad_fcs = Signal(bool(0)) error_bad_fcs = Signal(bool(0))
@ -109,6 +117,8 @@ def bench():
m_axis_tlast=m_axis_tlast, m_axis_tlast=m_axis_tlast,
m_axis_tuser=m_axis_tuser, m_axis_tuser=m_axis_tuser,
ptp_ts=ptp_ts,
start_packet=start_packet, start_packet=start_packet,
error_bad_frame=error_bad_frame, error_bad_frame=error_bad_frame,
error_bad_fcs=error_bad_fcs error_bad_fcs=error_bad_fcs

View File

@ -32,21 +32,30 @@ THE SOFTWARE.
module test_axis_xgmii_rx_64; module test_axis_xgmii_rx_64;
// Parameters // Parameters
parameter DATA_WIDTH = 64;
parameter KEEP_WIDTH = (DATA_WIDTH/8);
parameter CTRL_WIDTH = (DATA_WIDTH/8);
parameter PTP_PERIOD_NS = 4'h6;
parameter PTP_PERIOD_FNS = 16'h6666;
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
reg rst = 0; reg rst = 0;
reg [7:0] current_test = 0; reg [7:0] current_test = 0;
reg [63:0] xgmii_rxd = 64'h0707070707070707; reg [DATA_WIDTH-1:0] xgmii_rxd = 64'h0707070707070707;
reg [7:0] xgmii_rxc = 8'hff; reg [CTRL_WIDTH-1:0] xgmii_rxc = 8'hff;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
// Outputs // Outputs
wire [63:0] m_axis_tdata; wire [DATA_WIDTH-1:0] m_axis_tdata;
wire [7:0] m_axis_tkeep; wire [KEEP_WIDTH-1:0] m_axis_tkeep;
wire m_axis_tvalid; wire m_axis_tvalid;
wire m_axis_tlast; wire m_axis_tlast;
wire m_axis_tuser; wire [USER_WIDTH-1:0] m_axis_tuser;
wire [1:0] start_packet; wire [1:0] start_packet;
wire error_bad_frame; wire error_bad_frame;
wire error_bad_fcs; wire error_bad_fcs;
@ -58,7 +67,8 @@ initial begin
rst, rst,
current_test, current_test,
xgmii_rxd, xgmii_rxd,
xgmii_rxc xgmii_rxc,
ptp_ts
); );
$to_myhdl( $to_myhdl(
m_axis_tdata, m_axis_tdata,
@ -76,7 +86,16 @@ initial begin
$dumpvars(0, test_axis_xgmii_rx_64); $dumpvars(0, test_axis_xgmii_rx_64);
end end
axis_xgmii_rx_64 axis_xgmii_rx_64 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.USER_WIDTH(USER_WIDTH)
)
UUT ( UUT (
.clk(clk), .clk(clk),
.rst(rst), .rst(rst),
@ -87,6 +106,7 @@ UUT (
.m_axis_tvalid(m_axis_tvalid), .m_axis_tvalid(m_axis_tvalid),
.m_axis_tlast(m_axis_tlast), .m_axis_tlast(m_axis_tlast),
.m_axis_tuser(m_axis_tuser), .m_axis_tuser(m_axis_tuser),
.ptp_ts(ptp_ts),
.start_packet(start_packet), .start_packet(start_packet),
.error_bad_frame(error_bad_frame), .error_bad_frame(error_bad_frame),
.error_bad_fcs(error_bad_fcs) .error_bad_fcs(error_bad_fcs)

View File

@ -46,25 +46,38 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench(): def bench():
# Parameters # Parameters
DATA_WIDTH = 32
KEEP_WIDTH = (DATA_WIDTH/8)
CTRL_WIDTH = (DATA_WIDTH/8)
ENABLE_PADDING = 1 ENABLE_PADDING = 1
ENABLE_DIC = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
PTP_TAG_ENABLE = 0
PTP_TAG_WIDTH = 16
USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
rst = Signal(bool(0)) rst = Signal(bool(0))
current_test = Signal(intbv(0)[4:]) current_test = Signal(intbv(0)[8:])
s_axis_tdata = Signal(intbv(0)[32:]) s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
s_axis_tkeep = Signal(intbv(0)[4:]) s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
s_axis_tvalid = Signal(bool(0)) s_axis_tvalid = Signal(bool(0))
s_axis_tlast = Signal(bool(0)) s_axis_tlast = Signal(bool(0))
s_axis_tuser = Signal(bool(0)) s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
ifg_delay = Signal(intbv(0)[8:]) ifg_delay = Signal(intbv(0)[8:])
# Outputs # Outputs
s_axis_tready = Signal(bool(0)) s_axis_tready = Signal(bool(0))
xgmii_txd = Signal(intbv(0x07070707)[32:]) xgmii_txd = Signal(intbv(0x07070707)[DATA_WIDTH:])
xgmii_txc = Signal(intbv(0xf)[4:]) xgmii_txc = Signal(intbv(0xf)[CTRL_WIDTH:])
m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
m_axis_ptp_ts_valid = Signal(bool(0))
start_packet = Signal(bool(0)) start_packet = Signal(bool(0))
error_underflow = Signal(bool(0)) error_underflow = Signal(bool(0))
@ -116,6 +129,11 @@ def bench():
xgmii_txd=xgmii_txd, xgmii_txd=xgmii_txd,
xgmii_txc=xgmii_txc, xgmii_txc=xgmii_txc,
ptp_ts=ptp_ts,
m_axis_ptp_ts=m_axis_ptp_ts,
m_axis_ptp_ts_tag=m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid=m_axis_ptp_ts_valid,
ifg_delay=ifg_delay, ifg_delay=ifg_delay,
start_packet=start_packet, start_packet=start_packet,

View File

@ -32,25 +32,38 @@ THE SOFTWARE.
module test_axis_xgmii_tx_32; module test_axis_xgmii_tx_32;
// Parameters // Parameters
parameter DATA_WIDTH = 32;
parameter KEEP_WIDTH = (DATA_WIDTH/8);
parameter CTRL_WIDTH = (DATA_WIDTH/8);
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter ENABLE_DIC = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter PTP_TAG_ENABLE = 0;
parameter PTP_TAG_WIDTH = 16;
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
reg rst = 0; reg rst = 0;
reg [3:0] current_test = 0; reg [7:0] current_test = 0;
reg [31:0] s_axis_tdata = 0; reg [DATA_WIDTH-1:0] s_axis_tdata = 0;
reg [3:0] s_axis_tkeep = 0; reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0;
reg s_axis_tvalid = 0; reg s_axis_tvalid = 0;
reg s_axis_tlast = 0; reg s_axis_tlast = 0;
reg s_axis_tuser = 0; reg [USER_WIDTH-1:0] s_axis_tuser = 0;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
reg [7:0] ifg_delay = 0; reg [7:0] ifg_delay = 0;
// Outputs // Outputs
wire s_axis_tready; wire s_axis_tready;
wire [31:0] xgmii_txd; wire [DATA_WIDTH-1:0] xgmii_txd;
wire [3:0] xgmii_txc; wire [CTRL_WIDTH-1:0] xgmii_txc;
wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts;
wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag;
wire m_axis_ptp_ts_valid;
wire start_packet; wire start_packet;
wire error_underflow; wire error_underflow;
@ -65,12 +78,16 @@ initial begin
s_axis_tvalid, s_axis_tvalid,
s_axis_tlast, s_axis_tlast,
s_axis_tuser, s_axis_tuser,
ptp_ts,
ifg_delay ifg_delay
); );
$to_myhdl( $to_myhdl(
s_axis_tready, s_axis_tready,
xgmii_txd, xgmii_txd,
xgmii_txc, xgmii_txc,
m_axis_ptp_ts,
m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid,
start_packet, start_packet,
error_underflow error_underflow
); );
@ -81,8 +98,17 @@ initial begin
end end
axis_xgmii_tx_32 #( axis_xgmii_tx_32 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.PTP_TAG_ENABLE(PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(PTP_TAG_WIDTH),
.USER_WIDTH(USER_WIDTH)
) )
UUT ( UUT (
.clk(clk), .clk(clk),
@ -95,6 +121,10 @@ UUT (
.s_axis_tuser(s_axis_tuser), .s_axis_tuser(s_axis_tuser),
.xgmii_txd(xgmii_txd), .xgmii_txd(xgmii_txd),
.xgmii_txc(xgmii_txc), .xgmii_txc(xgmii_txc),
.ptp_ts(ptp_ts),
.m_axis_ptp_ts(m_axis_ptp_ts),
.m_axis_ptp_ts_tag(m_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(m_axis_ptp_ts_valid),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),
.start_packet(start_packet), .start_packet(start_packet),
.error_underflow(error_underflow) .error_underflow(error_underflow)

View File

@ -46,25 +46,40 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench(): def bench():
# Parameters # Parameters
DATA_WIDTH = 64
KEEP_WIDTH = (DATA_WIDTH/8)
CTRL_WIDTH = (DATA_WIDTH/8)
ENABLE_PADDING = 1 ENABLE_PADDING = 1
ENABLE_DIC = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
PTP_PERIOD_NS = 0x6
PTP_PERIOD_FNS = 0x6666
PTP_TS_ENABLE = 0
PTP_TS_WIDTH = 96
PTP_TAG_ENABLE = 0
PTP_TAG_WIDTH = 16
USER_WIDTH = (PTP_TAG_WIDTH if PTP_TS_ENABLE and PTP_TAG_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
rst = Signal(bool(0)) rst = Signal(bool(0))
current_test = Signal(intbv(0)[8:]) current_test = Signal(intbv(0)[8:])
s_axis_tdata = Signal(intbv(0)[64:]) s_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
s_axis_tkeep = Signal(intbv(0)[8:]) s_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
s_axis_tvalid = Signal(bool(0)) s_axis_tvalid = Signal(bool(0))
s_axis_tlast = Signal(bool(0)) s_axis_tlast = Signal(bool(0))
s_axis_tuser = Signal(bool(0)) s_axis_tuser = Signal(intbv(0)[USER_WIDTH:])
ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
ifg_delay = Signal(intbv(0)[8:]) ifg_delay = Signal(intbv(0)[8:])
# Outputs # Outputs
s_axis_tready = Signal(bool(0)) s_axis_tready = Signal(bool(0))
xgmii_txd = Signal(intbv(0x0707070707070707)[64:]) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
xgmii_txc = Signal(intbv(0xff)[8:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:])
m_axis_ptp_ts = Signal(intbv(0)[PTP_TS_WIDTH:])
m_axis_ptp_ts_tag = Signal(intbv(0)[PTP_TAG_WIDTH:])
m_axis_ptp_ts_valid = Signal(bool(0))
start_packet = Signal(intbv(0)[2:]) start_packet = Signal(intbv(0)[2:])
error_underflow = Signal(bool(0)) error_underflow = Signal(bool(0))
@ -116,6 +131,11 @@ def bench():
xgmii_txd=xgmii_txd, xgmii_txd=xgmii_txd,
xgmii_txc=xgmii_txc, xgmii_txc=xgmii_txc,
ptp_ts=ptp_ts,
m_axis_ptp_ts=m_axis_ptp_ts,
m_axis_ptp_ts_tag=m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid=m_axis_ptp_ts_valid,
ifg_delay=ifg_delay, ifg_delay=ifg_delay,
start_packet=start_packet, start_packet=start_packet,

View File

@ -32,25 +32,40 @@ THE SOFTWARE.
module test_axis_xgmii_tx_64; module test_axis_xgmii_tx_64;
// Parameters // Parameters
parameter DATA_WIDTH = 64;
parameter KEEP_WIDTH = (DATA_WIDTH/8);
parameter CTRL_WIDTH = (DATA_WIDTH/8);
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter ENABLE_DIC = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter PTP_PERIOD_NS = 4'h6;
parameter PTP_PERIOD_FNS = 16'h6666;
parameter PTP_TS_ENABLE = 0;
parameter PTP_TS_WIDTH = 96;
parameter PTP_TAG_ENABLE = 0;
parameter PTP_TAG_WIDTH = 16;
parameter USER_WIDTH = (PTP_TS_ENABLE && PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
reg rst = 0; reg rst = 0;
reg [7:0] current_test = 0; reg [7:0] current_test = 0;
reg [63:0] s_axis_tdata = 0; reg [DATA_WIDTH-1:0] s_axis_tdata = 0;
reg [7:0] s_axis_tkeep = 0; reg [KEEP_WIDTH-1:0] s_axis_tkeep = 0;
reg s_axis_tvalid = 0; reg s_axis_tvalid = 0;
reg s_axis_tlast = 0; reg s_axis_tlast = 0;
reg s_axis_tuser = 0; reg [USER_WIDTH-1:0] s_axis_tuser = 0;
reg [PTP_TS_WIDTH-1:0] ptp_ts = 0;
reg [7:0] ifg_delay = 0; reg [7:0] ifg_delay = 0;
// Outputs // Outputs
wire s_axis_tready; wire s_axis_tready;
wire [63:0] xgmii_txd; wire [DATA_WIDTH-1:0] xgmii_txd;
wire [7:0] xgmii_txc; wire [CTRL_WIDTH-1:0] xgmii_txc;
wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts;
wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag;
wire m_axis_ptp_ts_valid;
wire [1:0] start_packet; wire [1:0] start_packet;
wire error_underflow; wire error_underflow;
@ -65,12 +80,16 @@ initial begin
s_axis_tvalid, s_axis_tvalid,
s_axis_tlast, s_axis_tlast,
s_axis_tuser, s_axis_tuser,
ptp_ts,
ifg_delay ifg_delay
); );
$to_myhdl( $to_myhdl(
s_axis_tready, s_axis_tready,
xgmii_txd, xgmii_txd,
xgmii_txc, xgmii_txc,
m_axis_ptp_ts,
m_axis_ptp_ts_tag,
m_axis_ptp_ts_valid,
start_packet, start_packet,
error_underflow error_underflow
); );
@ -81,8 +100,19 @@ initial begin
end end
axis_xgmii_tx_64 #( axis_xgmii_tx_64 #(
.DATA_WIDTH(DATA_WIDTH),
.KEEP_WIDTH(KEEP_WIDTH),
.CTRL_WIDTH(CTRL_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.PTP_TS_ENABLE(PTP_TS_ENABLE),
.PTP_TS_WIDTH(PTP_TS_WIDTH),
.PTP_TAG_ENABLE(PTP_TAG_ENABLE),
.PTP_TAG_WIDTH(PTP_TAG_WIDTH),
.USER_WIDTH(USER_WIDTH)
) )
UUT ( UUT (
.clk(clk), .clk(clk),
@ -95,6 +125,10 @@ UUT (
.s_axis_tuser(s_axis_tuser), .s_axis_tuser(s_axis_tuser),
.xgmii_txd(xgmii_txd), .xgmii_txd(xgmii_txd),
.xgmii_txc(xgmii_txc), .xgmii_txc(xgmii_txc),
.ptp_ts(ptp_ts),
.m_axis_ptp_ts(m_axis_ptp_ts),
.m_axis_ptp_ts_tag(m_axis_ptp_ts_tag),
.m_axis_ptp_ts_valid(m_axis_ptp_ts_valid),
.ifg_delay(ifg_delay), .ifg_delay(ifg_delay),
.start_packet(start_packet), .start_packet(start_packet),
.error_underflow(error_underflow) .error_underflow(error_underflow)

View File

@ -54,6 +54,14 @@ def bench():
ENABLE_PADDING = 1 ENABLE_PADDING = 1
ENABLE_DIC = 1 ENABLE_DIC = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
TX_PTP_TS_ENABLE = 0
TX_PTP_TS_WIDTH = 96
TX_PTP_TAG_ENABLE = 0
TX_PTP_TAG_WIDTH = 16
RX_PTP_TS_ENABLE = 0
RX_PTP_TS_WIDTH = 96
TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1
RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
@ -68,9 +76,11 @@ def bench():
tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
tx_axis_tvalid = Signal(bool(0)) tx_axis_tvalid = Signal(bool(0))
tx_axis_tlast = Signal(bool(0)) tx_axis_tlast = Signal(bool(0))
tx_axis_tuser = Signal(bool(0)) tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:])
xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:])
tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:])
ifg_delay = Signal(intbv(0)[8:]) ifg_delay = Signal(intbv(0)[8:])
# Outputs # Outputs
@ -79,9 +89,12 @@ def bench():
rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
rx_axis_tvalid = Signal(bool(0)) rx_axis_tvalid = Signal(bool(0))
rx_axis_tlast = Signal(bool(0)) rx_axis_tlast = Signal(bool(0))
rx_axis_tuser = Signal(bool(0)) rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:])
xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:])
tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:])
tx_axis_ptp_ts_valid = Signal(bool(0))
tx_start_packet = Signal(intbv(0)[2:]) tx_start_packet = Signal(intbv(0)[2:])
tx_error_underflow = Signal(bool(0)) tx_error_underflow = Signal(bool(0))
rx_start_packet = Signal(intbv(0)[2:]) rx_start_packet = Signal(intbv(0)[2:])
@ -173,6 +186,12 @@ def bench():
xgmii_txd=xgmii_txd, xgmii_txd=xgmii_txd,
xgmii_txc=xgmii_txc, xgmii_txc=xgmii_txc,
tx_ptp_ts=tx_ptp_ts,
rx_ptp_ts=rx_ptp_ts,
tx_axis_ptp_ts=tx_axis_ptp_ts,
tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid,
tx_start_packet=tx_start_packet, tx_start_packet=tx_start_packet,
tx_error_underflow=tx_error_underflow, tx_error_underflow=tx_error_underflow,
rx_start_packet=rx_start_packet, rx_start_packet=rx_start_packet,

View File

@ -38,6 +38,14 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8);
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter ENABLE_DIC = 1; parameter ENABLE_DIC = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter TX_PTP_TS_ENABLE = 0;
parameter TX_PTP_TS_WIDTH = 96;
parameter TX_PTP_TAG_ENABLE = 0;
parameter TX_PTP_TAG_WIDTH = 16;
parameter RX_PTP_TS_ENABLE = 0;
parameter RX_PTP_TS_WIDTH = 96;
parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1;
parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
@ -52,9 +60,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0;
reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0;
reg tx_axis_tvalid = 0; reg tx_axis_tvalid = 0;
reg tx_axis_tlast = 0; reg tx_axis_tlast = 0;
reg tx_axis_tuser = 0; reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0;
reg [DATA_WIDTH-1:0] xgmii_rxd = 0; reg [DATA_WIDTH-1:0] xgmii_rxd = 0;
reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; reg [CTRL_WIDTH-1:0] xgmii_rxc = 0;
reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0;
reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0;
reg [7:0] ifg_delay = 0; reg [7:0] ifg_delay = 0;
// Outputs // Outputs
@ -63,9 +73,12 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata;
wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire [KEEP_WIDTH-1:0] rx_axis_tkeep;
wire rx_axis_tvalid; wire rx_axis_tvalid;
wire rx_axis_tlast; wire rx_axis_tlast;
wire rx_axis_tuser; wire [RX_USER_WIDTH-1:0] rx_axis_tuser;
wire [DATA_WIDTH-1:0] xgmii_txd; wire [DATA_WIDTH-1:0] xgmii_txd;
wire [CTRL_WIDTH-1:0] xgmii_txc; wire [CTRL_WIDTH-1:0] xgmii_txc;
wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts;
wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag;
wire tx_axis_ptp_ts_valid;
wire [1:0] tx_start_packet; wire [1:0] tx_start_packet;
wire tx_error_underflow; wire tx_error_underflow;
wire [1:0] rx_start_packet; wire [1:0] rx_start_packet;
@ -89,6 +102,8 @@ initial begin
tx_axis_tuser, tx_axis_tuser,
xgmii_rxd, xgmii_rxd,
xgmii_rxc, xgmii_rxc,
tx_ptp_ts,
rx_ptp_ts,
ifg_delay ifg_delay
); );
$to_myhdl( $to_myhdl(
@ -100,6 +115,9 @@ initial begin
rx_axis_tuser, rx_axis_tuser,
xgmii_txd, xgmii_txd,
xgmii_txc, xgmii_txc,
tx_axis_ptp_ts,
tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid,
tx_start_packet, tx_start_packet,
tx_error_underflow, tx_error_underflow,
rx_start_packet, rx_start_packet,
@ -118,7 +136,15 @@ eth_mac_10g #(
.CTRL_WIDTH(CTRL_WIDTH), .CTRL_WIDTH(CTRL_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.TX_USER_WIDTH(TX_USER_WIDTH),
.RX_USER_WIDTH(RX_USER_WIDTH)
) )
UUT ( UUT (
.rx_clk(rx_clk), .rx_clk(rx_clk),
@ -140,6 +166,11 @@ UUT (
.xgmii_rxc(xgmii_rxc), .xgmii_rxc(xgmii_rxc),
.xgmii_txd(xgmii_txd), .xgmii_txd(xgmii_txd),
.xgmii_txc(xgmii_txc), .xgmii_txc(xgmii_txc),
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.tx_axis_ptp_ts(tx_axis_ptp_ts),
.tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.tx_start_packet(tx_start_packet), .tx_start_packet(tx_start_packet),
.tx_error_underflow(tx_error_underflow), .tx_error_underflow(tx_error_underflow),
.rx_start_packet(rx_start_packet), .rx_start_packet(rx_start_packet),

View File

@ -54,6 +54,16 @@ def bench():
ENABLE_PADDING = 1 ENABLE_PADDING = 1
ENABLE_DIC = 1 ENABLE_DIC = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
PTP_PERIOD_NS = 0x6
PTP_PERIOD_FNS = 0x6666
TX_PTP_TS_ENABLE = 0
TX_PTP_TS_WIDTH = 96
TX_PTP_TAG_ENABLE = 0
TX_PTP_TAG_WIDTH = 16
RX_PTP_TS_ENABLE = 0
RX_PTP_TS_WIDTH = 96
TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1
RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
@ -68,9 +78,11 @@ def bench():
tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
tx_axis_tvalid = Signal(bool(0)) tx_axis_tvalid = Signal(bool(0))
tx_axis_tlast = Signal(bool(0)) tx_axis_tlast = Signal(bool(0))
tx_axis_tuser = Signal(bool(0)) tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:])
xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_rxd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:]) xgmii_rxc = Signal(intbv(0xff)[CTRL_WIDTH:])
tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:])
ifg_delay = Signal(intbv(0)[8:]) ifg_delay = Signal(intbv(0)[8:])
# Outputs # Outputs
@ -79,9 +91,12 @@ def bench():
rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
rx_axis_tvalid = Signal(bool(0)) rx_axis_tvalid = Signal(bool(0))
rx_axis_tlast = Signal(bool(0)) rx_axis_tlast = Signal(bool(0))
rx_axis_tuser = Signal(bool(0)) rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:])
xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:]) xgmii_txd = Signal(intbv(0x0707070707070707)[DATA_WIDTH:])
xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:]) xgmii_txc = Signal(intbv(0xff)[CTRL_WIDTH:])
tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:])
tx_axis_ptp_ts_valid = Signal(bool(0))
tx_start_packet = Signal(intbv(0)[2:]) tx_start_packet = Signal(intbv(0)[2:])
tx_error_underflow = Signal(bool(0)) tx_error_underflow = Signal(bool(0))
rx_start_packet = Signal(intbv(0)[2:]) rx_start_packet = Signal(intbv(0)[2:])
@ -173,6 +188,12 @@ def bench():
xgmii_txd=xgmii_txd, xgmii_txd=xgmii_txd,
xgmii_txc=xgmii_txc, xgmii_txc=xgmii_txc,
tx_ptp_ts=tx_ptp_ts,
rx_ptp_ts=rx_ptp_ts,
tx_axis_ptp_ts=tx_axis_ptp_ts,
tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid,
tx_start_packet=tx_start_packet, tx_start_packet=tx_start_packet,
tx_error_underflow=tx_error_underflow, tx_error_underflow=tx_error_underflow,
rx_start_packet=rx_start_packet, rx_start_packet=rx_start_packet,

View File

@ -38,6 +38,16 @@ parameter CTRL_WIDTH = (DATA_WIDTH/8);
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter ENABLE_DIC = 1; parameter ENABLE_DIC = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter PTP_PERIOD_NS = 4'h6;
parameter PTP_PERIOD_FNS = 16'h6666;
parameter TX_PTP_TS_ENABLE = 0;
parameter TX_PTP_TS_WIDTH = 96;
parameter TX_PTP_TAG_ENABLE = 0;
parameter TX_PTP_TAG_WIDTH = 16;
parameter RX_PTP_TS_ENABLE = 0;
parameter RX_PTP_TS_WIDTH = 96;
parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1;
parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
@ -52,9 +62,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0;
reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0;
reg tx_axis_tvalid = 0; reg tx_axis_tvalid = 0;
reg tx_axis_tlast = 0; reg tx_axis_tlast = 0;
reg tx_axis_tuser = 0; reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0;
reg [DATA_WIDTH-1:0] xgmii_rxd = 0; reg [DATA_WIDTH-1:0] xgmii_rxd = 0;
reg [CTRL_WIDTH-1:0] xgmii_rxc = 0; reg [CTRL_WIDTH-1:0] xgmii_rxc = 0;
reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0;
reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0;
reg [7:0] ifg_delay = 0; reg [7:0] ifg_delay = 0;
// Outputs // Outputs
@ -63,9 +75,12 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata;
wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire [KEEP_WIDTH-1:0] rx_axis_tkeep;
wire rx_axis_tvalid; wire rx_axis_tvalid;
wire rx_axis_tlast; wire rx_axis_tlast;
wire rx_axis_tuser; wire [RX_USER_WIDTH-1:0] rx_axis_tuser;
wire [DATA_WIDTH-1:0] xgmii_txd; wire [DATA_WIDTH-1:0] xgmii_txd;
wire [CTRL_WIDTH-1:0] xgmii_txc; wire [CTRL_WIDTH-1:0] xgmii_txc;
wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts;
wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag;
wire tx_axis_ptp_ts_valid;
wire [1:0] tx_start_packet; wire [1:0] tx_start_packet;
wire tx_error_underflow; wire tx_error_underflow;
wire [1:0] rx_start_packet; wire [1:0] rx_start_packet;
@ -89,6 +104,8 @@ initial begin
tx_axis_tuser, tx_axis_tuser,
xgmii_rxd, xgmii_rxd,
xgmii_rxc, xgmii_rxc,
tx_ptp_ts,
rx_ptp_ts,
ifg_delay ifg_delay
); );
$to_myhdl( $to_myhdl(
@ -100,6 +117,9 @@ initial begin
rx_axis_tuser, rx_axis_tuser,
xgmii_txd, xgmii_txd,
xgmii_txc, xgmii_txc,
tx_axis_ptp_ts,
tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid,
tx_start_packet, tx_start_packet,
tx_error_underflow, tx_error_underflow,
rx_start_packet, rx_start_packet,
@ -118,7 +138,17 @@ eth_mac_10g #(
.CTRL_WIDTH(CTRL_WIDTH), .CTRL_WIDTH(CTRL_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.TX_USER_WIDTH(TX_USER_WIDTH),
.RX_USER_WIDTH(RX_USER_WIDTH)
) )
UUT ( UUT (
.rx_clk(rx_clk), .rx_clk(rx_clk),
@ -140,6 +170,11 @@ UUT (
.xgmii_rxc(xgmii_rxc), .xgmii_rxc(xgmii_rxc),
.xgmii_txd(xgmii_txd), .xgmii_txd(xgmii_txd),
.xgmii_txc(xgmii_txc), .xgmii_txc(xgmii_txc),
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.tx_axis_ptp_ts(tx_axis_ptp_ts),
.tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.tx_start_packet(tx_start_packet), .tx_start_packet(tx_start_packet),
.tx_error_underflow(tx_error_underflow), .tx_error_underflow(tx_error_underflow),
.rx_start_packet(rx_start_packet), .rx_start_packet(rx_start_packet),

View File

@ -48,8 +48,17 @@ build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)
def bench(): def bench():
# Parameters # Parameters
DATA_WIDTH = 8
ENABLE_PADDING = 1 ENABLE_PADDING = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
TX_PTP_TS_ENABLE = 0
TX_PTP_TS_WIDTH = 96
TX_PTP_TAG_ENABLE = 0
TX_PTP_TAG_WIDTH = 16
RX_PTP_TS_ENABLE = 0
RX_PTP_TS_WIDTH = 96
TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1
RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1
# Inputs # Inputs
clk = Signal(bool(0)) clk = Signal(bool(0))
@ -60,13 +69,15 @@ def bench():
rx_rst = Signal(bool(0)) rx_rst = Signal(bool(0))
tx_clk = Signal(bool(0)) tx_clk = Signal(bool(0))
tx_rst = Signal(bool(0)) tx_rst = Signal(bool(0))
tx_axis_tdata = Signal(intbv(0)[8:]) tx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
tx_axis_tvalid = Signal(bool(0)) tx_axis_tvalid = Signal(bool(0))
tx_axis_tlast = Signal(bool(0)) tx_axis_tlast = Signal(bool(0))
tx_axis_tuser = Signal(bool(0)) tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:])
gmii_rxd = Signal(intbv(0)[8:]) gmii_rxd = Signal(intbv(0)[DATA_WIDTH:])
gmii_rx_dv = Signal(bool(0)) gmii_rx_dv = Signal(bool(0))
gmii_rx_er = Signal(bool(0)) gmii_rx_er = Signal(bool(0))
tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:])
rx_clk_enable = Signal(bool(1)) rx_clk_enable = Signal(bool(1))
tx_clk_enable = Signal(bool(1)) tx_clk_enable = Signal(bool(1))
rx_mii_select = Signal(bool(0)) rx_mii_select = Signal(bool(0))
@ -75,13 +86,16 @@ def bench():
# Outputs # Outputs
tx_axis_tready = Signal(bool(0)) tx_axis_tready = Signal(bool(0))
rx_axis_tdata = Signal(intbv(0)[8:]) rx_axis_tdata = Signal(intbv(0)[DATA_WIDTH:])
rx_axis_tvalid = Signal(bool(0)) rx_axis_tvalid = Signal(bool(0))
rx_axis_tlast = Signal(bool(0)) rx_axis_tlast = Signal(bool(0))
rx_axis_tuser = Signal(bool(0)) rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:])
gmii_txd = Signal(intbv(0)[8:]) gmii_txd = Signal(intbv(0)[DATA_WIDTH:])
gmii_tx_en = Signal(bool(0)) gmii_tx_en = Signal(bool(0))
gmii_tx_er = Signal(bool(0)) gmii_tx_er = Signal(bool(0))
tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:])
tx_axis_ptp_ts_valid = Signal(bool(0))
tx_start_packet = Signal(bool(0)) tx_start_packet = Signal(bool(0))
tx_error_underflow = Signal(bool(0)) tx_error_underflow = Signal(bool(0))
rx_start_packet = Signal(bool(0)) rx_start_packet = Signal(bool(0))
@ -177,6 +191,12 @@ def bench():
gmii_tx_en=gmii_tx_en, gmii_tx_en=gmii_tx_en,
gmii_tx_er=gmii_tx_er, gmii_tx_er=gmii_tx_er,
tx_ptp_ts=tx_ptp_ts,
rx_ptp_ts=rx_ptp_ts,
tx_axis_ptp_ts=tx_axis_ptp_ts,
tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid,
rx_clk_enable=rx_clk_enable, rx_clk_enable=rx_clk_enable,
tx_clk_enable=tx_clk_enable, tx_clk_enable=tx_clk_enable,

View File

@ -32,8 +32,17 @@ THE SOFTWARE.
module test_eth_mac_1g; module test_eth_mac_1g;
// Parameters // Parameters
parameter DATA_WIDTH = 8;
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter TX_PTP_TS_ENABLE = 0;
parameter TX_PTP_TS_WIDTH = 96;
parameter TX_PTP_TAG_ENABLE = 0;
parameter TX_PTP_TAG_WIDTH = 16;
parameter RX_PTP_TS_ENABLE = 0;
parameter RX_PTP_TS_WIDTH = 96;
parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1;
parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1;
// Inputs // Inputs
reg clk = 0; reg clk = 0;
@ -44,13 +53,15 @@ reg rx_clk = 0;
reg rx_rst = 0; reg rx_rst = 0;
reg tx_clk = 0; reg tx_clk = 0;
reg tx_rst = 0; reg tx_rst = 0;
reg [7:0] tx_axis_tdata = 0; reg [DATA_WIDTH-1:0] tx_axis_tdata = 0;
reg tx_axis_tvalid = 0; reg tx_axis_tvalid = 0;
reg tx_axis_tlast = 0; reg tx_axis_tlast = 0;
reg tx_axis_tuser = 0; reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0;
reg [7:0] gmii_rxd = 0; reg [DATA_WIDTH-1:0] gmii_rxd = 0;
reg gmii_rx_dv = 0; reg gmii_rx_dv = 0;
reg gmii_rx_er = 0; reg gmii_rx_er = 0;
reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0;
reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0;
reg rx_clk_enable = 1; reg rx_clk_enable = 1;
reg tx_clk_enable = 1; reg tx_clk_enable = 1;
reg rx_mii_select = 0; reg rx_mii_select = 0;
@ -59,13 +70,16 @@ reg [7:0] ifg_delay = 0;
// Outputs // Outputs
wire tx_axis_tready; wire tx_axis_tready;
wire [7:0] rx_axis_tdata; wire [DATA_WIDTH-1:0] rx_axis_tdata;
wire rx_axis_tvalid; wire rx_axis_tvalid;
wire rx_axis_tlast; wire rx_axis_tlast;
wire rx_axis_tuser; wire [RX_USER_WIDTH-1:0] rx_axis_tuser;
wire [7:0] gmii_txd; wire [DATA_WIDTH-1:0] gmii_txd;
wire gmii_tx_en; wire gmii_tx_en;
wire gmii_tx_er; wire gmii_tx_er;
wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts;
wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag;
wire tx_axis_ptp_ts_valid;
wire tx_start_packet; wire tx_start_packet;
wire tx_error_underflow; wire tx_error_underflow;
wire rx_start_packet; wire rx_start_packet;
@ -89,6 +103,8 @@ initial begin
gmii_rxd, gmii_rxd,
gmii_rx_dv, gmii_rx_dv,
gmii_rx_er, gmii_rx_er,
tx_ptp_ts,
rx_ptp_ts,
rx_clk_enable, rx_clk_enable,
tx_clk_enable, tx_clk_enable,
rx_mii_select, rx_mii_select,
@ -104,6 +120,9 @@ initial begin
gmii_txd, gmii_txd,
gmii_tx_en, gmii_tx_en,
gmii_tx_er, gmii_tx_er,
tx_axis_ptp_ts,
tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid,
tx_start_packet, tx_start_packet,
tx_error_underflow, tx_error_underflow,
rx_start_packet, rx_start_packet,
@ -117,8 +136,17 @@ initial begin
end end
eth_mac_1g #( eth_mac_1g #(
.DATA_WIDTH(DATA_WIDTH),
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.TX_USER_WIDTH(TX_USER_WIDTH),
.RX_USER_WIDTH(RX_USER_WIDTH)
) )
UUT ( UUT (
.rx_clk(rx_clk), .rx_clk(rx_clk),
@ -140,6 +168,11 @@ UUT (
.gmii_txd(gmii_txd), .gmii_txd(gmii_txd),
.gmii_tx_en(gmii_tx_en), .gmii_tx_en(gmii_tx_en),
.gmii_tx_er(gmii_tx_er), .gmii_tx_er(gmii_tx_er),
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.tx_axis_ptp_ts(tx_axis_ptp_ts),
.tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.rx_clk_enable(rx_clk_enable), .rx_clk_enable(rx_clk_enable),
.tx_clk_enable(tx_clk_enable), .tx_clk_enable(tx_clk_enable),
.rx_mii_select(rx_mii_select), .rx_mii_select(rx_mii_select),

View File

@ -62,6 +62,16 @@ def bench():
ENABLE_PADDING = 1 ENABLE_PADDING = 1
ENABLE_DIC = 1 ENABLE_DIC = 1
MIN_FRAME_LENGTH = 64 MIN_FRAME_LENGTH = 64
PTP_PERIOD_NS = 0x6
PTP_PERIOD_FNS = 0x6666
TX_PTP_TS_ENABLE = 0
TX_PTP_TS_WIDTH = 96
TX_PTP_TAG_ENABLE = 0
TX_PTP_TAG_WIDTH = 16
RX_PTP_TS_ENABLE = 0
RX_PTP_TS_WIDTH = 96
TX_USER_WIDTH = (TX_PTP_TAG_WIDTH if TX_PTP_TS_ENABLE and TX_PTP_TAG_ENABLE else 0) + 1
RX_USER_WIDTH = (RX_PTP_TS_WIDTH if RX_PTP_TS_ENABLE else 0) + 1
BIT_REVERSE = 0 BIT_REVERSE = 0
SCRAMBLER_DISABLE = 0 SCRAMBLER_DISABLE = 0
PRBS31_ENABLE = 1 PRBS31_ENABLE = 1
@ -81,9 +91,11 @@ def bench():
tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) tx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
tx_axis_tvalid = Signal(bool(0)) tx_axis_tvalid = Signal(bool(0))
tx_axis_tlast = Signal(bool(0)) tx_axis_tlast = Signal(bool(0))
tx_axis_tuser = Signal(bool(0)) tx_axis_tuser = Signal(intbv(0)[TX_USER_WIDTH:])
serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_rx_data = Signal(intbv(0)[DATA_WIDTH:])
serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:]) serdes_rx_hdr = Signal(intbv(1)[HDR_WIDTH:])
tx_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
rx_ptp_ts = Signal(intbv(0)[RX_PTP_TS_WIDTH:])
ifg_delay = Signal(intbv(0)[8:]) ifg_delay = Signal(intbv(0)[8:])
tx_prbs31_enable = Signal(bool(0)) tx_prbs31_enable = Signal(bool(0))
rx_prbs31_enable = Signal(bool(0)) rx_prbs31_enable = Signal(bool(0))
@ -97,10 +109,13 @@ def bench():
rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:]) rx_axis_tkeep = Signal(intbv(0)[KEEP_WIDTH:])
rx_axis_tvalid = Signal(bool(0)) rx_axis_tvalid = Signal(bool(0))
rx_axis_tlast = Signal(bool(0)) rx_axis_tlast = Signal(bool(0))
rx_axis_tuser = Signal(bool(0)) rx_axis_tuser = Signal(intbv(0)[RX_USER_WIDTH:])
serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:]) serdes_tx_data = Signal(intbv(0)[DATA_WIDTH:])
serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:]) serdes_tx_hdr = Signal(intbv(1)[HDR_WIDTH:])
serdes_rx_bitslip = Signal(bool(0)) serdes_rx_bitslip = Signal(bool(0))
tx_axis_ptp_ts = Signal(intbv(0)[TX_PTP_TS_WIDTH:])
tx_axis_ptp_ts_tag = Signal(intbv(0)[TX_PTP_TAG_WIDTH:])
tx_axis_ptp_ts_valid = Signal(bool(0))
tx_start_packet = Signal(intbv(0)[2:]) tx_start_packet = Signal(intbv(0)[2:])
tx_error_underflow = Signal(bool(0)) tx_error_underflow = Signal(bool(0))
rx_start_packet = Signal(intbv(0)[2:]) rx_start_packet = Signal(intbv(0)[2:])
@ -189,6 +204,11 @@ def bench():
serdes_rx_data=serdes_rx_data, serdes_rx_data=serdes_rx_data,
serdes_rx_hdr=serdes_rx_hdr, serdes_rx_hdr=serdes_rx_hdr,
serdes_rx_bitslip=serdes_rx_bitslip, serdes_rx_bitslip=serdes_rx_bitslip,
tx_ptp_ts=tx_ptp_ts,
rx_ptp_ts=rx_ptp_ts,
tx_axis_ptp_ts=tx_axis_ptp_ts,
tx_axis_ptp_ts_tag=tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid=tx_axis_ptp_ts_valid,
tx_start_packet=tx_start_packet, tx_start_packet=tx_start_packet,
tx_error_underflow=tx_error_underflow, tx_error_underflow=tx_error_underflow,
rx_start_packet=rx_start_packet, rx_start_packet=rx_start_packet,

View File

@ -39,6 +39,16 @@ parameter HDR_WIDTH = (DATA_WIDTH/32);
parameter ENABLE_PADDING = 1; parameter ENABLE_PADDING = 1;
parameter ENABLE_DIC = 1; parameter ENABLE_DIC = 1;
parameter MIN_FRAME_LENGTH = 64; parameter MIN_FRAME_LENGTH = 64;
parameter PTP_PERIOD_NS = 4'h6;
parameter PTP_PERIOD_FNS = 16'h6666;
parameter TX_PTP_TS_ENABLE = 0;
parameter TX_PTP_TS_WIDTH = 96;
parameter TX_PTP_TAG_ENABLE = 0;
parameter TX_PTP_TAG_WIDTH = 16;
parameter RX_PTP_TS_ENABLE = 0;
parameter RX_PTP_TS_WIDTH = 96;
parameter TX_USER_WIDTH = (TX_PTP_TS_ENABLE && TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1;
parameter RX_USER_WIDTH = (RX_PTP_TS_ENABLE ? RX_PTP_TS_WIDTH : 0) + 1;
parameter BIT_REVERSE = 0; parameter BIT_REVERSE = 0;
parameter SCRAMBLER_DISABLE = 0; parameter SCRAMBLER_DISABLE = 0;
parameter PRBS31_ENABLE = 1; parameter PRBS31_ENABLE = 1;
@ -58,9 +68,11 @@ reg [DATA_WIDTH-1:0] tx_axis_tdata = 0;
reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0; reg [KEEP_WIDTH-1:0] tx_axis_tkeep = 0;
reg tx_axis_tvalid = 0; reg tx_axis_tvalid = 0;
reg tx_axis_tlast = 0; reg tx_axis_tlast = 0;
reg tx_axis_tuser = 0; reg [TX_USER_WIDTH-1:0] tx_axis_tuser = 0;
reg [DATA_WIDTH-1:0] serdes_rx_data = 0; reg [DATA_WIDTH-1:0] serdes_rx_data = 0;
reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1; reg [HDR_WIDTH-1:0] serdes_rx_hdr = 1;
reg [TX_PTP_TS_WIDTH-1:0] tx_ptp_ts = 0;
reg [RX_PTP_TS_WIDTH-1:0] rx_ptp_ts = 0;
reg [7:0] ifg_delay = 0; reg [7:0] ifg_delay = 0;
reg tx_prbs31_enable = 0; reg tx_prbs31_enable = 0;
reg rx_prbs31_enable = 0; reg rx_prbs31_enable = 0;
@ -71,10 +83,13 @@ wire [DATA_WIDTH-1:0] rx_axis_tdata;
wire [KEEP_WIDTH-1:0] rx_axis_tkeep; wire [KEEP_WIDTH-1:0] rx_axis_tkeep;
wire rx_axis_tvalid; wire rx_axis_tvalid;
wire rx_axis_tlast; wire rx_axis_tlast;
wire rx_axis_tuser; wire [RX_USER_WIDTH-1:0] rx_axis_tuser;
wire [DATA_WIDTH-1:0] serdes_tx_data; wire [DATA_WIDTH-1:0] serdes_tx_data;
wire [HDR_WIDTH-1:0] serdes_tx_hdr; wire [HDR_WIDTH-1:0] serdes_tx_hdr;
wire serdes_rx_bitslip; wire serdes_rx_bitslip;
wire [TX_PTP_TS_WIDTH-1:0] tx_axis_ptp_ts;
wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag;
wire tx_axis_ptp_ts_valid;
wire [1:0] tx_start_packet; wire [1:0] tx_start_packet;
wire tx_error_underflow; wire tx_error_underflow;
wire [1:0] rx_start_packet; wire [1:0] rx_start_packet;
@ -102,6 +117,8 @@ initial begin
tx_axis_tuser, tx_axis_tuser,
serdes_rx_data, serdes_rx_data,
serdes_rx_hdr, serdes_rx_hdr,
tx_ptp_ts,
rx_ptp_ts,
ifg_delay, ifg_delay,
tx_prbs31_enable, tx_prbs31_enable,
rx_prbs31_enable rx_prbs31_enable
@ -116,6 +133,9 @@ initial begin
serdes_tx_data, serdes_tx_data,
serdes_tx_hdr, serdes_tx_hdr,
serdes_rx_bitslip, serdes_rx_bitslip,
tx_axis_ptp_ts,
tx_axis_ptp_ts_tag,
tx_axis_ptp_ts_valid,
tx_start_packet, tx_start_packet,
tx_error_underflow, tx_error_underflow,
rx_error_count, rx_error_count,
@ -140,6 +160,16 @@ eth_mac_phy_10g #(
.ENABLE_PADDING(ENABLE_PADDING), .ENABLE_PADDING(ENABLE_PADDING),
.ENABLE_DIC(ENABLE_DIC), .ENABLE_DIC(ENABLE_DIC),
.MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH),
.PTP_PERIOD_NS(PTP_PERIOD_NS),
.PTP_PERIOD_FNS(PTP_PERIOD_FNS),
.TX_PTP_TS_ENABLE(TX_PTP_TS_ENABLE),
.TX_PTP_TS_WIDTH(TX_PTP_TS_WIDTH),
.TX_PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE),
.TX_PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH),
.RX_PTP_TS_ENABLE(RX_PTP_TS_ENABLE),
.RX_PTP_TS_WIDTH(RX_PTP_TS_WIDTH),
.TX_USER_WIDTH(TX_USER_WIDTH),
.RX_USER_WIDTH(RX_USER_WIDTH),
.BIT_REVERSE(BIT_REVERSE), .BIT_REVERSE(BIT_REVERSE),
.SCRAMBLER_DISABLE(SCRAMBLER_DISABLE), .SCRAMBLER_DISABLE(SCRAMBLER_DISABLE),
.PRBS31_ENABLE(PRBS31_ENABLE), .PRBS31_ENABLE(PRBS31_ENABLE),
@ -167,6 +197,11 @@ UUT (
.serdes_rx_data(serdes_rx_data), .serdes_rx_data(serdes_rx_data),
.serdes_rx_hdr(serdes_rx_hdr), .serdes_rx_hdr(serdes_rx_hdr),
.serdes_rx_bitslip(serdes_rx_bitslip), .serdes_rx_bitslip(serdes_rx_bitslip),
.tx_ptp_ts(tx_ptp_ts),
.rx_ptp_ts(rx_ptp_ts),
.tx_axis_ptp_ts(tx_axis_ptp_ts),
.tx_axis_ptp_ts_tag(tx_axis_ptp_ts_tag),
.tx_axis_ptp_ts_valid(tx_axis_ptp_ts_valid),
.tx_start_packet(tx_start_packet), .tx_start_packet(tx_start_packet),
.tx_error_underflow(tx_error_underflow), .tx_error_underflow(tx_error_underflow),
.rx_start_packet(rx_start_packet), .rx_start_packet(rx_start_packet),