Hello everyone!
I’ve noticed, that my test runs pretty slowly, though the test itslef and the DUT are not very complicated. I looked through the profiling report, and found out, that calling “start_item” and “finish_item” in my sequence takes about 98% of entire resourses, used in simulation. Way too much, I guess=)
What’s wrong with these methods? Is it a common place, or maybe there are some techniques, that allow to speed up transfers between sequencer and driver?
Thank you!
I’m not aware of any specific problems with start_item/finish_item. Perhaps you could include your sequence code?
In reply to tfitz:
Sure.
here’s sequence
class v_data_sequence extends uvm_sequence#( v_data_transaction #( .V_DATA_WIDTH(V_DATA_WIDTH), .N_COMP(N_COMP_IN),
.Y_WIDTH(Y_WIDTH),
.X_WIDTH(X_WIDTH)
)
);
parameter IN_IMAGE_X_WIDTH = 2560;
parameter IN_IMAGE_Y_WIDTH = 1920;
parameter PIX_IN_INPUT_IMAGE = IN_IMAGE_X_WIDTH + IN_IMAGE_Y_WIDTH;
read_file_class #(
.IMAGE_SIZE_X(IN_IMAGE_X_WIDTH),
.IMAGE_SIZE_Y(IN_IMAGE_Y_WIDTH),
.PIX_WIDTH(24),
.ADJUST_PIX_WIDTH(10),
.LITTLE_ENDIAN(1)
) reader;
v_data_transaction #(
.V_DATA_WIDTH(V_DATA_WIDTH),
.N_COMP(N_COMP_IN),
.Y_WIDTH(Y_WIDTH),
.X_WIDTH(X_WIDTH)
) v_data_tx;
function new( string name = "" );
super.new( name );
endfunction: new
task body();
bit [24-1:0] vd_mx [IN_IMAGE_Y_WIDTH-1:0][IN_IMAGE_X_WIDTH-1:0];
int line_num = 0;
int elem_n = 0;
int file_id;
int results;
bit [V_DATA_WIDTH-1:0] pix;
file_id = $fopen("input_image.dat", "rb");
reader = read_file_class #(
.IMAGE_SIZE_X(IN_IMAGE_X_WIDTH),
.IMAGE_SIZE_Y(IN_IMAGE_Y_WIDTH),
.PIX_WIDTH(24),
.ADJUST_PIX_WIDTH(10),
.LITTLE_ENDIAN(1)
)::type_id::create( .name( "reader"));
reader.read_from_file(
.vd_mx(vd_mx),
.start_offset(0),
.file_id(file_id)
);
for (int line_num = 0; line_num < Y_SIZE; line_num++)
begin
for (int elem_n = 0; elem_n < X_SIZE + 2*UNACTIVE_PART; elem_n++)
begin
v_data_tx = v_data_transaction #(
.V_DATA_WIDTH(V_DATA_WIDTH),
.N_COMP(N_COMP_IN),
.Y_WIDTH(Y_WIDTH),
.X_WIDTH(X_WIDTH)
)::type_id::create( .name( "v_data_tx" ));
start_item( v_data_tx );
//assert( v_data_tx.randomize() );
if ((elem_n >= UNACTIVE_PART) && (elem_n < X_SIZE + UNACTIVE_PART))
begin
v_data_tx.x_active = 1;
end
else
begin
v_data_tx.x_active = 0;
end
if (v_data_tx.x_active)
begin
v_data_tx.x = elem_n - UNACTIVE_PART;
end
else
begin
v_data_tx.x = '0;
end
v_data_tx.y = line_num;
if (~line_num)
begin
if (~elem_n)
begin
pix = vd_mx[line_num+512][elem_n+1024][7:0];//R
end
else
begin
pix = vd_mx[line_num+512][elem_n+1024][15:8];//G
end
end
else
begin
if (~elem_n)
begin
pix = vd_mx[line_num+512][elem_n+1024][15:8];//G
end
else
begin
pix = vd_mx[line_num+512][elem_n+1024][23:16];//B
end
end
v_data_tx.v_data = pix;//line_num + elem_n;
finish_item( v_data_tx );
end
end
endtask: body
`uvm_object_utils( v_data_sequence )
endclass: v_data_sequence
and here’s part of a driver code
forever
begin
seq_item_port.get_next_item( v_data_tx );
send_word(
.v_data(v_data_tx.v_data),
.y(v_data_tx.y),
.x(v_data_tx.x),
.x_active(v_data_tx.x_active)
);
seq_item_port.item_done();
end
...
task v_data_driver::send_word (
bit [N_COMP-1:0] [V_DATA_WIDTH-1:0] v_data,
bit [Y_WIDTH-1:0] y,
bit [X_WIDTH-1:0] x,
bit x_active
);
foreach (v_data[i])
begin
v_data_bus.v_data[i] <= v_data[i];
end
v_data_bus.y <= y;
v_data_bus.x <= x;
v_data_bus.x_active <= x_active;
repeat (3) @(posedge v_data_bus.clk);
v_data_bus.pix_en <= 1'b1;
@(posedge v_data_bus.clk)
v_data_bus.pix_en <= 1'b0;
endtask
sorry about indents (or, should i say, their absence). I used Notepad and it turn out to be a disaster)
In reply to trogers:
I find it hard to believe if this is your only running sequence that start/finish_item would be slowing your simulation down. You would be calling them only once every 4 clock cycles. Maybe you are reading the profile incorrectly. You should work with your simulation vendor to explore more options.
In reply to dave_59:
yeah, it’s a surprise for me too. But here’s profiling report, and lines 92 and 146 are the ones, where start_item and finish_item are called respectively. I use QuestaSim 10.0b, maybe i face this problem because of my old Questa version?
UPD: looked what happens in uvm_sequencer_base.svh:1017
task uvm_sequencer_base::wait_for_item_done(uvm_sequence_base sequence_ptr,
int transaction_id);
int sequence_id;
sequence_id = sequence_ptr.m_get_sqr_sequence_id(m_sequencer_id, 1);
m_wait_for_item_sequence_id = -1;
m_wait_for_item_transaction_id = -1;
if (transaction_id == -1)
wait (m_wait_for_item_sequence_id == sequence_id);
else
wait ((m_wait_for_item_sequence_id == sequence_id &&
m_wait_for_item_transaction_id == transaction_id));
endtask
line 1017 is
if (transaction_id == -1)
wait (m_wait_for_item_sequence_id == sequence_id);