Skip to content

Commit

Permalink
Merge branch 'isa_uvm_dma_fix' into 'devel'
Browse files Browse the repository at this point in the history
bugfix in pcie verification

See merge request ndk/ndk-fpga!108
  • Loading branch information
jakubcabal committed Nov 18, 2024
2 parents 0375ef8 + 9febf9c commit 3620954
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 13 deletions.
2 changes: 1 addition & 1 deletion comp/ver/axi/axi4s_rc_agent.sv
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class Axi4S_RC_agent #(DATA_WIDTH = 512, USER_WIDTH = 161, ITEM_WIDTH_IN = 8, ST
$cast(tr, transaction);
while(sof[offset / REGION_ITEMS]) // two SOFs not allowed in the same region
moveBlock();
while(eof[(offset + tr.data.size - 1) / REGION_ITEMS]) // two EOFs not allowed in the same region
while((offset + tr.data.size - 1) < REGIONS*REGION_ITEMS && eof[(offset + tr.data.size - 1)/REGION_ITEMS]) // two EOFs not allowed in the same region
moveBlock();
/* if(SOF_CTRL)
while(((offset / REGION_ITEMS) != tr.sof) || (((offset % REGION_ITEMS) / BLOCK_SIZE) != tr.sof_pos)) // find correct SOF AND find correct SOF position
Expand Down
237 changes: 237 additions & 0 deletions comp/ver/axi/axi4s_rc_meter.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
/*!
* \file axi4s_rc_meter.sv
* \brief Get statistic from axi4s
* \author Radek Iša <[email protected]>
* \date 2024
* \copyright CESNET, z. s. p. o.
*/

/* SPDX-License-Identifier: BSD-3-Clause */

class Axi4S_RC_meter #(DATA_WIDTH = 512, USER_WIDTH = 137, ITEM_WIDTH_IN = 8, ST_COUNT = 4) extends Monitor;

localparam REGIONS = ST_COUNT;
localparam REGION_SIZE = 1;
localparam ITEM_WIDTH = 8;
localparam BLOCK_SIZE = DATA_WIDTH/REGIONS/ITEM_WIDTH;

protected int sof_pos[REGIONS];
protected int eof_pos[REGIONS];

localparam ITEMS = REGIONS * REGION_SIZE * BLOCK_SIZE;
localparam REGION_ITEMS = REGION_SIZE * BLOCK_SIZE;
localparam WORD_BLOCKS = REGIONS * REGION_SIZE;
localparam SOF_POS_WIDTH = $clog2(REGION_SIZE);
localparam EOF_POS_WIDTH = $clog2(REGION_SIZE * BLOCK_SIZE);

protected virtual iAxi4SRx#(DATA_WIDTH, USER_WIDTH, ITEM_WIDTH_IN) vif;
protected sv_common_pkg::stats speed;
protected int unsigned speed_curr;
protected logic inframe;
protected int old_inframe = 0;

