fpga: lib: Add ZPU support to SV transport adapter

Original-commit: 105d8d1661d76bfe7264798a691b061366c94898
This commit is contained in:
Wade Fife
2023-01-10 14:18:59 -08:00
committed by michael-west
parent c847bec9e1
commit 6c4c231aa5
5 changed files with 282 additions and 222 deletions
@@ -10,10 +10,12 @@
module eth_ifc_all_tb; module eth_ifc_all_tb;
eth_ifc_tb #(.TEST_NAME("ORIGINAL"), .ENET_W(64), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(0)) ORIGINAL (); eth_ifc_tb #(.TEST_NAME("ORIGINAL"), .ENET_W(64), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(0), .PREAMBLE_BYTES(6), .CPU_PREAMBLE(0)) ORIGINAL ();
eth_ifc_tb #(.TEST_NAME("64B"), .ENET_W(64), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1)) ETH64 (); eth_ifc_tb #(.TEST_NAME("64B_X4XX"), .ENET_W(64), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1), .PREAMBLE_BYTES(0), .CPU_PREAMBLE(0)) ETH64_X4XX ();
eth_ifc_tb #(.TEST_NAME("512B"), .ENET_W(512), .CPU_W(64), .CHDR_W(512), .SV_ETH_IFC(1)) ETH512_CHDR512 (); eth_ifc_tb #(.TEST_NAME("64B_N3XX"), .ENET_W(64), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1), .PREAMBLE_BYTES(6), .CPU_PREAMBLE(0)) ETH64_N3XX ();
eth_ifc_tb #(.TEST_NAME("512_64B"), .ENET_W(512), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1)) ETH512_CHDR64 (); eth_ifc_tb #(.TEST_NAME("64B_X3XX"), .ENET_W(64), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1), .PREAMBLE_BYTES(6), .CPU_PREAMBLE(1)) ETH64_X3XX ();
eth_ifc_tb #(.TEST_NAME("512_128B"), .ENET_W(512), .CPU_W(64), .CHDR_W(128), .SV_ETH_IFC(1)) ETH512_CHDR128 (); eth_ifc_tb #(.TEST_NAME("512B"), .ENET_W(512), .CPU_W(64), .CHDR_W(512), .SV_ETH_IFC(1), .PREAMBLE_BYTES(0), .CPU_PREAMBLE(0)) ETH512_CHDR512 ();
eth_ifc_tb #(.TEST_NAME("512_64B"), .ENET_W(512), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1), .PREAMBLE_BYTES(0), .CPU_PREAMBLE(0)) ETH512_CHDR64 ();
eth_ifc_tb #(.TEST_NAME("512_128B"), .ENET_W(512), .CPU_W(64), .CHDR_W(128), .SV_ETH_IFC(1), .PREAMBLE_BYTES(0), .CPU_PREAMBLE(0)) ETH512_CHDR128 ();
endmodule endmodule
+205 -181
View File
@@ -5,16 +5,36 @@
// //
// Module: eth_ifc_tb // Module: eth_ifc_tb
// //
// Description: Testbench for eth_interface // Description:
//
// Testbench for eth_ipv4_interface and eth_interface. Both DUTs should have
// the same behavior, but eth_interface only supports 64-bit and does not
// support having preamble bytes on the CPU interface.
//
// Parameters:
//
// TEST_NAME : Name of this test (for the reporting outputs)
// SV_ETH_IFC : If true, use eth_ipv4_interface (SystemVerilog) as the
// DUT, otherwise use eth_interface (Verilog, 64-bit only).
// ENET_W : Width of the Ethernet interface to simulate
// CPU_W : Width of the CPU interface to simulate
// CHDR_W : Width of the CHDR interface to simulate
// PREAMBLE_BYTES : Number of preamble bytes expected by then Ethernet
// interface. Can be 0 or 6.
// CPU_PREAMBLE : If true, then the CPU interface will expect
// PREAMBLE_BYTES (for ZPU). Otherwise it will expect 0
// bytes of preamble (for ARM CPU).
// //
module eth_ifc_tb #( module eth_ifc_tb #(
parameter TEST_NAME = "eth_ifc_tb", parameter TEST_NAME = "eth_ifc_tb",
parameter SV_ETH_IFC = 1, parameter SV_ETH_IFC = 1,
parameter ENET_W = 64, parameter ENET_W = 64,
parameter CPU_W = 64, parameter CPU_W = 64,
parameter CHDR_W = 64 parameter CHDR_W = 64,
)( parameter PREAMBLE_BYTES = 0,
parameter CPU_PREAMBLE = 0
) (
/* no IO */ /* no IO */
); );
// Include macros and time declarations for use with PkgTestExec // Include macros and time declarations for use with PkgTestExec
@@ -43,7 +63,6 @@ module eth_ifc_tb #(
localparam ETH_PERIOD = (ENET_W==512) ? 3.1:5.0; localparam ETH_PERIOD = (ENET_W==512) ? 3.1:5.0;
// can set PREAMBLE_BYTES to 0 or 6 if SV_ETH_IFC, but otherwise // can set PREAMBLE_BYTES to 0 or 6 if SV_ETH_IFC, but otherwise
// it's hard-coded to 6. (0 is normal for 100G)(6 is normal for old Xge) // it's hard-coded to 6. (0 is normal for 100G)(6 is normal for old Xge)
localparam PREAMBLE_BYTES = SV_ETH_IFC ? 0 : 6;
// Include for register offsets // Include for register offsets
`include "../eth_regs.vh" `include "../eth_regs.vh"
// allows the DUT to push full words and tb does not check tuser/tkeep of packets it's transmitting // allows the DUT to push full words and tb does not check tuser/tkeep of packets it's transmitting
@@ -139,9 +158,9 @@ module eth_ifc_tb #(
if (SV_ETH_IFC) begin : gen_new_dut if (SV_ETH_IFC) begin : gen_new_dut
eth_ipv4_interface #( eth_ipv4_interface #(
.PREAMBLE_BYTES(PREAMBLE_BYTES), .PREAMBLE_BYTES(PREAMBLE_BYTES),
.CPU_PREAMBLE(CPU_PREAMBLE),
.CPU_FIFO_SIZE(MTU), .CPU_FIFO_SIZE(MTU),
.CHDR_FIFO_SIZE(MTU), .CHDR_FIFO_SIZE(MTU),
.PROTOVER(PROTOVER), .PROTOVER(PROTOVER),
@@ -150,7 +169,7 @@ module eth_ifc_tb #(
.RT_TBL_SIZE(RT_TBL_SIZE), .RT_TBL_SIZE(RT_TBL_SIZE),
.BASE(BASE),.SYNC(SYNC), .BASE(BASE),.SYNC(SYNC),
.ENET_W(ENET_W),.CPU_W(CPU_W),.CHDR_W(CHDR_W) .ENET_W(ENET_W),.CPU_W(CPU_W),.CHDR_W(CHDR_W)
) eth_interface ( ) eth_ipv4_interface_i (
.bus_clk(clk),.bus_rst(reset),.eth_pause_req(),.* .bus_clk(clk),.bus_rst(reset),.eth_pause_req(),.*
); );
end else begin : gen_old_dut end else begin : gen_old_dut
@@ -229,7 +248,7 @@ module eth_ifc_tb #(
.PROTOVER(PROTOVER), .NODE_INST(NODE_INST), .MTU(MTU), .PROTOVER(PROTOVER), .NODE_INST(NODE_INST), .MTU(MTU),
.REG_AWIDTH(REG_AWIDTH), .RT_TBL_SIZE(RT_TBL_SIZE), .REG_AWIDTH(REG_AWIDTH), .RT_TBL_SIZE(RT_TBL_SIZE),
.BASE(BASE) .BASE(BASE)
) eth_interface ( ) eth_interface_i (
.*, .*,
.my_udp_port (my_udp_chdr_port) .my_udp_port (my_udp_chdr_port)
); );
@@ -281,6 +300,7 @@ module eth_ifc_tb #(
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
task test_reset(); task test_reset();
test.start_test({TEST_NAME,"::Wait for Reset"}, 10us);
wait(!reset); wait(!reset);
repeat (10) @(posedge clk); repeat (10) @(posedge clk);
test.end_test(); test.end_test();
@@ -355,12 +375,12 @@ module eth_ifc_tb #(
typedef ChdrPacket #(CHDR_W,CHDR_USER_W) ChdrPacket_t; typedef ChdrPacket #(CHDR_W,CHDR_USER_W) ChdrPacket_t;
task automatic test_ethcpu(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0); task automatic test_ethcpu(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
TestExec test_e2c = new();
automatic EthXportPacket_t send[$]; automatic EthXportPacket_t send[$];
automatic CpuXportPacket_t expected[$]; automatic CpuXportPacket_t expected[$];
automatic int sample_sum = 0; automatic int sample_sum = 0;
test_e2c.start_test({TEST_NAME,"::Ethernet to CPU"}, 60us); $display("%s::Ethernet to CPU", TEST_NAME);
// This path is // This path is
// eth_rx -> s_mac(eth_adapter) -> s_mac(eth_dispatch) -> // eth_rx -> s_mac(eth_adapter) -> s_mac(eth_dispatch) ->
//// in_reg(AXI_FIFO)(SIZE=1) //// in_reg(AXI_FIFO)(SIZE=1)
@@ -377,11 +397,21 @@ module eth_ifc_tb #(
automatic ipv4_hdr_t ipv4_hdr = DEFAULT_IPV4_HDR; automatic ipv4_hdr_t ipv4_hdr = DEFAULT_IPV4_HDR;
automatic udp_hdr_t udp_hdr; automatic udp_hdr_t udp_hdr;
automatic raw_pkt_t pay,udp_raw; automatic raw_pkt_t pay,udp_raw;
automatic int preamble; automatic int eth_preamble;
automatic int cpu_preamble;
if (PREAMBLE_BYTES == 6) preamble = NORMAL_PREAMBLE; // eth_preamble refers to the preamble to add or expect on the Ethernet
else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE; // interface whereas cpu_preamble is the preamble to add or expect on the
else $fatal(1, "Invalid PREAMBLE_BYTES"); // CPU interface. The CHDR interface never has a preamble.
if (PREAMBLE_BYTES == 6) begin
eth_preamble = NORMAL_PREAMBLE;
cpu_preamble = CPU_PREAMBLE ? NORMAL_PREAMBLE : NO_PREAMBLE;
end else if (PREAMBLE_BYTES == 0) begin
eth_preamble = NO_PREAMBLE;
cpu_preamble = NO_PREAMBLE;
end else begin
$fatal(1, "Invalid PREAMBLE_BYTES");
end
expected[i] = new; expected[i] = new;
send[i] = new; send[i] = new;
@@ -391,13 +421,13 @@ module eth_ifc_tb #(
.ramp_inc(1),.pkt(pay),.SWIDTH(8)); .ramp_inc(1),.pkt(pay),.SWIDTH(8));
sample_sum += num_samples[i]; sample_sum += num_samples[i];
udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay, udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
.preamble(preamble)); .preamble(eth_preamble));
send[i].push_bytes(udp_raw); send[i].push_bytes(udp_raw);
send[i].tkeep_to_tuser(.ERROR_PROB(ERROR_PROB)); send[i].tkeep_to_tuser(.ERROR_PROB(ERROR_PROB));
// rebuild the expected packet for comparison without the preamble // rebuild the expected packet for comparison without the preamble
udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay, udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
.preamble(NO_PREAMBLE)); .preamble(cpu_preamble));
expected[i].push_bytes(udp_raw); expected[i].push_bytes(udp_raw);
expected[i].tkeep_to_tuser(); expected[i].tkeep_to_tuser();
@@ -439,17 +469,17 @@ module eth_ifc_tb #(
void'(expected.pop_front()); void'(expected.pop_front());
++drop_count; ++drop_count;
++pkt_num; ++pkt_num;
$display("Droped packet %d",pkt_num); $display("Dropped packet: %d",pkt_num);
`ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2c"); `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2c");
end end
if (expected.size() > 0) begin if (expected.size() > 0) begin
++pkt_num; ++pkt_num;
$display("Rcvd packet %d",pkt_num); $display("Received packet: %d",pkt_num);
void'(expected.pop_front()); void'(expected.pop_front());
end end
end end
if (SV_ETH_IFC) begin if (SV_ETH_IFC) begin
$display("Verify drop count is %d",drop_count); $display("Drop count: %d",drop_count);
reg_rd_check(REG_CPU_DROPPED,drop_count); reg_rd_check(REG_CPU_DROPPED,drop_count);
end end
end else begin end else begin
@@ -464,8 +494,6 @@ module eth_ifc_tb #(
end end
end end
join join
test_e2c.end_test();
endtask : test_ethcpu endtask : test_ethcpu
task automatic wait_for_udp_packets(int udp_dest_port); task automatic wait_for_udp_packets(int udp_dest_port);
@@ -491,12 +519,11 @@ module eth_ifc_tb #(
task automatic test_cpueth(int num_samples[$]); task automatic test_cpueth(int num_samples[$]);
TestExec test_c2e = new();
automatic CpuXportPacket_t send[$]; automatic CpuXportPacket_t send[$];
automatic EthXportPacket_t expected[$]; automatic EthXportPacket_t expected[$];
automatic int sample_sum = 0; automatic int sample_sum = 0;
test_c2e.start_test({TEST_NAME,"::CPU to Ethernet"}, 60us); $display("%s::CPU to Ethernet", TEST_NAME);
// This path is // This path is
// c2e -> (eth_adapter) s_cpu -> // c2e -> (eth_adapter) s_cpu ->
//// (ARM_DEFRAMER)(IF ARM) //// (ARM_DEFRAMER)(IF ARM)
@@ -522,7 +549,7 @@ module eth_ifc_tb #(
.ramp_inc(1),.pkt(pay),.SWIDTH(8)); .ramp_inc(1),.pkt(pay),.SWIDTH(8));
sample_sum += num_samples[i]; sample_sum += num_samples[i];
udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay, udp_raw = build_udp_pkt(eth_hdr,ipv4_hdr,udp_hdr,pay,
.preamble(NO_PREAMBLE)); .preamble(CPU_PREAMBLE ? preamble : NO_PREAMBLE));
send[i].push_bytes(udp_raw); send[i].push_bytes(udp_raw);
send[i].tkeep_to_tuser(); send[i].tkeep_to_tuser();
@@ -564,9 +591,8 @@ module eth_ifc_tb #(
end end
end end
join join
test_c2e.end_test();
endtask : test_cpueth endtask : test_cpueth
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Ethernet to CHDR test // Ethernet to CHDR test
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -604,12 +630,12 @@ module eth_ifc_tb #(
endfunction : unflatten_chdr endfunction : unflatten_chdr
task automatic test_ethchdr(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0); task automatic test_ethchdr(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
TestExec test_e2v = new();
automatic EthXportPacket_t send[$]; automatic EthXportPacket_t send[$];
automatic ChdrXportPacket_t expected[$]; automatic ChdrXportPacket_t expected[$];
automatic int sample_sum = 0; automatic int sample_sum = 0;
test_e2v.start_test({TEST_NAME,"::Ethernet to CHDR"}, 60us); $display("%s::Ethernet to CHDR", TEST_NAME);
// This path is // This path is
// eth_rx -> s_mac(eth_adapter) -> s_mac(eth_dispatch) -> // eth_rx -> s_mac(eth_adapter) -> s_mac(eth_dispatch) ->
//// in_reg(AXI_FIFO)(SIZE=1) //// in_reg(AXI_FIFO)(SIZE=1)
@@ -715,17 +741,17 @@ module eth_ifc_tb #(
void'(expected.pop_front()); void'(expected.pop_front());
++drop_count; ++drop_count;
++pkt_num; ++pkt_num;
$display("Dropped packet %d",pkt_num); $display("Dropped packet: %d",pkt_num);
`ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2v"); `ASSERT_ERROR(drop_count < EXPECT_DROPS,"Exceeded anticipated number of dropped packets e2v");
end end
if (expected.size() > 0) begin if (expected.size() > 0) begin
++pkt_num; ++pkt_num;
$display("Rcvd packet %d",pkt_num); $display("Received packet: %d",pkt_num);
void'(expected.pop_front()); void'(expected.pop_front());
end end
end end
if (SV_ETH_IFC) begin if (SV_ETH_IFC) begin
$display("Verify drop count is %d",drop_count); $display("Drop count: %d",drop_count);
reg_rd_check(REG_CHDR_DROPPED,drop_count); reg_rd_check(REG_CHDR_DROPPED,drop_count);
end end
end else begin end else begin
@@ -740,17 +766,14 @@ module eth_ifc_tb #(
end end
end end
join join
test_e2v.end_test();
endtask : test_ethchdr; endtask : test_ethchdr;
task automatic test_chdreth(int num_samples[$]); task automatic test_chdreth(int num_samples[$]);
TestExec test_v2e = new();
automatic ChdrXportPacket_t send[$]; automatic ChdrXportPacket_t send[$];
automatic EthXportPacket_t expected[$]; automatic EthXportPacket_t expected[$];
automatic int sample_sum = 0; automatic int sample_sum = 0;
test_v2e.start_test({TEST_NAME,"::CHDR to Ethernet"}, 60us); $display("%s::CHDR to Ethernet", TEST_NAME);
// This path is // This path is
// v2e -> s_chdr(eth_adapter) -> s_axis_rfnoc (xport_adapter_gen) -> // v2e -> s_chdr(eth_adapter) -> s_axis_rfnoc (xport_adapter_gen) ->
//// axi_demux_mgmt_filter (AXI_DEMUX) (IF ALLOW_DISC) (discards discovery packets) //// axi_demux_mgmt_filter (AXI_DEMUX) (IF ALLOW_DISC) (discards discovery packets)
@@ -877,8 +900,6 @@ module eth_ifc_tb #(
end end
end end
join join
test_v2e.end_test();
endtask : test_chdreth endtask : test_chdreth
integer cached_mgmt_seqnum = 0; integer cached_mgmt_seqnum = 0;
@@ -887,7 +908,6 @@ module eth_ifc_tb #(
`include "../../core/rfnoc_chdr_internal_utils.vh" `include "../../core/rfnoc_chdr_internal_utils.vh"
`include "../../xport/rfnoc_xport_types.vh" `include "../../xport/rfnoc_xport_types.vh"
task automatic test_chdr_endpoint(); task automatic test_chdr_endpoint();
TestExec test_e2v = new();
automatic EthXportPacket_t send[$]; automatic EthXportPacket_t send[$];
automatic EthXportPacket_t expected[$]; automatic EthXportPacket_t expected[$];
automatic int sample_sum = 0; automatic int sample_sum = 0;
@@ -909,8 +929,7 @@ module eth_ifc_tb #(
automatic int preamble; automatic int preamble;
localparam NODE_INST=0; localparam NODE_INST=0;
test_e2v.start_test({TEST_NAME,"::ChdrEndpoint"}, 60us); test.start_test({TEST_NAME,"::ChdrEndpoint"}, 60us);
expected[0] = new; expected[0] = new;
send[0] = new; send[0] = new;
@@ -1030,170 +1049,175 @@ module eth_ifc_tb #(
end end
end end
join join
test_e2v.end_test();
test.end_test();
endtask : test_chdr_endpoint endtask : test_chdr_endpoint
//---------------------------------------------------- //----------------------------------------------------
// Main test loop // Main test loop
//---------------------------------------------------- //----------------------------------------------------
initial begin : tb_main initial begin : tb_main
automatic int num_samples[$]; automatic int num_samples[$];
automatic int cpu_num_samples[$]; automatic int cpu_num_samples[$];
automatic int expected_drops; automatic int expected_drops;
localparam QUICK = 0; localparam QUICK = 0;
test.start_tb(TEST_NAME); test.start_tb(TEST_NAME);
test.start_test({TEST_NAME,"::Wait for Reset"}, 10us); // Check some parameters
clk_gen.start(); if (!SV_ETH_IFC) begin
eth_clk_gen.start(); `ASSERT_FATAL(CHDR_W == 64, "Legacy transport adapter only supports 64-bit CHDR");
clk_gen.reset(); `ASSERT_FATAL(CPU_PREAMBLE == 0, "CPU preamble is not supported on legacy transport adapter");
eth_clk_gen.reset(); end
eth.run(); clk_gen.start();
cpu.run(); eth_clk_gen.start();
v.run(); clk_gen.reset();
eth_clk_gen.reset();
eth.run();
cpu.run();
v.run();
test_reset(); test_reset();
test_registers(); test_registers();
test_chdr_endpoint();
test_chdr_endpoint(); // Check what happens if the input bandwidth exceeds
// the devices ability to consume packets
// This can happen in matched bandwidth cases
// if there is hold off from upstream
// Dropped packets exceed the drop count cause an error
// The actual dropped count is compared versus the real count
test.start_test({TEST_NAME,"::Input overrun"}, 200us);
// Check what happens if the input bandwidth exceeds eth.set_master_stall_prob(0);
// the devices ability to consume packets eth.set_slave_stall_prob(0);
// This can happen in matched bandwidth cases cpu.set_master_stall_prob(0);
// if there is hold off from upstream cpu.set_slave_stall_prob(0);
// Dropped packets exceed the drop count cause an error v.set_master_stall_prob(0);
// The actual dropped count is compared versus the real count v.set_slave_stall_prob(0);
test.start_test({TEST_NAME,"::Input overrun"}, 200us);
eth.set_master_stall_prob(0); num_samples = {7936,7936,7936,7936,7936,320,
eth.set_slave_stall_prob(0); 7936,7936,7936,7936,7936,320};
cpu.set_master_stall_prob(0);
cpu.set_slave_stall_prob(0);
v.set_master_stall_prob(0);
v.set_slave_stall_prob(0);
num_samples = {7936,7936,7936,7936,7936,320, // The actual number of expected drops depends on the
7936,7936,7936,7936,7936,320}; // bus width difference between ENET_W and CHDR/CPU_W
// The actual number of expected drops depends on the // in this SIM unlimited Ethernet bandwidth is coming in at over 300 MHZ
// bus width difference between ENET_W and CHDR/CPU_W // and output runs at 200 MHZ. This causes excess BW on transmitter even when matched.
expected_drops = 9;
// in this SIM unlimited Ethernet bandwidth is coming in at over 300 MHZ test_ethchdr(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
// and output runs at 200 MHZ. This causes excess BW on transmitter even when matched. test_ethcpu(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
expected_drops = 9;
test_ethchdr(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0)); test.end_test();
test_ethcpu(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
test.end_test();
eth.set_master_stall_prob(38); eth.set_master_stall_prob(38);
eth.set_slave_stall_prob(38); eth.set_slave_stall_prob(38);
cpu.set_master_stall_prob(38); cpu.set_master_stall_prob(38);
cpu.set_slave_stall_prob(38); cpu.set_slave_stall_prob(38);
v.set_master_stall_prob(38); v.set_master_stall_prob(38);
v.set_slave_stall_prob(38); v.set_slave_stall_prob(38);
num_samples = {1,2,3,4,5,6,7,8, num_samples = {1,2,3,4,5,6,7,8,
ENET_W/8-1,ENET_W/8,ENET_W/8+1, ENET_W/8-1,ENET_W/8,ENET_W/8+1,
2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1, 2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1,
CPU_W/8-1,CPU_W/8,CPU_W/8+1, CPU_W/8-1,CPU_W/8,CPU_W/8+1,
2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1, 2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1,
CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1, CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1,
2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1 2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1
}; };
// add some extra samples for CPU packets to try to get above the min // Add some extra samples for CPU packets to try to get above the min
//packet size of 64. (just the headers makes up 42 bytes) // packet size of 64 (just the headers make up 42 bytes). This way we still
//this way we still have some short packets to drop, but not as many. // have some short packets to drop, but not as many.
foreach (num_samples[i]) cpu_num_samples[i] = num_samples[i]+20; foreach (num_samples[i]) cpu_num_samples[i] = num_samples[i]+20;
test.start_test({TEST_NAME,"::PacketW Combos NO Errors"}, 10us); test.start_test({TEST_NAME,"::PacketW Combos NO Errors"}, 10us);
fork // run in parallel fork // run in parallel
// ethrx // ethrx
test_ethcpu(cpu_num_samples,.ERROR_PROB(0)); test_ethcpu(cpu_num_samples,.ERROR_PROB(0));
test_ethchdr(num_samples,.ERROR_PROB(0)); test_ethchdr(num_samples,.ERROR_PROB(0));
// ethtx // ethtx
test_chdreth(num_samples); test_chdreth(num_samples);
test_cpueth(num_samples); test_cpueth(num_samples);
join
test.end_test();
if (!QUICK) begin
test.start_test({TEST_NAME,"::PacketW Combos Errors"}, 10us);
fork // run in parallel
// ethrx
test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
test_ethchdr(num_samples,.ERROR_PROB(2));
// ethtx
test_chdreth(num_samples);
test_cpueth(num_samples);
join
test.end_test();
num_samples = {16,32,64,128,256,512,1024,1500,1522,9000};
test.start_test({TEST_NAME,"::Pwr2 NoErrors"}, 60us);
fork // run in parallel
// ethrx
test_ethcpu(cpu_num_samples,.ERROR_PROB(0));
test_ethchdr(num_samples,.ERROR_PROB(0));
// ethtx
test_chdreth(num_samples);
test_cpueth(num_samples);
join join
test.end_test(); test.end_test();
end
eth.set_master_stall_prob(0); if (!QUICK) begin
eth.set_slave_stall_prob(0);
cpu.set_master_stall_prob(0);
cpu.set_slave_stall_prob(0);
v.set_master_stall_prob(0);
v.set_slave_stall_prob(0);
num_samples = {1,2,3,4,5,6,7,8, test.start_test({TEST_NAME,"::PacketW Combos Errors"}, 10us);
ENET_W/8-1,ENET_W/8,ENET_W/8+1, fork // run in parallel
2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1, // ethrx
CPU_W/8-1,CPU_W/8,CPU_W/8+1, test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1, test_ethchdr(num_samples,.ERROR_PROB(2));
CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1, // ethtx
2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1 test_chdreth(num_samples);
}; test_cpueth(num_samples);
test.start_test({TEST_NAME,"::Pktw NoStall+Error"}, 10us); join
fork // run in parallel test.end_test();
// ethrx
test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
test_ethchdr(num_samples,.ERROR_PROB(2));
// ethtx
test_chdreth(num_samples);
test_cpueth(num_samples);
join
test.end_test();
// repeat with back to back cpu/chdr packets num_samples = {16,32,64,128,256,512,1024,1500,1522,9000};
test.start_test({TEST_NAME,"::Serial Pktw NoStall+Error"}, 10us); test.start_test({TEST_NAME,"::Pwr2 NoErrors"}, 60us);
fork // run in parallel fork // run in parallel
// ethrx // ethrx
begin test_ethcpu(cpu_num_samples,.ERROR_PROB(0));
test_ethcpu(cpu_num_samples,.ERROR_PROB(2)); test_ethchdr(num_samples,.ERROR_PROB(0));
test_ethchdr(num_samples,.ERROR_PROB(2)); // ethtx
end test_chdreth(num_samples);
// ethtx test_cpueth(num_samples);
begin join
test_chdreth(num_samples); test.end_test();
test_cpueth(num_samples); end
end
join
test.end_test();
// End the TB, but don't $finish, since we don't want to kill other eth.set_master_stall_prob(0);
// instances of this testbench that may be running. eth.set_slave_stall_prob(0);
test.end_tb(0); cpu.set_master_stall_prob(0);
cpu.set_slave_stall_prob(0);
v.set_master_stall_prob(0);
v.set_slave_stall_prob(0);
// Kill the clocks to end this instance of the testbench num_samples = {1,2,3,4,5,6,7,8,
clk_gen.kill(); ENET_W/8-1,ENET_W/8,ENET_W/8+1,
eth_clk_gen.kill(); 2*ENET_W/8-1,2*ENET_W/8,2*ENET_W/8+1,
CPU_W/8-1,CPU_W/8,CPU_W/8+1,
2*CPU_W/8-1,2*CPU_W/8,2*CPU_W/8+1,
CHDR_W/8-1,CHDR_W/8,CHDR_W/8+1,
2*CHDR_W/8-1,2*CHDR_W/8,2*CHDR_W/8+1
};
test.start_test({TEST_NAME,"::Pktw NoStall+Error"}, 10us);
fork // run in parallel
// ethrx
test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
test_ethchdr(num_samples,.ERROR_PROB(2));
// ethtx
test_chdreth(num_samples);
test_cpueth(num_samples);
join
test.end_test();
// repeat with back to back cpu/chdr packets
test.start_test({TEST_NAME,"::Serial Pktw NoStall+Error"}, 10us);
fork // run in parallel
// ethrx
begin
test_ethcpu(cpu_num_samples,.ERROR_PROB(2));
test_ethchdr(num_samples,.ERROR_PROB(2));
end
// ethtx
begin
test_chdreth(num_samples);
test_cpueth(num_samples);
end
join
test.end_test();
// End the TB, but don't $finish, since we don't want to kill other
// instances of this testbench that may be running.
test.end_tb(0);
// Kill the clocks to end this instance of the testbench
clk_gen.kill();
eth_clk_gen.kill();
end // initial begin end // initial begin
endmodule endmodule
+10 -5
View File
@@ -42,7 +42,10 @@
// NODE_INST : The node type to return for a node-info discovery // NODE_INST : The node type to return for a node-info discovery
// DROP_UNKNOWN_MAC : Drop packets not addressed to us? // DROP_UNKNOWN_MAC : Drop packets not addressed to us?
// DROP_MIN_PACKET : Drop packets smaller than 64 bytes? // DROP_MIN_PACKET : Drop packets smaller than 64 bytes?
// PREAMBLE_BYTES : Number of bytes of Preamble expected // PREAMBLE_BYTES : Number of bytes of preamble on Ethernet interface
// CPU_PREAMBLE : Set to 1 to use PREAMBLE_BYTES on CPU interface
// (for ZPU) or set to 0 to remove preamble on CPU
// interface (for ARM CPU).
// ADD_SOF : Add a SOF indication into the tuser field of the e2c // ADD_SOF : Add a SOF indication into the tuser field of the e2c
// path. If false use TKEEP instead of USER. // path. If false use TKEEP instead of USER.
// SYNC : Set to 1 if the c2e/e2c, v2e/e2v, and eth_rx/eth_tx are // SYNC : Set to 1 if the c2e/e2c, v2e/e2v, and eth_rx/eth_tx are
@@ -80,6 +83,7 @@ module eth_ipv4_chdr_adapter #(
bit DROP_UNKNOWN_MAC = 0, bit DROP_UNKNOWN_MAC = 0,
bit DROP_MIN_PACKET = 0, bit DROP_MIN_PACKET = 0,
int PREAMBLE_BYTES = 6, int PREAMBLE_BYTES = 6,
bit CPU_PREAMBLE = 0,
bit ADD_SOF = 1, bit ADD_SOF = 1,
bit SYNC = 0, bit SYNC = 0,
int ENET_W = 64, int ENET_W = 64,
@@ -180,11 +184,12 @@ module eth_ipv4_chdr_adapter #(
.CPU_FIFO_SIZE (CPU_FIFO_SIZE), .CPU_FIFO_SIZE (CPU_FIFO_SIZE),
.CHDR_FIFO_SIZE (CHDR_FIFO_SIZE), .CHDR_FIFO_SIZE (CHDR_FIFO_SIZE),
.PREAMBLE_BYTES (PREAMBLE_BYTES), .PREAMBLE_BYTES (PREAMBLE_BYTES),
.CPU_PREAMBLE (CPU_PREAMBLE),
.MAX_PACKET_BYTES (MAX_PACKET_BYTES), .MAX_PACKET_BYTES (MAX_PACKET_BYTES),
.DROP_UNKNOWN_MAC (DROP_UNKNOWN_MAC), .DROP_UNKNOWN_MAC (DROP_UNKNOWN_MAC),
.DROP_MIN_PACKET (DROP_MIN_PACKET), .DROP_MIN_PACKET (DROP_MIN_PACKET),
.ENET_W (ENET_W) .ENET_W (ENET_W)
) eth_dispatch_i ( ) eth_ipv4_chdr_dispatch_i (
.eth_pause_req (eth_pause_req), .eth_pause_req (eth_pause_req),
.eth_rx (eth_rx1), .eth_rx (eth_rx1),
.e2v (e2v1), .e2v (e2v1),
@@ -379,17 +384,17 @@ module eth_ipv4_chdr_adapter #(
end end
end end
if (PREAMBLE_BYTES > 0) begin : gen_add_preamble if (PREAMBLE_BYTES > 0 && !CPU_PREAMBLE) begin : gen_c2e_add_preamble
// Add pad of PREAMBLE_BYTES empty bytes to the ethernet packet going // Add pad of PREAMBLE_BYTES empty bytes to the ethernet packet going
// from the CPU to the SFP. This padding added before MAC addresses // from the CPU to the SFP. This padding added before MAC addresses
// aligns the source and destination IP addresses, UDP headers etc. // aligns the source and destination IP addresses, UDP headers etc.
// Note that the xge_mac_wrapper strips this padding to recreate the // Note that the xge_mac_wrapper strips this padding to recreate the
// ethernet packet. // ethernet packet.
axi4s_add_bytes #(.ADD_START(0),.ADD_BYTES(PREAMBLE_BYTES) axi4s_add_bytes #(.ADD_START(0),.ADD_BYTES(PREAMBLE_BYTES)
) add_header ( ) axi4s_add_bytes_c2e (
.i(c2e1), .o(c2e2) .i(c2e1), .o(c2e2)
); );
end else begin : gen_no_preamble end else begin : gen_c2e_no_preamble
always_comb begin : c2e2_assign always_comb begin : c2e2_assign
`AXI4S_ASSIGN(c2e2,c2e1) `AXI4S_ASSIGN(c2e2,c2e1)
end end
+54 -30
View File
@@ -19,7 +19,10 @@
// Parameters: // Parameters:
// - CPU_FIFO_SIZE: Log2 of the FIFO depth (in bytes) for the CPU egress path // - CPU_FIFO_SIZE: Log2 of the FIFO depth (in bytes) for the CPU egress path
// - CHDR_FIFO_SIZE: Log2 of the FIFO depth (in bytes) for the CHDR egress path // - CHDR_FIFO_SIZE: Log2 of the FIFO depth (in bytes) for the CHDR egress path
// - PREAMBLE_BYTES: Number of bytes in the Preamble // - PREAMBLE_BYTES: Number of bytes of preamble on Ethernet interface
// - CPU_PREAMBLE: Set to 1 to use PREAMBLE_BYTES on CPU interface (for ZPU)
// or set to 0 to remove preamble on CPU interface (for ARM
// CPU).
// - DROP_UNKNOWN_MAC: Drop packets not addressed to us? // - DROP_UNKNOWN_MAC: Drop packets not addressed to us?
// - DROP_MIN_PACKET: Drop packets smaller than 64 bytes? // - DROP_MIN_PACKET: Drop packets smaller than 64 bytes?
// - ENET_W: Width of AXI bus going to Ethernet Mac // - ENET_W: Width of AXI bus going to Ethernet Mac
@@ -42,13 +45,14 @@ module eth_ipv4_chdr_dispatch #(
int CPU_FIFO_SIZE = $clog2(8*1024), int CPU_FIFO_SIZE = $clog2(8*1024),
int CHDR_FIFO_SIZE = $clog2(8*1024), int CHDR_FIFO_SIZE = $clog2(8*1024),
int PREAMBLE_BYTES = 6, int PREAMBLE_BYTES = 6,
int CPU_PREAMBLE = 0,
int MAX_PACKET_BYTES = 2**16-1, int MAX_PACKET_BYTES = 2**16-1,
bit DROP_UNKNOWN_MAC = 0, bit DROP_UNKNOWN_MAC = 0,
bit DROP_MIN_PACKET = 0, bit DROP_MIN_PACKET = 0,
int ENET_W = 64 int ENET_W = 64
)( )(
// Clock domain: eth_rx.clk (other interface clocks are unused) // Clock domain: eth_rx.clk (other interface clocks are unused)
// AXI-Stream interfaces // AXI-Stream interfaces
output logic eth_pause_req, output logic eth_pause_req,
AxiStreamIf.slave eth_rx, // tUser={error,trailing bytes}; AxiStreamIf.slave eth_rx, // tUser={error,trailing bytes};
@@ -133,14 +137,17 @@ module eth_ipv4_chdr_dispatch #(
// tUser = {not used}; // tUser = {not used};
AxiStreamIf #(.DATA_WIDTH(ENET_W),.TKEEP(0),.TUSER(0)) AxiStreamIf #(.DATA_WIDTH(ENET_W),.TKEEP(0),.TUSER(0))
chdr1(eth_rx.clk,eth_rx.rst); chdr1(eth_rx.clk,eth_rx.rst);
// tUser = {not used};
AxiStreamIf #(.DATA_WIDTH(ENET_W),.TKEEP(0),.TUSER(0),.MAX_PACKET_BYTES(MAX_PACKET_BYTES))
chdr2(eth_rx.clk,eth_rx.rst);
// chdr_out_fifo // chdr_out_fifo
// e2v(OUTPUT) // e2v(OUTPUT)
//--------------------------------------- //---------------------------------------
// Strip Bytes // Strip Preamble Bytes
//--------------------------------------- //---------------------------------------
if (PREAMBLE_BYTES > 0) begin : gen_strip_preamble if (PREAMBLE_BYTES > 0 && !CPU_PREAMBLE) begin : gen_strip_preamble
// Strip the preamble // Keep the preamble since the CPU expects it.
always_comb begin always_comb begin
`AXI4S_ASSIGN(inp,eth_rx); `AXI4S_ASSIGN(inp,eth_rx);
end end
@@ -148,7 +155,8 @@ module eth_ipv4_chdr_dispatch #(
) strip_preamble ( ) strip_preamble (
.i(inp),.o(in0) .i(inp),.o(in0)
); );
end else begin : gen_no_preamble end else begin : gen_no_strip_preamble
// Remove the preamble since CHDR and CPU don't expect it.
always_comb begin always_comb begin
`AXI4S_ASSIGN(in0,eth_rx); `AXI4S_ASSIGN(in0,eth_rx);
end end
@@ -220,12 +228,12 @@ module eth_ipv4_chdr_dispatch #(
reached_min_packet_old <= 1'b0; reached_min_packet_old <= 1'b0;
// Statemachine Decisions // Statemachine Decisions
eth_dst_is_broadcast <=1'b0; eth_dst_is_broadcast <= 1'b0;
eth_dst_is_me <=1'b0; eth_dst_is_me <= 1'b0;
udp_dst_is_me <=1'b0; udp_dst_is_me <= 1'b0;
ipv4_dst_is_me <=1'b0; ipv4_dst_is_me <= 1'b0;
ipv4_protocol_is_udp <=1'b0; ipv4_protocol_is_udp <= 1'b0;
eth_type_is_ipv4 <=1'b0; eth_type_is_ipv4 <= 1'b0;
end else begin end else begin
eth_dst_addr_old <= eth_dst_addr_new; eth_dst_addr_old <= eth_dst_addr_new;
eth_src_addr_old <= eth_src_addr_new; eth_src_addr_old <= eth_src_addr_new;
@@ -248,22 +256,24 @@ module eth_ipv4_chdr_dispatch #(
end end
end end
// get the fields - don't use assign. assign will not activate with changes to in0. // Get the fields - don't use assign. assign will not activate with changes
// to in0.
localparam int OFFSET = CPU_PREAMBLE ? PREAMBLE_BYTES : 0;
always_comb begin : get_fields always_comb begin : get_fields
eth_dst_addr_new = in0.get_packet_field48(eth_dst_addr_old,DST_MAC_BYTE,.NETWORK_ORDER(1)); eth_dst_addr_new = in0.get_packet_field48(eth_dst_addr_old, OFFSET+DST_MAC_BYTE, .NETWORK_ORDER(1));
eth_src_addr_new = in0.get_packet_field48(eth_src_addr_old,SRC_MAC_BYTE,.NETWORK_ORDER(1)); eth_src_addr_new = in0.get_packet_field48(eth_src_addr_old, OFFSET+SRC_MAC_BYTE, .NETWORK_ORDER(1));
ip_version_new = in0.get_packet_byte(ip_version_old,IP_VERSION_BYTE); ip_version_new = in0.get_packet_byte (ip_version_old, OFFSET+IP_VERSION_BYTE);
ip_protocol_new = in0.get_packet_byte(ip_protocol_old,PROTOCOL_BYTE); ip_protocol_new = in0.get_packet_byte (ip_protocol_old, OFFSET+PROTOCOL_BYTE );
ipv4_src_addr_new = in0.get_packet_field32(ipv4_src_addr_old,SRC_IP_BYTE,.NETWORK_ORDER(1)); ipv4_src_addr_new = in0.get_packet_field32(ipv4_src_addr_old, OFFSET+SRC_IP_BYTE, .NETWORK_ORDER(1));
ipv4_dst_addr_new = in0.get_packet_field32(ipv4_dst_addr_old,DST_IP_BYTE,.NETWORK_ORDER(1)); ipv4_dst_addr_new = in0.get_packet_field32(ipv4_dst_addr_old, OFFSET+DST_IP_BYTE, .NETWORK_ORDER(1));
udp_src_port_new = in0.get_packet_field16(udp_src_port_old,SRC_PORT_BYTE,.NETWORK_ORDER(1)); udp_src_port_new = in0.get_packet_field16(udp_src_port_old, OFFSET+SRC_PORT_BYTE, .NETWORK_ORDER(1));
udp_dst_port_new = in0.get_packet_field16(udp_dst_port_old,DST_PORT_BYTE,.NETWORK_ORDER(1)); udp_dst_port_new = in0.get_packet_field16(udp_dst_port_old, OFFSET+DST_PORT_BYTE, .NETWORK_ORDER(1));
eth_type_new = in0.get_packet_field16(eth_type_old,ETH_TYPE_BYTE,.NETWORK_ORDER(1)); eth_type_new = in0.get_packet_field16(eth_type_old, OFFSET+ETH_TYPE_BYTE, .NETWORK_ORDER(1));
end end
always_comb begin : reached_bytes always_comb begin : reached_bytes
reached_min_packet_new = in1.reached_packet_byte(MIN_PACKET_SIZE_BYTE); reached_min_packet_new = in1.reached_packet_byte(OFFSET+MIN_PACKET_SIZE_BYTE);
reached_end_of_udp = in1.reached_packet_byte(DST_PORT_BYTE+3);// we have enough to decide reached_end_of_udp = in1.reached_packet_byte(OFFSET+DST_PORT_BYTE+3);// we have enough to decide
end end
// calculate error conditions // calculate error conditions
@@ -498,7 +508,7 @@ module eth_ipv4_chdr_dispatch #(
.i(cpu0),.o(cpu1) .i(cpu0),.o(cpu1)
); );
// The CPU can be slow to respond (relative to packet wirespeed) so // The CPU can be slow to respond (relative to packet wire speed) so
// extra buffer for packets destined there so it doesn't back up. // extra buffer for packets destined there so it doesn't back up.
axi4s_fifo #( axi4s_fifo #(
.SIZE(CPU_FIFO_SIZE-$clog2(ENET_W/8)) .SIZE(CPU_FIFO_SIZE-$clog2(ENET_W/8))
@@ -521,9 +531,9 @@ module eth_ipv4_chdr_dispatch #(
); );
// The transport should hook up to a crossbar downstream, which // The transport should hook up to a crossbar downstream, which
// may backpressure this module because it is in the middle of // may back-pressure this module because it is in the middle of
// transferring a packet. To ensure that upstream logic is not // transferring a packet. To ensure that upstream logic is not
// blocked, we instantiate at laeast one packet of buffering here. // blocked, we instantiate at least one packet of buffering here.
// The actual size is set by CHDR_FIFO_SIZE. // The actual size is set by CHDR_FIFO_SIZE.
logic [15:0] chdr_occupied; logic [15:0] chdr_occupied;
logic [15:0] chdr_occupied_q; logic [15:0] chdr_occupied_q;
@@ -532,11 +542,25 @@ module eth_ipv4_chdr_dispatch #(
.SIZE(CHDR_FIFO_WORD_SIZE) .SIZE(CHDR_FIFO_WORD_SIZE)
) chdr_fifo_i ( ) chdr_fifo_i (
.clear(1'b0),.space(),.occupied(chdr_occupied), .clear(1'b0),.space(),.occupied(chdr_occupied),
.i(chdr1),.o(e2v) .i(chdr1),.o(chdr2)
); );
// documentation requires pause requests to be set for a minimum of 16 clocks. // Remove the preamble on the CHDR path if it was not already removed.
// I'm providing the same gauranteed min time in the set and clear direction if (PREAMBLE_BYTES > 0 && CPU_PREAMBLE) begin : gen_strip_chdr_preamble
axi4s_remove_bytes #(
.REM_START(0), .REM_END(PREAMBLE_BYTES-1)
) strip_preamble (
.i(chdr2), .o(e2v)
);
end else begin : gen_no_strip_chdr_preamble
always_comb begin
`AXI4S_ASSIGN(e2v, chdr2);
end
end
// Documentation requires pause requests to be set for a minimum of 16
// clocks. I'm providing the same guaranteed min time in the set and clear
// direction.
logic [3:0] pause_timer; logic [3:0] pause_timer;
typedef enum logic [1:0] { typedef enum logic [1:0] {
ST_IDLE = 2'd0, ST_IDLE = 2'd0,
+6 -1
View File
@@ -20,7 +20,10 @@
// NODE_INST : The node type to return for a node-info discovery // NODE_INST : The node type to return for a node-info discovery
// DROP_UNKNOWN_MAC : Drop packets not addressed to us? // DROP_UNKNOWN_MAC : Drop packets not addressed to us?
// DROP_MIN_PACKET : Drop packets smaller than 64 bytes? // DROP_MIN_PACKET : Drop packets smaller than 64 bytes?
// PREAMBLE_BYTES : Number of bytes of Preamble expected // PREAMBLE_BYTES : Number of bytes of preamble on Ethernet interface
// CPU_PREAMBLE : Set to 1 to use PREAMBLE_BYTES on CPU interface
// (for ZPU) or set to 0 to remove preamble on CPU
// interface (for ARM CPU).
// ADD_SOF : Add a SOF indication into the tuser field of e2c // ADD_SOF : Add a SOF indication into the tuser field of e2c
// SYNC : Set to 1 if the c2e/e2c, v2e/e2v, and eth_rx/eth_tx are // SYNC : Set to 1 if the c2e/e2c, v2e/e2v, and eth_rx/eth_tx are
// synchronous to each other. Set to 0 to insert clock // synchronous to each other. Set to 0 to insert clock
@@ -47,6 +50,7 @@ module eth_ipv4_interface #(
bit DROP_UNKNOWN_MAC = 0, bit DROP_UNKNOWN_MAC = 0,
bit DROP_MIN_PACKET = 0, bit DROP_MIN_PACKET = 0,
int PREAMBLE_BYTES = 6, int PREAMBLE_BYTES = 6,
bit CPU_PREAMBLE = 0,
bit ADD_SOF = 1, bit ADD_SOF = 1,
bit SYNC = 0, bit SYNC = 0,
bit PAUSE_EN = 0, bit PAUSE_EN = 0,
@@ -351,6 +355,7 @@ module eth_ipv4_interface #(
.DROP_UNKNOWN_MAC(DROP_UNKNOWN_MAC), .DROP_UNKNOWN_MAC(DROP_UNKNOWN_MAC),
.DROP_MIN_PACKET (DROP_MIN_PACKET ), .DROP_MIN_PACKET (DROP_MIN_PACKET ),
.PREAMBLE_BYTES (PREAMBLE_BYTES ), .PREAMBLE_BYTES (PREAMBLE_BYTES ),
.CPU_PREAMBLE (CPU_PREAMBLE ),
.ADD_SOF (ADD_SOF ), .ADD_SOF (ADD_SOF ),
.SYNC (SYNC ), .SYNC (SYNC ),
.ENET_W (ENET_W ), .ENET_W (ENET_W ),