umtrx: need pkt gate for max rate bursting in eth tx chain

This commit is contained in:
Josh Blum
2014-04-18 12:22:59 -07:00
parent b8b5319c6d
commit 54030551e3
3 changed files with 92 additions and 6 deletions

View File

@@ -39,4 +39,5 @@ packet_verifier.v \
fifo19_pad.v \ fifo19_pad.v \
axi_fifo.v \ axi_fifo.v \
axi_fifo_2clk.v \ axi_fifo_2clk.v \
axi_packet_gate.v \
)) ))

View File

@@ -0,0 +1,78 @@
//
// Copyright 2012 Ettus Research LLC
//
// Hold packets in fifo until they are complete. This prevents slowly-built packets
// from clogging up the downstream. This block will hold up to 255 packets.
// Will permanently block if a single packet is bigger than the fifo.
// Will also drop any packet with an error signalled on the last line.
// This is useful after an ethernet interface to drop packets with bad CRCs.
module axi_packet_gate
#(parameter WIDTH=68,
parameter SIZE=10)
(input clk,
input reset,
input clear,
input [WIDTH-1:0] i_tdata,
input i_tlast,
input i_terror,
input i_tvalid,
output i_tready,
output [WIDTH-1:0] o_tdata,
output o_tlast,
output o_tvalid,
input o_tready
);
reg [7:0] num_packets;
reg dump;
wire o_tvalid_int, o_tready_int, i_tvalid_int, i_tready_int;
assign i_tvalid_int = (~dump & (num_packets != 8'hFF)) ? i_tvalid : 1'b0;
assign i_tready = (~dump & (num_packets != 8'hFF)) ? i_tready_int : 1'b0;
assign o_tvalid = (num_packets != 8'h0) ? o_tvalid_int : 1'b0;
assign o_tready_int = (num_packets != 8'h0) ? o_tready : 1'b0;
wire last_in = i_tvalid_int & i_tready_int & i_tlast;
wire last_out = o_tvalid_int & o_tready_int & o_tlast;
always @(posedge clk)
if(reset | clear)
begin
num_packets <= 8'd0;
dump <= 1'b0;
end
else
if(dump)
if(num_packets != 8'd0)
if(last_out)
num_packets <= num_packets - 8'd1;
else
;
else
dump <= 1'b0;
else
if(last_in)
if(i_terror)
begin
dump <= 1'b1;
if(last_out)
num_packets <= num_packets - 8'd1;
end
else if(~last_out)
num_packets <= num_packets + 8'd1;
else
;
else if(last_out)
num_packets <= num_packets - 8'd1;
axi_fifo #(.SIZE(SIZE), .WIDTH(WIDTH+1)) axi_fifo
(.clk(clk), .reset(reset), .clear(clear | (dump & (num_packets == 8'd0))),
.i_tdata({i_tlast,i_tdata}), .i_tvalid(i_tvalid_int), .i_tready(i_tready_int),
.o_tdata({o_tlast,o_tdata}), .o_tvalid(o_tvalid_int), .o_tready(o_tready_int));
endmodule // axi_packet_gate

View File

@@ -124,13 +124,20 @@ module simple_gemac_wrapper
// TX FIFO Chain // TX FIFO Chain
wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy; wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy;
wire [7:0] tx_ll_data; wire [7:0] tx_ll_data;
wire [35:0] tx_f36_data_int1, tx_f36_data_int2; wire [35:0] tx_f36_data_int0, tx_f36_data_int1, tx_f36_data_int2;
wire tx_f36_src_rdy_int1, tx_f36_dst_rdy_int1, tx_f36_src_rdy_int2, tx_f36_dst_rdy_int2; wire tx_f36_src_rdy_int0, tx_f36_dst_rdy_int0, tx_f36_src_rdy_int1, tx_f36_dst_rdy_int1, tx_f36_src_rdy_int2, tx_f36_dst_rdy_int2;
fifo_2clock_cascade #(.WIDTH(36), .SIZE(TXFIFOSIZE)) tx_2clk_fifo axi_fifo_2clk #(.WIDTH(36), .SIZE(0)) tx_2clk_fifo
(.wclk(sys_clk), .datain(tx_f36_data), .src_rdy_i(tx_f36_src_rdy), .dst_rdy_o(tx_f36_dst_rdy), .space(), (.i_aclk(sys_clk), .i_tdata(tx_f36_data), .i_tvalid(tx_f36_src_rdy), .i_tready(tx_f36_dst_rdy),
.rclk(tx_clk), .dataout(tx_f36_data_int1), .src_rdy_o(tx_f36_src_rdy_int1), .dst_rdy_i(tx_f36_dst_rdy_int1), .occupied(), .o_aclk(tx_clk), .o_tdata(tx_f36_data_int0), .o_tvalid(tx_f36_src_rdy_int0), .o_tready(tx_f36_dst_rdy_int0),
.arst(reset)); .reset(reset));
axi_packet_gate #(.WIDTH(36), .SIZE(TXFIFOSIZE)) fully_buffer_outgoing_eth_pkts
(
.clk(tx_clk), .reset(reset), .clear(0),
.i_tdata(tx_f36_data_int0), .i_tvalid(tx_f36_src_rdy_int0), .i_tready(tx_f36_dst_rdy_int0), .i_tlast(tx_f36_data_int0[33]), .i_terror(0),
.o_tdata(tx_f36_data_int1), .o_tvalid(tx_f36_src_rdy_int1), .o_tready(tx_f36_dst_rdy_int2), .o_tlast()
);
ethtx_realign ethtx_realign ethtx_realign ethtx_realign
(.clk(tx_clk), .reset(tx_reset), .clear(clear), (.clk(tx_clk), .reset(tx_reset), .clear(clear),