Skip to content

Commit e32d8e8

Browse files
packet_filter: Initial commit
- 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 <istvan.szekely@analog.com>
1 parent 9770fd6 commit e32d8e8

File tree

26 files changed

+826
-132
lines changed

26 files changed

+826
-132
lines changed

library/drivers/common/filter.sv

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
`include "utils.svh"
2+
3+
package filter_pkg;
4+
5+
import logger_pkg::*;
6+
7+
class filter_class;
8+
9+
protected bit [31:0] position;
10+
protected logic [7:0] value;
11+
protected bit equals;
12+
13+
bit result;
14+
15+
function new(
16+
input bit [31:0] position,
17+
input logic [7:0] value,
18+
input bit equals = 1);
19+
20+
this.position = position;
21+
this.value = value;
22+
this.equals = equals;
23+
this.result = 0;
24+
endfunction: new
25+
26+
function void apply_filter(input logic [7:0] packet[]);
27+
logic [7:0] value;
28+
29+
value = packet[this.position];
30+
for (int i=0; i< $size(value); i++)
31+
if (this.value[i] == 1'bx || this.value[i] == 1'bz) continue;
32+
else if (this.value[i] != value[i]) begin
33+
this.result = !equals;
34+
return;
35+
end
36+
37+
this.result = equals;
38+
return;
39+
endfunction: apply_filter
40+
41+
endclass: filter_class
42+
43+
44+
class filter_tree_class;
45+
46+
protected bit filter_type; // 0 - all leaf nodes/cells are evaluated with logical or
47+
// 1 - all leaf nodes/cells are evaluated with logical and
48+
49+
bit result;
50+
51+
protected filter_class filter[];
52+
filter_tree_class ft[];
53+
54+
function new(
55+
input bit filter_type,
56+
input bit [31:0] nr_of_filters,
57+
input bit [31:0] nr_of_filter_trees);
58+
59+
this.filter_type = filter_type;
60+
this.result = filter_type;
61+
this.filter = new[nr_of_filters];
62+
this.ft = new[nr_of_filter_trees];
63+
endfunction: new
64+
65+
function void add_filter(
66+
input bit [31:0] filter_nr,
67+
input bit [31:0] position,
68+
input logic [7:0] value,
69+
input bit equals = 1);
70+
71+
this.filter[filter_nr] = new (position, value, equals);
72+
endfunction: add_filter
73+
74+
function void add_filter_tree(
75+
input bit [31:0] filter_tree_nr,
76+
input bit filter_type,
77+
input bit [31:0] nr_of_filters,
78+
input bit [31:0] nr_of_filter_trees);
79+
80+
this.ft[filter_tree_nr] = new (filter_type, nr_of_filters, nr_of_filter_trees);
81+
endfunction: add_filter_tree
82+
83+
function void remove_filters();
84+
this.filter = new[0];
85+
this.ft = new[0];
86+
endfunction: remove_filters
87+
88+
task apply_filter(input logic [7:0] packet[]);
89+
if (this.filter != null) begin
90+
for (int i=0; i<this.filter.size(); i++) begin
91+
this.filter[i].apply_filter(packet);
92+
end
93+
for (int i=0; i<this.filter.size(); i++) begin
94+
if (filter_type)
95+
this.result = this.result & this.filter[i].result;
96+
else
97+
this.result = this.result | this.filter[i].result;
98+
end
99+
end
100+
101+
if (this.ft != null) begin
102+
for (int i=0; i<this.ft.size(); i++) begin
103+
this.ft[i].apply_filter(packet);
104+
end
105+
for (int i=0; i<this.ft.size(); i++) begin
106+
if (filter_type)
107+
this.result = this.result & this.ft[i].result;
108+
else
109+
this.result = this.result | this.ft[i].result;
110+
end
111+
end
112+
endtask: apply_filter
113+
114+
endclass: filter_tree_class
115+
116+
endpackage: filter_pkg

library/drivers/common/scoreboard.sv

Lines changed: 113 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,15 @@ package scoreboard_pkg;
88
import logger_pkg::*;
99
import x_monitor_pkg::*;
1010
import mailbox_pkg::*;
11+
import filter_pkg::*;
1112

1213
class scoreboard extends xil_component;
1314

14-
typedef enum bit { CYCLIC=0, ONESHOT } sink_type_t;
15-
protected sink_type_t sink_type;
15+
typedef enum bit {
16+
CYCLIC=0, // the source data will remain in the buffer after a check
17+
ONESHOT // the source data will be consumed with the sink data
18+
} transfer_type_t;
19+
protected transfer_type_t transfer_type;
1620

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

2731
// counters and synchronizers
2832
protected bit enabled;
33+
protected bit filter_enabled;
2934
protected bit byte_streams_empty_sig;
3035

3136
// protected event end_of_first_cycle;
@@ -34,37 +39,86 @@ package scoreboard_pkg;
3439
protected event source_transaction_event;
3540
protected event sink_transaction_event;
3641

42+
// filter trees
43+
protected filter_tree_class filter_tree_source;
44+
protected filter_tree_class filter_tree_sink;
45+
3746
// constructor
3847
function new(input string name);
3948

4049
super.new(name);
4150

4251
this.enabled = 0;
43-
this.sink_type = ONESHOT;
52+
this.transfer_type = ONESHOT;
4453
this.source_byte_stream_size = 0;
4554
this.sink_byte_stream_size = 0;
4655
this.byte_streams_empty_sig = 1;
56+
this.filter_enabled = 0;
4757

4858
endfunction: new
4959

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

54-
this.source_monitor = source_monitor;
64+
if (!this.enabled)
65+
this.source_monitor = source_monitor;
66+
else
67+
`ERROR(("Cannot set source monitor while scoreboard is running"));
5568

