Goroutines in Verilog
A `goroutine` is a lightweight thread of execution.
```verilog
module main;
initial begin
// Calling the function directly
f("direct");
// Calling the function asynchronously
fork
f("goroutine");
join_none
// Anonymous function call
fork
$display("going");
join_none
// Small delay to allow async tasks to complete
#10;
$display("done");
end
// Function definition
task f(input reg [7:0] from);
integer i;
begin
for (i = 0; i < 3; i = i + 1) begin
$display("%s : %0d", from, i);
end
end
endtask
endmoduleSuppose we have a function call f(s). Here’s how we’d call that in the usual way, running it synchronously.
initial begin
f("direct");
endTo invoke this function asynchronously, use the fork keyword. This new fork will execute concurrently with the calling one.
initial begin
fork
f("goroutine");
join_none
endYou can also start an anonymous function call asynchronously with fork.
initial begin
fork
$display("going");
join_none
endOur two function calls are running asynchronously now. We use a small delay to wait for them to finish.
initial begin
#10;
$display("done");
endWhen we run this program, we see the output of the blocking call first, then the output of the other asynchronous calls. The asynchronous tasks’ output may be interleaved, because they are being run concurrently.
$ iverilog -o main main.v && vvp main
direct : 0
direct : 1
direct : 2
goroutine : 0
going
goroutine : 1
goroutine : 2
doneNext we’ll look at a complement to fork in concurrent Verilog programs: channels.