Fri Oct 14, 2016 2:52 am
I'm pretty new to verilog and I'm getting a bit confused over the way
events are threated and they way it may lead to undeterminism (ref.
AFAIU the 5 /regions/ of events are traversed in series but within a
region there's no strict rule on how the simulator engine need to
process events. Now, while in vhdl multiple drivers are handled through
resolution functions, it doesn't seem that verilog provide the same
approach, therefore it would be perfectly valid to set a net or a
register to multiple values in the code (please confirm).
I'm mostly dealing with verilog when driving signal hierarchically
through my testbench and I'm wondering whether I need to be aware about
something more specific since I'm afraid I haven't completely grasped
the undeterminism behavior.
Any pointer/suggestion/comment is appreciated.
Sat Oct 15, 2016 4:43 am
Verilog does have drive strengths and built-in net-resolution functions: if one driver is driving a "strong 1" and another driver is driving a "weak 0" on the same net at the same time, the net will be resolved to a value of 1 just the way you would expect. If you start specifying drive strengths your code is generally not synthesizable, but it's OK to do it in testbenches or simulation models, for example to model a pullup resistor on an open-drain output.
I'm not sure what you mean by "perfectly valid to set a net or a register to multiple values in the code." Are you talking about sequentially in the same block of code, or driving your net/register from different blocks of code? Sequentially is totally OK. Like inside the same initial or always block:
my_reg = 0;
my_reg = 1;
Driving the same signal from multiple code blocks is usually considered not very good coding style and may not be handled by synthesis tools, but Verilog allows it.
When the same net is driven to different values at the same simulation time and the result depends on which order the code was executed, it's called a race condition. I do not recommend spending too much effort learning how Verilog simulators decide which to execute first -- better to learn to code so that it isn't left to chance, or use tools that find race conditions for you. The standard gives simulators a lot of leeway there and different simulators will execute in a different order while all being correct.
A common coding style rule in Verilog is: if it's combinatorial, use blocking assignments. If it's a flip-flop, use non-blocking:
z = a & b; // blocking assignment "="
always @(posedge clk)
z <= a & b; // non-blocking assignment "=>"