Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   VHDL (http://www.velocityreviews.com/forums/f18-vhdl.html)
-   -   Problems switching to ieee.numeric_std.all (http://www.velocityreviews.com/forums/t868943-problems-switching-to-ieee-numeric_std-all.html)

aleksa 03-01-2012 04:27 PM

Problems switching to ieee.numeric_std.all
 
My VHD files now begin with

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

and I have some questions...



Example1:

I'm copying CURRENT to ADDR, but limiting to 999:

-- 2^10 = 1024
signal CURRENT, ADDR : unsigned(9 downto 0);

if CURRENT < 1000 then
ADDR <= CURRENT;
else
ADDR <= to_unsigned(999, ADDR'length);
end if;

At first I had "ADDR <= 999" but had to change it.
Is "to_unsigned" the correct way?

Next, if I have to use "to_unsigned", is it safe to use
"if CURRENT < 1000" or should I use
"if CURRENT < to_unsigned(1000, CURRENT'length)" ?



Example2:

I have a data bus defined like this:
signal DOUT : std_logic_vector(17 downto 0);

and DOUT is aliased into 3 unsigned indexes:

alias INDEX1 : unsigned(3 downto 0) is DOUT ( 3 downto 0);
alias INDEX2 : unsigned(8 downto 0) is DOUT (12 downto 4);
alias INDEX3 : unsigned(4 downto 0) is DOUT (17 downto 13);

I get the error that the types are incompatible.

Should I not use alias here, but create another signal?
signal INDEX1 : unsigned(3 downto 0);

INDEX1 <= DOUT(3 downto 0);
INDEX1 <= to_unsigned(DOUT(3 downto 0));
none of the above works.. how do I write it?



Example3:

signal DOUT : std_logic;
signal COUNTER : unsigned(15 downto 0);
signal INDEX : unsigned( 3 downto 0);

DOUT <= COUNTER(to_integer(INDEX));

Is that the correct way of extracting one bit?



I'll probably ask more questions after I grasp these :)



Brian Drummond 03-02-2012 12:41 AM

Re: Problems switching to ieee.numeric_std.all
 
On Thu, 01 Mar 2012 17:27:40 +0100, aleksa wrote:

> My VHD files now begin with
>
> library ieee;
> use ieee.std_logic_1164.all;
> use ieee.numeric_std.all;

good...

Find the source for the numeric_std package.
In the Xilinx installation on this machine it's at
/opt/Xilinx/12.4/ISE_DS/ISE/vhdl/src/ieee/numeric_std.vhd

And look at the declarations in the package (you can ignore the package
body below it) - or find the same information in documentation if you
prefer.

> Example1:
> ADDR <= to_unsigned(999, ADDR'length);
> Is "to_unsigned" the
> correct way?


Essentially yes.

> is it safe to use "if CURRENT < 1000" ?


You will find the package contains a declaration:
function "<" (L: UNSIGNED; R: INTEGER) return BOOLEAN;
Which tells you ... Yes.

It is a little odd that you can freely mix integers and [un]signed in
expressions, thanks to the overloaded operators, but you can't assign one
to the other, because assignment is not an operator.

(Some languages do pretend that assignment is an operator - but that
leads to problems far worse than any of VHDL's quirks!)

But back to
ADDR <= to_unsigned(999, ADDR'length);
If you find yourself doing this a lot, and the code is becoming
unbearably ugly, how about this:

subtype Address is unsigned(9 downto 0);
constant Last_Address : Address := to_unsigned(999, Address'length);
-- and other related declarations, safe in a package somewhere

signal CURRENT, ADDR : Address;

if CURRENT < Last_Address then
ADDR <= CURRENT;
else
ADDR <= Last_Address;
end if;

Can you see how this expresses the intent more clearly, as well as
behaving better if you decide to change the address range?
(e.g. if you grep for all the 999s and forget to change the 1000...)

> Example2:


> signal DOUT : std_logic_vector(17 downto 0);
> alias INDEX1 : unsigned(3 downto 0) is DOUT ( 3 downto 0);
> I get the error that the types are incompatible.


They are. So...
First, if you were to create another signal,

> signal INDEX1 : unsigned(3 downto 0);
> how do I write it?

INDEX1 <= unsigned(DOUT( 3 downto 0));

You need the type conversion here. (It is a conversion between related
types of the same size, and it costs nothing in HW of course! but tells
the compiler the change in types is intentional)

Now I have not used alias with different types in the alias expression.
You obviously need a type conversion, but I don't see why it shouldn't
work... So try

alias INDEX1 : unsigned(3 downto 0) is unsigned(DOUT( 3 downto 0));
and report back the result. If it works, use it.

> signal DOUT : std_logic;
> signal COUNTER : unsigned(15 downto 0); signal INDEX : unsigned( 3
> downto 0);
>
> DOUT <= COUNTER(to_integer(INDEX));
>
> Is that the correct way of extracting one bit?


Yes. But again, if you find yourself always converting INDEX to integer,
don't be scared to make it an integer (actually, a natural range 0 to 15)
in the first place.

If you are writing a lot of conversions, that is a pointer that you
haven't thought the design through fully yet.

Once you learn to use the type system instead of fighting it, code will
flow with little ugliness - and a very few conversions, usually at
boundaries between "things". You should be able to point to each
remaining conversion, and argue that there is a good and necessary reason
for it. (For example, the external memory model you need, expects
std_logic_vectors on its ports, so you have to convert your unsigned
address to slv on the output port)

- Brian

scrts 03-02-2012 08:48 AM

Re: Problems switching to ieee.numeric_std.all
 

> Example1:
>
> I'm copying CURRENT to ADDR, but limiting to 999:
>
> -- 2^10 = 1024
> signal CURRENT, ADDR : unsigned(9 downto 0);
>
> if CURRENT < 1000 then
> ADDR <= CURRENT;
> else
> ADDR <= to_unsigned(999, ADDR'length);
> end if;


ADDR is already unsigned, what's the point to do to_unsigned here? Afaik
to_unsigned() is mainly used to type-convert integer or signed numbers to
unsigned. slv->unsigned use unsigned().



aleksa 03-02-2012 09:13 AM

Re: Problems switching to ieee.numeric_std.all
 

"scrts" <hidden@email.com> wrote in message news:jiq1gc$1kd$1@dont-email.me...
>
>> Example1:
>>
>> I'm copying CURRENT to ADDR, but limiting to 999:
>>
>> -- 2^10 = 1024
>> signal CURRENT, ADDR : unsigned(9 downto 0);
>>
>> if CURRENT < 1000 then
>> ADDR <= CURRENT;
>> else
>> ADDR <= to_unsigned(999, ADDR'length);
>> end if;

>


> ADDR is already unsigned, what's the point to do to_unsigned here?


You mean like this?
ADDR <= unsigned(999);
"The expression can not be converted to type unsigned."


> to_unsigned() is mainly used to type-convert integer to unsigned


Isn't 999 an integer?



aleksa 03-02-2012 10:03 AM

Re: Problems switching to ieee.numeric_std.all
 

"Brian Drummond" <brian@shapes.demon.co.uk> wrote in message news:jip501$qo2$1@dont-email.me...

> subtype Address is unsigned(9 downto 0);
> constant Last_Address : Address := to_unsigned(999, Address'length);
> -- and other related declarations, safe in a package somewhere
>
> signal CURRENT, ADDR : Address;
>
> if CURRENT < Last_Address then
> ADDR <= CURRENT;
> else
> ADDR <= Last_Address;
> end if;
>


Good to know, thank you.



> Now I have not used alias with different types in the alias expression.
> You obviously need a type conversion, but I don't see why it shouldn't
> work... So try
>
> alias INDEX1 : unsigned(3 downto 0) is unsigned(DOUT( 3 downto 0));
> and report back the result. If it works, use it.


It doesn't work in ISE 13.3.
"type conversion unsigned can not be an alias name"



scrts 03-02-2012 10:07 AM

Re: Problems switching to ieee.numeric_std.all
 
> You mean like this?
> ADDR <= unsigned(999);
> "The expression can not be converted to type unsigned."


ADDR <= 999; but not sure. To be exact, You may use ADDR <= X"3E7";



aleksa 03-02-2012 10:15 AM

Re: Problems switching to ieee.numeric_std.all
 

"scrts" <hidden@email.com> wrote in message news:jiq641$nhb$1@dont-email.me...
>> You mean like this?
>> ADDR <= unsigned(999);
>> "The expression can not be converted to type unsigned."

>
> ADDR <= 999; but not sure. To be exact, You may use ADDR <= X"3E7";


From my first post:
"At first I had "ADDR <= 999" but had to change it."



Enrik Berkhan 03-02-2012 11:29 AM

Re: Problems switching to ieee.numeric_std.all
 
scrts <hidden@email.com> wrote:
>> ADDR <= unsigned(999);
>> "The expression can not be converted to type unsigned."

>
> ADDR <= 999; but not sure. To be exact, You may use ADDR <= X"3E7";


- you can't assign an integer to unsigned without conversion.
- ADDR <= X"3E7" will work only if ADDR has 12 elements unless you are
using VHDL-2008's enhanced bit string literals.

Enrik

aleksa 03-02-2012 01:53 PM

Re: Problems switching to ieee.numeric_std.all
 
One more question:

ADDR : unsigned(9 downto 0);
OFFSET : unsigned(4 downto 0);

this is what I want:
ADDR <= OFFSET + 1000;

this is how I've written it:
ADDR <= OFFSET + to_unsigned(1000, ADDR'length);

correct?



aleksa 03-04-2012 12:41 PM

Re: Problems switching to ieee.numeric_std.all
 

"Alan Fitch" <apf@invalid.invalid> wrote in message news:K8WdnZNhR-o-zc7SnZ2dnUVZ8jOdnZ2d@brightview.co.uk...
> On 02/03/12 13:53, aleksa wrote:
>> One more question:
>>
>> ADDR : unsigned(9 downto 0);
>> OFFSET : unsigned(4 downto 0);
>>
>> this is what I want:
>> ADDR <= OFFSET + 1000;
>>
>> this is how I've written it:
>> ADDR <= OFFSET + to_unsigned(1000, ADDR'length);
>>
>> correct?
>>
>>

>
> That's not necessary. "+" is overloaded for unsigned + unsigned, natural
> + unsigned, unsigned + natural - all returning unsigned. So you can write
>
> ADDR <= OFFSET + 1000;


Width mismatch. <ADDR> has a width of 10 bits but assigned expression is 5-bit wide.

In the VHDL math tricks:
Y <= A + B; -- Maximum (A'Length, B'Length)
Y <= A + 10; -- A'Length

Since ISE complains if I just "+ 1000",
I wanted to convert "1000" to "B" in the first example.

It works, but I don't know if that is the correct approach.




BTW, I know that 2^5 is 32 and that 1000+32
may overflow 10 bits... but I don't care.




All times are GMT. The time now is 09:51 AM.

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