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

Packet filter #118

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
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