5669
endfunction: set_source_stream
5770

5871
function void set_sink_stream(
5972
x_monitor sink_monitor);
6073

61-
this.sink_monitor = sink_monitor;
62-
63-
endfunction: set_sink_stream
74+
if (!this.enabled)
75+
this.sink_monitor = sink_monitor;
76+
else
77+
`ERROR(("Cannot set sink monitor while scoreboard is running"));
78+
79+
endfunction: set_sink_stream
80+
81+
// enable data filtering
82+
function void enable_filtering();
83+
if (!this.enabled)
84+
this.filter_enabled = 1;
85+
else
86+
`ERROR(("Cannot enable data filtering while scoreboard is running"));
87+
endfunction: enable_filtering
88+
89+
// disable data filtering
90+
function void disable_filtering();
91+
if (!this.enabled)
92+
this.filter_enabled = 0;
93+
else
94+
`ERROR(("Cannot disable data filtering while scoreboard is running"));
95+
endfunction: disable_filtering
96+
97+
// set filter tree
98+
function void set_filter_tree_source(
99+
filter_tree_class filter_tree);
100+
101+
if (!this.enabled)
102+
this.filter_tree_source = filter_tree;
103+
else
104+
`ERROR(("Cannot change filter tree while scoreboard is running"));
105+
endfunction: set_filter_tree_source
106+
107+
function void set_filter_tree_sink(
108+
filter_tree_class filter_tree);
109+
110+
if (!this.enabled)
111+
this.filter_tree_sink = filter_tree;
112+
else
113+
`ERROR(("Cannot change filter tree while scoreboard is running"));
114+
endfunction: set_filter_tree_sink
64115

65116
// run task
66117
task run();
67118

119+
if (this.filter_tree_source == null && this.filter_tree_sink == null && this.filter_enabled)
120+
`ERROR(("No filter tree is set"));
121+
68122
fork
69123
this.enabled = 1;
70124
this.get_source_transaction();
@@ -83,15 +137,15 @@ package scoreboard_pkg;
83137
endtask: stop
84138

85139
// set sink type
86-
function void set_sink_type(input bit sink_type);
140+
function void set_transfer_type(input bit transfer_type);
87141

88142
if (!this.enabled) begin
89-
this.sink_type = sink_type_t'(sink_type);
143+
this.transfer_type = transfer_type_t'(transfer_type);
90144
end else begin
91-
`ERROR(("ERROR Scoreboard: Can not configure sink_type while scoreboard is running."));
145+
`ERROR(("ERROR Scoreboard: Can not configure transfer_type while scoreboard is running."));
92146
end
93147

94-
endfunction: set_sink_type
148+
endfunction: set_transfer_type
95149

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

105159
// get sink type
106-
function bit get_sink_type();
107-
return this.sink_type;
160+
function bit get_transfer_type();
161+
return this.transfer_type;
108162
endfunction
109163

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

120174
logic [7:0] source_byte;
175+
logic [7:0] packet [];
121176

122177
forever begin
123178
fork begin
@@ -127,19 +182,31 @@ package scoreboard_pkg;
127182
join_any
128183
disable fork;
129184
end join
185+
130186
if (this.enabled == 0)
131187
break;
132188

