Queue Push and Pop

Hi Friends,

I am using a queue in the scoreboard to store the expected data (Tx data). For storing the data in the queue, I use push_back method in a task called collect_tx_data. Whenever I get a Rx data from the Rx monitor, I pop out one data from tx data queue using pop_front method in my task called compare_data. I compare the two data’s and if they do not match, I push the Tx data back into the queue using push_front this time, so that I can compare the same Tx data with the next coming Rx data.

Now the issue is that this push_front method seems to be malfunctioning somehow. Because after pushing this data in the front of the queue, when I pop it back using pop_front, some new data comes out!! After every push, I check the size of the queue and I see it increasing, but still I do not get back the pushed data again. Please have a look at the code below and help me understand what wrong I am doing here:

collect_tx_data:

**task**collect_tx_data();
trans tx_mon_trans = new();
@(global_var_pkg::start_txseq);
$display("Scoreboard_message: Collecting the TX Data for comparison\n");
   **forever begin**
	txmon2fifo.get(tx_mon_trans);
	<font color=DarkOrange>exp_data_q.push_back(tx_mon_trans);</font>
	$display("\nCollect TX DATA: The size of exp_data_q is %d \n", exp_data_q.size);
   **end**<font color=RoyalBlue>//forever</font>
**endtask**: collect_tx_data

compare_data:

**task** compare_data();
trans expected_data = new;
trans received_data = new;

@(global_var_pkg::start_txseq);

   **forever begin**
	$display("\nCompare data: The size of exp_data_q is %d \n", exp_data_q.size);
	rxmon2fifo.get(received_data);	<font color=RoyalBlue>//Blocking call</font>
	<font color=DarkOrange>expected_data = exp_data_q.pop_front();</font>

expected_data.print();	<font color=RoyalBlue>//for debug purpose only</font>
received_data.print();	<font color=RoyalBlue>//for debug purpose only</font>

	**if**(expected_data.compare(received_data) == 1'b1) **begin
	**$display("\nScoreboard_message: Transmitted data matches the received data");
	**end else begin**
		$display (" INFO : Pushing back the TX DATA to the exp_data_q" );
		<font color=DarkOrange>exp_data_q.push_front(expected_data);</font>
	**end**<font color=RoyalBlue>//if (expected_data.compare(received_data) == 1'b1)</font>

   **end**<font color=RoyalBlue>//forever</font>

**endtask**: compare_data

Just now I noticed that even if I run the following code, I get different values printed for exp_data_q[0] in every iteration.

Code:

collect_tx_data:

task collect_tx_data();
trans tx_mon_trans = new();
@(global_var_pkg::start_txseq);

forever begin
txmon2fifo.get(tx_mon_trans);
exp_data_q.push_back(tx_mon_trans);
$display(“\nCollect TX DATA: The size of exp_data_q is %d \n”, exp_data_q.size);
end //forever

endtask : collect_tx_data

compare_data:

task compare_data();
trans received_data = new;
@(global_var_pkg::start_txseq);

   forever begin

	$display("\nCompare data: The size of exp_data_q is %d \n", exp_data_q.size);
	rxmon2fifo.get(received_data);	//Blocking call
	exp_data_q[0].print();	//for debug purpose only

   end //forever

endtask : compare_data</font>

I am not even popping out the data ever, still the exp_data_q[0] changes!
Is there anything fundamentally wrong I am trying do with the queue?

Please help me understand this.

Vivek,

The problem could be somewhere else. Are you cloning the data when you do a txmon2fifo.put()?

Also, why do you need a separate exp_data_q? Your compare_data() task could have txmon2fifo.get(expected_data) instead.

Hi Dave,

Thanks for the reply. I need to store the tx data in a queue because there is a latency between my tx and rx data and I am using ovm_analysis_port write method in my tx monitor to send the transactions to the scoreboard.

Vivek,

The latency should not matter if the data remains in order. The two get()s will block until you have both a tx and rx data available.

You didn’t respond to my question about clone. See [thread]880[/thread]

Dave Rich

Hi Dave,

Thanks a lot for following up. The latency in this case is a matter of concern because its not simple transmission and reception of data… at the receive side there are some complications like alignment of data and some other operations etc, which needs the environment to have a queue to store the Tx data.

By the way, I worked upon this issue yesterday and narrowed down the problem with some dummy tests …eventually I found the exact issue and corrected it. The issue was that whenever I pushed a new data in my expected data queue in the scoreboard, all the elements of that queue changed their value to this new data! And the reason for this was that from my Tx monitor, I was writing this data transaction to scoreboard using a forever loop, but I was not creating a new class for doing this. In tx monitor I used the new() constructor for my data class outside the forever loop. So in fact, I was overwriting and passing the same reference to the scoreboard each time and all the elements of my expected data queue got the same reference and hence the same data.

Now I am constructing the new transaction class in every iteration in forever loop and it is working fine!

Thanks again for you concern and support on this issue. :)