function new(string i, virtual iAxi4SRx#(DATA_WIDTH, USER_WIDTH, ITEM_WIDTH_IN) v);
super.new(i);
speed = new();
vif = v;
endfunction

virtual task setEnabled();
enabled = 1;
fork
run();
join_none;
endtask

function int hasSOF();
if (USER_WIDTH==137) // ULTRASCALE
return vif.cb.TUSER[21:20];
else begin // 7SERIES
if (!inframe)
return vif.cb.TVALID;
else
return 0;
end
endfunction

function int hasEOF();
if (USER_WIDTH==137) // ULTRASCALE
return vif.cb.TUSER[27:26];
else begin // 7SERIES
return vif.cb.TLAST;
end
endfunction

function logic [3:0] fbe(int unsigned index);
if(USER_WIDTH== 137) begin
return vif.cb.TUSER[(index+1)*4-1 -: 4];
end else if (USER_WIDTH == 60) begin
return vif.cb.TUSER[3:0];
end else begin
$write("NOT SUPPORTED AXI USER_WIDTH\n");
$stop();
end
endfunction

function logic [3:0] lbe(int unsigned index);
if(USER_WIDTH== 137) begin
return vif.cb.TUSER[(index+1)*4+7 -: 4];
end else if (USER_WIDTH == 60) begin
return vif.cb.TUSER[7:4];
end else begin
$write("NOT SUPPORTED AXI USER_WIDTH\n");
$stop();
end
endfunction

function int sofPos(int index);
if(SOF_POS_WIDTH == 0) begin
return 0;
end

if (USER_WIDTH==137) // ULTRASCALE
return index;
else begin // 7SERIES
return 0;
end
endfunction

function int eofPos(int index);
int pos = 0;
int j = 0;

if (EOF_POS_WIDTH == 0) begin
return 0;
end

if (USER_WIDTH==137) begin // ULTRASCALE
if ((vif.cb.TUSER[26] && vif.cb.TUSER[31:31] == index))
return vif.cb.TUSER[30:28];
if ((vif.cb.TUSER[27] && vif.cb.TUSER[35:35] == index))
return vif.cb.TUSER[34:32];
end else begin // 7SERIES
for (j = 0; j < REGION_ITEMS; j++) begin
if (vif.cb.TKEEP[j]==1'b0)
break;
pos = j;
end
return pos;
end
return -1;
endfunction

function int isSOF(int index);
if (USER_WIDTH==137) begin // ULTRASCALE
if ((vif.cb.TUSER[20] && vif.cb.TUSER[23:23] == index) ||
(vif.cb.TUSER[21] && vif.cb.TUSER[25:25] == index))
return 1;
end else begin // 7SERIES
if (!old_inframe)
return vif.cb.TVALID;
end
return 0;
endfunction

function int isEOF(int index);
if (USER_WIDTH==137) begin // ULTRASCALE
if ((vif.cb.TUSER[26] && vif.cb.TUSER[31:31] == index) ||
(vif.cb.TUSER[27] && vif.cb.TUSER[35:35] == index))
return 1;
end else begin // 7SERIES
return hasEOF(); // only 1 region
end
return 0;
endfunction

task run_meter();
speed_curr = 0;
speed.reset();

while (enabled) begin
time speed_start_time;
time speed_end_time;
const int unsigned mesures = 100;
string msg;

speed_end_time = $time();
forever begin
time step_speed_end_time = speed_end_time;
time step_speed_start_time;

for (int unsigned it = 0; it < mesures; it++) begin
step_speed_start_time = step_speed_end_time;

#(1us);
step_speed_end_time = $time();
speed.next_val(real'(speed_curr)/((step_speed_end_time-step_speed_start_time)/1ns));

speed_curr = 0;
end

begin
real min, max, avg, std_dev;

speed_start_time = speed_end_time;
speed_end_time = step_speed_end_time;
speed.count(min, max, avg, std_dev);
msg = $sformatf("\n\tSpeed [%0dns:%0dns]\n\t\tAverage : %0.2fGb/s std_dev %0.2fGb/s\n\t\tmin : %0.2fGb/s max %0.2fGb/s",
speed_start_time/1ns, speed_end_time/1ns, avg*ITEM_WIDTH, std_dev*ITEM_WIDTH, min*ITEM_WIDTH, max*ITEM_WIDTH);
$write({"\n", this.inst , "\n", msg, "\n"});
speed.reset();
end
end
end
endtask


virtual task run();
inframe = 0;

fork
run_meter();
join_none


while (enabled) begin
int unsigned data_frame_size = 0;

do begin
@(vif.monitor_cb);
end while (enabled && !(vif.monitor_cb.TVALID && vif.monitor_cb.TREADY));

if (!enabled)
break;

for (int unsigned it = 0; it < REGIONS; it++) begin
if (inframe == 1) begin
if (isEOF(it)) begin
data_frame_size += eofPos(it)+1;
inframe = 0;
if (isSOF(it)) begin
data_frame_size += (REGION_SIZE - sofPos(it))*BLOCK_SIZE;
inframe = 1;
end
old_inframe = inframe;
end else begin
data_frame_size += REGION_SIZE*BLOCK_SIZE;
end
end else begin
if (isSOF(it)) begin
if (isEOF(it)) begin
data_frame_size += (eofPos(it)+1 - sofPos(it)*BLOCK_SIZE);
inframe = 0;
end else begin
data_frame_size += (REGION_SIZE - sofPos(it))*BLOCK_SIZE;
inframe = 1;
end
old_inframe = inframe;
end else begin
data_frame_size += 0;
end
end
end
speed_curr += data_frame_size;
end
endtask

endclass
1 change: 1 addition & 0 deletions comp/ver/axi/sv_axi_pcie_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ package sv_axi_pcie_pkg;
import sv_common_pkg::*;
import sv_axi_pkg::*;

`include "axi4s_rc_meter.sv"
`include "axi4s_rc_agent.sv"
`include "axi4s_rq_meter.sv"
`include "axi4s_rq_agent.sv"
Expand Down
4 changes: 4 additions & 0 deletions comp/ver/pcie/avalon_rq_monitor.sv
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ class avalon_rq_monitor extends sv_common_pkg::Monitor;

state = IDLE;
hl_tr.data = data;
if (hl_tr.type_tr == PCIE_RQ_WRITE && hl_tr.data.size() != hl_tr.length) begin
$error("%s\n Indicated size in header (%0d) is not same as payload size\n%s", `__FILE__, hl_tr.length, hl_tr.convert2string());
$stop();
end
$cast(to, hl_tr);
foreach(cbs[it]) begin
cbs[it].post_rx(to, inst);
Expand Down
18 changes: 12 additions & 6 deletions comp/ver/pcie/axi_agent.sv
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class axi_agent #(RCB, MPS, DEVICE, DATA_WIDTH) extends agent #(RCB, MPS);
sv_axi_pcie_pkg::Axi4S_RQ_meter #(DATA_WIDTH, RQ_TUSER_WIDTH, 32, RQ_ST_COUNT) axiRQ_meter;
AxiResponder #(DATA_WIDTH, RQ_TUSER_WIDTH, 32) axiRQ_responder;
AxiDriver #(DATA_WIDTH, RC_TUSER_WIDTH, 32, RC_ST_COUNT) axiRC;
sv_axi_pcie_pkg::Axi4S_RC_meter #(DATA_WIDTH, RC_TUSER_WIDTH, 32, RC_ST_COUNT) axiRC_meter;
string inst;

function new (string inst, sv_common_pkg::tTransMbx mbx_input, virtual iAxi4STx #(DATA_WIDTH, RQ_TUSER_WIDTH, 32) vif_rx, virtual iAxi4SRx #(DATA_WIDTH, RC_TUSER_WIDTH, 32) vif_tx);
Expand All @@ -82,31 +83,36 @@ class axi_agent #(RCB, MPS, DEVICE, DATA_WIDTH) extends agent #(RCB, MPS);
//Request modules
rq_monitor = new();
rq_monitor.setCallbacks(this.tags_req_cbs);
axiRQ = new({inst, "AXI Request "}, vif_rx);
axiRQ_meter = new({inst, "AXI Meter "}, vif_rx);
axiRQ = new({inst, "AXI RQ Request "}, vif_rx);
axiRQ_meter = new({inst, "AXI RQ Meter "}, vif_rx);
axiRQ.setCallbacks(rq_monitor.axi_rq_cbs);
axiRQ_responder = new({inst, " AXI Responder"}, vif_rx);
axiRQ_responder = new({inst, " AXI RQ Responder"}, vif_rx);

//Response modules
rc_driver_cbs = new(4);
rc_driver = new({inst, " PCIE TO AXI DRIVER"}, pcie_sq_cbs.mbx_response);
rc_driver.setCallbacks(rc_driver_cbs);
axiRC = new({inst, " AXI Response agent"}, rc_driver_cbs.mbx_response, vif_tx);
axiRC = new({inst, " AXI RC Response agent"}, rc_driver_cbs.mbx_response, vif_tx);
axiRC_meter = new({inst, "AXI RC Meter "}, vif_tx);
endfunction

task setEnabled();
axiRQ.setEnabled();
axiRQ_meter.setEnabled();
rq_monitor.setEnabled();
super.setEnabled();
axiRQ_responder.setEnabled();
rc_driver.setEnabled();
axiRC.setEnabled();

axiRQ_meter.setEnabled();
axiRC_meter.setEnabled();
endtask

task setDisabled();
axiRQ.setDisabled();
axiRQ_meter.setDisabled();
axiRC_meter.setDisabled();

axiRQ.setDisabled();
rq_monitor.setDisabled();
super.setDisabled();
axiRQ_responder.setDisabled();
Expand Down
4 changes: 4 additions & 0 deletions comp/ver/pcie/axi_rq_monitor.sv
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class axi_rq_monitor extends sv_common_pkg::Monitor;
hl_tr.display({inst, " Create PCIE RQ"});
end

if (hl_tr.type_tr == PCIE_RQ_WRITE && hl_tr.data.size() != hl_tr.length) begin
$error("%s\n Indicated size in header (%0d) is not same as payload size\n%s", `__FILE__, hl_tr.length, hl_tr.convert2string());
$stop();
end
foreach(cbs[it]) begin
cbs[it].post_rx(hl_tr, inst);
end
Expand Down
19 changes: 13 additions & 6 deletions comp/ver/pcie/pcie_transaction.sv
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class PcieCompletion extends sv_common_pkg::Transaction;
string num_to_str;
string s = "";

$sformat(num_to_str, "PcieCompletion\n\tlower addr %h\n\tlength %d\n\ttag %h\n\tbyte_count %d\n\tCompleted %b\n", lower_address, length, tag, byte_count, completed);
$sformat(num_to_str, "PcieCompletion\n\trequester ID %h\n\tlower addr %h\n\tlength %d\n\ttag %h\n\tbyte_count %d\n\tCompleted %b\n", requester_id, lower_address, length*4, tag, byte_count, completed);
s = {s, num_to_str};

for (int unsigned i = 0; i < data.size; i++) begin
Expand Down Expand Up @@ -147,6 +147,7 @@ class PcieRequest extends sv_common_pkg::Transaction;
byte unsigned data_que[$];
int unsigned data_length;
logic [63:0] address;
logic [4-1:0] lbe;

//deserialize data
if (data.size() > 0) begin
Expand Down Expand Up @@ -179,17 +180,23 @@ class PcieRequest extends sv_common_pkg::Transaction;
$finish();
end

if(data_length > 4) begin
lbe = this.lbe[3:0];
end else begin
lbe = fbe;
end

// corect length transaction by lbe
if (this.lbe[3] == 1'b1 || (data_length == 4 && this.lbe[3:0] == 4'b0000)) begin
if (lbe[3] == 1'b1) begin
; //do nothing
end else if (this.lbe[3:2] == 2'b01) begin
end else if (lbe[3:2] == 2'b01) begin
data_length -= 1;
data_que.pop_back();
end else if (this.lbe[3:1] == 3'b001) begin
end else if (lbe[3:1] == 3'b001) begin
data_length -= 2;
data_que.pop_back();
data_que.pop_back();
end else if (this.lbe[3:0] == 4'b0001) begin
end else if (lbe[3:0] == 4'b0001) begin
data_length -= 3;
data_que.pop_back();
data_que.pop_back();
Expand All @@ -208,7 +215,7 @@ class PcieRequest extends sv_common_pkg::Transaction;
string num_to_str;
string s = "";

$sformat(num_to_str, "PcieRequest\n\tTransaction type : %s\n\taddr %h\n\tlength %d\n\ttag %h\n\tfbe : %h \tlbe : %h\n", type_tr, {addr, 2'b00}, length*4, tag, fbe, lbe);
$sformat(num_to_str, "PcieRequest\n\tTransaction type : %s\n\trequester ID %h\n\taddr %h\n\tlength %d\n\ttag %h\n\tfbe : %h \tlbe : %h\n", type_tr, requester_id, {addr, 2'b00}, length*4, tag, fbe, lbe);
s = {s, num_to_str};

for (int unsigned i = 0; i < data.size; i++) begin
Expand Down

0 comments on commit 3620954

Please sign in to comment.