fpga: Multiple X300 FPGA bugfixes and enhancements
- Fixed 10GigE firmware communication issues and sequence errors for TX - Multiple changes to help ease timing closure - Cleaned up build scripts - Switched to Xilinx ISE 14.7 as the default build tool for X300 Original-commit: 64d71dcbc5fa6790385b288de25224d386b047b0
This commit is contained in:
@@ -18,4 +18,6 @@ cvita_insert_tlast.v \
|
||||
cvita_dest_lookup.v \
|
||||
cvita_chunker.v \
|
||||
cvita_dechunker.v \
|
||||
axis_packet_debug.v \
|
||||
cvita_packet_debug.v \
|
||||
))
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// Copyright 2014 Ettus Research LLC
|
||||
//
|
||||
|
||||
module axis_packet_debug (
|
||||
input clk,
|
||||
input reset,
|
||||
input clear,
|
||||
|
||||
//Packet In
|
||||
input [63:0] tdata,
|
||||
input tlast,
|
||||
input tvalid,
|
||||
input tready,
|
||||
|
||||
//Per packet info
|
||||
output reg pkt_strobe,
|
||||
output reg [15:0] length,
|
||||
output reg [63:0] checksum,
|
||||
|
||||
//Statistics
|
||||
output reg [31:0] pkt_count
|
||||
);
|
||||
|
||||
localparam ST_HEADER = 1'b0;
|
||||
localparam ST_DATA = 1'b1;
|
||||
|
||||
//Packet state logic
|
||||
reg pkt_state;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
pkt_state <= ST_HEADER;
|
||||
end else if (tvalid & tready) begin
|
||||
pkt_state <= tlast ? ST_HEADER : ST_DATA;
|
||||
end
|
||||
end
|
||||
|
||||
//Trigger logic
|
||||
always @(posedge clk)
|
||||
if (reset)
|
||||
pkt_strobe <= 1'b0;
|
||||
else
|
||||
pkt_strobe <= tvalid & tready & tlast;
|
||||
|
||||
//Length capture
|
||||
always @(posedge clk)
|
||||
if (reset || pkt_state == ST_HEADER)
|
||||
length <= tlast ? 16'd8 : 16'd0;
|
||||
else
|
||||
if (tvalid & tready)
|
||||
length <= length + 16'd8;
|
||||
|
||||
//Checksum capture
|
||||
always @(posedge clk)
|
||||
if (reset || pkt_state == ST_HEADER)
|
||||
checksum <= 64'd0;
|
||||
else
|
||||
if (tvalid & tready)
|
||||
checksum <= checksum ^ tdata;
|
||||
|
||||
//Counts
|
||||
always @(posedge clk)
|
||||
if (reset | clear) begin
|
||||
pkt_count <= 32'd0;
|
||||
end else begin
|
||||
if (tvalid & tready & tlast) begin
|
||||
pkt_count <= pkt_count + 32'd1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // cvita_packet_debug
|
||||
@@ -0,0 +1,108 @@
|
||||
//
|
||||
// Copyright 2014 Ettus Research LLC
|
||||
//
|
||||
|
||||
module cvita_packet_debug (
|
||||
input clk,
|
||||
input reset,
|
||||
input clear,
|
||||
|
||||
//Packet In
|
||||
input [63:0] tdata,
|
||||
input tlast,
|
||||
input tvalid,
|
||||
input tready,
|
||||
|
||||
//Per packet info
|
||||
output reg pkt_strobe,
|
||||
output reg [63:0] header,
|
||||
output reg [63:0] timestamp,
|
||||
output reg [15:0] actual_length,
|
||||
output reg [63:0] checksum,
|
||||
|
||||
//Statistics
|
||||
output reg [31:0] pkt_count,
|
||||
output reg [31:0] ctrl_pkt_count
|
||||
);
|
||||
|
||||
localparam ST_HEADER = 2'd0;
|
||||
localparam ST_TIME = 2'd1;
|
||||
localparam ST_DATA = 2'd2;
|
||||
|
||||
//Packet state logic
|
||||
reg [1:0] pkt_state;
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
pkt_state <= ST_HEADER;
|
||||
end else if (tvalid & tready) begin
|
||||
case(pkt_state)
|
||||
ST_HEADER: begin
|
||||
if (!tlast)
|
||||
pkt_state <= (tdata[61]) ? ST_TIME : ST_DATA;
|
||||
end
|
||||
ST_TIME: begin
|
||||
pkt_state <= (tlast) ? ST_HEADER : ST_DATA;
|
||||
end
|
||||
ST_DATA: begin
|
||||
pkt_state <= (tlast) ? ST_HEADER : ST_DATA;
|
||||
end
|
||||
default: pkt_state <= ST_HEADER;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//Trigger logic
|
||||
always @(posedge clk)
|
||||
if (reset)
|
||||
pkt_strobe <= 1'b0;
|
||||
else
|
||||
pkt_strobe <= tvalid & tready & tlast;
|
||||
|
||||
//Header capture
|
||||
always @(posedge clk)
|
||||
if (reset)
|
||||
header <= 64'd0;
|
||||
else if (pkt_state == ST_HEADER)
|
||||
if (tvalid & tready)
|
||||
header <= tdata;
|
||||
|
||||
//Timestamp capture
|
||||
always @(posedge clk)
|
||||
if (reset)
|
||||
timestamp <= 64'd0;
|
||||
else if (pkt_state == ST_TIME)
|
||||
if (tvalid & tready)
|
||||
timestamp <= tdata;
|
||||
|
||||
//Length capture
|
||||
always @(posedge clk)
|
||||
if (reset || pkt_state == ST_HEADER)
|
||||
actual_length <= (tvalid & tready & tlast) ? 16'd8 : 16'd0;
|
||||
else
|
||||
if (tvalid & tready)
|
||||
actual_length <= actual_length + 16'd8;
|
||||
|
||||
//Checksum capture
|
||||
always @(posedge clk)
|
||||
if (reset || pkt_state == ST_HEADER)
|
||||
checksum <= 64'd0;
|
||||
else if (pkt_state == ST_DATA)
|
||||
if (tvalid & tready)
|
||||
checksum <= checksum ^ tdata;
|
||||
|
||||
//Counts
|
||||
always @(posedge clk)
|
||||
if (reset | clear) begin
|
||||
pkt_count <= 32'd0;
|
||||
ctrl_pkt_count <= 32'd0;
|
||||
end else begin
|
||||
if (tvalid & tready & tlast) begin
|
||||
pkt_count <= pkt_count + 32'd1;
|
||||
if (pkt_state == ST_HEADER && tdata[63])
|
||||
ctrl_pkt_count <= ctrl_pkt_count + 32'd1;
|
||||
else if (header[63])
|
||||
ctrl_pkt_count <= ctrl_pkt_count + 32'd1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // cvita_packet_debug
|
||||
+99
-159
@@ -76,138 +76,130 @@ module eth_dispatch
|
||||
output [31:0] debug
|
||||
);
|
||||
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// State machine declarations
|
||||
//
|
||||
reg [2:0] state;
|
||||
//---------------------------------------------------------
|
||||
reg [2:0] state;
|
||||
|
||||
localparam WAIT_PACKET = 0;
|
||||
localparam READ_HEADER = 1;
|
||||
localparam FORWARD_ZPU = 2;
|
||||
localparam FORWARD_ZPU_AND_XO = 3;
|
||||
localparam FORWARD_XO = 4;
|
||||
localparam FORWARD_RADIO_CORE = 5;
|
||||
localparam DROP_PACKET = 6;
|
||||
localparam CLASSIFY_PACKET = 7;
|
||||
localparam WAIT_PACKET = 0;
|
||||
localparam READ_HEADER = 1;
|
||||
localparam FORWARD_ZPU = 2;
|
||||
localparam FORWARD_ZPU_AND_XO = 3;
|
||||
localparam FORWARD_XO = 4;
|
||||
localparam FORWARD_RADIO_CORE = 5;
|
||||
localparam DROP_PACKET = 6;
|
||||
localparam CLASSIFY_PACKET = 7;
|
||||
|
||||
|
||||
//
|
||||
// Small RAM stores packet header during parsing.
|
||||
//
|
||||
// IJB consider changing HEADER_RAM_SIZE to 7
|
||||
localparam HEADER_RAM_SIZE = 9;
|
||||
(*ram_style="distributed"*)
|
||||
reg [68:0] header_ram [HEADER_RAM_SIZE-1:0];
|
||||
reg [3:0] header_ram_addr;
|
||||
reg drop_this_packet;
|
||||
(*ram_style="distributed"*) reg [68:0] header_ram [HEADER_RAM_SIZE-1:0];
|
||||
|
||||
wire header_done = (header_ram_addr == HEADER_RAM_SIZE-1);
|
||||
reg fwd_input;
|
||||
reg [3:0] header_ram_addr;
|
||||
wire header_done = (header_ram_addr == HEADER_RAM_SIZE-1);
|
||||
reg fwd_input;
|
||||
|
||||
//
|
||||
reg [63:0] in_tdata_reg;
|
||||
reg [63:0] in_tdata_reg;
|
||||
|
||||
//
|
||||
wire out_tvalid;
|
||||
wire out_tready;
|
||||
wire out_tlast;
|
||||
wire [3:0] out_tuser;
|
||||
wire [63:0] out_tdata;
|
||||
wire out_tvalid;
|
||||
wire out_tready;
|
||||
wire out_tlast;
|
||||
wire [3:0] out_tuser;
|
||||
wire [63:0] out_tdata;
|
||||
|
||||
//
|
||||
// Output AXI-Stream interface to VITA Radio Core
|
||||
wire [63:0] vita_pre_tdata;
|
||||
wire [3:0] vita_pre_tuser;
|
||||
wire vita_pre_tlast;
|
||||
wire vita_pre_tvalid;
|
||||
wire vita_pre_tready;
|
||||
wire [63:0] vita_pre_tdata;
|
||||
wire [3:0] vita_pre_tuser;
|
||||
wire vita_pre_tlast;
|
||||
wire vita_pre_tvalid;
|
||||
wire vita_pre_tready;
|
||||
// Output AXI-Stream interface to ZPU
|
||||
wire [63:0] zpu_pre_tdata;
|
||||
wire [3:0] zpu_pre_tuser;
|
||||
wire zpu_pre_tlast;
|
||||
wire zpu_pre_tvalid;
|
||||
wire zpu_pre_tready;
|
||||
wire [63:0] zpu_pre_tdata;
|
||||
wire [3:0] zpu_pre_tuser;
|
||||
wire zpu_pre_tlast;
|
||||
wire zpu_pre_tvalid;
|
||||
wire zpu_pre_tready;
|
||||
// Output AXI-Stream interface to cross-over MAC
|
||||
wire [63:0] xo_pre_tdata;
|
||||
wire [3:0] xo_pre_tuser;
|
||||
wire xo_pre_tlast;
|
||||
wire xo_pre_tvalid;
|
||||
wire xo_pre_tready;
|
||||
wire [63:0] xo_pre_tdata;
|
||||
wire [3:0] xo_pre_tuser;
|
||||
wire xo_pre_tlast;
|
||||
wire xo_pre_tvalid;
|
||||
wire xo_pre_tready;
|
||||
|
||||
//
|
||||
// Packet Parse Flags
|
||||
//
|
||||
reg is_eth_dst_addr;
|
||||
reg is_eth_broadcast;
|
||||
reg is_eth_type_ipv4;
|
||||
reg is_ipv4_dst_addr;
|
||||
reg is_ipv4_proto_udp;
|
||||
reg is_ipv4_proto_icmp;
|
||||
reg [1:0] is_udp_dst_ports;
|
||||
reg is_icmp_no_fwd;
|
||||
reg is_chdr;
|
||||
reg is_eth_dst_addr;
|
||||
reg is_eth_broadcast;
|
||||
reg is_eth_type_ipv4;
|
||||
reg is_ipv4_dst_addr;
|
||||
reg is_ipv4_proto_udp;
|
||||
reg is_ipv4_proto_icmp;
|
||||
reg [1:0] is_udp_dst_ports;
|
||||
reg is_icmp_no_fwd;
|
||||
reg is_chdr;
|
||||
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// Settings regs
|
||||
//
|
||||
|
||||
wire [47:0] my_mac;
|
||||
//---------------------------------------------------------
|
||||
|
||||
// MAC address for the dispatcher module.
|
||||
// This value is used to determine if the packet is meant
|
||||
// for this device should be consumed
|
||||
wire [47:0] my_mac;
|
||||
setting_reg #(.my_addr(BASE), .awidth(16), .width(32)) sr_my_mac_lsb
|
||||
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
|
||||
.in(set_data),.out(my_mac[31:0]),.changed());
|
||||
|
||||
setting_reg #(.my_addr(BASE+1), .awidth(16), .width(16)) sr_my_mac_msb
|
||||
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
|
||||
.in(set_data),.out(my_mac[47:32]),.changed());
|
||||
|
||||
wire [31:0] my_ip;
|
||||
|
||||
// IP address for the dispatcher module.
|
||||
// This value is used to determine if the packet is addressed
|
||||
// to this device
|
||||
wire [31:0] my_ip;
|
||||
setting_reg #(.my_addr(BASE+2), .awidth(16), .width(32)) sr_my_ip
|
||||
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
|
||||
.in(set_data),.out(my_ip[31:0]),.changed());
|
||||
|
||||
wire [15:0] my_port0, my_port1;
|
||||
|
||||
// This module supports two destination ports
|
||||
wire [15:0] my_port0, my_port1;
|
||||
setting_reg #(.my_addr(BASE+3), .awidth(16), .width(32)) sr_udp_port
|
||||
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
|
||||
.in(set_data),.out({my_port1[15:0],my_port0[15:0]}),.changed());
|
||||
|
||||
// forward_ndest: Forward to crossover path if MAC Addr in packet
|
||||
// does not match "my_mac"
|
||||
// forward_bcast: Forward broadcasts to crossover path
|
||||
wire forward_ndest, forward_bcast;
|
||||
setting_reg #(.my_addr(BASE+4), .awidth(16), .width(2)) sr_forward_ctrl
|
||||
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
|
||||
.in(set_data),.out({forward_ndest, forward_bcast}),.changed());
|
||||
|
||||
//ICMP Type and Code to forward packet to ZPU
|
||||
wire [7:0] my_icmp_type, my_icmp_code;
|
||||
setting_reg #(.my_addr(BASE+5), .awidth(16), .width(16)) sr_icmp_ctrl
|
||||
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
|
||||
.in(set_data),.out({my_icmp_type, my_icmp_code}),.changed());
|
||||
|
||||
assign debug =
|
||||
{
|
||||
1'b0, state, //4
|
||||
1'b0, in_tvalid, in_tready, in_tlast, //4
|
||||
1'b0, is_eth_dst_addr, is_eth_broadcast, is_eth_type_ipv4,
|
||||
is_ipv4_dst_addr, is_ipv4_proto_udp, is_udp_dst_ports, //8
|
||||
header_ram_addr[3:0], //4
|
||||
4'b0, 8'b0
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// Packet Forwarding State machine.
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// Read input packet and store the header into a RAM for
|
||||
// classification. A header is defined as HEADER_RAM_SIZE
|
||||
// number of 64-bit words.
|
||||
// Based on clasification results, output the packet to the
|
||||
// VITA port, crossover(XO) port or the ZPU. Note that the
|
||||
// XO and ZPU ports require fully framed Eth packets so data
|
||||
// from the RAM has to be replayed on the output. The state
|
||||
// machine will hold off input packets until the header is
|
||||
// replayed. The state machine also supports dropping pkts.
|
||||
|
||||
always @(posedge clk)
|
||||
if (reset || clear) begin
|
||||
state <= WAIT_PACKET;
|
||||
header_ram_addr <= 0;
|
||||
drop_this_packet <= 0;
|
||||
fwd_input <= 0;
|
||||
end else begin
|
||||
// Defaults.
|
||||
drop_this_packet <= 0;
|
||||
|
||||
case(state)
|
||||
//
|
||||
// Wait for start of a packet
|
||||
@@ -250,15 +242,15 @@ module eth_dispatch
|
||||
end else if (is_eth_broadcast) begin
|
||||
header_ram_addr <= 0;
|
||||
state <= forward_bcast? FORWARD_ZPU_AND_XO : FORWARD_ZPU;
|
||||
end else if (!is_eth_dst_addr) begin
|
||||
end else if (!is_eth_dst_addr && forward_ndest) begin
|
||||
header_ram_addr <= 0;
|
||||
state <= forward_ndest? FORWARD_XO : DROP_PACKET;
|
||||
state <= FORWARD_XO;
|
||||
end else if (!is_eth_dst_addr && !forward_ndest) begin
|
||||
header_ram_addr <= HEADER_RAM_SIZE - 1;
|
||||
state <= DROP_PACKET;
|
||||
end else if ((is_udp_dst_ports != 0) && is_chdr) begin
|
||||
header_ram_addr <= 6; // Jump to CHDR
|
||||
state <= FORWARD_RADIO_CORE;
|
||||
end else if (drop_this_packet) begin
|
||||
header_ram_addr <= HEADER_RAM_SIZE-1;
|
||||
state <= DROP_PACKET;
|
||||
end else begin
|
||||
header_ram_addr <= 0;
|
||||
state <= FORWARD_ZPU;
|
||||
@@ -328,10 +320,14 @@ module eth_dispatch
|
||||
endcase // case (state)
|
||||
end // else: !if(reset || clear)
|
||||
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// Classifier State machine.
|
||||
// Deep packet inspection during header ingress.
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// As the packet header is pushed into the RAM, set classification
|
||||
// bits so that by the time the input state machine reaches the
|
||||
// CLASSIFY_PACKET state, the packet has been fully identified.
|
||||
|
||||
always @(posedge clk)
|
||||
if (reset || clear) begin
|
||||
is_eth_dst_addr <= 1'b0;
|
||||
@@ -343,10 +339,6 @@ module eth_dispatch
|
||||
is_udp_dst_ports <= 0;
|
||||
is_icmp_no_fwd <= 0;
|
||||
is_chdr <= 1'b0;
|
||||
|
||||
//space_in_fifo <= 0;
|
||||
//is_there_fifo_space <= 1;
|
||||
//packet_length <= 0;
|
||||
end else if (in_tvalid && in_tready) begin // if (reset || clear)
|
||||
in_tdata_reg <= in_tdata;
|
||||
|
||||
@@ -426,9 +418,9 @@ module eth_dispatch
|
||||
end // if (in_tvalid && in_tready)
|
||||
|
||||
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// Output (Egress) Interface muxing
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
assign out_tready =
|
||||
(state == DROP_PACKET) ||
|
||||
((state == FORWARD_RADIO_CORE) && vita_pre_tready) ||
|
||||
@@ -448,7 +440,6 @@ module eth_dispatch
|
||||
(state == READ_HEADER) ||
|
||||
(out_tready && fwd_input);
|
||||
|
||||
|
||||
//
|
||||
// Because we can forward to both the ZPU and XO FIFO's concurrently
|
||||
// we have to make sure both can accept data in the same cycle.
|
||||
@@ -461,25 +452,22 @@ module eth_dispatch
|
||||
assign zpu_pre_tvalid = out_tvalid &&
|
||||
((state == FORWARD_ZPU) ||
|
||||
((state == FORWARD_ZPU_AND_XO) && xo_pre_tready));
|
||||
assign vita_pre_tvalid = out_tvalid && (state == FORWARD_RADIO_CORE);
|
||||
assign vita_pre_tvalid = out_tvalid &&
|
||||
(state == FORWARD_RADIO_CORE);
|
||||
|
||||
assign {zpu_pre_tuser,zpu_pre_tdata} = ((state == FORWARD_ZPU_AND_XO) || (state == FORWARD_ZPU)) ?
|
||||
{out_tuser,out_tdata} : 0;
|
||||
assign {zpu_pre_tlast, zpu_pre_tuser, zpu_pre_tdata} = {out_tlast, out_tuser, out_tdata};
|
||||
assign {xo_pre_tlast, xo_pre_tuser, xo_pre_tdata} = {out_tlast, out_tuser, out_tdata};
|
||||
assign {vita_pre_tlast, vita_pre_tuser, vita_pre_tdata} = {out_tlast, out_tuser, out_tdata};
|
||||
|
||||
assign {xo_pre_tuser,xo_pre_tdata} = ((state == FORWARD_ZPU_AND_XO) || (state == FORWARD_XO)) ?
|
||||
{out_tuser,out_tdata} : 0;
|
||||
|
||||
assign {vita_pre_tuser,vita_pre_tdata} = (state == FORWARD_RADIO_CORE) ? {out_tuser,out_tdata} : 0;
|
||||
|
||||
assign zpu_pre_tlast = out_tlast && ((state == FORWARD_ZPU) || (state == FORWARD_ZPU_AND_XO));
|
||||
|
||||
assign xo_pre_tlast = out_tlast && ((state == FORWARD_XO) || (state == FORWARD_ZPU_AND_XO));
|
||||
|
||||
assign vita_pre_tlast = out_tlast && (state == FORWARD_RADIO_CORE);
|
||||
|
||||
//
|
||||
// Egress FIFO's (Large)
|
||||
//
|
||||
//---------------------------------------------------------
|
||||
// Egress FIFO's
|
||||
//---------------------------------------------------------
|
||||
// These FIFO's have to be fairly large to prevent any egress
|
||||
// port from backpressuring the input state machine.
|
||||
// The ZPU and XO ports are inherently slow consumers so they
|
||||
// get a large buffer. The VITA port is fast but high throughput
|
||||
// so even that needs a large FIFO.
|
||||
|
||||
axi_fifo #(.WIDTH(69),.SIZE(10))
|
||||
axi_fifo_zpu (
|
||||
.clk(clk),
|
||||
@@ -525,52 +513,4 @@ module eth_dispatch
|
||||
.occupied()
|
||||
);
|
||||
|
||||
assign debug_flags = {vita_pre_tready,xo_pre_tready,zpu_pre_tready};
|
||||
|
||||
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
|
||||
wire vready, zready, oready;
|
||||
wire vvalid, zvalid, ovalid;
|
||||
|
||||
reg [2:0] ed_state;
|
||||
localparam ED_IDLE = 3'd0;
|
||||
localparam ED_IN_HDR = 3'd1;
|
||||
localparam ED_VITA = 3'd2;
|
||||
localparam ED_ZPU = 3'd3;
|
||||
localparam ED_OUT = 3'd4;
|
||||
localparam ED_DROP = 3'd5;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
// for now, send everything to zpu
|
||||
/*
|
||||
always @(posedge clk)
|
||||
if(reset | clear)
|
||||
ed_state <= ED_IDLE;
|
||||
else
|
||||
case(ed_state)
|
||||
ED_IDLE:
|
||||
if(vready & zready & oready & in_tvalid)
|
||||
;
|
||||
endcase // case (ed_state)
|
||||
*/
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
axi_packet_gate #(.WIDTH(64), .SIZE(10)) vita_gate
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata(in_tdata), .i_tlast(), .i_terror(), .i_tvalid(1'b0), .i_tready(vready),
|
||||
.o_tdata(vita_tdata), .o_tlast(vita_tlast), .o_tvalid(vita_tvalid), .o_tready(vita_tready));
|
||||
|
||||
axi_packet_gate #(.WIDTH(68), .SIZE(10)) zpu_gate
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata({in_tuser,in_tdata}), .i_tlast(in_tlast), .i_terror(in_tuser[3]), .i_tvalid(in_tvalid), .i_tready(in_tready),
|
||||
.o_tdata({zpu_tuser,zpu_tdata}), .o_tlast(zpu_tlast), .o_tvalid(zpu_tvalid), .o_tready(zpu_tready));
|
||||
|
||||
axi_packet_gate #(.WIDTH(68), .SIZE(10)) out_gate
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata({in_tuser,in_tdata}), .i_tlast(), .i_terror(), .i_tvalid(1'b0), .i_tready(oready),
|
||||
.o_tdata({out_tuser,out_tdata}), .o_tlast(out_tlast), .o_tvalid(out_tvalid), .o_tready(out_tready));
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
endmodule // eth_dispatch
|
||||
|
||||
@@ -26,24 +26,27 @@ module eth_interface
|
||||
output [31:0] debug
|
||||
);
|
||||
|
||||
wire [63:0] v2ef_tdata;
|
||||
wire [3:0] v2ef_tuser;
|
||||
wire v2ef_tlast, v2ef_tvalid, v2ef_tready;
|
||||
wire [63:0] v2ef_tdata;
|
||||
wire [3:0] v2ef_tuser;
|
||||
wire v2ef_tlast, v2ef_tvalid, v2ef_tready;
|
||||
|
||||
// //////////////////////////////////////////////////////////////
|
||||
// Incoming Ethernet path
|
||||
// Includes FIFO on the output going to ZPU
|
||||
|
||||
wire [63:0] epg_tdata_int;
|
||||
wire [3:0] epg_tuser_int;
|
||||
wire epg_tlast_int, epg_tvalid_int, epg_tready_int;
|
||||
|
||||
wire [63:0] epg_tdata_int;
|
||||
wire [3:0] epg_tuser_int;
|
||||
wire epg_tlast_int, epg_tvalid_int, epg_tready_int;
|
||||
|
||||
//
|
||||
// Packet gate ensures on entire ingressing packet is buffered before feeding it downstream so that it bursts
|
||||
// efficiently internally without holding resources allocted for longer than optimal. This also means that an upstream
|
||||
// error discovered in the packet can allow the packet to be destroyed here, before it gets deeper into the USRP.
|
||||
//
|
||||
axi_packet_gate #(.WIDTH(68), .SIZE(10)) packet_gater //holds 8K pkts
|
||||
// This gate must be able to hold at least 9900 bytes which is the maximum length between the SOF and EOF
|
||||
// as asserted by the 1G and 10G MACs. This is required in case one of the max size packets has an error
|
||||
// and needs to be dropped. With SIZE=11, this gate will hold 2 8k packets.
|
||||
axi_packet_gate #(.WIDTH(68), .SIZE(11)) packet_gater
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
|
||||
.i_tdata({eth_rx_tuser, eth_rx_tdata}), .i_tlast(eth_rx_tlast),
|
||||
@@ -56,20 +59,30 @@ module eth_interface
|
||||
//
|
||||
// Based on programmed rules, parse network headers and decide which internal destination(s) this packet will be forwarded to.
|
||||
//
|
||||
wire [63:0] e2z_tdata_int;
|
||||
wire [3:0] e2z_tuser_int;
|
||||
wire e2z_tlast_int, e2z_tvalid_int, e2z_tready_int;
|
||||
wire [2:0] dispatch_debug_flags;
|
||||
|
||||
wire [63:0] e2v_tdata_int;
|
||||
wire e2v_tlast_int, e2v_tvalid_int, e2v_tready_int;
|
||||
|
||||
wire [63:0] e2z_tdata_int;
|
||||
wire [3:0] e2z_tuser_int;
|
||||
wire e2z_tlast_int, e2z_tvalid_int, e2z_tready_int;
|
||||
wire [2:0] dispatch_debug_flags;
|
||||
|
||||
eth_dispatch #(.BASE(BASE+8)) eth_dispatch
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.set_stb(set_stb), .set_addr(set_addr) , .set_data(set_data),
|
||||
.in_tdata(epg_tdata_int), .in_tuser(epg_tuser_int), .in_tlast(epg_tlast_int), .in_tvalid(epg_tvalid_int), .in_tready(epg_tready_int),
|
||||
.vita_tdata(e2v_tdata), .vita_tlast(e2v_tlast), .vita_tvalid(e2v_tvalid), .vita_tready(e2v_tready),
|
||||
.vita_tdata(e2v_tdata_int), .vita_tlast(e2v_tlast_int), .vita_tvalid(e2v_tvalid_int), .vita_tready(e2v_tready_int),
|
||||
.zpu_tdata(e2z_tdata_int), .zpu_tuser(e2z_tuser_int), .zpu_tlast(e2z_tlast_int), .zpu_tvalid(e2z_tvalid_int), .zpu_tready(e2z_tready_int),
|
||||
.xo_tdata(xo_tdata), .xo_tuser(xo_tuser), .xo_tlast(xo_tlast), .xo_tvalid(xo_tvalid), .xo_tready(xo_tready), // to other eth port
|
||||
.debug_flags(dispatch_debug_flags),.debug(debug));
|
||||
|
||||
axi_fifo_short #(.WIDTH(65)) e2v_pipeline_srl
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
.i_tdata({e2v_tlast_int,e2v_tdata_int}), .i_tvalid(e2v_tvalid_int), .i_tready(e2v_tready_int),
|
||||
.o_tdata({e2v_tlast,e2v_tdata}), .o_tvalid(e2v_tvalid), .o_tready(e2v_tready),
|
||||
.space(), .occupied()
|
||||
);
|
||||
|
||||
//
|
||||
// ZPU can be slow to respond (relative to packet wirespeed) so extra buffer for packets destined there so it doesn't back up.
|
||||
//
|
||||
@@ -82,16 +95,16 @@ module eth_interface
|
||||
// Outgoing Ethernet path
|
||||
// Includes FIFOs on path from VITA router, from ethernet crossover, and on the overall output
|
||||
|
||||
wire [63:0] eth_tx_tdata_int;
|
||||
wire [3:0] eth_tx_tuser_int;
|
||||
wire eth_tx_tlast_int, eth_tx_tvalid_int, eth_tx_tready_int;
|
||||
wire [63:0] eth_tx_tdata_int;
|
||||
wire [3:0] eth_tx_tuser_int;
|
||||
wire eth_tx_tlast_int, eth_tx_tvalid_int, eth_tx_tready_int;
|
||||
|
||||
wire [63:0] xi_tdata_int;
|
||||
wire [3:0] xi_tuser_int;
|
||||
wire xi_tlast_int, xi_tvalid_int, xi_tready_int;
|
||||
wire [63:0] xi_tdata_int;
|
||||
wire [3:0] xi_tuser_int;
|
||||
wire xi_tlast_int, xi_tvalid_int, xi_tready_int;
|
||||
|
||||
wire [63:0] v2e_tdata_int;
|
||||
wire v2e_tlast_int, v2e_tvalid_int, v2e_tready_int;
|
||||
wire [63:0] v2e_tdata_int;
|
||||
wire v2e_tlast_int, v2e_tvalid_int, v2e_tready_int;
|
||||
|
||||
axi_fifo #(.WIDTH(65),.SIZE(VITA_FIFOSIZE)) vitaout_fifo
|
||||
(.clk(clk), .reset(reset), .clear(clear),
|
||||
@@ -124,37 +137,4 @@ module eth_interface
|
||||
.o_tdata({eth_tx_tlast,eth_tx_tuser,eth_tx_tdata}), .o_tvalid(eth_tx_tvalid), .o_tready(eth_tx_tready));
|
||||
|
||||
|
||||
//
|
||||
// Provide instrumentation so that abnormal FIFO conditions can be identifed.
|
||||
//
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
|
||||
setting_reg #(.my_addr(BASE+15), .awidth(16), .width(1)) sr_reset_fifo_debug
|
||||
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
|
||||
.in(set_data),.out(),.changed(clear_debug_flags));
|
||||
|
||||
always @(posedge clk)
|
||||
if (reset)
|
||||
debug_flags <= 0;
|
||||
else if (clear_debug_flags)
|
||||
debug_flags <= 0;
|
||||
else
|
||||
debug_flags <= debug_flags | {eth_rx_tuser[3],
|
||||
~eth_tx_tready_int,
|
||||
~xi_tready,
|
||||
~v2e_tready,
|
||||
~e2z_tready_int,
|
||||
~eth_rx_tready,
|
||||
~dispatch_debug_flags[2:0]};
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
assign debug_flags = {eth_rx_tuser[3],
|
||||
~eth_tx_tready_int,
|
||||
~xi_tready,
|
||||
~v2e_tready,
|
||||
~e2z_tready_int,
|
||||
~eth_rx_tready,
|
||||
~dispatch_debug_flags[2:0]};
|
||||
|
||||
|
||||
endmodule // eth_interface
|
||||
|
||||
@@ -151,7 +151,7 @@ module xge_mac_wrapper
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
wire [63:0] rx_tdata_int;
|
||||
wire [3:0] rx_tuser_int;
|
||||
wire rx_talst_int;
|
||||
wire rx_tlast_int;
|
||||
wire rx_tvalid_int;
|
||||
wire rx_tready_int;
|
||||
|
||||
@@ -194,7 +194,7 @@ module xge_mac_wrapper
|
||||
// Large FIFO must be able to run input side at 64b@156MHz to sustain 10Gb Rx.
|
||||
//
|
||||
|
||||
axi64_8k_2clk_fifo rxfifo_2clk
|
||||
axi64_4k_2clk_fifo rxfifo_2clk
|
||||
(
|
||||
.s_aresetn(~xgmii_reset),
|
||||
.s_aclk(xgmii_clk),
|
||||
@@ -235,7 +235,7 @@ module xge_mac_wrapper
|
||||
wire tx_sof_int3;
|
||||
|
||||
|
||||
axi64_8k_2clk_fifo txfifo_2clk_1x
|
||||
axi64_4k_2clk_fifo txfifo_2clk_1x
|
||||
(
|
||||
.s_aresetn(~xgmii_reset),
|
||||
.s_aclk(sys_clk),
|
||||
|
||||
Reference in New Issue
Block a user