Hi all! I have a task in the SV interface that simply shifts input data, here is the code:
task write(logic [0:9] data_tx);
$display("DATA_TX_CALL: 0b%10b" , data_tx);
repeat(10) begin
@(cb);
$display("DATA_TX: 0b%10b" , data_tx);
cb.txp <= data_tx[0];
cb.txn <= ~data_tx[0];
data_tx = { data_tx[1:9] , 1'b0}; // Doesn't work with NBA
end
endtask // write
The code works when I use the blocking assignment in data_tx shifting, but I have a problem when NBA is used. Here is the log from task execution with NBA:
DATA_TX_CALL: 0b0101011000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
DATA_TX: 0b0000000000
As I understand the code is legal and data_tx should be updated in NBA region each time @(cb) event occurs. Have no clue why data_tx always equals to zero.
Why this shift is corrupted? Could someone please explain?
You need to show this code with more context. Is this task a method of a class? If that’s true, then data_tx is an automatic variable. You should’ve gotten a compiler error trying to make an NBA to an automatic variable.
Hi Dave.
NBA intend was to make sure that shifting occurs in NBA region and the first draft of the code had a shifting before clocking block drivesrepeat statement:
repeat(10) begin
@(cb);
$display("DATA_TX: 0b%10b" , data_tx);
data_tx <= { data_tx[1:9] , 1'b0};
cb.txp <= data_tx[0];
cb.txn <= ~data_tx[0];
end
And when it didn’t work I tried to fix it somehow. So I don’t think that I did any criminal here, I meant NBA usage. Please, correct me if I’m wrong.
I tried your code and it works fine with a single write(), but it failed when I tried more than one write() task. Here is the code and the log:
Your problem is data_tx is a static variable and you have a pending NBA assignment scheduled to it when you exit and immediately re-enter the task write(). The argument value that was copied in gets overwritten by the NBA.