Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New Feature] Packet Sniffer #105

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
merge rx and tx in vfpga
  • Loading branch information
LuhaoLiu committed Dec 8, 2024
commit 659b80a34937276e0d25114e56eaa73358961a3d
137 changes: 137 additions & 0 deletions examples_hw/apps/packet_sniffer/hdl/packet_scheduler.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* Packet Sniifer RX/TX Scheduler & Merger
*/
import lynxTypes::*;

module packet_sniffer_sched (
input logic aclk,
input logic aresetn,

AXI4S.s sink_rx,
AXI4S.s sink_tx,
AXI4S.m src
);

AXI4S #(.AXI4S_DATA_BITS(AXI_NET_BITS)) sink_rx_r ();
AXI4S #(.AXI4S_DATA_BITS(AXI_NET_BITS)) sink_tx_r ();

logic sink_rx_first, sink_tx_first;
always_ff @(posedge aclk) begin
if (aresetn == 1'b0) begin
sink_rx_first <= 1;
sink_tx_first <= 1;
end else begin
if (sink_rx.tvalid & sink_rx.tready) begin
sink_rx_first <= 0;
if (sink_rx.tlast) begin
sink_rx_first <= 1;
end
end
if (sink_tx.tvalid & sink_tx.tready) begin
sink_tx_first <= 0;
if (sink_tx.tlast) begin
sink_tx_first <= 1;
end
end
end
end

axis_data_fifo_rx_sniffer_vfpga axis_data_fifo_rx_sniffer_vfpga_inst (
.s_axis_aresetn(aresetn),
.s_axis_aclk(aclk),
.s_axis_tvalid(sink_rx.tvalid),
.s_axis_tready(sink_rx.tready),
.s_axis_tdata(sink_rx.tdata),
.s_axis_tkeep(sink_rx.tkeep),
.s_axis_tlast(sink_rx.tlast),
//.m_axis_aclk(aclk),
.m_axis_tvalid(sink_rx_r.tvalid),
.m_axis_tready(sink_rx_r.tready),
.m_axis_tdata(sink_rx_r.tdata),
.m_axis_tkeep(sink_rx_r.tkeep),
.m_axis_tlast(sink_rx_r.tlast)
);

axis_data_fifo_tx_sniffer_vfpga axis_data_fifo_tx_sniffer_vfpga_inst (
.s_axis_aresetn(aresetn),
.s_axis_aclk(aclk),
.s_axis_tvalid(sink_tx.tvalid),
.s_axis_tready(sink_tx.tready),
.s_axis_tdata(sink_tx.tdata),
.s_axis_tkeep(sink_tx.tkeep),
.s_axis_tlast(sink_tx.tlast),
//.m_axis_aclk(aclk),
.m_axis_tvalid(sink_tx_r.tvalid),
.m_axis_tready(sink_tx_r.tready),
.m_axis_tdata(sink_tx_r.tdata),
.m_axis_tkeep(sink_tx_r.tkeep),
.m_axis_tlast(sink_tx_r.tlast)
);

logic [63:0] packets_order; // save order of arriving packets (0 for rx and 1 for tx)
logic [6:0] packets_cnt; // the number valid bits in packets_order
logic [63:0] packets_order_next;
logic [6:0] packets_cnt_next;
always_ff @(posedge aclk) begin
if (aresetn == 1'b0) begin
packets_order <= 0;
packets_cnt <= 0;
end else begin
packets_order <= packets_order_next;
packets_cnt <= packets_cnt_next;
end
end

always_comb begin
src.tvalid = 0;
src.tdata = 0;
src.tkeep = 0;
src.tlast = 0;
sink_rx_r.tready = 0;
sink_tx_r.tready = 0;

if (packets_cnt > 0) begin
if (packets_order[0] == 1'b0) begin
// rx -> src
src.tvalid = sink_rx_r.tvalid;
src.tdata = sink_rx_r.tdata;
src.tkeep = sink_rx_r.tkeep;
src.tlast = sink_rx_r.tlast;
sink_rx_r.tready = src.tready;
end else begin
// tx -> src
src.tvalid = sink_tx_r.tvalid;
src.tdata = sink_tx_r.tdata;
src.tkeep = sink_tx_r.tkeep;
src.tlast = sink_tx_r.tlast;
sink_tx_r.tready = src.tready;
end
end
end

logic packets_dec_flg; // 1: src finished sending a packet
logic [1:0] packets_inc_cnt; // 0, 1 or 2
logic [63:0] packets_inc_content;
always_comb begin
packets_dec_flg = 0;
packets_inc_cnt = 0;
packets_inc_content = 64'b00;
if (src.tlast & src.tvalid & src.tready) begin
packets_dec_flg = 1;
end
if (sink_rx.tvalid & sink_rx.tready & sink_rx_first & sink_tx.tvalid & sink_tx.tready & sink_tx_first) begin
packets_inc_cnt = 2;
packets_inc_content = 64'b10;
end else if (sink_rx.tvalid & sink_rx.tready & sink_rx_first) begin
packets_inc_cnt = 1;
packets_inc_content = 64'b00;
end else if (sink_tx.tvalid & sink_tx.tready & sink_tx_first) begin
packets_inc_cnt = 1;
packets_inc_content = 64'b01;
end

packets_cnt_next = packets_cnt + packets_inc_cnt - packets_dec_flg;
packets_order_next = (packets_order | (packets_inc_content << packets_cnt)) >> packets_dec_flg;
end

endmodule
9 changes: 8 additions & 1 deletion examples_hw/apps/packet_sniffer/init_ip.tcl
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
# Debug ILA
create_ip -name ila -vendor xilinx.com -library ip -version 6.2 -module_name ila_packet_sniffer_vfpga
set_property -dict [list CONFIG.C_PROBE22_WIDTH {4} CONFIG.C_PROBE21_WIDTH {1} CONFIG.C_PROBE20_WIDTH {32} CONFIG.C_PROBE9_WIDTH {28} CONFIG.C_PROBE8_WIDTH {48} CONFIG.C_PROBE7_WIDTH {4} CONFIG.C_PROBE6_WIDTH {6} CONFIG.C_PROBE5_WIDTH {64} CONFIG.C_PROBE4_WIDTH {32} CONFIG.C_PROBE3_WIDTH {2} CONFIG.C_PROBE2_WIDTH {64} CONFIG.C_PROBE1_WIDTH {1} CONFIG.C_PROBE0_WIDTH {1} CONFIG.C_NUM_OF_PROBES {37} CONFIG.C_EN_STRG_QUAL {1} CONFIG.ALL_PROBE_SAME_MU_CNT {2}] [get_ips ila_packet_sniffer_vfpga]
set_property -dict [list CONFIG.C_PROBE38_WIDTH {1} CONFIG.C_PROBE37_WIDTH {64} CONFIG.C_PROBE36_WIDTH {1} CONFIG.C_PROBE35_WIDTH {1} CONFIG.C_PROBE34_WIDTH {512} CONFIG.C_PROBE33_WIDTH {1} CONFIG.C_PROBE32_WIDTH {64} CONFIG.C_PROBE31_WIDTH {1} CONFIG.C_PROBE30_WIDTH {1} CONFIG.C_PROBE29_WIDTH {512} CONFIG.C_PROBE28_WIDTH {1} CONFIG.C_PROBE27_WIDTH {1} CONFIG.C_PROBE26_WIDTH {64} CONFIG.C_PROBE25_WIDTH {1} CONFIG.C_PROBE24_WIDTH {1} CONFIG.C_PROBE23_WIDTH {512} CONFIG.C_PROBE22_WIDTH {4} CONFIG.C_PROBE21_WIDTH {1} CONFIG.C_PROBE20_WIDTH {32} CONFIG.C_PROBE9_WIDTH {28} CONFIG.C_PROBE8_WIDTH {48} CONFIG.C_PROBE7_WIDTH {4} CONFIG.C_PROBE6_WIDTH {6} CONFIG.C_PROBE5_WIDTH {64} CONFIG.C_PROBE4_WIDTH {32} CONFIG.C_PROBE3_WIDTH {2} CONFIG.C_PROBE2_WIDTH {64} CONFIG.C_PROBE1_WIDTH {1} CONFIG.C_PROBE0_WIDTH {1} CONFIG.C_NUM_OF_PROBES {39} CONFIG.C_EN_STRG_QUAL {1} CONFIG.ALL_PROBE_SAME_MU_CNT {2}] [get_ips ila_packet_sniffer_vfpga]

# FIFO
create_ip -name axis_data_fifo -vendor xilinx.com -library ip -version 2.0 -module_name axis_data_fifo_rx_sniffer_vfpga
set_property -dict [list CONFIG.TDATA_NUM_BYTES {64} CONFIG.IS_ACLK_ASYNC {0} CONFIG.FIFO_DEPTH {64} CONFIG.HAS_TKEEP {1} CONFIG.HAS_TLAST {1} ] [get_ips axis_data_fifo_rx_sniffer_vfpga]
create_ip -name axis_data_fifo -vendor xilinx.com -library ip -version 2.0 -module_name axis_data_fifo_tx_sniffer_vfpga
set_property -dict [list CONFIG.TDATA_NUM_BYTES {64} CONFIG.IS_ACLK_ASYNC {0} CONFIG.FIFO_DEPTH {64} CONFIG.HAS_TKEEP {1} CONFIG.HAS_TLAST {1} ] [get_ips axis_data_fifo_tx_sniffer_vfpga]
76 changes: 53 additions & 23 deletions examples_hw/apps/packet_sniffer/vfpga_top.svh
Original file line number Diff line number Diff line change
@@ -26,15 +26,43 @@ logic [31:0] wrote_len; // size of wrote data length (shoul
logic [31:0] wrote_len_n;
logic req_sent_flg;
logic [3:0] outstanding_req; // number of outstanding sq_wr requests
logic within_packet_not_first;
logic within_packet;
logic within_packet_not_last;
// fixed parameters
parameter SIZE_PER_REQ_BIT = 15;
parameter SIZE_PER_REQ = 1 << SIZE_PER_REQ_BIT; // size per sq_wr request


AXI4S #(.AXI4S_DATA_BITS(AXI_NET_BITS)) axis_sniffer_merged ();
packet_sniffer_sched inst_packet_sniffer_sched (
.aclk(aclk),
.aresetn(aresetn),
.sink_rx(axis_rx_sniffer),
.sink_tx(axis_tx_sniffer),
.src(axis_sniffer_merged)
);

always_ff @(posedge aclk) begin
if (aresetn == 1'b0) begin
within_packet_not_first <= 0;
end else begin
if (axis_sniffer_merged.tvalid && axis_sniffer_merged.tready) begin
within_packet_not_first <= 1;
if (axis_sniffer_merged.tlast) begin
within_packet_not_first <= 0;
end
end
end
end
assign within_packet = within_packet_not_first | (axis_sniffer_merged.tvalid & axis_sniffer_merged.tready);
assign within_packet_not_last = within_packet & (~(axis_sniffer_merged.tvalid & axis_sniffer_merged.tready & axis_sniffer_merged.tlast));

always_comb begin
axis_rx_sniffer.tie_off_s();
axis_tx_sniffer.tie_off_s();
axis_sniffer_merged.tie_off_s();
filter_config.valid = 1'b1;
filter_config.data = 64'b00000000_00000000_00000000_00000000_00000000_10000000_00000000_00000000; // ignore udp/ipv4 payload
filter_config.data = sniffer_ctrl_filter;
// e.g. 64'b00000000_00000000_00000000_00000000_00000000_10000000_00000000_00000000 (ignore udp/ipv4 payload)
end

/*
@@ -124,7 +152,7 @@ always_ff @(posedge aclk) begin
end else begin
case (sniffer_state)
2'b00: begin
if (sniffer_ctrl_0 && sniffer_ctrl_1) begin
if (sniffer_ctrl_0 && sniffer_ctrl_1 && (~within_packet_not_last)) begin
sniffer_state <= 2'b01;
sniffer_size <= 0;
sniffer_timer <= 0;
@@ -135,13 +163,13 @@ always_ff @(posedge aclk) begin
if (axis_src_active.tvalid) begin
sniffer_size <= sniffer_size + 64;
end
if (~sniffer_ctrl_0) begin
if ((~sniffer_ctrl_0) && (~within_packet_not_last)) begin
sniffer_state <= 2'b11;
end
end
2'b11: begin
// if (wrote_len[SIZE_PER_REQ_BIT-1:0] == 0) begin
if (outstanding_req == 0 && wrote_len[SIZE_PER_REQ_BIT-1:0] == 0) begin
if (wrote_len[SIZE_PER_REQ_BIT-1:0] == 0) begin
// if (outstanding_req == 0 && wrote_len[SIZE_PER_REQ_BIT-1:0] == 0) begin
sniffer_state <= 2'b00;
end
end
@@ -188,11 +216,11 @@ always_comb begin
// Data
axis_sink_active.tready = 1'b1;

axis_src_active.tdata = {2{sniffer_timer[63:0], sniffer_timer[63:0] + 1, sniffer_timer[63:0] + 2, sniffer_timer[63:0] + 3}};
axis_src_active.tdata = axis_sniffer_merged.tdata;
axis_src_active.tkeep = ~0;
axis_src_active.tid = 0;
axis_src_active.tlast = ((sniffer_state == 2'b01 || sniffer_state == 2'b11) && wrote_len_n[SIZE_PER_REQ_BIT-1:0] == 0) ? 1'b1 : 1'b0;
axis_src_active.tvalid = (sniffer_state == 2'b01 && wrote_len < sniffer_host_len) ? (sniffer_timer[19:0] == 0) : (
axis_src_active.tvalid = (sniffer_state == 2'b01 && wrote_len < sniffer_host_len) ? (axis_sniffer_merged.tvalid) : (
(sniffer_state == 2'b11 && wrote_len < sniffer_host_len) ? (wrote_len[SIZE_PER_REQ_BIT-1:0] != 0) : 1'b0);
end

@@ -223,18 +251,20 @@ ila_packet_sniffer_vfpga inst_ila_packet_sniffer_vfpga (
.probe20(wrote_len), // 32
.probe21(req_sent_flg), // 1
.probe22(outstanding_req), // 4
.probe23(0),
.probe24(0),
.probe25(0),
.probe26(0),
.probe27(0),
.probe28(0),
.probe29(0),
.probe30(0),
.probe31(0),
.probe32(0),
.probe33(0),
.probe34(0),
.probe35(0),
.probe36(0)
.probe23(axis_sniffer_merged.tdata), // 512
.probe24(axis_sniffer_merged.tvalid), // 1
.probe25(axis_sniffer_merged.tready), // 1
.probe26(axis_sniffer_merged.tkeep), // 64
.probe27(axis_sniffer_merged.tlast), // 1
.probe28(within_packet_not_last), // 1
.probe29(axis_rx_sniffer.tdata), // 512
.probe30(axis_rx_sniffer.tvalid),
.probe31(axis_rx_sniffer.tready),
.probe32(axis_rx_sniffer.tkeep), // 64
.probe33(axis_rx_sniffer.tlast),
.probe34(axis_tx_sniffer.tdata), // 512
.probe35(axis_tx_sniffer.tvalid),
.probe36(axis_tx_sniffer.tready),
.probe37(axis_tx_sniffer.tkeep), // 64
.probe38(axis_tx_sniffer.tlast)
);