--==========================================================
-- Design units : MATRIXstruc
--                (entity, architecture and configuration)
--
-- File name    : MATRIXstruc.vhd
--
-- Purpose      : 2 dim systolic arrary for matrix multiplication
--
-- Limitations  : None
--
-- Library      : WORK
--
-- Dependencies : IEEE,MATRIXpack,multiplier benchmark
--
-- Author       : Hans-Peter Eich, REFT
--
-- Simulator    : Synopsys V3.1a on SUN SPARCstation 10
--
-----------------------------------------------------------
-- Revision list
-- Version Author Date           Changes
--
-- V1.0    hpe    03.04.95       ESA standard and 
--                               one dimensional arrays
-- V2.0    cjt    31.08.95       Completely new description
--=========================================================
-- Though this is a two dimesional circuit, it is necessary
-- to give numbers to the cells in a linear order. So the
-- connecting internal lines can be described in a one dimensional
-- way, which is important for a synthesis with the Synopsys
-- Design Analyzer.
--=========================================================

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE work.MATRIXpack.ALL;

ENTITY MATRIXstruc IS
  GENERIC (M : Positive := 4;  -- bit length of input vector
           N : Positive := 8;  -- bit length of output vector
           E : Positive := 4); -- bandwidth of input matrices
  PORT (StrAIn  : IN  std_logic_vector((E*M)-1 DOWNTO 0); -- stream in matrix A 
        StrBIn  : IN  std_logic_vector((E*M)-1 DOWNTO 0); -- stream in matrix B
        Reset_N : IN  std_logic; -- asynchronuous reset on active low
        clock   : IN  std_logic; -- clock input
        StrCOut : OUT std_logic_vector(((2*E-1)*N)-1 DOWNTO 0)); -- stream out matrix C

END MATRIXstruc;

--============================ARCHITECTURE==================

ARCHITECTURE Structure OF MATRIXstruc IS

SIGNAL temp_A : std_logic_vector((E*E*M)-1 DOWNTO 0);
SIGNAL temp_B : std_logic_vector((E*E*M)-1 DOWNTO 0);
SIGNAL temp_C : std_logic_vector((E*(E-1)*N)-1 DOWNTO 0); 
SIGNAL zero: std_logic_vector(N-1 DOWNTO 0);

BEGIN
  
  init_zero : FOR i IN 0 TO N-1 GENERATE
    zero(i) <= '0';
  END GENERATE; --end index i

  index : FOR i IN 0 TO (E*E)-1 GENERATE

      special_Cases: IF (i=0)
                     OR ((i<(e-1)) AND (i/=0))
                     OR (i=E-1)
                     OR (((i MOD E)=E-1) AND (i/=E*E-1) AND (i/=E-1))
                     OR (((i MOD E)=0) AND (i/=0) AND (i/=E*(E-1)))
                     OR (i=E*(E-1))
                     OR ((i<E*E-1) AND (i>E*(E-1)))
                     OR (i=E*E-1) GENERATE

                     -- 1. matrix element in the upper corner
                     first_case: IF (i=0) GENERATE
 
                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => StrAIn((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => StrBIn((i*M)+M-1 DOWNTO (i*M)),
                                      C_In    => temp_C(i*N+N-1 DOWNTO i*N ),
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => temp_A((i+E)*M+M-1 DOWNTO (i+E)*M),
                                      B_Out   => temp_B((i+1)*M+M-1 DOWNTO (i+1)*M),
                                      C_Out   => StrCOut(E*N-1 DOWNTO (E-1)*N));
     
                     END GENERATE;

                     -- 2. matrix elements on the upper left side except No. 0 and No. (E-1)
                     second_case : IF (i<(e-1)) AND (i/=0) GENERATE
 
                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => StrAIn((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => temp_B((i*M)+M-1 DOWNTO (i*M)),
                                      C_In    => temp_C(i*N+N-1 DOWNTO i*N),
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => temp_A((i+E)*M+M-1 DOWNTO (i+E)*M),
                                      B_Out   => temp_B((i+1)*M+M-1 DOWNTO (i+1)*M),
                                      C_Out   => StrCOut((E+i)*N-1 DOWNTO (E+i-1)*N));
     
                     END GENERATE;

                     -- 3. matrix element on the left corner
                     third_case : IF (i=E-1) GENERATE
 
                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => StrAIn((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => temp_B((i*M)+M-1 DOWNTO (i*M)),
                                      C_In    => zero,
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => temp_A((i+E)*M+M-1 DOWNTO (i+E)*M),
                                      B_Out   => OPEN,
                                      C_Out   => StrCOut((E+i)*N-1 DOWNTO (E+i-1)*N));
     
                     END GENERATE;

                     -- 4. matrix elements on the lower left side except No. (E-1) and No. (E*E-1)
                     fourth_case : IF ((i MOD E)=E-1) AND (i/=E*E-1) AND (i/=E-1) GENERATE

                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => temp_A((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => temp_B((i*M)+M-1 DOWNTO (i*M)),
                                      C_In    => zero,
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => temp_A((i+E)*M+M-1 DOWNTO (i+E)*M),
                                      B_Out   => OPEN,
                                      C_Out   => temp_C((i-E-1)*N+N-1 DOWNTO (i-E-1)*N));
     
                     END GENERATE;

                     -- 5. matrix elements on the upper right side except No. 0 and No. (E*(E-1))
                     fifth_case : IF ((i MOD E)=0) AND (i/=0) AND (i/=E*(E-1)) GENERATE
 
                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => temp_A((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => StrBIn((i/E)*M+M-1 DOWNTO (i/E)*M),
                                      C_In    => temp_C(i*N+N-1 DOWNTO i*N),
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => temp_A((i+E)*M+M-1 DOWNTO (i+E)*M),
                                      B_Out   => temp_B((i+1)*M+M-1 DOWNTO (i+1)*M),
                                      C_Out   => StrCOut((E-(i/E))*N-1 DOWNTO (E-(i/E)-1)*N));
     
                     END GENERATE;

                     -- 6. matrix element on the right corner
                     sixth_case : IF (i=E*(E-1)) GENERATE
 
                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => temp_A((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => StrBIn((i/E)*M+M-1 DOWNTO (i/E)*M),
                                      C_In    => zero,
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => OPEN,
                                      B_Out   => temp_B((i+1)*M+M-1 DOWNTO (i+1)*M),
                                      C_Out   => StrCOut(N-1 DOWNTO 0));
     
                     END GENERATE;

                     -- 7. matrix elements on the lower right side except No. (E*E-1) and No. (E*(E-1))
                     seventh_case : IF (i<E*E-1) AND (i>E*(E-1)) GENERATE
 
                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => temp_A((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => temp_B((i*M)+M-1 DOWNTO (i*M)),
                                      C_In    => zero,
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => OPEN,
                                      B_Out   => temp_B((i+1)*M+M-1 DOWNTO (i+1)*M),
                                      C_Out   => temp_C((i-E-1)*N+N-1 DOWNTO (i-E-1)*N));
     
                     END GENERATE;

                     -- 8. matrix element on the lower corner
                     eighth_case : IF (i=E*E-1) GENERATE
 
                     cell : MATRIXcell
                            GENERIC MAP(M,N)
                            PORT MAP (A_In    => temp_A((i*M)+M-1 DOWNTO (i*M)),
                                      B_In    => temp_B((i*M)+M-1 DOWNTO (i*M)),
                                      C_In    => zero,
                                      Reset_N => Reset_N,
                                      clock   => clock,
                                      A_Out   => OPEN,
                                      B_Out   => OPEN,
                                      C_Out   => temp_C((i-E-1)*N+N-1 DOWNTO (i-E-1)*N));
     
                     END GENERATE;

      END GENERATE;

      other_cases : IF NOT ((i=0)
                           OR ((i<(e-1)) AND (i/=0))
                           OR (i=E-1)
                           OR (((i MOD E)=E-1) AND (i/=E*E-1) AND (i/=E-1))
                           OR (((i MOD E)=0) AND (i/=0) AND (i/=E*(E-1)))
                           OR (i=E*(E-1))
                           OR ((i<E*E-1) AND (i>E*(E-1)))
                           OR (i=E*E-1)) GENERATE  -- all other elements
 
                    cell : MATRIXcell
                           GENERIC MAP(M,N)
                           PORT MAP (A_In    => temp_A((i*M)+M-1 DOWNTO (i*M)),
                                     B_In    => temp_B((i*M)+M-1 DOWNTO (i*M)),
                                     C_In    => temp_C(i*N+N-1 DOWNTO i*N),
                                     Reset_N => Reset_N,
                                     clock   => clock,
                                     A_Out   => temp_A((i+E)*M+M-1 DOWNTO (i+E)*M),
                                     B_Out   => temp_B((i+1)*M+M-1 DOWNTO (i+1)*M),
                                     C_Out   => temp_C((i-E-1)*N+N-1 DOWNTO (i-E-1)*N));
     
      END GENERATE;


  END GENERATE; -- end index i

  
END Structure;

--============================CONFIGURATION=================

CONFIGURATION MATRIXstruc_Config OF MATRIXstruc IS
  FOR Structure
    FOR index
      FOR special_cases
        FOR first_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
        FOR second_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
        FOR third_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
        FOR fourth_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
        FOR fifth_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
        FOR sixth_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
        FOR seventh_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
        FOR eighth_case
          FOR cell : MATRIXcell
            USE ENTITY work.MATRIXcell(Structure);
          END FOR;
        END FOR;
      END FOR;
      FOR other_cases
        FOR cell : MATRIXcell
          USE ENTITY work.MATRIXcell(Structure);
        END FOR;
      END FOR;
    END FOR;
  END FOR;
END MATRIXstruc_Config;

<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>