Hi,
I want to fork multiple forever blocks using for loop. what is the best way!!
not sure if the solutions I’m trying below would work.
Thanks in advance.
//required output
fork //fork 3 forever blocks
forever begin
wait(xyz[0] == 1);
//code for loop0
end
forever begin
wait(xyz[1] == 1);
//code for loop1
end
forever begin
wait(xyz[2] == 1);
//code for loop2
end
join
//solution im thinking
//***********want to wait till three forever blocks join**************
for(int i=0; i<3; i++) begin
fork
automatic int j = i;
forever begin
wait(xyz[j] == 1);
//code inside task written below but explicitly written here
end
join
end
//alternate trial - ideally I think both solutions give the same result
//just thinking forever might cause hang to the code above. So moved it into the task
for(int i=0; i<3; i++) begin
fork
automatic int j = i;
myLoop(j); //task
join
end
task myLoop(int i);
forever begin
wait(xyz[i] == 1);
@(posedge m_vif.uclk);
if(!Flag[i]) begin
wait_time[i] = getWaitTime();
Flag[i] = 1;
end
memclk_cycle[i] += 1;
if (memclk_cycle[i] == wait_time[i]) begin
Flag[i] = 0;
memclk_cycle[i] = 0;
xyz[i] = 0;
end
end
endtask
In reply to NaveenReddy:
Your solution and alternate have no fork statements. And without knowing what kind code you intent to put in the loop, it will be hard to give a best recommendation.
In reply to dave_59:
Hi Dave, thanks for pointing out the missing fork join. I have updated my code and the code i would be placing inside forever block.
In reply to NaveenReddy:
There really is no difference in terms of potential to hang if you put the code in a task or not.
It’s up to you to decide if using the task makes your code more readable. If this is a method of a class, putting it in a task makes it easier t override.
BTW, I recommend that you keep things synchronized by only using a clock edge and not using wait statements. Use
@(posedge m_vif.uclk iff xyz[i] == 1)
In reply to dave_59:
Thanks Dave for the suggestion.
will the fork waits for all the three forever loops to join?
Also, in some post I read you suggesting to use it like below #1
what would be the best way to use #1 or #2 ?
// #1
forever @(posedge m_vif.uclk iff xyz[i] == 1) begin
//code
end
//#2
forever begin
@(posedge m_vif.uclk iff xyz[i] == 1);
//code
// Question: is this way #2 correct or should the code be embedded in begin end blocks ?
end
In reply to NaveenReddy:
You need to use fork/join*_none*. I missed that.
You can put endless number of begin/ed blocks around a single statement. I prefer to use the minimum required, but sometimes it can make the code more readable. For example
if (cond)
statement1;
statement2;
statement3;
It’s not clear that only statement1 is part of the if conditional. Better to write
if (cond) begin
statement1;
end
statement2;
statement3;
In reply to NaveenReddy:
In reply to dave_59:
Thanks Dave for the suggestion.
will the fork waits for all the three forever loops to join?
Also, in some post I read you suggesting to use it like below #1
what would be the best way to use #1 or #2 ?
// #1
forever @(posedge m_vif.uclk iff xyz[i] == 1) begin
//code
end
//#2
forever begin
@(posedge m_vif.uclk iff xyz[i] == 1);
//code
// Question: is this way #2 correct or should the code be embedded in begin end blocks ?
end
Dave pardon me for bugging more on this thread.
if I want the iff condition to be applied to all the below lines
will the #2 method i wrote below works?
//#1 is straight forward since the code will be embedded in begin end blocks
//#2 but in this, the iff condition is terminated by ; and the following statements are not
// enclosed in begin end blocks. so, in that case, how would the code behave?
forever begin
@(posedge m_vif.uclk iff xyz[i] == 1); //no begin end block here. so i believe this would only be applied to the immediate if condition here. Please correct me if I'm wrong
if(!Flag[i]) begin
wait_time[i] = getWaitTime();
Flag[i] = 1;
end
memclk_cycle[i] += 1;
if (memclk_cycle[i] == wait_time[i]) begin
Flag[i] = 0;
memclk_cycle[i] = 0;
xyz[i] = 0;
end
end