title: Synthesizable multidimensional arrays in VHDL
body: <p>I need to use multidimensional arrays to represent matrices in my design. I have tried the two available options: </p>
  
  <ol>
  <li><p>Declaring array of arrays </p>
  
  <pre><code>type t11 is array (0 to c1_r2) of std_logic_vector(31 downto 0);
  type t1 is array (0 to r1) of t11; --r1*c1_r2 matrix
  </code></pre></li>
  <li><p>Multidimensional arrays. </p>
  
  <pre><code>type matrix  is array (natural range &lt;&gt;, natural range &lt;&gt;)
                 of std_logic_vector(31 downto 0);
  </code></pre></li>
  </ol>
  
  <p>However, in both the cases my post synthesis simulation in xilinx gives me the error "Sliced name is allowed only on single-dimensional arrays". 
  What is the correct way of using multidimensional arrays in synthesizable vhdl design? Any inputs would be welcome.</p>
  
  <p>I am using the XST Synthesizer that comes with Xilinx ISE.
  I am indexing both i and j, as my matrix dimension is m * n * 32.</p>
  
  <p>My net a_in in the entity </p>
  
  <pre><code>    a_in: in  matrix (0 to size - 1, 0 to size - 1);
  </code></pre>
  
  <p>got modified to</p>
  
  <pre><code>    a_in : in STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 );
  </code></pre>
  
  <p>In my program, I access values from the matrix inside two generate statements for k and m as: </p>
  
  <pre><code>    add_instx: add 
              port map (
                  a =&gt; a_in(k,m),
                  b =&gt; b_in(k,m),
                  clk =&gt; clk,
                  sclr =&gt; clr,
                  ce =&gt; start,
                  result =&gt; temp_out(k,m),
                  rdy =&gt; add_over(k,m)
              );
  </code></pre>
  
  <p>My test bench input for a_in is given as</p>
  
  <pre><code>    a_in &lt;= (("00111111100000000000000000000000", "00000000000000000000000000000000"),("00000000000000000000000000000000", "00111111100000000000000000000000"));
  </code></pre>
  
  <p>My synthesis generated warnings of the type: Xst:387 - The KEEP property attached to the net  may hinder timing optimization. You may achieve better results by removing this property. However, I have not set any keep property and I am not sure where to look for this property. Please help! Thanks a lot.</p>
  
  <p>I apologize for not adding the complete code. Please find below the code and package. </p>
  
  <pre><code>    library IEEE;
      use IEEE.STD_LOGIC_1164.ALL;
      use IEEE.NUMERIC_STD.ALL;
      use work.mat_pak.all;
  
  
      entity newproj is
          generic ( size:  natural := 2 );
          port ( 
              clk:                in  std_logic;
              clr:                in  std_logic;
              start:              in  std_logic;
              a_in:               in  matrix (0 to size - 1, 0 to size - 1);
              b_in:               in  matrix (0 to size - 1, 0 to size - 1);
              aplusb:             out matrix (0 to size - 1, 0 to size - 1);
              parallel_add_done:  out std_logic);
      end newproj;
  
      architecture Behavioral of newproj is
      COMPONENT add --This is a 32 bit floating point add IP core
        PORT (
          a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
          b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
          clk : IN STD_LOGIC;
           sclr : IN STD_LOGIC;
           ce : IN STD_LOGIC;
          result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
           rdy: OUT STD_LOGIC
        );
      END COMPONENT;
  
          signal temp_out: matrix (0 to size - 1, 0 to size - 1) :=  (others =&gt; (others =&gt; (others =&gt; '0')));  
          signal add_over: bmatrix (0 to size - 1, 0 to size - 1) := (others =&gt; (others =&gt; '0'));  
  
      begin
  
          g0: 
              for k in  0 to mat_dim generate 
              g0x: 
                  for m in 0 to mat_dim generate
                  add_instx: add 
                      port map (
                          a =&gt; a_in(k,m),
                          b =&gt; b_in(k,m),
                          clk =&gt; clk,
                          sclr =&gt; clr,
                          ce =&gt; start,
                          result =&gt; temp_out(k,m),
                          rdy =&gt; add_over(k,m)
                      );
              end generate;   
          end generate;
  
          aplusb &lt;= temp_out;
  
           p1_add:
          process (add_over)
              variable check_all_done: std_logic;
          begin
              check_all_done := '1';
              for k in 0 to mat_dim loop
                  for m in 0 to mat_dim loop
                      check_all_done := check_all_done and add_over(k)(m);
                  end loop;
              end loop;
              parallel_add_done &lt;= check_all_done;
          end process;
  
      end Behavioral;
  </code></pre>
  
  <p>The package used here is:</p>
  
  <pre><code>    library IEEE;
      use IEEE.STD_LOGIC_1164.all;
      use IEEE.NUMERIC_STD.ALL;
  
  
      package mat_pak is
  
          CONSTANT mat_dim : natural := 2;
  
          type matrix  is array (natural range &lt;&gt;, natural range &lt;&gt;)
                     of std_logic_vector(31 downto 0);
          type bmatrix is array (natural range &lt;&gt;, natural range &lt;&gt;) 
                     of std_logic;                      
  
  
      end mat_pak;
  </code></pre>
  
  <p>The post synthesis simulation model file modified the entity in terms of ordering and data type, on its own. The entity looks as below:</p>
  
  <pre><code>    library IEEE;
      use IEEE.STD_LOGIC_1164.ALL;
      library UNISIM;
      use UNISIM.VCOMPONENTS.ALL;
      use UNISIM.VPKG.ALL;
  
      entity newproj is
        port (
          clk : in STD_LOGIC := 'X'; 
          clr : in STD_LOGIC := 'X'; 
          start : in STD_LOGIC := 'X'; 
          parallel_add_done : out STD_LOGIC; 
          a_in : in STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 ); 
          b_in : in STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 ); 
          aplusb : out STD_LOGIC_VECTOR3 ( 1 downto 0 , 1 downto 0 , 31 downto 0 ) 
        );
      end newproj;
  </code></pre>