title: VHDL dynamic range selection synthesizable code
body: <p>Working on a complex range selection logic.</p>
  
  <p>There are too many combinations as select signals and too many ranges to choose and concatenate.</p>
  
  <p>I am looking for a better way to make it readable, with meaningful variables which generated from pre-defined constants and dynamic inputs.</p>
  
  <p>A simplified example as followings, not sure if it is synthesizable or not.</p>
  
  <pre><code>library ieee;
  use ieee.std_logic_1164.all;
  
  entity fum is
  end entity;
  
  architecture foo of fum is
      signal sel:             std_logic_vector (1 downto 0);
      signal selected_range:  std_logic_vector (5 downto 0);
      signal counter:         std_logic_vector (7 downto 0);
  
      constant BASE_ADDR_LOW: integer := 2;
      constant RANGE1_BITS  : integer := 2;
      -- this is simplified
      -- dozens of constants involved, and their values can be configured before compiling.
  begin
  
  some_process:
      process (sel, counter)
      variable range0_high : integer := BASE_ADDR_LOW;
      variable range1_low  : integer := 0;
      variable range1_high : integer := 0;
      begin
  
      if (sel = "00") then
      -- this is simpilfied as well
      -- dozens of inputs as sel involved, for 50+ combinations via nested if and case
          range0_high := BASE_ADDR_LOW+1; -- 3
          range1_low  := range0_high+2;   -- 5
          range1_high := range1_low+RANGE1_BITS-1; -- 6
  
      -- the following elsif will not work as the range1 has 0 bit.
      -- not sure if there is a better way to do this
  
      -- elsif (sel = "01" ) then
      --  range0_high := BASE_ADDR_LOW+1; -- 5
      --  range1_low  := range0_high+2;   -- N/A
      --  range1_high := range1_low+RANGE1_BITS;  --N/A
      else
          range0_high := BASE_ADDR_LOW;   -- 2
          range1_low  := range0_high+2;   -- 4
          range1_high := range1_low+RANGE1_BITS; --6
      end if;
  
      -- using variables in range
      selected_ranges &lt;= counter(range1_high downto range1_low) &amp; counter(range0_high downto 0);
  
      end process;
  end architecture;
  </code></pre>
  
  <p>and is there any way to make a synthesizable code if some fields could be 0 bit?</p>
  
  <pre><code>-- e.g. range0_high = 5, range1_* not in use
  -- selected_ranges &lt;= *nothing &amp;* counter(5 downto 0);
  </code></pre>