[noob] signed binary

M

Massi

Hi all,
little question for you:
i've this code
BINOUT <= "1111111111111111" when BININ >= "1111111111110000" and BININ <=
"0000000000001000" else

(it's an example)
how can i tell VHDL to consider that "1111...." a negative number and not a
positive one?
I tried with signed("11111....") but i get an error..
I'd like to avoid local vars because the lookup table is very big..

Thanks..
libraries loaded are

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

and the error is

Type conversion (to signed) can not have string literal operand.

bye
 
J

Jonathan Bromley

BINOUT <= "1111111111111111" when BININ >= "1111111111110000" and BININ <=
"0000000000001000" else

how can i tell VHDL to consider that "1111...." a negative number and not a
positive one?
I tried with signed("11111....") but i get an error..
I'd like to avoid local vars because the lookup table is very big..

Thanks..
libraries loaded are

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

aaargh... that way lies confusion and madness.

Please get into the habit of doing The Right Thing (TM):

use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- NEVER use std_logic_(un)signed
-- Avoid std_logic_arith, use numeric_std instead

Now you can have SIGNED and UNSIGNED co-existing in the same module
without difficulty or confusion; you get conversion functions with
sensible names; and you get a reasonably complete set of arithmetic
operations on SIGNED and UNSIGNED.

signed("11111111") is an error because the data type of the constant
"11111111" is not well defined. It might be a string, a bit-vector, a
std_logic_vector, an UNSIGNED, a SIGNED... and although some of
those may legally be type-converted to SIGNED, some can't.
However, "11111111" is a perfectly valid constant of type SIGNED,
so just tell the compiler what data type you want it to be:

signed'("11111111")

(note the apostrophe between signed and the opening parenthesis).

Note, also, that numeric_std allows you to compare signed or unsigned
things directly with integers; so you could much more elegantly
write your example (assuming BININ is of type SIGNED):

BINOUT <= "1111111111111111"
when (BININ >= -16) and (BININ <= 8)
else...

If BININ is a port of std_logic_vector type (a common situation) then
you will need to type-convert it to SIGNED for this to work:

signal S_BININ: SIGNED(BININ'range);
....
S_BININ <= SIGNED(BININ);

and now you do all your SIGNED tests on S_BININ.

Finally, instead of the true ghastliness of
BINOUT <= "1111111111111111";
please consider writing a handy conversion function:

subtype t_binout is signed(BINOUT'range);
function to_binout(n: integer) return t_binout is begin
return to_signed(n, t_binout'length);
end;

and then you can easily write
BINOUT <= to_binout(-1);

If you find that all this type conversion and functions stuff is just
too much, you can instead respond to the siren calls of Verilog.
It'll be SOOOO much easier for the first few months. Only after
the first few years will you start to notice that maybe VHDL's
type system isn't such a bad thing after all...
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
M

Massi

Jonathan said:

lol
thank you very VERY much for your help :)

I must admin i did not understand much of your post :p but I did this
signal S_BININ: SIGNED(BININ'range);
...
S_BININ <= SIGNED(BININ);

and THAN this
signed'("11111111")

and all seems to work fine..

BUT you are not safe yet :p

I did a little testbench, and even if every "right" value works fine, a
"wrong" value give me this error

# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the
result will be 'X'(es).
# Time: 274222530 ns Iteration: 0 Instance: /tb_testdiscretizer
# Test FAILED:

something to do with my last "else" tense?

(others => '-');

And the last thing :p
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- NEVER use std_logic_(un)signed
-- Avoid std_logic_arith, use numeric_std instead

so all i need is
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
?

Thank you SO much :)
 
R

Ralf Hildebrandt

Massi said:
# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the
result will be 'X'(es).
# Time: 274222530 ns Iteration: 0 Instance: /tb_testdiscretizer
# Test FAILED:

something to do with my last "else" tense?

(others => '-');

Yes. Integers do not have these Values. Therefore something is lost
during conversion and this warning tells you this.

The workaround is to avoid the conversion of a std_(u)logicvector /
signed / unsigned to integer. Often this can be done converting the
integer in the opposite direction.

Example:

signal my_vec : std_ulogic_vector(bitwidth-1 downto 0);

if (to_integer(signed(my_vec)) = 42) then

if (my_vec = std_ulogic_vector(to_signed(42,my_vec'length))) then

The 2nd if-clause will not give such warnings.



Ralf
 
M

Massi

Ralf said:
Yes. Integers do not have these Values. Therefore something is lost
during conversion and this warning tells you this.

uhm.. i don't think there is any conversion to integer..
at least, i didn't want to do that lol
So, i've a std_logic_vector as output, and the value assigned depends on
many "where" conditions
When no "where" is true, i want to assign the value "-------" (and
std_logic_vector DOES have this value, right?)
So, what's the correct way to do that?
Or maybe have i not to assign a value to the output when no condition is
true? i don't think that's a great solution..

thank you :)
 
J

Jonathan Bromley

I must admin i did not understand much of your post :p

Sorry, that wasn't intentional :)
but I did this


and THAN this


and all seems to work fine..

yes, it's a good thing to do
BUT you are not safe yet :p

I did a little testbench, and even if every "right" value works fine, a
"wrong" value give me this error

# ** Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the
result will be 'X'(es).
# Time: 274222530 ns Iteration: 0 Instance: /tb_testdiscretizer
# Test FAILED:

something to do with my last "else" tense?

(others => '-');

"-----" is OK as a value for a SIGNED or UNSIGNED vector.
Are you trying to do some other arithmetic operation with
this value? If you are, then it's probably correct for the result
to be X, because you don't know (don't care) what the value is,
so you don't know (don't care) what the result is.
And the last thing :p

so all i need is
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
?

Absolutely correct.

std_logic_(un)signed are convenient for some very
simple situations (like writing a counter using a std_logic_vector)
but they are very limited and restrictive, so I always recommend
that you should not use them. (Some people disagree.)

std_logic_arith is an older version of numeric_std.
numeric_std is better in every way, so there is no sense in using
std_logic_arith unless it's needed to maintain an old design.

Would the nice people at Xilinx (and possibly others), who set
their VHDL editors to have std_logic_unsigned+std_logic_arith
as the default, please make themselves known so that we can
shout at them very loudly? Thanks!
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
M

Massi

Jonathan said:
Sorry, that wasn't intentional :)

That's because i'm so noob :p
"-----" is OK as a value for a SIGNED or UNSIGNED vector.
Are you trying to do some other arithmetic operation with
this value? If you are, then it's probably correct for the result
to be X, because you don't know (don't care) what the value is,
so you don't know (don't care) what the result is.

mmm. no..
no arithmetic operation, i just have to set a std_logic_vector value to
"-------", just to understand that this value is "wrong"..
And it seems i cannot get this to work..

Example:

BINOUT <= "1111" when BININ >= "0001" and BININ <= "1100"
else (others => '-');

and this gives an error..
std_logic_(un)signed are convenient for some very
simple situations (like writing a counter using a std_logic_vector)
but they are very limited and restrictive, so I always recommend
that you should not use them. (Some people disagree.)
std_logic_arith is an older version of numeric_std.
numeric_std is better in every way, so there is no sense in using
std_logic_arith unless it's needed to maintain an old design.

I will follow my master's way and i will always use only those libraries :p
 
R

Ralf Hildebrandt

Massi wrote:

uhm.. i don't think there is any conversion to integer..
at least, i didn't want to do that lol
So, i've a std_logic_vector as output, and the value assigned depends on
many "where" conditions
When no "where" is true, i want to assign the value "-------" (and
std_logic_vector DOES have this value, right?)
So, what's the correct way to do that?

Yes, that is a correct way.
But if you seek for logic reduction it is better to assign (others=>'X')
to the vector.


Neverteheless aus you have written in your 1st post
BINOUT <= "1111111111111111" when BININ >= "1111111111110000" and BININ <=
"0000000000001000" else

there _are_ some arithmetic operations (the comparisons). Arithemetic
operations can be easily performed if you use signed, unsigned or
integer as type.
And to make the next step: arithmetic operations should be never done
with std_(u)logic_vectors, because it is ambiguous whether the operand
is treated as to be a signed or unsigned vector. Manual conversions to
the type signed or unsigned clear the ambiguity.

Ralf
 
M

Massi

Jonathan said:

i go on having BIG troubles with this malicious vhdl :p

I've to create some simple code (the big part of the project is in C++) but
i always have much problems with signed values...

The first part of the project is this (almost functional, but the "others
=>" isn't working)

library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity name is
port(
BININ : in std_logic_vector(0 to 3);
BINOUT : out std_logic_vector(0 to 3)
);
end name;
architecture rrgen of name is
signal S_BININ: SIGNED(BININ'range);
begin
S_BININ <= SIGNED(BININ);
BINOUT <= "1111" when S_BININ >= signed'("1001") and S_BININ <=
signed'("0100") else
(others => '-');
end rrgen;

As i said before, this block is working, excepting the "default" value
"others=>'-'"
Is there any error in this code? may i change anything?

And then, the HARD block :p

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity unnamed is
port(
BININ : in std_logic_vector(0 to 3);
BINOUT : out std_logic_vector(0 to 3)
);
end unnamed;

architecture rrgen of unnamed is
constant pi : std_logic_vector(0 to 3) := "1010";
constant duepi : std_logic_vector(0 to 3) := "1010";
constant pimezzi : std_logic_vector(0 to 3) := "0101";
signal S_PI: SIGNED(pi'range);
signal S_DUEPI: SIGNED(duepi'range);
signal S_PIMEZZI: SIGNED(pimezzi'range);
signal S_BININ: SIGNED(BININ'range);

begin
S_PI <= SIGNED(pi);
S_DUEPI <= SIGNED(duepi);
S_PIMEZZI <= SIGNED(pimezzi);
S_BININ <= SIGNED(BININ);

while S_BININ < -S_PI loop
S_BININ <= S_BININ + S_DUEPI;
end loop;
while S_BININ > S_PI loop
S_BININ <= S_BININ - S_DUEPI;
end loop;

BINOUT <= S_PI-S_BININ when S_BININ > S_PIMEZZI else
-S_PI-S_BININ when S_BININ < -S_PIMEZZI else
S_BININ;
end rrgen;

and, simply, nothing works...
i get errors in the while, in the assignment, in the operators, everywhere!

What drives me crazy is that the "target" of this module is SO SIMPLE, but
so hard (for me..) to obtain.. i befin hating signed numbers :p

thanks very very much to everyone will try to help me..
I hope Jonathan will loose some time with me.. again :p
 
J

Jonathan Bromley

i go on having BIG troubles with this malicious vhdl :p

It's not really out to get you...
The first part of the project is this (almost functional, but the "others
=>" isn't working)

library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity name is
port(
BININ : in std_logic_vector(0 to 3);
BINOUT : out std_logic_vector(0 to 3)
);
end name;
architecture rrgen of name is
signal S_BININ: SIGNED(BININ'range);
begin
S_BININ <= SIGNED(BININ);
BINOUT <= "1111" when S_BININ >= signed'("1001") and S_BININ <=
signed'("0100") else
(others => '-');
end rrgen;

As i said before, this block is working, excepting the "default" value
"others=>'-'"

I'm not sure I understand. Is this *really* all the code? I don't
think there is anything wrong with it. I suspect it's your testbench
that's causing the trouble. What do you find is "not working"?
Simulation, or synthesis, or real hardware?

However, there *is* something strange. If you care that BINOUT = 1111
when BININ is between -7 and +4, but you don't care what it is for any
other values of BININ, then why bother with the don't-care? Why not
merely force BINOUT to 1111 at all times? That is exactly what a
synthesis tool would do from your code. What is the intent of
your design?
Is there any error in this code? may i change anything?

See above; and also consider the following cleanup:

BINOUT <= "1111" when S_BININ >= -7 and S_BININ <= 4
else (others => '-');

Even better, since your input is only 4 bits wide, consider
writing it as a lookup table using a CASE statement, which will
probably create simpler hardware:

architecture....

process (BININ)
begin
case BININ is
when "0000" => BINOUT <= "0000";
when "0001" => BINOUT <= "1000";
when "0010" => BINOUT <= "0100";
when "0011" => BINOUT <= "0010";
when "0100" => BINOUT <= "0001";
when "0101" => BINOUT <= "1100";
when "0110" => BINOUT <= "0110";
when "0111" => BINOUT <= "0011";
when "1000" => BINOUT <= "1110";
when "1001" => BINOUT <= "0111";
when "1010" => BINOUT <= "1000";
when "1011" => BINOUT <= "0100";
when "1100" => BINOUT <= "0010";
when "1101" => BINOUT <= "0001";
when "1110" => BINOUT <= "0000";
when "1111" => BINOUT <= "0000";
when others => BINOUT <= "----";
end case;
end process;

My values on BINOUT are only examples, of course - you
would need to choose your own values.


architecture rrgen of unnamed is
constant pi : std_logic_vector(0 to 3) := "1010";
constant duepi : std_logic_vector(0 to 3) := "1010";
constant pimezzi : std_logic_vector(0 to 3) := "0101";
signal S_PI: SIGNED(pi'range);
signal S_DUEPI: SIGNED(duepi'range);
signal S_PIMEZZI: SIGNED(pimezzi'range);
signal S_BININ: SIGNED(BININ'range);

begin
S_PI <= SIGNED(pi);
S_DUEPI <= SIGNED(duepi);
S_PIMEZZI <= SIGNED(pimezzi);
S_BININ <= SIGNED(BININ);

while S_BININ < -S_PI loop
S_BININ <= S_BININ + S_DUEPI;
end loop;
while S_BININ > S_PI loop
S_BININ <= S_BININ - S_DUEPI;
end loop;

BINOUT <= S_PI-S_BININ when S_BININ > S_PIMEZZI else
-S_PI-S_BININ when S_BININ < -S_PIMEZZI else
S_BININ;
end rrgen;

and, simply, nothing works...

No. It won't. You are failing to understand the operation of signal
assignment, and several other things too.
i get errors in the while, in the assignment, in the operators, everywhere!

Yes... you need at least one PROCESS in the design, to contain the
while loops and multiple assignments. Your WHILE loops would never
work in their present form, because you are testing a signal before
it has had a chance to update. And finally, I fear you are failing
to understand some fundamental ideas about arithmetic overflow
and twos-complement number representation.
What drives me crazy is that the "target" of this module is SO SIMPLE

What are you trying to do? It looks like maybe it's some sort of
iterative algorithm to reduce an angle into one quadrant.
Is this just a piece of software that happens to be written
in VHDL (maybe part of a testbench)? Or is it intended to
be built as a piece of hardware? Iterative algorithms in
hardware often need registers and a controlling state
machine, and there's nothing like that in your code.
But an angle-reduction operation can usually be done
in a single step, by choosing the right arithmetic
operations.

Be clear with us about what you're trying to do, and we may
be able to fix some of your misunderstandings. At the moment,
your code is what we skilled engineers like to describe as "broken".
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
M

Massi

Jonathan Bromley wrote:

First of all, thanks for your time and patience :p
I'm not sure I understand. Is this *really* all the code? I don't
think there is anything wrong with it. I suspect it's your testbench
that's causing the trouble. What do you find is "not working"?
Simulation, or synthesis, or real hardware?

mmm non exactly the real code.
I mean, i've posted the problem with just 4 bits and just one line in the
conditions.
Really the code works with 16-32 bits and with much more conditions
However, there *is* something strange. If you care that BINOUT = 1111
when BININ is between -7 and +4, but you don't care what it is for any
other values of BININ, then why bother with the don't-care?

That's not true.
I CARE that binout has a "special" value when binin is not in any condition.
And the "else (others => '-') tense is not working, dunno why..
do you think the code is right?
i will control the testbench code..
No. It won't. You are failing to understand the operation of signal
assignment, and several other things too.

many other things, i think..
What are you trying to do? It looks like maybe it's some sort of
iterative algorithm to reduce an angle into one quadrant.

I'm trying to get the BININ (an angle) into the (-pi,+pi) sector
(this is intended to be done with the while part)
and than if the angle is in the (0,pi) sector, i'd like to assign to BINOUT
the value -BININ, else i leave BININ as output

NB: 4 bit is just an example, like the value i gave the constants..

talking about "-BININ", i realize that i'm SO noob.. every "-" in that piece
of code is giving me an error.. i'm getting crazy :)
Is this just a piece of software that happens to be written
in VHDL (maybe part of a testbench)? Or is it intended to
be built as a piece of hardware?

it's intended to be built as hardware..
At least, it should be ready to be built..
Be clear with us about what you're trying to do, and we may
be able to fix some of your misunderstandings. At the moment,
your code is what we skilled engineers like to describe as "broken".

Broken is the most beautiful word that i could assign to my code, lol

thank you so SO much for your time..
 
J

Jonathan Bromley

Really the code works with 16-32 bits and with much more conditions
OK.

I CARE that binout has a "special" value when binin is not in any condition.

In which case, (others=>'-') is not a good value to give it :)

Using the '-' logic value is appropriate if there is a set of input
conditions that you know will never happen in practice. By setting
the output to '-' in this situation, you get 2 benefits:
1) if, in simulation, the "bad" input ever happens, you will
see the crazy output value and know that something is wrong
2) in synthesis, the tool will interpret '-' to mean "user does not
care what happens, so synthesis can build whatever gives
the simplest/smallest logic".

If you want a special error-flag value that can be detected by
other hardware, you need to set up some special pattern of
ones and zeros and assign that to the output in your error case.
Hardware can never DETECT '-' values. That value effectively
means "either a 1 or a 0, but I don't know or don't care which".
No way can that be detected by any hardware gate!
And the "else (others => '-') tense is not working, dunno why..
do you think the code is right?

Yes, definitely. The problem is elsewhere.
I'm trying to get the BININ (an angle) into the (-pi,+pi) sector
(this is intended to be done with the while part)

NB: 4 bit is just an example, like the value i gave the constants..

OK. The big question, then, is: what's the range and scaling of your
input angle? If it has been carefully chosen, the angle-collapsing
operation will be very easy; if not, you may need to implement some
fairly complicated division operation or iterative reduction.
and than if the angle is in the (0,pi) sector, i'd like to assign to BINOUT
the value -BININ, else i leave BININ as output

That's just an absolute-value operation, yes?

BINOUT <= std_logic_vector(abs signed(BININ));

Or if that's not supported by your tools (unlikely):

process ( BININ )
begin
if BININ(BININ'LEFT) = '1' then
-- BININ is negative: negate it
BINOUT <= std_logic_vector( - signed(BININ) );
else
-- BININ is positive: just copy it
BINOUT <= BININ;
end if;
end process;
talking about "-BININ", i realize that i'm SO noob.. every "-" in that piece
of code is giving me an error.. i'm getting crazy :)

But you can easily do "minus" on a SIGNED value... the problem is that
your signal BININ was a std_logic_vector, and this has no arithmetic
meaning. Put the same bit-pattern into a SIGNED vector and it has
a specific numeric value, and it can be negated. See my
example code above.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
M

Massi

Jonathan said:
In which case, (others=>'-') is not a good value to give it :)

I don't think i understand.
If i don't put a default "tense" the value of the output remains the last
output assigned, right?
and the same if i assign ------ you say... mmm... even if i assign all Z i
think.. mmm ... so? :)
at this point i can simply take out the last else lol!
Yes, definitely. The problem is elsewhere.

ok, i'll work on it, 10x
OK. The big question, then, is: what's the range and scaling of your
input angle? If it has been carefully chosen, the angle-collapsing
operation will be very easy; if not, you may need to implement some
fairly complicated division operation or iterative reduction.

mmm no, theorically tha angle can be totally random..
Or if that's not supported by your tools (unlikely):
process ( BININ )
begin
if BININ(BININ'LEFT) = '1' then
-- BININ is negative: negate it
BINOUT <= std_logic_vector( - signed(BININ) );
else
-- BININ is positive: just copy it
BINOUT <= BININ;
end if;
end process;

nice piece of code :)
little question for you, master
in std_logic_vector( - signed(BININ) ); the "std_logic_vector" is a kind of
cast?
this solves me much problems!
another little question: in the other problem you told me do declare a
signal to be able to "sign" the value. Right?
here i see there is no signal, but you simpli sign the binin value.
So if in a process block i call a signed(constant) this constant is used as
a signed value?
That's paradise for me lol
But you can easily do "minus" on a SIGNED value... the problem is that
your signal BININ was a std_logic_vector, and this has no arithmetic
meaning. Put the same bit-pattern into a SIGNED vector and it has
a specific numeric value, and it can be negated. See my
example code above.

yes, your code was wonderful and helped me so much.
my last and biggest problem is taking the binin value in the -pi, +pi sector
:p
do i need other process blocks? can i declare many process block in the same
architecture?

thanks thanks thanks
Come to italy for a beer lol
 
J

Jonathan Bromley

I don't think i understand.
If i don't put a default "tense"

I think the usual English word is "clause" - but no problem...
the value of the output remains the last output assigned, right?

Yes, and then the code would not be good for synthesis.
and the same if i assign ------ you say... mmm... even if i assign all Z i
think.. mmm ... so? :)

If you assign -----, you are telling the synthesis tool "please build
SOMETHING here, but I don't care what I get, so make it as
simple as possible". If you assign ZZZZZ, you are saying "please
float the outputs in this case" - and that is MUCH more difficult.

If you assign (for example) "1000000" then you have a fixed
"error flag" value that can be tested somewhere else in the system.
at this point i can simply take out the last else lol!

no, as I mentioned above, that would make the code BAD for
synthesis, because it would create latches.
ok, i'll work on it, 10x

Tell us about what your test bench is doing...
mmm no, theorically tha angle can be totally random..

I understand that you can feed any angle value into this logic, but
my question was this: Let's suppose (as an example) that your
angle values are 16 bits. That's an integer range -32768 to
+32767. On this scale, what integer value represents +pi?

Here are some possible choices that might make sense:

(1) +pi = 180 degrees: integer value = +180
(2) +pi = 3.142 radians: integer value = +3142
(3) +pi = half a circle: integer value = +32768

Case (3) is brilliantly simple: your 16-bit integer
range -32768 to +32767 now represents exactly
-pi to +pi and you NEVER need to do angle reduction!
But maybe you NEED to represent angles larger than +pi.
So, let's try another choice - again, only for an example:

(4) +pi = half a circle; max. range = +/-4 circles;
so we represent +pi using integer 32768/8 = 4096

Why is this a good idea? Because we can now reduce any
angle into a -pi..+pi range simply by throwing away the top
three bits of the integer value! The bottom 13 bits (12 downto 0)
provide the reduced angle, in the range -4096 to +4095, same as
-pi to (nearly) +pi.

WHATEVER you do, the algorithm for reducing an angle into the
range -pi to +pi is essentially the same as "remainder after
dividing by 2pi". Dividing, by any number, is difficult in hardware
*unless the number is an exact power of 2*. This is the reason
why my choices (3) and (4) are such a good idea.

However, MULTIPLICATION is rather easy in FPGA hardware
because (at least in Xilinx and Altera parts) you probably
have built-in integer multiplier logic available. So, it
is a very good idea to use a multiplier to re-scale all
your angle values so that pi is represented by an
exact power of 2. After that multiplication, reducing
the angle to the -pi..+pi range is very simple: just
throw away some high-order (most significant) bits.

Any other way of doing it will be much harder to code -
too hard for this discussion :-(
nice piece of code :)
little question for you, master
in std_logic_vector( - signed(BININ) ); the "std_logic_vector" is a kind of
cast?

Yes. It's called an "array type conversion". SIGNED and
STD_LOGIC_VECTOR are both defined in exactly the same way:
they are arrays of STD_LOGIC, indexed by integer. Given two
types that are "closely related" in this way, VHDL allows you to
convert from one to the other by using the type name as if it
was a conversion function. The bit pattern is copied without
modification. The "signed" is also the same kind of cast.
this solves me much problems!

Me too :)
another little question: in the other problem you told me do declare a
signal to be able to "sign" the value. Right?
here i see there is no signal, but you simpli sign the binin value.
So if in a process block i call a signed(constant) this constant is used as
a signed value?
That's paradise for me lol

Yes, but you must be careful with constants.

VHDL knows that BININ is a STD_LOGIC_VECTOR, and therefore
it can be converted to SIGNED as you saw. But what about this...

SIGNED("111") ???? -- ERROR

What is the data type of "111"? Is it STRING? BIT_VECTOR?
STD_LOGIC_VECTOR? It could be any of those. VHDL cannot
decide. So the expression is illegal. HOWEVER, "111" is also
a satisfactory way to write a SIGNED constant. So we can
tell VHDL that the constant is of SIGNED data type, using
the type qualification syntax I showed you before:

SIGNED'("111") -- note the added apostrophe '

Now there is NO type conversion taking place. We are telling
the compiler that it must try to understand the "111" constant
as a SIGNED constant. This is OK.
Come to italy for a beer lol

Well now... here's a better idea: Come to the south of England
for a Doulos VHDL training class, and we'll introduce you to the
wonderful beer from our local brewery here in Ringwood :-D
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
M

Massi

Jonathan said:
I think the usual English word is "clause" - but no problem...

i don't think that's the only problem of my english :p
don't you ever sleep jonathan?
you are what is called "24h live support" lol
no, as I mentioned above, that would make the code BAD for
synthesis, because it would create latches.

so i should add a custom VALID std_logic_vector indicating the error.
That's clear, now :p
Tell us about what your test bench is doing...

mmm, the strange part of this error is that the testbanch just gives a bit
vector as input, reads a bit vector as output and compares this to the
"right" value given by user
maybe it has some problems comparing a "-----" with a true bit vector?
(in the "wrong" line i gave a bit vector as output, expecting a "not
working" from the testbench.. and it works, but giving me that warning..)
I understand that you can feed any angle value into this logic, but
my question was this: Let's suppose (as an example) that your
angle values are 16 bits. That's an integer range -32768 to
+32767. On this scale, what integer value represents +pi? [cut]
(2) +pi = 3.142 radians: integer value = +3142 [cut]
Any other way of doing it will be much harder to code -
too hard for this discussion :-(

mmm, i'll try to explain.
i NEED to give "real" angles, so in radians.
And that's the first problem.
Than, the bit vector in input is a fixed point binary number, where
fractional and integer bits depends on the specific problem.
I mean, i told you that this piece of code is a "son" of a C++ module.
Depending on what the C++ is doing, i can have, example, 4, 8, 12... bits
for fractional part, constants take their values depending on that, and
input value changes depending on that.
So it's hard for me to think to "take out" some bits to take the input
to -pi,+pi sector.
What scares me is that you goon avoiding while tenses, that's the only way i
see for this problem

did i explain me?
Yes, but you must be careful with constants.
SIGNED'("111") -- note the added apostrophe '

right, but if i declared a constant as a std_bit_vector is enough for me to
do signed(constant) right?
it seems there's a little (little!) light at the end of the tunnel lol
Well now... here's a better idea: Come to the south of England
for a Doulos VHDL training class, and we'll introduce you to the
wonderful beer from our local brewery here in Ringwood :-D

beer -> good
vhdl -> bad
:p
 
M

Massi

Jonathan said:

Little progress here..
The second part, all what is out of the loop, is working fine.
I tried building also the while block: i couldn't believe to my eyes when
all my code was compiled right (lol) but there's no chance to get it
working..

That's it:

signal TEMP_BININ: std_logic_vector(0 to 15);
begin

TEMP_BININ <= BININ;
process ( TEMP_BININ )
begin
WHILE (signed(TEMP_BININ) > signed(pi)) or (signed(TEMP_BININ)
< -signed(pi)) LOOP
if signed(TEMP_BININ) > signed(pi) then
TEMP_BININ <= std_logic_vector( signed(TEMP_BININ) -
signed(duepi) );
else
TEMP_BININ <= std_logic_vector( signed(TEMP_BININ) +
signed(duepi) );
end if;
END LOOP;
end process;

as you can see, i declared a temp signal (obviously i couldn't assign values
to a input port), assigned to it the BININ value, and then tried to work on
this value with a process.
It's compiled without errors or warning, but not working..
it says

# ** Warning: NUMERIC_STD.">": metavalue detected, returning FALSE
# Time: 0 ps Iteration: 0 Instance: /unnamed

in the first loop, than says nothing, but no output is created..

dunno where to beat my head :(
 
A

Andy

A slight topic-branch here, but I think there are other uses and
implications (in HW and simulation) of assigning '-' to a signal.

Jonathan said:
Using the '-' logic value is appropriate if there is a set of input
conditions that you know will never happen in practice. By setting
the output to '-' in this situation, you get 2 benefits:
1) if, in simulation, the "bad" input ever happens, you will
see the crazy output value and know that something is wrong
2) in synthesis, the tool will interpret '-' to mean "user does not
care what happens, so synthesis can build whatever gives
the simplest/smallest logic".

It is often the case that the input conditions are known to exist, but
you still don't care what your outputs do when the input condition does
occur. The second benefit is correct, but the first one is not so
simple: by assigning the output to (others => '-'), downstream logic
will either choke on it, or ignore it. If it chokes, it is an
indication that the downstream logic may be faulty (or perhaps coded
incorrectly).

Sometimes it can be non-trivial to code logic that accepts don't-care
inputs and simulates without blowing up, even thought the circuitry
would work just fine. Addition is a good example.

Assuming there is a flag to tell you when input data is valid, it can
be done fairly easily and optimally:

if valid then
output <= input + 1;
else
output <= (others => '-');
end if;

The valid signal will get optimized out in synthesis, and the result
will be a simple adder, yet it will also simulate correctly, since
don't-care + 1 is still don't-care.

I've also used don't-care inputs in simulation testbenches to test
certain features.

Andy
 
J

Jonathan Bromley

don't you ever sleep jonathan?

Yes, but not at the same time as you do - I'm in
the USA this week.
I tried building also the while block: i couldn't believe to my eyes when
all my code was compiled right (lol) but there's no chance to get it
working..

[snip]

OUCH.

Taking a much simpler example: Suppose I want to take a
std_logic_vector and shift it to the left until I see a '1' bit in
the left-most position.

signal in_vec: std_logic_vector(L downto R);
....
process (in_vec)
begin
while in_vec(in_vec'left) /= '1' loop
in_vec <= in_vec(L-1 downto R) & '0'; -- shift left
end loop;
end process;

Now, that looks quite simple, doesn't it? But you need to
know that signal assignment using <= DOES NOT TAKE
EFFECT IMMEDIATELY. It schedules the signal change for
the next "delta cycle". So the loop goes like this:

do the test, find in_vec(in_vec'left) = '0'
do the signal assignment, BUT in_vec doesn't change YET
loop back, test in_vec again, it's still the same
do the signal assignment again, shifting the OLD value of in_vec
...

so your loop will iterate indefinitely, in zero simulated time.
It will lock-up your simulator, and it will not create
useful hardware.

You have designed a piece of hardware that "eats its tail" -
it continually updates its own input from its own output -
that will never work! And VHDL correctly refuses to help you!
You simply can't use this trick to design hardware to
implement an iterative algorithm.

To make this work you must build a clocked register that
holds the intermediate result of the calculation, and then
does one step of the calculation on each clock cycle.

That means the calculation will take more than one
clock cycle, and indeed you don't know how many
cycles it will take. As a result, you need a system
where a new input value is provided, then your device
goes away and calculates for several clock cycles
until it's happy, and then it provides the correct
answer together with a flag bit to say "yes, this
data is correct". Only then can you supply a new
input data value.

Designing this would be quite straightforward for
someone who has a background in digital design.
But I sense that your background is in software,
or mathematics, and definitely not in digital -
so I suggest you need to get some extended
assistance, from a course or a good textbook.
I don't know what is available in Italian, but
in English we like Mark Zwolinski's book
"Digital Systems Design using VHDL". It's
designed as a student text.

Are you SURE you can't get the system to provide
angles that are scaled so pi is represented as
an exact power of 2? It would be soooooo much
easier.....

Sorry, I must sign off now - too much distraction
from the day job :-(
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
(e-mail address removed)
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top