Here is an example of negative index I'm talking about
@CLK:
Buf := Rx & Buf(WIDTH-2 downto 1);
THAT IS NOT A LOOP!
I'm trying to shift buffer to right. But this neat 1-line code should be
modified and becomes cumbersome because the generic WIDTH parameter can be
any integer > 0. This means if WIDTH = 1 I'm getting (-1 downto 1) loop and
when WIDTH = 2 I'm getting (0 downto 1 loop). Both these cases should be
handeled specially in VHDL (using if clause). In Pascal/C and any other
general-purpose language negative loops like
for I := WIDTH-2 downto 1 do
...
are ignored for width < 2 cases. VHDL compiler could ignore as well, but it
complains "negative index" instead.
No, no, no. VHDL also ignores procedural loops with no trips,
like that. You can't take slices of an array in C anyway!
Please now, tell me what you want to happen in the example...
I guess you are trying to shift the single bit Rx into the multi-bit
register Buf. If that's true, your code is wrong, I think.
Presumably Buf is declared
Buf: std_logic_vector(WIDTH-1 downto 0);
If this is right, and Rx is a single bit, then
Buf := Rx & Buf(WIDTH-2 downto 1)
is erroneous because the right-hand side is one bit shorter than
the left!
However, let's suppose that your Rx is in fact 2 bits. In that
case it would be ridiculous to have WIDTH < 2, because you could
never assign Rx into Buf!
I guess your shift operation should be correctly coded:
Buf := Rx & Buf(WIDTH-1 downto 1);
This will work correctly for any WIDTH >= 2.
However, if WIDTH=1 you have a problem because the shift register
is not a shift register at all, but merely a simple register.
Strictly speaking VHDL should handle this, because Buf(0 downto 1)
should be a null range, but some tools complain about it. This
is the one and only case where your argument might have some force.
If you really must do such a thing, then simply USE a loop!
This code assumes that Buf was declared with a DOWNTO range - it is
possible, but a little harder, to write code that works correctly
with both TO and DOWNTO ranges, but I don't think that is necessary.
for i in Buf'RANGE loop
if i = Buf'LEFT then
Buf(i) := Rx;
else
Buf(i) := Buf(i+1);
end if;
end loop;
I agree that this is not so pretty as the single-line slice, but
it's easy to understand, fairly efficient in simulation, and
for synthesis it is just as good as the other form.
--
Jonathan Bromley, Consultant
DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services
Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web:
http://www.doulos.com
The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.