multiplying std logic vectors

Discussion in 'VHDL' started by abilashreddyg@gmail.com, Dec 15, 2006.

  1. Guest

    Hi,
    I have the following code.

    signal a,b,c,d:std_logic_vector(17 downto 0);
    signal out :std_logic_vector(36 downto 0);
    out <= a*b + c*d;

    My synthesis tool errors out complaining of mismatched array sizes.

    A work around I used was this:
    out <= ('0' & (a*b)) + ('0' & (c*d)) ;

    Is this the general practice or is there an easier way around?

    Thanks.
    , Dec 15, 2006
    #1
    1. Advertising

  2. Signal "out" is declared as 37-bit. The product of two 18-bit unsigned
    values will be 36-bit. If your result must have 37 bits, you could just
    concatenate one bit to the original equation for "out". You don't really
    need to distribute.

    Regards,
    Bob



    wrote:
    > Hi,
    > I have the following code.
    >
    > signal a,b,c,d:std_logic_vector(17 downto 0);
    > signal out :std_logic_vector(36 downto 0);
    > out <= a*b + c*d;
    >
    > My synthesis tool errors out complaining of mismatched array sizes.
    >
    > A work around I used was this:
    > out <= ('0' & (a*b)) + ('0' & (c*d)) ;
    >
    > Is this the general practice or is there an easier way around?
    >
    > Thanks.
    >
    Robert G. Kaimer Jr., Dec 15, 2006
    #2
    1. Advertising

  3. Rob Dekker Guest

    Abilash,

    Which package are you using (to multiply the two std_logic_vectors) ?
    Let me take a guess : The Synopsis "std_logic_unsigned" (or signed) package ?
    They are both based on the Synopsys "std_logic_arith" package, which has a function called
    "EXT" which does zero-extension, and SEXT which does sign extension.
    So here you go :

    out <= ext(a*b + c*d, out'length)

    Rob

    <> wrote in message news:...
    > Hi,
    > I have the following code.
    >
    > signal a,b,c,d:std_logic_vector(17 downto 0);
    > signal out :std_logic_vector(36 downto 0);
    > out <= a*b + c*d;
    >
    > My synthesis tool errors out complaining of mismatched array sizes.
    >
    > A work around I used was this:
    > out <= ('0' & (a*b)) + ('0' & (c*d)) ;
    >
    > Is this the general practice or is there an easier way around?
    >
    > Thanks.
    >
    Rob Dekker, Dec 15, 2006
    #3
  4. a écrit :
    > Hi,
    > I have the following code.
    >
    > signal a,b,c,d:std_logic_vector(17 downto 0);
    > signal out :std_logic_vector(36 downto 0);
    > out <= a*b + c*d;
    >
    > My synthesis tool errors out complaining of mismatched array sizes.
    >
    > A work around I used was this:
    > out <= ('0' & (a*b)) + ('0' & (c*d)) ;
    >
    > Is this the general practice or is there an easier way around?


    First, drop the std_logic_arith packages and use numeric_std. Replace
    your std_logic_vector's with signed's or unsigned's (depending on what
    you need).
    Second, resize your vectors before adding them (almost as you did) :

    out <= resize(a*b, out'length) + resize(a*b, out'length);

    The '+' operator will always return a result the size of its longest
    operand. If you want the carry bit, you need to extend the operand.

    Nicolas
    Nicolas Matringe, Dec 15, 2006
    #4
  5. Andy Guest

    Ditto on numeric_std functions and types, especially since in this
    case, the result is too large for integer subtypes (my preference).

    And, as Robert mentioned, you can do the arithmetic and then resize
    once:

    out <= resize(a * b + c * d, out'length);


    Andy


    Nicolas Matringe wrote:
    > a écrit :
    > > Hi,
    > > I have the following code.
    > >
    > > signal a,b,c,d:std_logic_vector(17 downto 0);
    > > signal out :std_logic_vector(36 downto 0);
    > > out <= a*b + c*d;
    > >
    > > My synthesis tool errors out complaining of mismatched array sizes.
    > >
    > > A work around I used was this:
    > > out <= ('0' & (a*b)) + ('0' & (c*d)) ;
    > >
    > > Is this the general practice or is there an easier way around?

    >
    > First, drop the std_logic_arith packages and use numeric_std. Replace
    > your std_logic_vector's with signed's or unsigned's (depending on what
    > you need).
    > Second, resize your vectors before adding them (almost as you did) :
    >
    > out <= resize(a*b, out'length) + resize(a*b, out'length);
    >
    > The '+' operator will always return a result the size of its longest
    > operand. If you want the carry bit, you need to extend the operand.
    >
    > Nicolas
    Andy, Dec 18, 2006
    #5
  6. Andy a écrit :
    > Ditto on numeric_std functions and types, especially since in this
    > case, the result is too large for integer subtypes (my preference).
    >
    > And, as Robert mentioned, you can do the arithmetic and then resize
    > once:
    >
    > out <= resize(a * b + c * d, out'length);


    I don't have any tool here at home so I can't check but are you sure
    that this will actually output the adder carry on the MSB ? Seems to me
    that this will only sign-extend a truncated (no carry) result.

    Nicolas
    Nicolas Matringe, Dec 18, 2006
    #6
  7. Andy Guest

    oops, you are correct. The arithmeticly correct result requires
    separate resizing of the products.

    I'm too used to using integers, where it just figures it out
    (arithmeticly correct). Too bad we're limited to 32 bit signed integer
    values. And they simulate MUCH faster to boot.

    Andy


    Nicolas Matringe wrote:
    > Andy a écrit :
    > > Ditto on numeric_std functions and types, especially since in this
    > > case, the result is too large for integer subtypes (my preference).
    > >
    > > And, as Robert mentioned, you can do the arithmetic and then resize
    > > once:
    > >
    > > out <= resize(a * b + c * d, out'length);

    >
    > I don't have any tool here at home so I can't check but are you sure
    > that this will actually output the adder carry on the MSB ? Seems to me
    > that this will only sign-extend a truncated (no carry) result.
    >
    > Nicolas
    Andy, Dec 18, 2006
    #7
  8. Rob Dekker Guest

    Nicolas,

    You are right. For some reason, the standard packages (including numeric_std)
    define addition as a N+N=N bit operation. The carry bit get lost by default.

    To preserve the carry bit, you need to extend at least one argument first :

    out <= resize(a * b, out'length) + c * d ;

    For consistency, it might make more sense to concat both arguments.

    out <= resize(a * b, out'length) + resize(c * d,out'length) ;

    So then we are back at Abilash' original proposal, although 'resize' is more versatile
    than pre-pending a '0' because 'resize' will always adjust to the size of the target,
    while prepending will just adjust one bit.

    The 'good' thing is that VHDL forces you to think about the carry bit and if you want to preserve it or not.

    Rob

    "Nicolas Matringe" <> wrote in message news:4586fc27$0$9756$...
    > Andy a écrit :
    >> Ditto on numeric_std functions and types, especially since in this
    >> case, the result is too large for integer subtypes (my preference).
    >>
    >> And, as Robert mentioned, you can do the arithmetic and then resize
    >> once:
    >>
    >> out <= resize(a * b + c * d, out'length);

    >
    > I don't have any tool here at home so I can't check but are you sure that this will actually output the adder carry on the MSB ?
    > Seems to me that this will only sign-extend a truncated (no carry) result.
    >
    > Nicolas
    Rob Dekker, Dec 18, 2006
    #8
  9. Rob Dekker a écrit :
    > Nicolas,
    >
    > You are right. For some reason, the standard packages (including numeric_std)
    > define addition as a N+N=N bit operation. The carry bit get lost by default.
    >
    > To preserve the carry bit, you need to extend at least one argument first :
    >
    > out <= resize(a * b, out'length) + c * d ;
    >
    > For consistency, it might make more sense to concat both arguments.
    >
    > out <= resize(a * b, out'length) + resize(c * d,out'length) ;


    That actually was my previous proposal :eek:)

    Nicolas
    Nicolas Matringe, Dec 19, 2006
    #9
    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. David Harmon
    Replies:
    2
    Views:
    2,899
    cplusplus
    Jun 14, 2006
  2. John Cho
    Replies:
    4
    Views:
    676
    cplusplus
    Jun 14, 2006
  3. Edith Gross
    Replies:
    5
    Views:
    1,108
    Jerry Coffin
    May 1, 2005
  4. Replies:
    3
    Views:
    685
    Shadowman
    Mar 26, 2008
  5. Guest
    Replies:
    0
    Views:
    429
    Guest
    Sep 14, 2005
Loading...

Share This Page