Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

Getting a comparator out of an ALM in arithmetic mode

So I am trying to get an adder/subtractor/comparator out of an ALM. According to the documentation I've seen, the ALM has a 4-input and 3-input LUT available before each full adder. There are two of these 4LUT+3LUT+adder pairs per ALM, which must use at most up to 8 inputs, with at least 4 shared.

This is the logic I am trying to fit into the ALM:

s_nota <= (others => r_nota);

s_notb <= (others => r_notb);

s_eq <= (others => r_eq);

s_widea(r_rega'left+2) <= '0';

s_wideb(r_rega'left+2) <= '0';

s_widea(r_rega'left+1 downto 1) <= s_nota xor r_rega xor (r_regb and s_eq);

s_wideb(r_rega'left+1 downto 1) <= s_notb xor (r_regb and not s_eq);

s_widea(0) <= '1';

s_wideb(0) <= r_cin;

s_widex <= std_logic_vector(unsigned(s_widea) + unsigned(s_wideb));

Here r_rega and r_regb are the vectors to be added/compared. r_nota, r_notb, r_eq, r_cin are global registers for the whole process.

With a circuit like the above, I get: add, sub, compare less than, compare less than equal, compare equal, etc. just by changing the control lines.

However, quartus refuses to put this into a single adder chain. Instead it splits out the s_widea into another ALM. Why? How can I force it to do what I want? This circuit is on the critical path of my design, and my experiments with the design explorer (cutting r_eq) show an 8% gain in fMAX if quartus would pack it as I intended.

The e_eq and r_not[ab] are 3 shared signals for both halves of the ALM. The r_reg[ab] are 2 bits for each half. So AFAICT it should fit! Am I wrong? Is there an alternative circuit that does fit and achieves the same goal?

Thanks!

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Just for reference, here are the control line settings:

    a+b: r_nota=0, r_notb=0, r_cin=0, r_eq=0

    a-b: r_nota=0, r_notb=1, r_cin=1, r_eq=0

    b-a: r_nota=1, r_notb=0, r_cin=1, r_eq=0

    a=b: r_nota=1, r_notb=0, r_cin=1, r_eq=1

    a!=b: r_nota=0, r_notb=1, r_cin=0, r_eq=1

    a>b: r_nota=0, r_notb=1, r_cin=0, r_eq=0

    a>=b: r_nota=0, r_notb=1, r_cin=1, r_eq=0

    a<b: r_nota=1, r_notb=0, r_cin=0, r_eq=0

    a<=b: r_nota=1, r_notb=0, r_cin=1, r_eq=0