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

Infrastructure update #160

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
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
67 changes: 0 additions & 67 deletions library/drivers/common/mailbox.sv

This file was deleted.

254 changes: 94 additions & 160 deletions library/drivers/common/scoreboard.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,63 @@

package scoreboard_pkg;

import xil_common_vip_pkg::*;
import axi4stream_vip_pkg::*;
import axi_vip_pkg::*;
import logger_pkg::*;
import x_monitor_pkg::*;
import mailbox_pkg::*;
import adi_common_pkg::*;
import pub_sub_pkg::*;

class scoreboard extends adi_component;
class scoreboard #(type data_type = int) extends adi_component;

typedef enum bit { CYCLIC=0, ONESHOT } sink_type_t;
protected sink_type_t sink_type;
class subscriber_class extends adi_subscriber #(data_type);

protected scoreboard #(data_type) scoreboard_ref;

protected data_type byte_stream [$];

function new(
input string name,
input scoreboard #(data_type) scoreboard_ref,
input adi_component parent = null);

super.new(name, parent);

this.scoreboard_ref = scoreboard_ref;
endfunction: new

virtual function void update(input data_type data [$]);
this.info($sformatf("Data received: %d", data.size()), ADI_VERBOSITY_MEDIUM);
while (data.size()) begin
this.byte_stream.push_back(data.pop_front());
end

if (this.scoreboard_ref.get_enabled()) begin
this.scoreboard_ref.compare_transaction();
end
endfunction: update

function data_type get_data();
return this.byte_stream.pop_front();
endfunction: get_data

function void put_data(data_type data);
this.byte_stream.push_back(data);
endfunction: put_data

// List of analysis ports from the monitors
protected x_monitor source_monitor;
protected x_monitor sink_monitor;
function int get_size();
return this.byte_stream.size();
endfunction: get_size

protected logic [7:0] source_byte_stream [$];
protected logic [7:0] sink_byte_stream [$];
function void clear_stream();
this.byte_stream.delete();
endfunction: clear_stream

protected int source_byte_stream_size;
protected int sink_byte_stream_size;
endclass: subscriber_class


subscriber_class subscriber_source;
subscriber_class subscriber_sink;

typedef enum bit { CYCLIC=0, ONESHOT } sink_type_t;
protected sink_type_t sink_type;

// counters and synchronizers
protected bit enabled;
Expand All @@ -31,8 +67,6 @@ package scoreboard_pkg;
// protected event end_of_first_cycle;
protected event byte_streams_empty;
protected event stop_scoreboard;
protected event source_transaction_event;
protected event sink_transaction_event;

