Skip to content

Commit

Permalink
packet_filter: Initial commit
Browse files Browse the repository at this point in the history
- Added a reusable packet filtering tree
- Added the filter to the monitoring module as an option
- Created the packet_filter project for demonstration purposes of the packet filtering tree

Signed-off-by: Istvan-Zsolt Szekely <[email protected]>
  • Loading branch information
IstvanZsSzekely committed Oct 18, 2024
1 parent 9770fd6 commit e32d8e8
Show file tree
Hide file tree
Showing 26 changed files with 826 additions and 132 deletions.
116 changes: 116 additions & 0 deletions library/drivers/common/filter.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
`include "utils.svh"

package filter_pkg;

import logger_pkg::*;

class filter_class;

protected bit [31:0] position;
protected logic [7:0] value;
protected bit equals;

bit result;

function new(
input bit [31:0] position,
input logic [7:0] value,
input bit equals = 1);

this.position = position;
this.value = value;
this.equals = equals;
this.result = 0;
endfunction: new

function void apply_filter(input logic [7:0] packet[]);
logic [7:0] value;

value = packet[this.position];
for (int i=0; i< $size(value); i++)
if (this.value[i] == 1'bx || this.value[i] == 1'bz) continue;
else if (this.value[i] != value[i]) begin
this.result = !equals;
return;
end

this.result = equals;
return;
endfunction: apply_filter

endclass: filter_class


class filter_tree_class;

protected bit filter_type; // 0 - all leaf nodes/cells are evaluated with logical or
// 1 - all leaf nodes/cells are evaluated with logical and

bit result;

protected filter_class filter[];
filter_tree_class ft[];

function new(
input bit filter_type,
input bit [31:0] nr_of_filters,
input bit [31:0] nr_of_filter_trees);

this.filter_type = filter_type;
this.result = filter_type;
this.filter = new[nr_of_filters];
this.ft = new[nr_of_filter_trees];
endfunction: new

function void add_filter(
input bit [31:0] filter_nr,
input bit [31:0] position,
input logic [7:0] value,
input bit equals = 1);

this.filter[filter_nr] = new (position, value, equals);
endfunction: add_filter

function void add_filter_tree(
input bit [31:0] filter_tree_nr,
input bit filter_type,
input bit [31:0] nr_of_filters,
input bit [31:0] nr_of_filter_trees);

this.ft[filter_tree_nr] = new (filter_type, nr_of_filters, nr_of_filter_trees);
endfunction: add_filter_tree

function void remove_filters();
this.filter = new[0];
this.ft = new[0];
endfunction: remove_filters

task apply_filter(input logic [7:0] packet[]);
if (this.filter != null) begin
for (int i=0; i<this.filter.size(); i++) begin
this.filter[i].apply_filter(packet);
end
for (int i=0; i<this.filter.size(); i++) begin
if (filter_type)
this.result = this.result & this.filter[i].result;
else
this.result = this.result | this.filter[i].result;
end
end

if (this.ft != null) begin
for (int i=0; i<this.ft.size(); i++) begin
this.ft[i].apply_filter(packet);
end
for (int i=0; i<this.ft.size(); i++) begin
if (filter_type)
this.result = this.result & this.ft[i].result;
else
this.result = this.result | this.ft[i].result;
end
end
endtask: apply_filter

endclass: filter_tree_class

endpackage: filter_pkg
141 changes: 113 additions & 28 deletions library/drivers/common/scoreboard.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ package scoreboard_pkg;
import logger_pkg::*;
import x_monitor_pkg::*;
import mailbox_pkg::*;
import filter_pkg::*;

class scoreboard extends xil_component;

typedef enum bit { CYCLIC=0, ONESHOT } sink_type_t;
protected sink_type_t sink_type;
typedef enum bit {
CYCLIC=0, // the source data will remain in the buffer after a check
ONESHOT // the source data will be consumed with the sink data
} transfer_type_t;
protected transfer_type_t transfer_type;

// List of analysis ports from the monitors
protected x_monitor source_monitor;
Expand All @@ -26,6 +30,7 @@ package scoreboard_pkg;

// counters and synchronizers
protected bit enabled;
protected bit filter_enabled;
protected bit byte_streams_empty_sig;

// protected event end_of_first_cycle;
Expand All @@ -34,37 +39,86 @@ package scoreboard_pkg;
protected event source_transaction_event;
protected event sink_transaction_event;

// filter trees
protected filter_tree_class filter_tree_source;
protected filter_tree_class filter_tree_sink;

// constructor
function new(input string name);

super.new(name);

this.enabled = 0;
this.sink_type = ONESHOT;
this.transfer_type = ONESHOT;
this.source_byte_stream_size = 0;
this.sink_byte_stream_size = 0;
this.byte_streams_empty_sig = 1;
this.filter_enabled = 0;

endfunction: new

// connect the analysis ports of the monitor to the scoreboard
function void set_source_stream(
x_monitor source_monitor);

this.source_monitor = source_monitor;
if (!this.enabled)
this.source_monitor = source_monitor;
else
`ERROR(("Cannot set source monitor while scoreboard is running"));

