On your specific questions:
//why did I need to delay this 2 time units?
You don't. Adding a transport delay to the clock branch and not the reset branch makes little or no sense.
//why do I need to reset the clk to 0 if this is a forever block and my first assignment is clk = 0 in the beginning?
You don't; the model is flawed. Remove the first clk=0
, or move it above the forever
.
//why #4? How did they calculate that?
No idea - it's just an arbitrary delay in your stimulus generation. It doesn't matter, as long as it's 'long enough'.
General points:
- You don't care about specifying delays when writing HDL code; this
is almost always a job for the tools. Your tools will work out real
silicon delays and back-annotate them into your code using sdf,
specify blocks
, and so on. If you want details, look at the simulation model output by your synth or place-and-route tools. - As long as you're careful about your use of blocking and non-blocking assignments then your code will 'work', even though you haven't explicitly put delays into it. 'Working' means that the outputs change in the correct order to preserve your required functionality.
- I think you may be confused in your understanding of 'rise/fall delays' and 'delaying outputs'. In general, at the HDL level, you're never concerned with signal rise or fall times; everything happens at a threshold voltage. An input changes at time x, and dependent outputs change at some later time. This is a propagation delay. For clocked circuits, the prop delay will depend on whether the output goes to 0 or goes to 1, which leads to unfortunate terminology involving 'rise delay' or 'fall delay' (actually propagation delay to 1, or to 0). You don't "delay your outputs so that your inputs generate a value before you calculate your outputs". Except in exceptional circumstances, you calculate your outputs immediately, and then specify how long it takes the outputs to actually propagate to the pins of your model.