Verilog regions are the systematic stages through which the simulator traverses through while executing the relavant code inside it. Before moving onto verilog regions, following are a few concepts which need to be remebered.
Timestep / Simulation Cycle :
This is basically the
internal
clock
that a simulator follows. It does not
have any time period or any delay. In fact the total number of timesteps or cycles
that a simulator executes depends on the
timescale
and the verilog code that has been written. One important thing to remember is that
the delays added in the verilog code determine how many timesteps will be there.
Essentially, the number of times a delay is begin executed in the code tells us how
many timesteps the simulator will run.
Timescale :
This is the term which tell you how much
a unit of delay is supposed to treated as in terms of time.
Given below is an image which can help understand the verilog scheduling regions.
The number of timesteps a simulator will run depends on the simulator and the code itself. In most of the simulators, the number of timesteps is decided by thr number of events happenning in certain time intervals, which is decided by the time scale and the use of # delays. Given below is an image which tries to explain the relation ship between the timesteps and its behavior in accordance with the verilog regions. A small snippet is given in the image to support the explaination.
module top; initial begin $display( "A" ); end initial begin #0; $display( "B" ); end initial begin #1; $display( "C" ); end endmodule
// Output // A // B // C // Explaination : "A" is executed in active region of 0 timestep, "B" is executed in inactive region of 0 timestep and "C" is executed in the active region of 1st timestep
module top; initial begin fork begin $display( "A" ); end begin #4; fork #0; join $display( "B" ); end begin fork #3; join #0; $display( "C" ); end join #0; $display( "D" ); end endmodule
// A -> #0 // C -> #3 // B -> #4 // D -> #4
module top; initial begin fork begin #0; $display( "A" ); end begin #0; #0; $display( "B" ); end join end endmodule
module top; initial begin fork begin #1; #0; $display( "A" ); end begin #0; #0; #1 $display( "B" ); end join end endmodule
module top; reg clk = 0; always@( clk ) begin clk = ~clk; end initial begin clk = 1; end endmodule
module top; initial begin $displaY("Active"); end initial begin #0; // Schedules everything after this in in-active region $display("Inactive"); end endmodule
module top; initial begin #0; $display( "A" ); end initial begin #0; $display( "B" ); end endmodule
module top; initial begin #0; $display( "A" ); end initial begin #0; #0; $display( "B" ); end endmodule
module top; initial begin fork $display( "A" ); $display( "B" ); $display( "C" ); $display( "D" ); $display( "E" ); $display( "F" ); join end endmodule
// There are multiple ways to solve this :) module top; initial begin fork #0 #0 $display( "A" ); #0 $display( "B" ); $display( "C" ); #0 #0 #0 $display( "D" ); #1 $display( "E" ); #2 $display( "F" ); join end endmodule