Forum Discussion

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

About multiplexer optimization issue need you help

I saw attached training presentation from ALTERA, it seems 5:1 mux can be absorbed into one LE. I compiled below codes(copy from attached slide), unfortunately, i can't get the same result as the training paper said. why? The result what i got is more than 2 LEs, 3 LEs for Cyclone serials and 2 ALUT for high-end device, such as ArriaGX.

library ieee;use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity mux_5x1 is
   port(
      clk    : in std_logic;
      reset  : in std_logic;
      sclr   : in std_logic;
      sload  : in std_logic;
      ena    : in std_logic;
      sel    : in std_logic;
      dia    : in std_logic;
      dib    : in std_logic;
      dic    : in std_logic;
      do     : out std_logic
   );
end entity;
architecture rtl of mux_5x1 is
--signal sclr: std_logic;
--signal sload: std_logic;
--signal ena: std_logic;
begin
process (clk,reset)
begin
    if reset='1' then
       do <= '0';
    elsif clk'event and clk='1' then
       if ena='1' then
          if sclr='1' then
             do <= '0';
          elsif sload='1' then
             do <= dic;
          else
             if sel='1' then
                do <= dib;
             else
                do <= dia;
             end if;
          end if;
       end if;
    end if; 
end process;
end rtl;

Also, i tried the option "Restructure Multiplexer" in settings->Analysis & Synthesis Settings -> More Settings... This option still hasn't any affection.

3 Replies

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

    Try this low-level primitive implementation:

    library ieee;
    use ieee.std_logic_1164.all;
    entity mux_5x1 is
       port(
          clk    : in std_logic;
          reset  : in std_logic;
          sclr   : in std_logic;
          sload  : in std_logic;
          ena    : in std_logic;
          sel    : in std_logic;
          dia    : in std_logic;
          dib    : in std_logic;
          dic    : in std_logic;
          do     : out std_logic
       );
    end entity;
    architecture rtl of mux_5x1 is
    signal d: std_logic;
    component dffeas
        port (
            d : in std_logic;
            clk : in std_logic;
            ena : in std_logic;
            clrn : in std_logic;
            asdata : in std_logic;
            sclr : in std_logic;
            sload : in std_logic;
            q : out std_logic );
    end component;
    begin
    d <= dib when sel = '1' else dia;
    lc: dffeas 
    port map (
       d => d,
       clk => clk,
       ena => ena,
       clrn => not reset,
       asdata => dic,
       sclr => sclr,
       sload => sload,
       q => do
    );
    end rtl;

    The question is of course, why does the Quartus compiler to use this compact implementation? There are at least two possible answers:

    - many of the signals connected to the DFFEAS primitive are LAB-wide signals, e.g. ena, sload, sclear. They can be only effectively used if more than one LEs is driven by the same signals.

    - It's known that Quartus can't always find an optimal LE implementation, e.g. using the carry chain for non-arithmetical problems. Examples have been discussed at Altera forum before.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It turns out the Quartus is acting intelligent in this case. If you implement 4 or more instances using the same control signals, it packs the complete bit multiplexer in one LE. You can check with this top entity:

    library ieee;
    use ieee.std_logic_1164.all;
    entity mux_5xN is
       
       generic(
          N: integer :=4
       );
       port(
          clk    : in std_logic;
          reset  : in std_logic;
          sclr   : in std_logic;
          sload  : in std_logic;
          ena    : in std_logic;
          sel    : in std_logic;
          dia    : in std_logic_vector(N-1 downto 0);
          dib    : in std_logic_vector(N-1 downto 0);
          dic    : in std_logic_vector(N-1 downto 0);
          do     : out std_logic_vector(N-1 downto 0)
       );
    end entity;
    architecture rtl of mux_5xN is
    component mux_5x1 is
       port(
          clk    : in std_logic;
          reset  : in std_logic;
          sclr   : in std_logic;
          sload  : in std_logic;
          ena    : in std_logic;
          sel    : in std_logic;
          dia    : in std_logic;
          dib    : in std_logic;
          dic    : in std_logic;
          do     : out std_logic
       );
    end component;
    begin
    bits:
    for i in 0 to N-1 generate
    mux: mux_5x1 
    port map (
       clk => clk,
       reset => reset,
       sclr => sclr,
       sload => sload,
       ena => ena,
       sel => sel,
       dia => dia(i), 
       dib => dib(i),
       dic => dic(i),
       do => do(i)
    );
    end generate;
    end rtl;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    It turns out the Quartus is acting intelligent in this case. If you implement 4 or more instances using the same control signals, it packs the complete bit multiplexer in one LE. You can check with this top entity:

    library ieee;
    use ieee.std_logic_1164.all;
    entity mux_5xN is
       
       generic(
          N: integer :=4
       );
       port(
          clk    : in std_logic;
          reset  : in std_logic;
          sclr   : in std_logic;
          sload  : in std_logic;
          ena    : in std_logic;
          sel    : in std_logic;
          dia    : in std_logic_vector(N-1 downto 0);
          dib    : in std_logic_vector(N-1 downto 0);
          dic    : in std_logic_vector(N-1 downto 0);
          do     : out std_logic_vector(N-1 downto 0)
       );
    end entity;
    architecture rtl of mux_5xN is
    component mux_5x1 is
       port(
          clk    : in std_logic;
          reset  : in std_logic;
          sclr   : in std_logic;
          sload  : in std_logic;
          ena    : in std_logic;
          sel    : in std_logic;
          dia    : in std_logic;
          dib    : in std_logic;
          dic    : in std_logic;
          do     : out std_logic
       );
    end component;
    begin
    bits:
    for i in 0 to N-1 generate
    mux: mux_5x1 
    port map (
       clk => clk,
       reset => reset,
       sclr => sclr,
       sload => sload,
       ena => ena,
       sel => sel,
       dia => dia(i), 
       dib => dib(i),
       dic => dic(i),
       do => do(i)
    );
    end generate;
    end rtl;

    --- Quote End ---

    Hi FvM,

    Thank you very much!

    I tried your both examples, they worked as the presentation show. Also, for the second example, i try both your mux_5x1 and my mux_5x1, they are both ok!