Procedural blocks refers to always
, always_ff
, always_comb
, always_latch
, initial
etc. blocks. While procedural assignment statements refers to assigning values to reg, integer etc., but not wires(nets).
wire
elements must be continuously driven by something, and cannot store a value. Henceforth, they are assigned values using continuous assignment statements.
reg
can be used to create registers in procedural blocks. Thus, it can store some value.
reg
elements can be used as output within an actual module declaration. But,reg
elements cannot be connected to the output port of a module instantiation.
Thus, a reg can drive a wire as RHS of an assign
statement. On the other way round, a wire can drive a reg in as RHS of a procedural block.
For clear idea about declaration of reg
or wire
, refer the image below:

So, whenever inferring to sequential logic, which stores/holds some value, declare that variable/port as reg
. Here, Q
is a reg
inside a module, but while instantiating this module inside some other module, then this port must be connected to a wire
.
Remember, wire
can only infer to combinational logic, while reg
can infer to either combinational or sequential logic.
Dave's blog is a good source for detailed information. For further information, refer to synthesizing difference and Verilog wire-reg links.