FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > VHDL

VHDL comp.lang.vhdl newsgroup / Usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 09-13-2006, 09:13 PM
Travis
Guest
 
Posts: n/a
Default Loop inside case?

Pardon me if this is a trivial question but my VHDL experience is
limited and rusty (sorry, I'm verilog). I'm modifying a pre-existing
unit that manages access to a giant register bank. This is handled
with a huge case statement and I need to modify the case statement to
support a new subset of addresses. These addresses correspond to a big
contiguous block of data and so I was hoping I could use a loop to
simplify the coding. Essentially what I'm looking for is the ability
to do the equivalent of the following:

case addr is
...
for i in 0 to count-1 loop
when (new_base_addr + i) =>
dataout <= new_reg(i);
end loop
...
end case

I've tried a standard for loop and a for-generate loop but neither will
synthesize (using the Xilinx Synthesis Tool). If anybody can show me
how to do this without manually entering every individual case that
would be awesome. Thanks.
- Travis

Reply With Quote
  #2 (permalink)  
Old 09-13-2006, 09:55 PM
Paul Uiterlinden
Guest
 
Posts: n/a
Default Re: Loop inside case?

Travis wrote:

> case addr is
> ...
> for i in 0 to count-1 loop
> when (new_base_addr + i) =>
> dataout <= new_reg(i);
> end loop
> ...
> end case


You cannot interleave a case statement and a loop statement as you try
to do. Also, the choices of a case statement must be static, so you
cannot use a variable or signal in a choice expression (so you cannot
use new_base_addr, unless it is a constant).

Why not use an IF statement, possibly IF .. ELSIF .. ELSIF ..

***for*i*in*0*to*count-1*loop
******if addr =*new_base_addr*+*i*then
*********dataout*<=*new_reg(i);
end if;
***end*loop;

--
Paul.

Reply With Quote
  #3 (permalink)  
Old 09-13-2006, 10:11 PM
Travis
Guest
 
Posts: n/a
Default Re: Loop inside case?

Paul Uiterlinden wrote:
> Travis wrote:
>
> > case addr is
> > ...
> > for i in 0 to count-1 loop
> > when (new_base_addr + i) =>
> > dataout <= new_reg(i);
> > end loop
> > ...
> > end case

>
> You cannot interleave a case statement and a loop statement as you try
> to do. Also, the choices of a case statement must be static, so you
> cannot use a variable or signal in a choice expression (so you cannot
> use new_base_addr, unless it is a constant).
>
> Why not use an IF statement, possibly IF .. ELSIF .. ELSIF ..
>
> for i in 0 to count-1 loop
> if addr = new_base_addr + i then
> dataout <= new_reg(i);
> end if;
> end loop;
>
> --
> Paul.


So there's no way to use a loop to generate the choices, even static
choices, in a case statement? That's unfortunate. As mentioned, I'm
modifying a pre-existing unit and simply updated the range of choices
in the case statement, so switching to an IF statement isn't really an
option without major refactoring. Is my only other option then to hand
code each choice (when new_base_addr + 1 ... when new_base_addr + 2 ...
etc..)? Thanks.
- Travis

Reply With Quote
  #4 (permalink)  
Old 09-13-2006, 10:24 PM
Andy Ray
Guest
 
Posts: n/a
Default Re: Loop inside case?

Travis wrote:
> Paul Uiterlinden wrote:
>> Travis wrote:
>>
>>> case addr is
>>> ...
>>> for i in 0 to count-1 loop
>>> when (new_base_addr + i) =>
>>> dataout <= new_reg(i);
>>> end loop
>>> ...
>>> end case

>> You cannot interleave a case statement and a loop statement as you try
>> to do. Also, the choices of a case statement must be static, so you
>> cannot use a variable or signal in a choice expression (so you cannot
>> use new_base_addr, unless it is a constant).
>>
>> Why not use an IF statement, possibly IF .. ELSIF .. ELSIF ..
>>
>> for i in 0 to count-1 loop
>> if addr = new_base_addr + i then
>> dataout <= new_reg(i);
>> end if;
>> end loop;
>>
>> --
>> Paul.

>
> So there's no way to use a loop to generate the choices, even static
> choices, in a case statement? That's unfortunate. As mentioned, I'm
> modifying a pre-existing unit and simply updated the range of choices
> in the case statement, so switching to an IF statement isn't really an
> option without major refactoring. Is my only other option then to hand
> code each choice (when new_base_addr + 1 ... when new_base_addr + 2 ...
> etc..)? Thanks.
> - Travis
>


Hi,

You can do

when 32 to 63 =>
dataout <= new_reg( addr );

or something similar. It will depend exactly how addr is specified as
this only works with specific types (ie ints not std_logic_vectors).

You may yet have some refactoring to do...

Cheers,

Andy
Reply With Quote
  #5 (permalink)  
Old 09-13-2006, 10:34 PM
Paul Uiterlinden
Guest
 
Posts: n/a
Default Re: Loop inside case?

Travis wrote:


> So there's no way to use a loop to generate the choices, even static
> choices, in a case statement? That's unfortunate. As mentioned,
> I'm modifying a pre-existing unit and simply updated the range of
> choices in the case statement, so switching to an IF statement isn't
> really an
> option without major refactoring. Is my only other option then to
> hand code each choice (when new_base_addr + 1 ... when new_base_addr
> + 2 ...
> etc..)? Thanks.


I'm not sure if this would work (no compiler at hand at the moment):

for i in 0 to count-1 loop
case addr is
when new_base_addr + i =>
dataout <= new_reg(i);
when ...
end case;
end loop;

After all, i is a constant. But VHDL is a bit peculiar with regards to
choices in the case statement. See e.g.
http://www.vhdl.org/comp.lang.vhdl/FAQ1.html#static.

--
Paul.
Reply With Quote
  #6 (permalink)  
Old 09-13-2006, 11:13 PM
KJ
Guest
 
Posts: n/a
Default Re: Loop inside case?


"Travis" <[email protected]> wrote in message
news:[email protected] ups.com...
> Pardon me if this is a trivial question but my VHDL experience is
> limited and rusty (sorry, I'm verilog). I'm modifying a pre-existing
> unit that manages access to a giant register bank. This is handled
> with a huge case statement and I need to modify the case statement to
> support a new subset of addresses. These addresses correspond to a big
> contiguous block of data and so I was hoping I could use a loop to
> simplify the coding. Essentially what I'm looking for is the ability
> to do the equivalent of the following:
>
> case addr is
> ...
> for i in 0 to count-1 loop
> when (new_base_addr + i) =>
> dataout <= new_reg(i);
> end loop
> ...
> end case
>
> I've tried a standard for loop and a for-generate loop but neither will
> synthesize (using the Xilinx Synthesis Tool). If anybody can show me
> how to do this without manually entering every individual case that
> would be awesome. Thanks.
> - Travis

How about something like this

if (Address is in the new range) then
Do your new stuff here
else
case -- The existing case statement
end case;
end if;

KJ


Reply With Quote
  #7 (permalink)  
Old 09-14-2006, 05:14 PM
Travis
Guest
 
Posts: n/a
Default Re: Loop inside case?

KJ wrote:
> "Travis" <[email protected]> wrote in message
> news:[email protected] ups.com...
> > Pardon me if this is a trivial question but my VHDL experience is
> > limited and rusty (sorry, I'm verilog). I'm modifying a pre-existing
> > unit that manages access to a giant register bank. This is handled
> > with a huge case statement and I need to modify the case statement to
> > support a new subset of addresses. These addresses correspond to a big
> > contiguous block of data and so I was hoping I could use a loop to
> > simplify the coding. Essentially what I'm looking for is the ability
> > to do the equivalent of the following:
> >
> > case addr is
> > ...
> > for i in 0 to count-1 loop
> > when (new_base_addr + i) =>
> > dataout <= new_reg(i);
> > end loop
> > ...
> > end case
> >
> > I've tried a standard for loop and a for-generate loop but neither will
> > synthesize (using the Xilinx Synthesis Tool). If anybody can show me
> > how to do this without manually entering every individual case that
> > would be awesome. Thanks.
> > - Travis

> How about something like this
>
> if (Address is in the new range) then
> Do your new stuff here
> else
> case -- The existing case statement
> end case;
> end if;
>
> KJ


Thanks to all for your suggestions. I think KJ's suggestion is
probably the only method that wouldn't require major rework but I had
already gone the route of putting together a perl script to generate
the code for me. I'm pretty happy with the result so I thought I'd
share it incase somebody else might find it useful. Thanks again.

------------------------------------------------

#!/usr/local/bin/perl -w
# Script:
# textgen.pl
# Description:
# Generates repeating strings with auto-increment integer or hex
values.
# Since double-quotes cannot be inside the input string, use '\q' to
insert a
# placeholder for a double-quote (").
# Arguments:
# 1 - The number of repetitions
# 2 - String with %#d (integer), %#x (hex) or %#b (binary)
placeholders.
# This uses the C-style printf formatting native to Perl.
# 3+ - The third and all remaining arguments are indicators of how
to
# update the values in the string. They take the format of
XY, where
# X is the initial value, is increment or decrement and Y
is the
# amount to increment or decrement.
# Sample:
# textgen.pl 3 "#%d, 0x%02x\n, \q%05b\q" 10-3 15+16 1+4
# > Output:
# #10, 0x0F, "00001"
# #7, 0x1F, "00101"
# #4, 0x2F, "01001"
################################################## #############################

use strict;

if($#ARGV < 1) {
die "Too few arguments";
}

my $i;
my $reps = $ARGV[0];
my $text = $ARGV[1];

# Convert input text linebreaks to real linebreaks
$text =~ s/\\n/\n/g;
# Convert \q to double-quote
$text =~ s/\\q/\\\"/g;

# Extract the value/increment pairs into arrays
my @values = splice(@ARGV, 2, $#ARGV);
my @inc = @values;

# Convert value/increment pairs to just values
for($i = 0; $i <= $#values; $i++) {
$values[$i] =~ /(\d+)[\+|-]\d+/;
$values[$i] = $1;
}
# Convert value/increment pairs to just increments
for($i = 0; $i <= $#inc; $i++) {
$inc[$i] =~ /\d+([\+|-]\d+)/;
$inc[$i] = $1;
# Remove '+' signs
$inc[$i] =~ s/\+//g;
}
# Extract the placeholders
my @places = ($text =~ /(%\d*[d|x|b])/g);

# Verify placeholders and arguments compatibility
if($#places != $#values) {
die "Invalid argument list";
}

# Print output
for(; $reps > 0; $reps--) {
# Create the value list
my $val;
my $valuelist = '';
foreach $val (@values) {
$valuelist .= ", $val";
}

# Create printf function from input string and current values
my $evalstr = "printf(\"$text\"$valuelist)";
# Evaluate (print out) printf string
eval $evalstr;

# Update the values
for($i = 0; $i <= $#values; $i++) {
$values[$i] += $inc[$i];
}
}

Reply With Quote
  #8 (permalink)  
Old 09-15-2006, 03:21 PM
Andy
Guest
 
Posts: n/a
Default Re: Loop inside case?

Since loops are unrolled in synthesis (and therefore must be staticly
bound), the index is "treated as static" in synthesis. This treatment
only exists in the backend, and has no effect on legal vhdl staticness.

Case statement targets must be locally static, meaning that at analysis
time, before elaboration, the compiler must be able to know the value
of each target. Among other things, even generic values and deferred
constants (i.e. whose values are only defined in a package body) cannot
be used as case statement targets, since the compiler must be able to
verify, at analysis time, that all possible choices are covered exactly
once.

Andy


Paul Uiterlinden wrote:
> Travis wrote:
>
>
> > So there's no way to use a loop to generate the choices, even static
> > choices, in a case statement? That's unfortunate. As mentioned,
> > I'm modifying a pre-existing unit and simply updated the range of
> > choices in the case statement, so switching to an IF statement isn't
> > really an
> > option without major refactoring. Is my only other option then to
> > hand code each choice (when new_base_addr + 1 ... when new_base_addr
> > + 2 ...
> > etc..)? Thanks.

>
> I'm not sure if this would work (no compiler at hand at the moment):
>
> for i in 0 to count-1 loop
> case addr is
> when new_base_addr + i =>
> dataout <= new_reg(i);
> when ...
> end case;
> end loop;
>
> After all, i is a constant. But VHDL is a bit peculiar with regards to
> choices in the case statement. See e.g.
> http://www.vhdl.org/comp.lang.vhdl/FAQ1.html#static.
>
> --
> Paul.


Reply With Quote
  #9 (permalink)  
Old 09-16-2006, 12:27 AM
Paul Uiterlinden
Guest
 
Posts: n/a
Default Re: Loop inside case?

Andy wrote:

> Since loops are unrolled in synthesis (and therefore must be
> staticly bound), the index is "treated as static" in synthesis. This
> treatment only exists in the backend, and has no effect on legal
> vhdl staticness.
>
> Case statement targets must be locally static, meaning that at
> analysis time, before elaboration, the compiler must be able to know
> the value of each target. Among other things, even generic values
> and deferred constants (i.e. whose values are only defined in a
> package body) cannot be used as case statement targets, since the
> compiler must be able to verify, at analysis time, that all possible
> choices are covered exactly once.


Thanks for the clarification. Of course I knew all this, but it had
sunken too deep for direct access. ;-)

--
Paul.

Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Incisive 05.6 coverage report, how do I deal with default case in a full case? Mr. Ken Verilog 2 11-29-2006 12:53 AM
CASE statement & LOOP Niv VHDL 16 07-07-2006 11:15 AM
now inside processes Olaf Petzold VHDL 5 11-19-2005 07:05 PM
How to look inside a RAM memory Giox FPGA 3 07-26-2005 07:58 AM
full case & parallel case Muruku ANAND Verilog 4 07-30-2003 09:56 PM


All times are GMT +1. The time now is 09:17 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved