I define the period as the time between two active edges.
Looking at the generated code, it seems that you're using positive-edge triggered logic.
For a 20ns clock, The first active edge, going from 0 to 1, happens at 3.0001ns the second active edge happens at 23.0001ns, the third at 43.0001ns, etc.
So the period is definitely 20ns.
The 3ns was definitely picked arbitrarily.
But whether the first active edge happens at 0.0002ns (it must happen at time-step 2 (0.2ps) because of the mentioned race-condition avoidance) or at 3.0001ns doesn't really matter, no?