[noob] signed binary

Discussion in 'VHDL' started by Massi, Jul 14, 2006.

  1. Massi

    Massi Guest

    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
    Massi, Jul 14, 2006
    #1
    1. Advertising

  2. On Fri, 14 Jul 2006 23:48:05 +0200, Massi
    <> wrote:

    > 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

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jul 14, 2006
    #2
    1. Advertising

  3. Mike Treseler, Jul 14, 2006
    #3
  4. Massi

    Massi Guest

    Jonathan Bromley wrote:
    > [cut]


    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 :)
    Massi, Jul 14, 2006
    #4
  5. Massi wrote:

    > # ** 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
    Ralf Hildebrandt, Jul 15, 2006
    #5
  6. Massi

    Massi Guest

    Ralf Hildebrandt wrote:

    > 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 :)
    Massi, Jul 15, 2006
    #6
  7. On Sat, 15 Jul 2006 00:52:40 +0200, Massi
    <> wrote:

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


    Sorry, that wasn't intentional :)

    > 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..


    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

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jul 15, 2006
    #7
  8. Massi

    Massi Guest

    Jonathan Bromley wrote:

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

    > 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
    Massi, Jul 15, 2006
    #8
  9. Massi wrote:


    >> 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?


    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
    Ralf Hildebrandt, Jul 15, 2006
    #9
  10. Massi

    Massi Guest

    Jonathan Bromley wrote:
    > [cut]


    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
    Massi, Jul 16, 2006
    #10
  11. On Sun, 16 Jul 2006 23:02:17 +0200, Massi
    <> wrote:

    >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

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jul 18, 2006
    #11
  12. Massi

    Massi Guest

    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..
    Massi, Jul 18, 2006
    #12
  13. On Tue, 18 Jul 2006 09:32:43 +0200, Massi
    <> wrote:

    >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.

    >> 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)
    >
    >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

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jul 18, 2006
    #13
  14. Massi

    Massi Guest

    Jonathan Bromley wrote:

    > 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!

    >> And the "else (others => '-') tense is not working, dunno why..
    >> do you think the code is right?

    > 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
    Massi, Jul 19, 2006
    #14
  15. On Wed, 19 Jul 2006 01:29:37 +0200,
    Massi <> wrote:


    >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.

    >>> And the "else (others => '-') tense is not working, dunno why..
    >>> do you think the code is right?

    >> Yes, definitely. The problem is elsewhere.

    >
    >ok, i'll work on it, 10x


    Tell us about what your test bench is doing...

    >> 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..


    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 :-(

    >> 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?


    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

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jul 19, 2006
    #15
  16. Massi

    Massi Guest

    Jonathan Bromley wrote:

    > 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
    Massi, Jul 19, 2006
    #16
  17. Massi

    Massi Guest

    Jonathan Bromley wrote:
    > [cut]


    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 :(
    Massi, Jul 19, 2006
    #17
  18. Massi

    Andy Guest

    Re: signed binary

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

    Jonathan Bromley wrote:
    > 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
    Andy, Jul 19, 2006
    #18
  19. On Wed, 19 Jul 2006 17:13:43 +0200,
    Massi <> wrote:

    > 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

    http://www.MYCOMPANY.com

    The contents of this message may contain personal views which
    are not the views of Doulos Ltd., unless specifically stated.
    Jonathan Bromley, Jul 20, 2006
    #19
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Weng Tianxiang
    Replies:
    4
    Views:
    3,026
    Weng Tianxiang
    Apr 7, 2005
  2. kyrpa83
    Replies:
    1
    Views:
    615
    kyrpa83
    Oct 17, 2007
  3. Replies:
    4
    Views:
    362
  4. Robert Somerville
    Replies:
    5
    Views:
    2,150
    Irmen de Jong
    Jan 8, 2010
  5. Rob1bureau
    Replies:
    1
    Views:
    798
    joris
    Feb 27, 2010
Loading...

Share This Page