Basic functions for working with ranges.
In Verilog, ranges are used in net and register declarations, and also in module- and gate-instance declarations to describe arrays of modules or gates.
For gate and module instances, the Verilog-2005 standard is pretty clear. 7.1.5 covers gate instances and 12.1.2 says that module instances have the same rules. In short, neither side has to be larger than the other, neither side has to be zero, and it always specifies abs(left-right)+1 occurrences (so that if they're the same it means one gate).
BOZO consider "negative" numbers and what they might mean.
The specification doesn't give similarly crisp semantics to net and reg ranges. Verilog-XL is horribly permissive, allowing even negative indexes and such. But Verilog-XL indeed seems to treat w[1:1] as a single bit, and in the Centaur design there are occurrences of [0:0] and [1:1] and such. So it may be that the semantics are supposed to be the same? It turns out that there are at least some differences, e.g., you're not allowed to select bit 0 from a plain wire, but you can select bit 0 from w[0:0], etc.
Historically, VL required the msb index is not smaller than the lsb index. But we now try to permit designs that use ranges that go from both high to low and low to high.
The difference is that for a wire like
Regardless of how the range is written, the wire behaves the same as far as operations like addition, concatenation, and so forth are concerned. This might seem pretty surprising. For instance,
wire [3:0] a = 4'b0001; wire [0:3] b = 4'b1000; wire [7:0] c = {a, b};
Results in
Where it does matter is when bits or parts are selected from the
wire. That is,