"valentin tihomirov" <
[email protected]>
wrote in message news:
[email protected]...
> 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:
[email protected]
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.