FPGARelated.com
Forums

XST vhdl adder with carry out : broken carry chain

Started by Bart De Zwaef July 29, 2004
Hi all, 

I need some help here for implementing an efficient adder with carry
out.
Target : V2Pro 
System : WinXP, ISE 6.2.03 sp3 

I am trying to implement a 16 bit adder with carry out. I use the vhdl
description for this as stated in the XST user guide (see src code
added at the bottom of this post):

q <= ('0'&a) + ('0'&b); 
where a and b are 16 bits, q is 17 bits. 

After PAR I see that the MSB of q (which is the carry out) is not
using the carry chain, but uses local routing. SO : functionally it is
OK, but timing is sub-optimal (about 250MHz in -5 V2Pro).

When I implement a 17 bit adder with carry out (so 1 bit larger) :
carry chain is OK, and we can get better timing (up to 290 MHz).

I also tried the adder from CoreGen but the result is the same. 
Is there anyone who managed to make an adder with carry-out that uses
the carry chain all the way, regardless of the width?

Your help is much appreciated, 
Bart 

---------------------------------------------------------------
--
--  File       tstAdderCy.vhd
--  Author     BADZ
--
--  Target     XC2VP20-5ff896 / XST ISE6.2.03i
--
--  Function : 16 bit adder with carry out
--    

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

-- synopsys translate_off
library unisim;
use unisim.vcomponents.all;
-- synopsys translate_on


entity tstAdderCy is
  port (
  sClk  : in std_logic;
  a      : in std_logic_vector(15 downto 0);
  b      : in std_logic_vector(15 downto 0);
  out1  : out std_logic_vector(16 downto 0)
  );
end tstAdderCy;

architecture arch of tstAdderCy is

signal areg, breg       : std_logic_vector(15 downto 0);
signal areg2, breg2      : std_logic_vector(15 downto 0);
signal tmp1              : std_logic_vector(16 downto 0);

begin

  process(sClk)
  begin
    if rising_edge(sClk) then
      -- tck 1
      areg  <= a;
      breg  <= b;
      -- tck 2
      areg2  <= areg;
      breg2  <= breg;
      -- tck 3
      tmp1  <= ("0"&areg2) + ("0"&breg2);  -- MSB of adder = last
carry out bit, but MAP does NOT use dedicated carry-nets => not OK for
timing
      -- tck4
      out1  <= tmp1;
    end if;
  end process;
end arch;
--------------------------------------------------------------
On 29 Jul 2004 04:20:49 -0700, zeeman_be@yahoo.com (Bart De Zwaef)
wrote:

>Hi all, > >I need some help here for implementing an efficient adder with carry >out. >Target : V2Pro >System : WinXP, ISE 6.2.03 sp3 > >I am trying to implement a 16 bit adder with carry out. I use the vhdl >description for this as stated in the XST user guide (see src code >added at the bottom of this post): > >q <= ('0'&a) + ('0'&b); >where a and b are 16 bits, q is 17 bits. > >After PAR I see that the MSB of q (which is the carry out) is not >using the carry chain, but uses local routing. SO : functionally it is >OK, but timing is sub-optimal (about 250MHz in -5 V2Pro). > >When I implement a 17 bit adder with carry out (so 1 bit larger) : >carry chain is OK, and we can get better timing (up to 290 MHz). > >I also tried the adder from CoreGen but the result is the same. >Is there anyone who managed to make an adder with carry-out that uses >the carry chain all the way, regardless of the width? > >Your help is much appreciated, >Bart
Hi Bart, I have observed exactly the same symptoms, but with another synthesiser (Synplify Pro). I think the problem is with MAP rather than the synthesiser. MAP doesn't seem to handle the last bit in an odd length carry chain well. My solution (as usual) was to create a module that instantiated the unisim components directly (with RLOC attributes), so that I got exactly what I wanted. BTW, this bug has been around for at least three years. At the time, I was having a lot of trouble implementing a 17 and 33 bit adders. I came to the conclusion that Xilinx's test suite probably only has even length adders. Regards, Allan.
Bart, Allan,
I've had this problem with odd length carry chains in adders as well. Adding
two 20 bit numbers gave me a 21 bit result, but the top carry bit went
'bad'. Looking back at my code, I fixed it by adding a dummy signal set to
'0' on the end of the input numbers with the syn_keep attribute, i.e. so it
now gives a 21 bit result from two 21 bit inputs. (I should add I used
Synplify for synthesis.)
cheers, Syms.
"Allan Herriman" <allan.herriman.hates.spam@ctam.com.au.invalid> wrote in
message news:beohg05lpj8mic8tplb4mhdvji0shbge2i@4ax.com...
> On 29 Jul 2004 04:20:49 -0700, zeeman_be@yahoo.com (Bart De Zwaef) > wrote: > > Hi Bart, > > I have observed exactly the same symptoms, but with another > synthesiser (Synplify Pro). I think the problem is with MAP rather > than the synthesiser. MAP doesn't seem to handle the last bit in an > odd length carry chain well. > > My solution (as usual) was to create a module that instantiated the > unisim components directly (with RLOC attributes), so that I got > exactly what I wanted. > > BTW, this bug has been around for at least three years. At the time, > I was having a lot of trouble implementing a 17 and 33 bit adders. I > came to the conclusion that Xilinx's test suite probably only has even > length adders. > > Regards, > Allan.
Actually, what you are describing is a VHDL coding issue, not a MAP
issue.  If you want a 21 bit result from a VHDL add (I don't know
Verilog well enough to say) you have to have at least one 21 bit input. 
VHDL won't assume that you expect a 21 bit result.  

