Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   VHDL (http://www.velocityreviews.com/forums/f18-vhdl.html)
-   -   Constant conversion (natural to std_logic_vector) (http://www.velocityreviews.com/forums/t57878-constant-conversion-natural-to-std_logic_vector.html)

a1_nocrap_exh@hotmail.com 04-10-2006 12:15 PM

Constant conversion (natural to std_logic_vector)
 
I am in a situation where I have to increase an address bus width in
bit of re-usable code.

In a package there is a list of constants which are used in the address
decode

constant abus_width : natural := 5;
constant REGISTER_A : std_logic_vector(abus_width-1 downto 0) :=
"00001";
constant REGISTER_B : std_logic_vector(abus_width-1 downto 0) :=
"00010";
etc.

I've now increased abus_width by 2 and now all the constant literals
need updating because they are the wrong width.

I thought I would try to work out a way of specifying the constants so
that they would grow with abus_width so that if we ever had to do this
again it would automatically work e.g.

library ieee;
use ieee.std_logic_arith.all;

constant abus_width : natural := 7;
constant REGISTER_A : std_logic_vector(abus_width-1 downto 0) :=
conv_std_logic_vector(16#01#,abus_width);
constant REGISTER_B : std_logic_vector(abus_width-1 downto 0) :=
conv_std_logic_vector(16#02#,abus_width);

However I now get the following warning "Case choice must be a locally
static expression." in the Case statements which use these constants.

But it IS locally static isnt it? It's a constant, it's in a package,
that package is referenced...

Anyone ever done anything like this before or got a better technique?

Regards

Alex Holland


a1_nocrap_exh@hotmail.com 04-10-2006 12:28 PM

Re: Constant conversion (natural to std_logic_vector)
 
I cannot use VHDL 93's HEX literal ( X'"AA" ) because my bus is not a
multiple of 4-bits wide.


Mike Treseler 04-10-2006 02:16 PM

Re: Constant conversion (natural to std_logic_vector)
 
a1_nocrap_exh@hotmail.com wrote:

> However I now get the following warning "Case choice must be a locally
> static expression." in the Case statements which use these constants.
> But it IS locally static isnt it? It's a constant, it's in a package,
> that package is referenced...


Sorry, that's the way it is.
Use an if/elsif/elsif
http://groups.google.com/groups/sear...c+short+answer

-- Mike Treseler

a1_nocrap_exh@hotmail.com 04-10-2006 03:37 PM

Re: Constant conversion (natural to std_logic_vector)
 
> Sorry, that's the way it is.
> Use an if/elsif/elsif
> http://groups.google.com/groups/sear...c+short+answer


Thanks for the link. But in this situation I am not doing anything
fancy. These ARE constants. It should work.

> A case expression is limited to operands that are scalar


But they are scalar, that is my point.

If I store my constants as naturals, and convert my std_logic_vector
signal to integer EVERYTHING works e.g.

constant REGISTER_A : natural := 1;
constant REGISTER_B : natural :=2;

case conv_integer(unsigned(addr)) is

when REGISTER_A =>

when REGISTER_B =>

when OTHERS =>

end case;

So I dont understand why I cannot store my constants as
std_logic_vectors that are pre-converted from naturals?

constant abus_width := 5;

constant REGISTER_A : std_logic_vector(abus_width-1 downto 0) :=
conv_std_logic_vector(16#01#, abus_width);

constant REGISTER_B : std_logic_vector(abus_width-1 downto 0) :=
conv_std_logic_vector(16#02#, abus_width);

case addr is

when REGISTER_A =>

when REGISTER_B =>

when OTHERS =>

end case;

I would switch to storing them as naturals, but the code containing the
case statement has already been to silicon, dont really want to change
anything in that file if I can help it.

I think I *will* find the syntax to make this warning go away.

Anyone?

Alex Holland


Charles, NG 04-10-2006 04:10 PM

Re: Constant conversion (natural to std_logic_vector)
 
You may find it easier if you use subtypes: e.g.

use ieee.numeric_std.all;
.. . . . .
subtype abus_type_t is std_logic_vector(7 downto 0);
.. . . . .
constant abus_sig_s : abus_type_t :=
std_logic_vector(to_unsigned(2, abus_type_t'length));

Then you only have to change the subtype dimensions in a single place if
your bus gets resized

Regards,
Charles

a1_nocrap_exh@hotmail.com 04-10-2006 04:22 PM

Re: Constant conversion (natural to std_logic_vector)
 
I am using subtypes in my code (not in my example) it doesnt help.


a1_nocrap_exh@hotmail.com 04-10-2006 04:34 PM

Re: Constant conversion (natural to std_logic_vector)
 
>use ieee.numeric_std.all;
> . . . . .
> subtype abus_type_t is std_logic_vector(7 downto 0);
> . . . . .
> constant abus_sig_s : abus_type_t :=
> std_logic_vector(to_unsigned(2, abus_type_t'length));
>
> Then you only have to change the subtype dimensions in a single place if
> your bus gets resized


Not that it matters but you dont have to use subtypes to only need to
change dimensions in a single place, look at my example I posted
earlier (or below), you change one constant "abus_width" and voila.

constant abus_width : natural := 7;

constant REGISTER_A : std_logic_vector(abus_width-1 downto 0) :=
conv_std_logic_vector(16#01#,abus_width);

constant REGISTER_B : std_logic_vector(abus_width-1 downto 0) :=
conv_std_logic_vector(16#01#,abus_width);

I've used std_logic_arith rather than numeric_std... I wonder if that
helps? I doubt it.

Charles, can you use a constant defined your way in a CASE statement?

Alex Holland


Mike Treseler 04-10-2006 04:42 PM

Re: Constant conversion (natural to std_logic_vector)
 
a1_nocrap_exh@hotmail.com wrote:
>>Sorry, that's the way it is.
>>Use an if/elsif/elsif
>>http://groups.google.com/groups/sear...c+short+answer

>
> Thanks for the link. But in this situation I am not doing anything
> fancy. These ARE constants. It should work.


It probably should, but it doesn't and this is a FAQ.

-- Mike Treseler

Marcus Harnisch 04-11-2006 11:42 AM

Re: Constant conversion (natural to std_logic_vector)
 
Alex,

a1_nocrap_exh@hotmail.com writes:
> I thought I would try to work out a way of specifying the constants so
> that they would grow with abus_width so that if we ever had to do this
> again it would automatically work e.g.
>
> library ieee;
> use ieee.std_logic_arith.all;
>
> constant abus_width : natural := 7;
> constant REGISTER_A : std_logic_vector(abus_width-1 downto 0) :=
> conv_std_logic_vector(16#01#,abus_width);
> constant REGISTER_B : std_logic_vector(abus_width-1 downto 0) :=
> conv_std_logic_vector(16#02#,abus_width);


You can either extend your registers widths to a multiple of 4 and use
the VHDL'93 syntax. In the case-statement you would have to extend the
case-expression to the same width and be done. Chances are that
Synthesis will strip the unused bits anyway.

Or, as someone else already noted, you could use if-elsif*-else
chains. Synthesis tools are also pretty good at generating the
expected logic in cases like this.

Alternatively you could assign the registers like this

constant REGISTER_A : std_logic_vector(abus_width-1 downto 0)
:= (0 => '1', others => '0');
constant REGISTER_B : std_logic_vector(abus_width-1 downto 0)
:= (1 => '1', others => '0');

(Actually I am not absolutely sure that this last assignment works as
expected. You'd have to try that yourself.)

> But it IS locally static isnt it? It's a constant, it's in a package,
> that package is referenced...


Not quite. Locally static expressions must be fixed at compile
time. Functions, such as `conv_std_logic_vector', defined in package
bodies are not. You could compile a different package body for
std_logic_arith with completely different function definitions and be
screwed.

Best regards,
Marcus

a1_nocrap_exh@hotmail.com 04-11-2006 03:58 PM

Re: Constant conversion (natural to std_logic_vector)
 
Hi Marcus,

Thanks for the reply, good suggestion for your alternative

> > But it IS locally static isnt it? It's a constant, it's in a package,
> > that package is referenced...

>
> Not quite. Locally static expressions must be fixed at compile
> time. Functions, such as `conv_std_logic_vector', defined in package
> bodies are not. You could compile a different package body for
> std_logic_arith with completely different function definitions and be
> screwed.


Ah, yes now I understand. It ISNT the case statement which needs to
resolve at compile time it's the WHEN operator. That is why I can
define my constants as naturals and convert my case argument to an
integer and it compiles fine e.g.

constant REGISTER_A : natural := 1;
constant REGISTER_B : natural := 2;

case conv_integer(unsigned(addr)) is

when REGISTER_A =>

when REGISTER_B =>

when OTHERS =>

end case;

Makes sense now, dont like it, but it makes sense.

Alex



All times are GMT. The time now is 08:33 PM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57