fpga: lib: Add ZPU support to SV transport adapter
Original-commit: 105d8d1661d76bfe7264798a691b061366c94898
This commit is contained in:
@@ -10,10 +10,12 @@
|
||||
|
||||
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("64B"), .ENET_W(64), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1)) ETH64 ();
|
||||
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("512_64B"), .ENET_W(512), .CPU_W(64), .CHDR_W(64), .SV_ETH_IFC(1)) ETH512_CHDR64 ();
|
||||
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("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_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("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("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("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
|
||||
|
||||
@@ -5,7 +5,25 @@
|
||||
//
|
||||
// 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 #(
|
||||
@@ -13,7 +31,9 @@ module eth_ifc_tb #(
|
||||
parameter SV_ETH_IFC = 1,
|
||||
parameter ENET_W = 64,
|
||||
parameter CPU_W = 64,
|
||||
parameter CHDR_W = 64
|
||||
parameter CHDR_W = 64,
|
||||
parameter PREAMBLE_BYTES = 0,
|
||||
parameter CPU_PREAMBLE = 0
|
||||
) (
|
||||
/* no IO */
|
||||
);
|
||||
@@ -43,7 +63,6 @@ module eth_ifc_tb #(
|
||||
localparam ETH_PERIOD = (ENET_W==512) ? 3.1:5.0;
|
||||
// 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)
|
||||
localparam PREAMBLE_BYTES = SV_ETH_IFC ? 0 : 6;
|
||||
// Include for register offsets
|
||||
`include "../eth_regs.vh"
|
||||
// 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
|
||||
|
||||
eth_ipv4_interface #(
|
||||
.PREAMBLE_BYTES(PREAMBLE_BYTES),
|
||||
.CPU_PREAMBLE(CPU_PREAMBLE),
|
||||
.CPU_FIFO_SIZE(MTU),
|
||||
.CHDR_FIFO_SIZE(MTU),
|
||||
.PROTOVER(PROTOVER),
|
||||
@@ -150,7 +169,7 @@ module eth_ifc_tb #(
|
||||
.RT_TBL_SIZE(RT_TBL_SIZE),
|
||||
.BASE(BASE),.SYNC(SYNC),
|
||||
.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(),.*
|
||||
);
|
||||
end else begin : gen_old_dut
|
||||
@@ -229,7 +248,7 @@ module eth_ifc_tb #(
|
||||
.PROTOVER(PROTOVER), .NODE_INST(NODE_INST), .MTU(MTU),
|
||||
.REG_AWIDTH(REG_AWIDTH), .RT_TBL_SIZE(RT_TBL_SIZE),
|
||||
.BASE(BASE)
|
||||
) eth_interface (
|
||||
) eth_interface_i (
|
||||
.*,
|
||||
.my_udp_port (my_udp_chdr_port)
|
||||
);
|
||||
@@ -281,6 +300,7 @@ module eth_ifc_tb #(
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
task test_reset();
|
||||
test.start_test({TEST_NAME,"::Wait for Reset"}, 10us);
|
||||
wait(!reset);
|
||||
repeat (10) @(posedge clk);
|
||||
test.end_test();
|
||||
@@ -355,12 +375,12 @@ module eth_ifc_tb #(
|
||||
typedef ChdrPacket #(CHDR_W,CHDR_USER_W) ChdrPacket_t;
|
||||
|
||||
task automatic test_ethcpu(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
|
||||
TestExec test_e2c = new();
|
||||
automatic EthXportPacket_t send[$];
|
||||
automatic CpuXportPacket_t expected[$];
|
||||
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
|
||||
// eth_rx -> s_mac(eth_adapter) -> s_mac(eth_dispatch) ->
|
||||
//// in_reg(AXI_FIFO)(SIZE=1)
|
||||
@@ -377,11 +397,21 @@ module eth_ifc_tb #(
|
||||
automatic ipv4_hdr_t ipv4_hdr = DEFAULT_IPV4_HDR;
|
||||
automatic udp_hdr_t udp_hdr;
|
||||
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;
|
||||
else if (PREAMBLE_BYTES == 0) preamble = NO_PREAMBLE;
|
||||
else $fatal(1, "Invalid PREAMBLE_BYTES");
|
||||
// eth_preamble refers to the preamble to add or expect on the Ethernet
|
||||
// interface whereas cpu_preamble is the preamble to add or expect on the
|
||||
// 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;
|
||||
send[i] = new;
|
||||
@@ -391,13 +421,13 @@ module eth_ifc_tb #(
|
||||
.ramp_inc(1),.pkt(pay),.SWIDTH(8));
|
||||
sample_sum += num_samples[i];
|
||||
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].tkeep_to_tuser(.ERROR_PROB(ERROR_PROB));
|
||||
|
||||
// rebuild the expected packet for comparison without the preamble
|
||||
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].tkeep_to_tuser();
|
||||
|
||||
@@ -439,17 +469,17 @@ module eth_ifc_tb #(
|
||||
void'(expected.pop_front());
|
||||
++drop_count;
|
||||
++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");
|
||||
end
|
||||
if (expected.size() > 0) begin
|
||||
++pkt_num;
|
||||
$display("Rcvd packet %d",pkt_num);
|
||||
$display("Received packet: %d",pkt_num);
|
||||
void'(expected.pop_front());
|
||||
end
|
||||
end
|
||||
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);
|
||||
end
|
||||
end else begin
|
||||
@@ -464,8 +494,6 @@ module eth_ifc_tb #(
|
||||
end
|
||||
end
|
||||
join
|
||||
|
||||
test_e2c.end_test();
|
||||
endtask : test_ethcpu
|
||||
|
||||
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[$]);
|
||||
TestExec test_c2e = new();
|
||||
automatic CpuXportPacket_t send[$];
|
||||
automatic EthXportPacket_t expected[$];
|
||||
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
|
||||
// c2e -> (eth_adapter) s_cpu ->
|
||||
//// (ARM_DEFRAMER)(IF ARM)
|
||||
@@ -522,7 +549,7 @@ module eth_ifc_tb #(
|
||||
.ramp_inc(1),.pkt(pay),.SWIDTH(8));
|
||||
sample_sum += num_samples[i];
|
||||
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].tkeep_to_tuser();
|
||||
|
||||
@@ -564,9 +591,8 @@ module eth_ifc_tb #(
|
||||
end
|
||||
end
|
||||
join
|
||||
test_c2e.end_test();
|
||||
|
||||
endtask : test_cpueth
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Ethernet to CHDR test
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -604,12 +630,12 @@ module eth_ifc_tb #(
|
||||
endfunction : unflatten_chdr
|
||||
|
||||
task automatic test_ethchdr(int num_samples[$], int ERROR_PROB=2, int EXPECT_DROPS=0);
|
||||
TestExec test_e2v = new();
|
||||
automatic EthXportPacket_t send[$];
|
||||
automatic ChdrXportPacket_t expected[$];
|
||||
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
|
||||
// eth_rx -> s_mac(eth_adapter) -> s_mac(eth_dispatch) ->
|
||||
//// in_reg(AXI_FIFO)(SIZE=1)
|
||||
@@ -715,17 +741,17 @@ module eth_ifc_tb #(
|
||||
void'(expected.pop_front());
|
||||
++drop_count;
|
||||
++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");
|
||||
end
|
||||
if (expected.size() > 0) begin
|
||||
++pkt_num;
|
||||
$display("Rcvd packet %d",pkt_num);
|
||||
$display("Received packet: %d",pkt_num);
|
||||
void'(expected.pop_front());
|
||||
end
|
||||
end
|
||||
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);
|
||||
end
|
||||
end else begin
|
||||
@@ -740,17 +766,14 @@ module eth_ifc_tb #(
|
||||
end
|
||||
end
|
||||
join
|
||||
test_e2v.end_test();
|
||||
|
||||
endtask : test_ethchdr;
|
||||
|
||||
task automatic test_chdreth(int num_samples[$]);
|
||||
TestExec test_v2e = new();
|
||||
automatic ChdrXportPacket_t send[$];
|
||||
automatic EthXportPacket_t expected[$];
|
||||
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
|
||||
// v2e -> s_chdr(eth_adapter) -> s_axis_rfnoc (xport_adapter_gen) ->
|
||||
//// axi_demux_mgmt_filter (AXI_DEMUX) (IF ALLOW_DISC) (discards discovery packets)
|
||||
@@ -877,8 +900,6 @@ module eth_ifc_tb #(
|
||||
end
|
||||
end
|
||||
join
|
||||
test_v2e.end_test();
|
||||
|
||||
endtask : test_chdreth
|
||||
|
||||
integer cached_mgmt_seqnum = 0;
|
||||
@@ -887,7 +908,6 @@ module eth_ifc_tb #(
|
||||
`include "../../core/rfnoc_chdr_internal_utils.vh"
|
||||
`include "../../xport/rfnoc_xport_types.vh"
|
||||
task automatic test_chdr_endpoint();
|
||||
TestExec test_e2v = new();
|
||||
automatic EthXportPacket_t send[$];
|
||||
automatic EthXportPacket_t expected[$];
|
||||
automatic int sample_sum = 0;
|
||||
@@ -909,8 +929,7 @@ module eth_ifc_tb #(
|
||||
automatic int preamble;
|
||||
localparam NODE_INST=0;
|
||||
|
||||
test_e2v.start_test({TEST_NAME,"::ChdrEndpoint"}, 60us);
|
||||
|
||||
test.start_test({TEST_NAME,"::ChdrEndpoint"}, 60us);
|
||||
|
||||
expected[0] = new;
|
||||
send[0] = new;
|
||||
@@ -1030,9 +1049,10 @@ module eth_ifc_tb #(
|
||||
end
|
||||
end
|
||||
join
|
||||
test_e2v.end_test();
|
||||
|
||||
test.end_test();
|
||||
endtask : test_chdr_endpoint
|
||||
|
||||
//----------------------------------------------------
|
||||
// Main test loop
|
||||
//----------------------------------------------------
|
||||
@@ -1044,7 +1064,12 @@ module eth_ifc_tb #(
|
||||
|
||||
test.start_tb(TEST_NAME);
|
||||
|
||||
test.start_test({TEST_NAME,"::Wait for Reset"}, 10us);
|
||||
// Check some parameters
|
||||
if (!SV_ETH_IFC) begin
|
||||
`ASSERT_FATAL(CHDR_W == 64, "Legacy transport adapter only supports 64-bit CHDR");
|
||||
`ASSERT_FATAL(CPU_PREAMBLE == 0, "CPU preamble is not supported on legacy transport adapter");
|
||||
end
|
||||
|
||||
clk_gen.start();
|
||||
eth_clk_gen.start();
|
||||
clk_gen.reset();
|
||||
@@ -1054,10 +1079,8 @@ module eth_ifc_tb #(
|
||||
cpu.run();
|
||||
v.run();
|
||||
|
||||
|
||||
test_reset();
|
||||
test_registers();
|
||||
|
||||
test_chdr_endpoint();
|
||||
|
||||
// Check what happens if the input bandwidth exceeds
|
||||
@@ -1087,6 +1110,7 @@ module eth_ifc_tb #(
|
||||
|
||||
test_ethchdr(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
|
||||
test_ethcpu(num_samples,.EXPECT_DROPS(expected_drops),.ERROR_PROB(0));
|
||||
|
||||
test.end_test();
|
||||
|
||||
eth.set_master_stall_prob(38);
|
||||
@@ -1104,9 +1128,9 @@ module eth_ifc_tb #(
|
||||
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
|
||||
};
|
||||
// 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)
|
||||
//this way we still have some short packets to drop, but not as many.
|
||||
// Add some extra samples for CPU packets to try to get above the min
|
||||
// packet size of 64 (just the headers make up 42 bytes). This way we still
|
||||
// have some short packets to drop, but not as many.
|
||||
foreach (num_samples[i]) cpu_num_samples[i] = num_samples[i]+20;
|
||||
test.start_test({TEST_NAME,"::PacketW Combos NO Errors"}, 10us);
|
||||
fork // run in parallel
|
||||
|
||||
@@ -42,7 +42,10 @@
|
||||
// NODE_INST : The node type to return for a node-info discovery
|
||||
// DROP_UNKNOWN_MAC : Drop packets not addressed to us?
|
||||
// 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
|
||||
// path. If false use TKEEP instead of USER.
|
||||
// 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_MIN_PACKET = 0,
|
||||
int PREAMBLE_BYTES = 6,
|
||||
bit CPU_PREAMBLE = 0,
|
||||
bit ADD_SOF = 1,
|
||||
bit SYNC = 0,
|
||||
int ENET_W = 64,
|
||||
@@ -180,11 +184,12 @@ module eth_ipv4_chdr_adapter #(
|
||||
.CPU_FIFO_SIZE (CPU_FIFO_SIZE),
|
||||
.CHDR_FIFO_SIZE (CHDR_FIFO_SIZE),
|
||||
.PREAMBLE_BYTES (PREAMBLE_BYTES),
|
||||
.CPU_PREAMBLE (CPU_PREAMBLE),
|
||||
.MAX_PACKET_BYTES (MAX_PACKET_BYTES),
|
||||
.DROP_UNKNOWN_MAC (DROP_UNKNOWN_MAC),
|
||||
.DROP_MIN_PACKET (DROP_MIN_PACKET),
|
||||
.ENET_W (ENET_W)
|
||||
) eth_dispatch_i (
|
||||
) eth_ipv4_chdr_dispatch_i (
|
||||
.eth_pause_req (eth_pause_req),
|
||||
.eth_rx (eth_rx1),
|
||||
.e2v (e2v1),
|
||||
@@ -379,17 +384,17 @@ module eth_ipv4_chdr_adapter #(
|
||||
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
|
||||
// from the CPU to the SFP. This padding added before MAC addresses
|
||||
// aligns the source and destination IP addresses, UDP headers etc.
|
||||
// Note that the xge_mac_wrapper strips this padding to recreate the
|
||||
// ethernet packet.
|
||||
axi4s_add_bytes #(.ADD_START(0),.ADD_BYTES(PREAMBLE_BYTES)
|
||||
) add_header (
|
||||
) axi4s_add_bytes_c2e (
|
||||
.i(c2e1), .o(c2e2)
|
||||
);
|
||||
end else begin : gen_no_preamble
|
||||
end else begin : gen_c2e_no_preamble
|
||||
always_comb begin : c2e2_assign
|
||||
`AXI4S_ASSIGN(c2e2,c2e1)
|
||||
end
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
// Parameters:
|
||||
// - 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
|
||||
// - 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_MIN_PACKET: Drop packets smaller than 64 bytes?
|
||||
// - ENET_W: Width of AXI bus going to Ethernet Mac
|
||||
@@ -42,6 +45,7 @@ module eth_ipv4_chdr_dispatch #(
|
||||
int CPU_FIFO_SIZE = $clog2(8*1024),
|
||||
int CHDR_FIFO_SIZE = $clog2(8*1024),
|
||||
int PREAMBLE_BYTES = 6,
|
||||
int CPU_PREAMBLE = 0,
|
||||
int MAX_PACKET_BYTES = 2**16-1,
|
||||
bit DROP_UNKNOWN_MAC = 0,
|
||||
bit DROP_MIN_PACKET = 0,
|
||||
@@ -133,14 +137,17 @@ module eth_ipv4_chdr_dispatch #(
|
||||
// tUser = {not used};
|
||||
AxiStreamIf #(.DATA_WIDTH(ENET_W),.TKEEP(0),.TUSER(0))
|
||||
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
|
||||
// e2v(OUTPUT)
|
||||
|
||||
//---------------------------------------
|
||||
// Strip Bytes
|
||||
// Strip Preamble Bytes
|
||||
//---------------------------------------
|
||||
if (PREAMBLE_BYTES > 0) begin : gen_strip_preamble
|
||||
// Strip the preamble
|
||||
if (PREAMBLE_BYTES > 0 && !CPU_PREAMBLE) begin : gen_strip_preamble
|
||||
// Keep the preamble since the CPU expects it.
|
||||
always_comb begin
|
||||
`AXI4S_ASSIGN(inp,eth_rx);
|
||||
end
|
||||
@@ -148,7 +155,8 @@ module eth_ipv4_chdr_dispatch #(
|
||||
) strip_preamble (
|
||||
.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
|
||||
`AXI4S_ASSIGN(in0,eth_rx);
|
||||
end
|
||||
@@ -248,22 +256,24 @@ module eth_ipv4_chdr_dispatch #(
|
||||
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
|
||||
eth_dst_addr_new = in0.get_packet_field48(eth_dst_addr_old,DST_MAC_BYTE,.NETWORK_ORDER(1));
|
||||
eth_src_addr_new = in0.get_packet_field48(eth_src_addr_old,SRC_MAC_BYTE,.NETWORK_ORDER(1));
|
||||
ip_version_new = in0.get_packet_byte(ip_version_old,IP_VERSION_BYTE);
|
||||
ip_protocol_new = in0.get_packet_byte(ip_protocol_old,PROTOCOL_BYTE);
|
||||
ipv4_src_addr_new = in0.get_packet_field32(ipv4_src_addr_old,SRC_IP_BYTE,.NETWORK_ORDER(1));
|
||||
ipv4_dst_addr_new = in0.get_packet_field32(ipv4_dst_addr_old,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_dst_port_new = in0.get_packet_field16(udp_dst_port_old,DST_PORT_BYTE,.NETWORK_ORDER(1));
|
||||
eth_type_new = in0.get_packet_field16(eth_type_old,ETH_TYPE_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, OFFSET+SRC_MAC_BYTE, .NETWORK_ORDER(1));
|
||||
ip_version_new = in0.get_packet_byte (ip_version_old, OFFSET+IP_VERSION_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, OFFSET+SRC_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, OFFSET+SRC_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, OFFSET+ETH_TYPE_BYTE, .NETWORK_ORDER(1));
|
||||
end
|
||||
|
||||
always_comb begin : reached_bytes
|
||||
reached_min_packet_new = in1.reached_packet_byte(MIN_PACKET_SIZE_BYTE);
|
||||
reached_end_of_udp = in1.reached_packet_byte(DST_PORT_BYTE+3);// we have enough to decide
|
||||
reached_min_packet_new = in1.reached_packet_byte(OFFSET+MIN_PACKET_SIZE_BYTE);
|
||||
reached_end_of_udp = in1.reached_packet_byte(OFFSET+DST_PORT_BYTE+3);// we have enough to decide
|
||||
end
|
||||
|
||||
// calculate error conditions
|
||||
@@ -521,9 +531,9 @@ module eth_ipv4_chdr_dispatch #(
|
||||
);
|
||||
|
||||
// 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
|
||||
// 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.
|
||||
logic [15:0] chdr_occupied;
|
||||
logic [15:0] chdr_occupied_q;
|
||||
@@ -532,11 +542,25 @@ module eth_ipv4_chdr_dispatch #(
|
||||
.SIZE(CHDR_FIFO_WORD_SIZE)
|
||||
) chdr_fifo_i (
|
||||
.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.
|
||||
// I'm providing the same gauranteed min time in the set and clear direction
|
||||
// Remove the preamble on the CHDR path if it was not already removed.
|
||||
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;
|
||||
typedef enum logic [1:0] {
|
||||
ST_IDLE = 2'd0,
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
// NODE_INST : The node type to return for a node-info discovery
|
||||
// DROP_UNKNOWN_MAC : Drop packets not addressed to us?
|
||||
// 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
|
||||
// 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
|
||||
@@ -47,6 +50,7 @@ module eth_ipv4_interface #(
|
||||
bit DROP_UNKNOWN_MAC = 0,
|
||||
bit DROP_MIN_PACKET = 0,
|
||||
int PREAMBLE_BYTES = 6,
|
||||
bit CPU_PREAMBLE = 0,
|
||||
bit ADD_SOF = 1,
|
||||
bit SYNC = 0,
|
||||
bit PAUSE_EN = 0,
|
||||
@@ -351,6 +355,7 @@ module eth_ipv4_interface #(
|
||||
.DROP_UNKNOWN_MAC(DROP_UNKNOWN_MAC),
|
||||
.DROP_MIN_PACKET (DROP_MIN_PACKET ),
|
||||
.PREAMBLE_BYTES (PREAMBLE_BYTES ),
|
||||
.CPU_PREAMBLE (CPU_PREAMBLE ),
|
||||
.ADD_SOF (ADD_SOF ),
|
||||
.SYNC (SYNC ),
|
||||
.ENET_W (ENET_W ),
|
||||
|
||||
Reference in New Issue
Block a user