endfunction: set_source_stream

function void set_sink_stream(
x_monitor sink_monitor);

this.sink_monitor = sink_monitor;

endfunction: set_sink_stream
if (!this.enabled)
this.sink_monitor = sink_monitor;
else
`ERROR(("Cannot set sink monitor while scoreboard is running"));

endfunction: set_sink_stream

// enable data filtering
function void enable_filtering();
if (!this.enabled)
this.filter_enabled = 1;
else
`ERROR(("Cannot enable data filtering while scoreboard is running"));
endfunction: enable_filtering

// disable data filtering
function void disable_filtering();
if (!this.enabled)
this.filter_enabled = 0;
else
`ERROR(("Cannot disable data filtering while scoreboard is running"));
endfunction: disable_filtering

// set filter tree
function void set_filter_tree_source(
filter_tree_class filter_tree);

if (!this.enabled)
this.filter_tree_source = filter_tree;
else
`ERROR(("Cannot change filter tree while scoreboard is running"));
endfunction: set_filter_tree_source

function void set_filter_tree_sink(
filter_tree_class filter_tree);

if (!this.enabled)
this.filter_tree_sink = filter_tree;
else
`ERROR(("Cannot change filter tree while scoreboard is running"));
endfunction: set_filter_tree_sink

// run task
task run();

if (this.filter_tree_source == null && this.filter_tree_sink == null && this.filter_enabled)
`ERROR(("No filter tree is set"));

fork
this.enabled = 1;
this.get_source_transaction();
Expand All @@ -83,15 +137,15 @@ package scoreboard_pkg;
endtask: stop

// set sink type
function void set_sink_type(input bit sink_type);
function void set_transfer_type(input bit transfer_type);

if (!this.enabled) begin
this.sink_type = sink_type_t'(sink_type);
this.transfer_type = transfer_type_t'(transfer_type);
end else begin
`ERROR(("ERROR Scoreboard: Can not configure sink_type while scoreboard is running."));
`ERROR(("ERROR Scoreboard: Can not configure transfer_type while scoreboard is running."));
end

endfunction: set_sink_type
endfunction: set_transfer_type

// clear source and sink byte streams
function void clear_streams();
Expand All @@ -103,8 +157,8 @@ package scoreboard_pkg;
endfunction: clear_streams

// get sink type
function bit get_sink_type();
return this.sink_type;
function bit get_transfer_type();
return this.transfer_type;
endfunction

// wait until source and sink byte streams are empty, full check
Expand All @@ -118,6 +172,7 @@ package scoreboard_pkg;
task get_source_transaction();

logic [7:0] source_byte;
logic [7:0] packet [];

forever begin
fork begin
Expand All @@ -127,19 +182,31 @@ package scoreboard_pkg;
join_any
disable fork;
end join

if (this.enabled == 0)
break;

