Search code examples
vhdl

Slice component allocation for carry multiplexer


I am having a problem with VHDL. I tried to use a counter to implement a very slow timer. Because it is very slow, the counter needs to count to 20,000,000 to overflow. that means this counter will employ a 25-bit counter and compare.

The code is as follows:

    runled_gen : process(resetb, clk0out)
    variable cnt2_temp : std_logic_vector(24 downto 0);
    variable toggle_en2 : std_logic;
begin

    if resetb = '0' then
        pulse_cnt2 <= "0000000000000000000000000";
        pulse_out2 <= '0';

    elsif clk0out = '1' and clk0out'event then
        cnt2_temp := pulse_cnt2 + 1;

        if cnt2_temp >= "1001100010010110100000000" then
            pulse_cnt2 <= "0000000000000000000000000";
            pulse_out2 <= not pulse_out2;

        else
            pulse_cnt2 <= cnt2_temp;
            pulse_out2 <= pulse_out2;
        end if;
    end if;

    runled <= pulse_out2;

end process;

When I try to synthesize and map, the following warning occurs:

WARNING:Pack:249 - The following adjacent carry multiplexers occupy different slice components. The resulting carry chain will have suboptimal timing. U1/U4/Mcompar_pulse_out2_cmp_ge0000_cy<10> U1/U4/Mcount_pulse_cnt2_cy<0>

If i reduce the bit size to 12, the warning disappears. So I guess this is caused by bit size. If my assumptions are correct, the number of comparisons that one MUXCY can process is limited. That's why it happens.

My questions are :

  1. Are my assumptions correct?

  2. Why 12? I mean, shouldn't it be like 8, 16, or 32?

  3. Is my method not correct? How should I implement this function?

Thank you very much!

Fajar


Solution

  • MUXCY is a Xilinx primitive so I assume you are targeting one of their devices. This component is a special hard wired 2-to-1 mux used to create a fast ripple-carry chain for adders. It is set up so that the carries from contiguous bits will flow through neighboring MUXCYs to minimize the propagation time of carries.

    This warning is telling you that a MUXCY path between the ">=" comparator bit-10 has to be routed on the switched fabric before feeding the carry logic for counter bit-0.

    The comparator is essentially a 25-bit subtractor in addition to your 25-bit adder. This results in the creation of a large cloud of combinational logic that prevents the placer from getting the best possible timing. If you still meet timing constraints then you can safely ignore this warning.

    You can break up the combinational path by registering the comparator result into a separate signal first:

    signal gte : std_logic;
    ...
    
    -- One less than original count to account for 1-cycle delay
    if cnt2_temp >= "1001100010010110011111111" then
      gte <= '1';
    else
      gte <= '0';
    end if;
    
    if gte = '1' then
      pulse_cnt2 <= (others => '0');
      pulse_out2 <= not pulse_out2;
    
    else
      pulse_cnt2 <= cnt2_temp;
      pulse_out2 <= pulse_out2;
    end if;
    

    It's worth noting that, in hardware, comparing for equality and inequality are cheaper operations than the other relational comparisons since they don't require the use of a carry chain. If you don't need fault tolerance to handle flipped bits or other erroneous behavior you can replace the ">=" test with "=" to reduce some of the logic and give the placer an easier job.

    Another opportunity for improvement is to break up the carry chain by implementing a prescalar counter that generates a synchronous clock enable for your current counter. For example you could have an 8-bit prescaler enabling a 17-bit counter. This will shorten the longest carry chain in your design and help boost speed.