Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Constant conversion (natural to std_logic_vector)

Reply
Thread Tools

Constant conversion (natural to std_logic_vector)

 
 
a1_nocrap_exh@hotmail.com
Guest
Posts: n/a
 
      04-10-2006
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

 
Reply With Quote
 
 
 
 
a1_nocrap_exh@hotmail.com
Guest
Posts: n/a
 
      04-10-2006
I cannot use VHDL 93's HEX literal ( X'"AA" ) because my bus is not a
multiple of 4-bits wide.

 
Reply With Quote
 
 
 
 
Mike Treseler
Guest
Posts: n/a
 
      04-10-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) 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
 
Reply With Quote
 
a1_nocrap_exh@hotmail.com
Guest
Posts: n/a
 
      04-10-2006
> 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

 
Reply With Quote
 
Charles, NG
Guest
Posts: n/a
 
      04-10-2006
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
 
Reply With Quote
 
a1_nocrap_exh@hotmail.com
Guest
Posts: n/a
 
      04-10-2006
I am using subtypes in my code (not in my example) it doesnt help.

 
Reply With Quote
 
a1_nocrap_exh@hotmail.com
Guest
Posts: n/a
 
      04-10-2006
>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

 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      04-10-2006
(E-Mail Removed) 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
 
Reply With Quote
 
Marcus Harnisch
Guest
Posts: n/a
 
      04-11-2006
Alex,

(E-Mail Removed) 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
 
Reply With Quote
 
a1_nocrap_exh@hotmail.com
Guest
Posts: n/a
 
      04-11-2006
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

 
Reply With Quote
 
 
 
Reply

Thread Tools

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 Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"error C2057: expected constant expression", "error C2466: cannot allocate an array of constant size 0". Why doesn't my simple program work??? hn.ft.pris@gmail.com C++ 13 01-22-2007 02:03 PM
pointers to constant characters and constant pointers to characters sam_cit@yahoo.co.in C Programming 4 12-14-2006 11:10 PM
len(var) is [CONSTANT] equal to len(var) == [CONSTANT]? Tor Erik Soenvisen Python 14 11-23-2006 09:57 PM
"Non-constant" constant can't be used as template argument Martin Magnusson C++ 2 10-08-2004 08:41 AM
Understanding How To Use #ifdef Constant #define Constant Sequence In Multible Files Christopher M. Lusardi C++ 1 09-02-2004 07:43 AM



Advertisments