Symon wrote:
> > Bart, Allan, > I've had this problem with odd length carry chains in adders as well. Adding > two 20 bit numbers gave me a 21 bit result, but the top carry bit went > 'bad'. Looking back at my code, I fixed it by adding a dummy signal set to > '0' on the end of the input numbers with the syn_keep attribute, i.e. so it > now gives a 21 bit result from two 21 bit inputs. (I should add I used > Synplify for synthesis.) > cheers, Syms. > "Allan Herriman" <allan.herriman.hates.spam@ctam.com.au.invalid> wrote in > message news:beohg05lpj8mic8tplb4mhdvji0shbge2i@4ax.com... > > On 29 Jul 2004 04:20:49 -0700, zeeman_be@yahoo.com (Bart De Zwaef) > > wrote: > > > > Hi Bart, > > > > I have observed exactly the same symptoms, but with another > > synthesiser (Synplify Pro). I think the problem is with MAP rather > > than the synthesiser. MAP doesn't seem to handle the last bit in an > > odd length carry chain well. > > > > My solution (as usual) was to create a module that instantiated the > > unisim components directly (with RLOC attributes), so that I got > > exactly what I wanted. > > > > BTW, this bug has been around for at least three years. At the time, > > I was having a lot of trouble implementing a 17 and 33 bit adders. I > > came to the conclusion that Xilinx's test suite probably only has even > > length adders. > > > > Regards, > > Allan.
-- Rick "rickman" Collins rick.collins@XYarius.com Ignore the reply address. To email me use the above address with the XY removed. Arius - A Signal Processing Solutions Company Specializing in DSP and FPGA design URL http://www.arius.com 4 King Ave 301-682-7772 Voice Frederick, MD 21701-3110 301-682-7666 FAX
Hi Rick,
This was a while ago, so take this with a pinch of salt, but, thinking back,
when I padded the input vectors with '0' to make everything 21 bits, the
carry went 'bad'. I replaced the '0' with a kept dummy signal set to '0',
which gave 'good' carry!
As I said, that was many beers ago, so I may've recalled incorrectly.
Cheers, Syms.
"rickman" <spamgoeshere4@yahoo.com> wrote in message
news:41093DB5.C924297E@yahoo.com...
> Actually, what you are describing is a VHDL coding issue, not a MAP > issue. If you want a 21 bit result from a VHDL add (I don't know > Verilog well enough to say) you have to have at least one 21 bit input. > VHDL won't assume that you expect a 21 bit result. > > Symon wrote: > > > > Bart, Allan, > > I've had this problem with odd length carry chains in adders as well.
Adding
> > two 20 bit numbers gave me a 21 bit result, but the top carry bit went > > 'bad'. Looking back at my code, I fixed it by adding a dummy signal set
to
> > '0' on the end of the input numbers with the syn_keep attribute, i.e. so
it
> > now gives a 21 bit result from two 21 bit inputs. (I should add I used > > Synplify for synthesis.) > > cheers, Syms.
On Thu, 29 Jul 2004 14:11:01 -0400, rickman <spamgoeshere4@yahoo.com>
wrote:

>Actually, what you are describing is a VHDL coding issue, not a MAP >issue. If you want a 21 bit result from a VHDL add (I don't know >Verilog well enough to say) you have to have at least one 21 bit input. >VHDL won't assume that you expect a 21 bit result.
Rick, it was a timing issue due to poor mapping, rather than a functional issue. Regards, Allan.
Allan Herriman wrote:
> > On Thu, 29 Jul 2004 14:11:01 -0400, rickman <spamgoeshere4@yahoo.com> > wrote: > > >Actually, what you are describing is a VHDL coding issue, not a MAP > >issue. If you want a 21 bit result from a VHDL add (I don't know > >Verilog well enough to say) you have to have at least one 21 bit input. > >VHDL won't assume that you expect a 21 bit result. > > Rick, it was a timing issue due to poor mapping, rather than a > functional issue.
That would be the problem the OP had. But the problem Symon described is a coding issue. But then he replied to my post and I may not have understood what he meant. -- Rick "rickman" Collins rick.collins@XYarius.com Ignore the reply address. To email me use the above address with the XY removed. Arius - A Signal Processing Solutions Company Specializing in DSP and FPGA design URL http://www.arius.com 4 King Ave 301-682-7772 Voice Frederick, MD 21701-3110 301-682-7666 FAX
Yeah, sorry Rick, I should clarify that when I said 'bad' I meant from a
timing point of view, not logic. I find that the tools rarely, if ever, make
logical errors these days. Maybe I'm just lucky? ;-)
cheers, Syms.
"rickman" <spamgoeshere4@yahoo.com> wrote in message
news:41095A10.6B315BF7@yahoo.com...
> > That would be the problem the OP had. But the problem Symon described > is a coding issue. But then he replied to my post and I may not have > understood what he meant.
Thanks for the help guys.

I agree with Symon : it's a timing issue, functionality is 100% ok.
And yes, it only happens when the carry out is the odd bit, not even.
I also believe that the problem is MAP related, not XST (although I
can not prove this).
I tried with the "KEEP" attribute (which is XST equivalent of the
synplify "syn_keep") : unfortunately this does not change anything.
Also USE_CARRY_CHAIN and some other attributes I tried didnt do the
trick.
I was hoping there would be a clean and simple workaround, because I
have a design with some 120 - 140 adders in it, I would hate to give
up on readable code. But right now I would be happy with something
that would work at all.

If I do find some solution I will surely post it here.

Bart.

"Symon" <symon_brewer@hotmail.com> wrote in message news:<2mt4u2FqmqabU1@uni-berlin.de>...
> Yeah, sorry Rick, I should clarify that when I said 'bad' I meant from a > timing point of view, not logic. I find that the tools rarely, if ever, make > logical errors these days. Maybe I'm just lucky? ;-) > cheers, Syms. > "rickman" <spamgoeshere4@yahoo.com> wrote in message > news:41095A10.6B315BF7@yahoo.com... > > > > That would be the problem the OP had. But the problem Symon described > > is a coding issue. But then he replied to my post and I may not have > > understood what he meant.
On 30 Jul 2004 03:17:08 -0700, zeeman_be@yahoo.com (Bart De Zwaef)
wrote:

>Thanks for the help guys. > >I agree with Symon : it's a timing issue, functionality is 100% ok. >And yes, it only happens when the carry out is the odd bit, not even. >I also believe that the problem is MAP related, not XST (although I >can not prove this). >I tried with the "KEEP" attribute (which is XST equivalent of the >synplify "syn_keep") : unfortunately this does not change anything. >Also USE_CARRY_CHAIN and some other attributes I tried didnt do the >trick. >I was hoping there would be a clean and simple workaround, because I >have a design with some 120 - 140 adders in it, I would hate to give >up on readable code. But right now I would be happy with something >that would work at all.
You don't need to change a line of your HDL source. Write a (e.g. Perl) script to read the EDIF and locate the carry chains. From that you can generate a UCF which has an RPM for each carry chain. This will force MAP to do the right thing. Regards, Allan.