// constructor
function new(
Expand All @@ -41,186 +75,86 @@ package scoreboard_pkg;

super.new(name, parent);

this.subscriber_source = new("Subscriber Source", this);
this.subscriber_sink = new("Subscriber Sink", this);

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

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;

endfunction: set_source_stream

function void set_sink_stream(
x_monitor sink_monitor);

this.sink_monitor = sink_monitor;

endfunction: set_sink_stream

// run task
task run();

fork
this.enabled = 1;
this.get_source_transaction();
this.get_sink_transaction();
this.compare_transaction();
join_none

this.enabled = 1;

this.info($sformatf("Scoreboard enabled"), ADI_VERBOSITY_MEDIUM);
endtask: run

// stop scoreboard
task stop();
this.enabled = 0;
->>stop_scoreboard;
this.clear_streams();
#1step;
this.byte_streams_empty_sig = 1;
endtask: stop

function bit get_enabled();
return this.enabled;
endfunction: get_enabled

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

if (!this.enabled) begin
this.sink_type = sink_type_t'(sink_type);
end else begin
this.error($sformatf("Can not configure sink_type while scoreboard is running."));
end

endfunction: set_sink_type

// clear source and sink byte streams
function void clear_streams();
this.source_byte_stream.delete();
this.sink_byte_stream.delete();

this.source_byte_stream_size = 0;
this.sink_byte_stream_size = 0;
endfunction: clear_streams

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

// clear source and sink byte streams
protected function void clear_streams();
this.subscriber_source.clear_stream();
this.subscriber_source.clear_stream();
endfunction: clear_streams

// wait until source and sink byte streams are empty, full check
task wait_until_complete();
if (this.byte_streams_empty_sig)
return;
@byte_streams_empty;
endtask

// get transaction data from source monitor
task get_source_transaction();

logic [7:0] source_byte;

forever begin
fork begin
fork
this.source_monitor.wait_for_transaction_event();
@stop_scoreboard;
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
this.source_monitor.mailbox.get(source_byte);
this.source_monitor.mailbox.put(source_byte);
this.source_byte_stream.push_front(source_byte);
end
this.source_byte_stream_size += this.source_monitor.mailbox.num();
this.info($sformatf("Source transaction received, size: %d - %d", this.source_monitor.mailbox.num(), this.source_byte_stream_size), ADI_VERBOSITY_MEDIUM);
->>source_transaction_event;
this.source_monitor.put_key();
end

endtask: get_source_transaction

// get transaction data from sink monitor
task get_sink_transaction();

logic [7:0] sink_byte;

forever begin
fork begin
fork
this.sink_monitor.wait_for_transaction_event();
@stop_scoreboard;
join_any
disable fork;
end join

if (this.enabled == 0)
break;

this.sink_monitor.get_key();
for (int i=0; i<this.sink_monitor.mailbox.num(); ++i) begin
this.sink_monitor.mailbox.get(sink_byte);
this.sink_monitor.mailbox.put(sink_byte);
this.sink_byte_stream.push_front(sink_byte);
end
this.sink_byte_stream_size += this.sink_monitor.mailbox.num();
this.info($sformatf("Sink transaction received, size: %d - %d", this.sink_monitor.mailbox.num(), this.sink_byte_stream_size), ADI_VERBOSITY_MEDIUM);
->>sink_transaction_event;
this.sink_monitor.put_key();
end

endtask: get_sink_transaction
@this.byte_streams_empty;
endtask: wait_until_complete

// compare the collected data
virtual task compare_transaction();

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

this.info($sformatf("Started"), ADI_VERBOSITY_MEDIUM);

forever begin : tx_path
if (this.enabled == 0)
break;
if ((this.source_byte_stream_size > 0) &&
(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)
this.source_byte_stream.push_front(source_byte);
else
this.source_byte_stream_size--;
sink_byte = this.sink_byte_stream.pop_back();
this.sink_byte_stream_size--;
this.info($sformatf("Source-sink data: exp %h - rcv %h", source_byte, sink_byte), ADI_VERBOSITY_MEDIUM);
if (source_byte != sink_byte) begin
this.error($sformatf("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;
end
fork begin
fork
@source_transaction_event;
@sink_transaction_event;
@stop_scoreboard;
join_any
byte_streams_empty_sig = 0;
disable fork;
end join
virtual function void compare_transaction();
data_type source_byte;
data_type sink_byte;

if (this.enabled == 0)
return;

while ((this.subscriber_source.get_size() > 0) &&
(this.subscriber_sink.get_size() > 0)) begin
byte_streams_empty_sig = 0;
source_byte = this.subscriber_source.get_data();
if (this.sink_type == CYCLIC)
this.subscriber_source.put_data(source_byte);
sink_byte = this.subscriber_sink.get_data();
this.info($sformatf("Source-sink data: exp %h - rcv %h", source_byte, sink_byte), ADI_VERBOSITY_MEDIUM);
if (source_byte != sink_byte) begin
this.error($sformatf("Failed at: exp %h - rcv %h", source_byte, sink_byte));
end
end

endtask /* compare_transaction */
if ((this.subscriber_source.get_size() == 0) &&
(this.subscriber_sink.get_size() == 0)) begin
this.byte_streams_empty_sig = 1;
->this.byte_streams_empty;
end
endfunction: compare_transaction

endclass

Expand Down
Loading
Loading