title: Making mp3 decoder VHDL code synthesizable
body: <p>I'm building an MP3 decoder using VHDL and I want to make it synthesizable knowing that for loops of variable size and selecting a variable size from a variable position in <code>std_logic_vector</code> is also not synthesizable</p>
  
  <p>so how do I get a loop to be synthesizable and how to make selecting a variable size from a <code>std_logic_vector</code> synthesizable</p>
  
  <pre><code>for j in 0 to switch_point_1-1 loop
        bits:= data(ptr+current+scale_lengths(j)-1 downto ptr+current);
        scalefac(j)(0) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
        scalefac(j)(1) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
        scalefac(j)(2) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
        current := current+ scale_lengths(j);
      end loop;
  </code></pre>
  
  <p>And another one</p>
  
  <pre><code>for j in switch_point_s-1 to cb_max loop
        for k in 0 to 2 loop
          -- window
        bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);
          scalefac(j)(k) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
          current := current+ scale_lengths(j);
        end loop;
      end loop;
  </code></pre>
  
  <p>This is one of the loops I have and there is a select in it<code>bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);</code> is also not synthesizable how can I make them synthesizable ?</p>
  
  <p>Full code:</p>
  
  <pre><code>    library IEEE;
  use IEEE.std_logic_1164.all;
  use IEEE.std_logic_unsigned.all;
  use ieee.numeric_std.all;
  use std.textio.all;
  use work.txt_util.all;
  --use txt_util.all;
   entity extract_main is
  port(
    data:in std_logic_vector(4095 downto 0);
    en: in std_logic;
  gr,clk:in std_logic;
  enabled:in std_logic;
  scsfi:in std_logic_vector(20 downto 0);
  ptr: in integer;
  windows_switching: in std_logic;
  block_type: in std_logic_vector(1 downto 0);
  mixed_block_flag: in std_logic;
  part2_3_length: in std_logic_vector(11 downto 0);
  slen1,slen2: in integer;
  saved_scalefac_in: in integer;
  saved_scalefac_out: out integer;
  ptr_out: out integer;
  enablenext:out std_logic
  );
  end extract_main;
  
  architecture a of extract_main is
  
    type intarr is array(20 downto 0) of integer;
    type scalef is array(20 downto 0) of intarr;
  
  
  
  begin
  
    process(clk)
      variable scalefac : scalef; 
      variable scale_lengths : intarr;
      variable mainInfoBegin,mainInfoSize : integer;
      variable blockType : integer;
      variable part2_length :integer;
      variable switch_point_1: integer;
      variable switch_point_s: integer;
      variable cb_max : integer;
      variable current: integer:=0; -- iterator on data
      variable it: integer;
      variable bits: std_logic_vector(3 downto 0):="0000";
      variable ptrout: integer;
      begin
        if enabled ='1' then
        --size of main data
        if falling_edge(clk) then
          if en = '1' then
        mainInfoSize := to_integer(UNSIGNED(part2_3_length));
  
        if windows_switching = '0' then
          blockType := 0;
        else
          blockType := to_integer(UNSIGNED(block_type));
        end if;
  
        if blockType = 2 and mixed_block_flag = '1' then
          part2_length := 17 * slen1 + 18 * slen2;
          scale_lengths(16) :=slen2;
          scale_lengths(15) :=slen2;
          scale_lengths(14) :=slen2;
          scale_lengths(13) :=slen2;
          scale_lengths(12) :=slen2;
          scale_lengths(11) :=slen2;
          scale_lengths(10) :=slen1;
          scale_lengths(9) :=slen1;
          scale_lengths(8) :=slen1;
          scale_lengths(7) :=slen1;
          scale_lengths(6) :=slen1;
          scale_lengths(5) :=slen1;
          scale_lengths(4) :=slen1;
          scale_lengths(3) :=slen1;
          scale_lengths(2) :=slen1;
          scale_lengths(1) :=slen1;
          scale_lengths(0) :=slen1;
          cb_max := 16;
          switch_point_1 := 8;
          switch_point_s := 9;
        elsif blockType = 2 and mixed_block_flag = '0' then
          part2_length := 18 * slen1 + 18 * slen2;
           scale_lengths(11) :=slen2;
          scale_lengths(10) :=slen2;
          scale_lengths(9) :=slen2;
          scale_lengths(8) :=slen2;
          scale_lengths(7) :=slen2;
          scale_lengths(6) :=slen2;
          scale_lengths(5) :=slen1;
          scale_lengths(4) :=slen1;
          scale_lengths(3) :=slen1;
          scale_lengths(2) :=slen1;
          scale_lengths(1) :=slen1;
          scale_lengths(0) :=slen1;
          switch_point_1 := 0;
          switch_point_s := 1;
          cb_max := 11;
      else
          part2_length := 11 * slen1 + 10 * slen2;
          --scalefactor_bands(20 downto 11) &lt;= slen2;
          --scalefactor_bands(10 downto 0)&lt;= slen1;
          scale_lengths(20) :=slen2;
          scale_lengths(19) :=slen2;
          scale_lengths(18) :=slen2;
          scale_lengths(17) :=slen2;
          scale_lengths(16) :=slen2;
          scale_lengths(15) :=slen2;
          scale_lengths(14) :=slen2;
          scale_lengths(13) :=slen2;
          scale_lengths(12) :=slen2;
          scale_lengths(11) :=slen2;
          scale_lengths(10) :=slen1;
          scale_lengths(9) :=slen1;
          scale_lengths(8) :=slen1;
          scale_lengths(7) :=slen1;
          scale_lengths(6) :=slen1;
          scale_lengths(5) :=slen1;
          scale_lengths(4) :=slen1;
          scale_lengths(3) :=slen1;
          scale_lengths(2) :=slen1;
          scale_lengths(1) :=slen1;
          scale_lengths(0) :=slen1;
          cb_max := 20;
        end if;
  
  
        if blockType = 2 and windows_switching = '1' then
          for j in 0 to switch_point_1-1 loop
           -- it:=0;
            --for e in ptr+current to ptr+current+scale_lengths(j)-1 loop
             -- bits(it) := ram(e)(0);
              --it := it+1;
            --end loop;
            bits:= data(ptr+current+scale_lengths(j)-1 downto ptr+current);
            scalefac(j)(0) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
            scalefac(j)(1) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
            scalefac(j)(2) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
            current := current+ scale_lengths(j);
          end loop;
          for j in switch_point_s-1 to cb_max loop
            for k in 0 to 2 loop
              -- window
           --   it:=0;
           -- for e in ptr+current to ptr+current+scale_lengths(j)-1 loop
           --   bits(it) := ram(e)(0);
           --   it := it+1;
            --end loop;
            bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);
              scalefac(j)(k) := to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
              current := current+ scale_lengths(j);
            end loop;
          end loop;
        else
          for j in 0 to 20 loop
            if gr ='0' or scsfi(j) ='0' then
             -- it:=0;
             -- for e in ptr+current to ptr+current+scale_lengths(j)-1 loop
             --   bits(it) := ram(e)(0);
              --  it := it+1;
              --end loop;
              bits:=data(ptr+current+scale_lengths(j)-1 downto ptr+current);
              scalefac(j)(0):= to_integer(UNSIGNED(bits(scale_lengths(j)-1 downto 0)));
              current := current+ scale_lengths(j);
            else
              scalefac(j)(0):= saved_scalefac_in;
            end if;
          end loop;
          if gr ='1' then
            if scsfi(0) /= '0' or scsfi(6) /='0' or scsfi(11)/='0' or scsfi(16)/='0' then
              saved_scalefac_out&lt;=scalefac(0)(0);
            end if;
  
          end if;
        end if;
        ptrout:=ptr+current;
        ptr_out&lt;=ptrout;
        enablenext&lt;='1';
      end if;
      end if;
    else enablenext&lt;='0';
      end if;
      end process;
  
  end;
  </code></pre>