Hello,
I’ve seen several examples of using mailboxes, to communicate between single producer and consumer “components”, basically I can have a mailbox on each of them and then when connecting them together I just assign the mailbox handles something like this:
module env();
producer prod;
consumer cons;
packet pkt;
mailbox #(packet)channel;
initial begin
channel= new(); //creating mailbox
prod= new(channel); //passing mailbox handle
cons= new(channel); //passing mailbox handle
fork
prod.run();
cons.run();
join
end
endmodule
I want to connect multiple producers to a single consumer (something similar when in UVM you have a component connected to several analysis exports from other components) Is there a better way of doing this than the following (Are there any risks on this approach?):
module env();
producer prod[];
consumer cons;
packet pkt;
mailbox #(packet)channel;
initial begin
channel= new(); //creating mailbox
prod= new[4]; // create dynamic array of producers
foreach(prod[i]) begin
prod[i] = new(channel); //passing mailbox handle to each producer
end
cons= new(channel); //passing mailbox handle
fork
foreach(prod[i]) begin
prod.run();
end
cons.run();
join
end
endmodule
PS: I know I could use UVM and avoid these questions but due to project’s restrictions I’m forced to use only SV.
Cheers,
-Ronald
In reply to rgarcia07:
Do you mean to run the 4 producers in series (which is what you have written), or do you want them executing in parallel? If in parallel, you may need some sort of arbitration scheme to keep one of the producers from being greedy.
In reply to dave_59:
In reply to rgarcia07:
Do you mean to run the 4 producers in series (which is what you have written), or do you want them executing in parallel? If in parallel, you may need some sort of arbitration scheme to keep one of the producers from being greedy.
Hi Dave,
I meant to act in parallel, any hint on how to achieve this is really appreciated, I thought that putting the prod[i].run() methods inside the fork-join I will get the each producer’s put() task running in parallel and blocking the mailbox.
module env();
producer prod[];
consumer cons;
packet pkt;
mailbox #(packet)channel;
initial begin
channel= new(); //creating mailbox
prod= new[4]; // create dynamic array of producers
foreach(prod[i]) begin
prod[i] = new(channel); //passing mailbox handle to each producer
end
cons= new(channel); //passing mailbox handle
fork
foreach(prod[i]) begin
fork
prod.run();
join
end
cons.run();
join
end
endmodule
Cheers,
-Ronald
In reply to rgarcia07:
In your original example, the foreach statement executes as a single process. In your second example, a fork-join with a single statement behaves the same as begin/end.
You need to use fork-join_none to spawn independent processes.
initial begin
channel= new(); //creating mailbox
prod= new[4]; // create dynamic array of producers
foreach(prod[i])
prod[i] = new(channel); //passing mailbox handle to each producer
cons= new(channel); //passing mailbox handle
foreach(prod[i])
fork
automatic int k=i;
prod[k].run();
join_none
cons.run();
end
In reply to dave_59:
Duh, I totally forgot the join_none, as usual many thanks for your help Dave :-)