133189
this.source_monitor.get_key();
134-
for (int i=0; i<this.source_monitor.mailbox.num(); ++i) begin
190+
packet = new [this.source_monitor.mailbox.num()];
191+
`INFOV(("Source packet length: %d", packet.size()), 200);
192+
for (int i=0; i<packet.size(); ++i) begin
135193
this.source_monitor.mailbox.get(source_byte);
136194
this.source_monitor.mailbox.put(source_byte);
137-
this.source_byte_stream.push_front(source_byte);
195+
packet[i] = source_byte;
138196
end
139-
this.source_byte_stream_size += this.source_monitor.mailbox.num();
140-
`INFOV(("Source transaction received, size: %d - %d", this.source_monitor.mailbox.num(), this.source_byte_stream_size), 200);
141-
->>source_transaction_event;
142197
this.source_monitor.put_key();
198+
199+
if (this.filter_enabled)
200+
this.filter_tree_source.apply_filter(packet);
201+
202+
if (!this.filter_enabled || this.filter_tree_source.result) begin
203+
for (int i=0; i<packet.size(); ++i) begin
204+
this.source_byte_stream.push_front(packet[i]);
205+
end
206+
this.source_byte_stream_size += packet.size();
207+
`INFOV(("Source transaction received, size: %d - %d", packet.size(), this.source_byte_stream_size), 200);
208+
->>source_transaction_event;
209+
end
143210
end
144211

145212
endtask: get_source_transaction
@@ -148,6 +215,7 @@ package scoreboard_pkg;
148215
task get_sink_transaction();
149216

150217
logic [7:0] sink_byte;
218+
logic [7:0] packet [];
151219

152220
forever begin
153221
fork begin
@@ -162,15 +230,26 @@ package scoreboard_pkg;
162230
break;
163231

164232
this.sink_monitor.get_key();
165-
for (int i=0; i<this.sink_monitor.mailbox.num(); ++i) begin
233+
packet = new [this.sink_monitor.mailbox.num()];
234+
`INFOV(("Sink packet length: %d", packet.size()), 200);
235+
for (int i=0; i<packet.size(); ++i) begin
166236
this.sink_monitor.mailbox.get(sink_byte);
167237
this.sink_monitor.mailbox.put(sink_byte);
168-
this.sink_byte_stream.push_front(sink_byte);
238+
packet[i] = sink_byte;
169239
end
170-
this.sink_byte_stream_size += this.sink_monitor.mailbox.num();
171-
`INFOV(("Sink transaction received, size: %d - %d", this.sink_monitor.mailbox.num(), this.sink_byte_stream_size), 200);
172-
->>sink_transaction_event;
173240
this.sink_monitor.put_key();
241+
242+
if (this.filter_enabled)
243+
this.filter_tree_sink.apply_filter(packet);
244+
245+
if (!this.filter_enabled || this.filter_tree_sink.result) begin
246+
for (int i=0; i<packet.size(); ++i) begin
247+
this.sink_byte_stream.push_front(packet[i]);
248+
end
249+
this.sink_byte_stream_size += packet.size();
250+
`INFOV(("Sink transaction received, size: %d - %d", packet.size(), this.sink_byte_stream_size), 200);
251+
->>sink_transaction_event;
252+
end
174253
end
175254

176255
endtask: get_sink_transaction
@@ -190,7 +269,7 @@ package scoreboard_pkg;
190269
(this.sink_byte_stream_size > 0)) begin
191270
byte_streams_empty_sig = 0;
192271
source_byte = this.source_byte_stream.pop_back();
193-
if (this.sink_type == CYCLIC)
272+
if (this.transfer_type == CYCLIC)
194273
this.source_byte_stream.push_front(source_byte);
195274
else
196275
this.source_byte_stream_size--;
@@ -201,10 +280,16 @@ package scoreboard_pkg;
201280
`ERROR(("Scoreboard failed at: exp %h - rcv %h", source_byte, sink_byte));
202281
end
203282
end else begin
204-
if ((this.source_byte_stream_size == 0) &&
205-
(this.sink_byte_stream_size == 0)) begin
206-
byte_streams_empty_sig = 1;
207-
->>byte_streams_empty;
283+
if (this.sink_byte_stream_size == 0) begin
284+
if (this.transfer_type == CYCLIC) begin
285+
byte_streams_empty_sig = 1;
286+
->>byte_streams_empty;
287+
end else begin
288+
if ((this.source_byte_stream_size == 0)) begin
289+
byte_streams_empty_sig = 1;
290+
->>byte_streams_empty;
291+
end
292+
end
208293
end
209294
fork begin
210295
fork

0 commit comments

Comments
 (0)