this.source_monitor.get_key();
for (int i=0; i<this.source_monitor.mailbox.num(); ++i) begin
packet = new [this.source_monitor.mailbox.num()];
`INFOV(("Source packet length: %d", packet.size()), 200);
for (int i=0; i<packet.size(); ++i) begin
this.source_monitor.mailbox.get(source_byte);
this.source_monitor.mailbox.put(source_byte);
this.source_byte_stream.push_front(source_byte);
packet[i] = source_byte;
end
this.source_byte_stream_size += this.source_monitor.mailbox.num();
`INFOV(("Source transaction received, size: %d - %d", this.source_monitor.mailbox.num(), this.source_byte_stream_size), 200);
->>source_transaction_event;
this.source_monitor.put_key();

if (this.filter_enabled)
this.filter_tree_source.apply_filter(packet);

if (!this.filter_enabled || this.filter_tree_source.result) begin
for (int i=0; i<packet.size(); ++i) begin
this.source_byte_stream.push_front(packet[i]);
end
this.source_byte_stream_size += packet.size();
`INFOV(("Source transaction received, size: %d - %d", packet.size(), this.source_byte_stream_size), 200);
->>source_transaction_event;
end
end

endtask: get_source_transaction
Expand All @@ -148,6 +215,7 @@ package scoreboard_pkg;
task get_sink_transaction();

logic [7:0] sink_byte;
logic [7:0] packet [];

forever begin
fork begin
Expand All @@ -162,15 +230,26 @@ package scoreboard_pkg;
break;

this.sink_monitor.get_key();
for (int i=0; i<this.sink_monitor.mailbox.num(); ++i) begin
packet = new [this.sink_monitor.mailbox.num()];
`INFOV(("Sink packet length: %d", packet.size()), 200);
for (int i=0; i<packet.size(); ++i) begin
this.sink_monitor.mailbox.get(sink_byte);
this.sink_monitor.mailbox.put(sink_byte);
this.sink_byte_stream.push_front(sink_byte);
packet[i] = sink_byte;
end
this.sink_byte_stream_size += this.sink_monitor.mailbox.num();
`INFOV(("Sink transaction received, size: %d - %d", this.sink_monitor.mailbox.num(), this.sink_byte_stream_size), 200);
->>sink_transaction_event;
this.sink_monitor.put_key();

if (this.filter_enabled)
this.filter_tree_sink.apply_filter(packet);

if (!this.filter_enabled || this.filter_tree_sink.result) begin
for (int i=0; i<packet.size(); ++i) begin
this.sink_byte_stream.push_front(packet[i]);
end
this.sink_byte_stream_size += packet.size();
`INFOV(("Sink transaction received, size: %d - %d", packet.size(), this.sink_byte_stream_size), 200);
->>sink_transaction_event;
end
end

endtask: get_sink_transaction
Expand All @@ -190,7 +269,7 @@ package scoreboard_pkg;
(this.sink_byte_stream_size > 0)) begin
byte_streams_empty_sig = 0;
source_byte = this.source_byte_stream.pop_back();
if (this.sink_type == CYCLIC)
if (this.transfer_type == CYCLIC)
this.source_byte_stream.push_front(source_byte);
else
this.source_byte_stream_size--;
Expand All @@ -201,10 +280,16 @@ package scoreboard_pkg;
`ERROR(("Scoreboard failed at: exp %h - rcv %h", source_byte, sink_byte));
end
end else begin
if ((this.source_byte_stream_size == 0) &&
(this.sink_byte_stream_size == 0)) begin
byte_streams_empty_sig = 1;
->>byte_streams_empty;
if (this.sink_byte_stream_size == 0) begin
if (this.transfer_type == CYCLIC) begin
byte_streams_empty_sig = 1;
->>byte_streams_empty;
end else begin
if ((this.source_byte_stream_size == 0)) begin
byte_streams_empty_sig = 1;
->>byte_streams_empty;
end
end
end
fork begin
fork
Expand Down
Loading

0 comments on commit e32d8e8

Please sign in to comment.