--------------------------------------------------------------------------------------------------------------- -- RISA Project -- Author: A.Greensted -- Module: -- Description: -- History: --------------------------------------------------------------------------------------------------------------- -- FPGA Coordinates/Directions -- N,S,E & W denote direction of combinatorial flow. i.e. E is data from left ot right -- Y -- ^ N -- | W E -- | S -- --+------> X -- | library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library ConfigLib; use ConfigLib.ConfigPkg.all; library FPGALib; use FPGALib.FPGAPkg.all; entity FPGA is generic( NUM_COLS : in positive := 6; -- X Dimension NUM_ROWS : in positive := 6); -- Y Dimension port ( clk : in std_logic; nReset : in std_logic; -- Pads (2 in, 2 out per IOBlock) padIn_N : in std_logic_vector((NUM_COLS*2)-1 downto 0); padOut_N : out std_logic_vector((NUM_COLS*2)-1 downto 0); padOutEn_N : out std_logic_vector((NUM_COLS*2)-1 downto 0); padIn_S : in std_logic_vector((NUM_COLS*2)-1 downto 0); padOut_S : out std_logic_vector((NUM_COLS*2)-1 downto 0); padOutEn_S : out std_logic_vector((NUM_COLS*2)-1 downto 0); padIn_E : in std_logic_vector((NUM_ROWS*2)-1 downto 0); padOut_E : out std_logic_vector((NUM_ROWS*2)-1 downto 0); padOutEn_E : out std_logic_vector((NUM_ROWS*2)-1 downto 0); padIn_W : in std_logic_vector((NUM_ROWS*2)-1 downto 0); padOut_W : out std_logic_vector((NUM_ROWS*2)-1 downto 0); padOutEn_W : out std_logic_vector((NUM_ROWS*2)-1 downto 0); -- Global Inputs globalInputs : in std_logic_vector(1 downto 0); -- Snap Connections (1 in, 1out per IOBlock) snapDIn_N : in std_logic_vector(NUM_COLS-1 downto 0); snapDOut_N : out std_logic_vector(NUM_COLS-1 downto 0); snapDIn_S : in std_logic_vector(NUM_COLS-1 downto 0); snapDOut_S : out std_logic_vector(NUM_COLS-1 downto 0); snapDIn_E : in std_logic_vector(NUM_ROWS-1 downto 0); snapDOut_E : out std_logic_vector(NUM_ROWS-1 downto 0); snapDIn_W : in std_logic_vector(NUM_ROWS-1 downto 0); snapDOut_W : out std_logic_vector(NUM_ROWS-1 downto 0); -- Logic Configuration lSelChnDIn : in std_logic; lSelChnDOut : out std_logic; lSelChnShiftEn : in std_logic; lCnfChnDIn : in std_logic; lCnfChnDOut : out std_logic; lCnfChnShiftEn : in std_logic; lCnfChnLoadEn : in std_logic; lCnfChnReadBackEn : in std_logic; -- Routing Configuration rSelChnDIn : in std_logic; rSelChnDOut : out std_logic; rSelChnShiftEn : in std_logic; rCnfChnDIn : in std_logic; rCnfChnDOut : out std_logic; rCnfChnShiftEn : in std_logic; rCnfChnLoadEn : in std_logic; rCnfChnReadBackEn : in std_logic); end FPGA; architecture General of FPGA is subtype X_RANGE is integer range 0 to (NUM_COLS-1); subtype Y_RANGE is integer range 0 to (NUM_ROWS-1); -- Cluster Outputs type CLUSTER_ARRAY_OUTPUTS is array (X_RANGE, Y_RANGE) of FPGATYPE_CLUSTER_OUTPUTS; signal clusterOutputs : CLUSTER_ARRAY_OUTPUTS; -- IOBlock Outputs type IOBLOCK_XARRAY_OUTPUTS is array (X_RANGE) of FPGATYPE_IOBLOCK_OUTPUTS; signal ioBlockOutputs_N : IOBLOCK_XARRAY_OUTPUTS; signal ioBlockOutputs_S : IOBLOCK_XARRAY_OUTPUTS; type IOBLOCK_YARRAY_OUTPUTS is array (Y_RANGE) of FPGATYPE_IOBLOCK_OUTPUTS; signal ioBlockOutputs_E : IOBLOCK_YARRAY_OUTPUTS; signal ioBlockOutputs_W : IOBLOCK_YARRAY_OUTPUTS; -- IO Block Routing Selection & Configuration chains signal rSelChnIO_N : std_logic_vector(0 to NUM_COLS); signal rSelChnIO_S : std_logic_vector(0 to NUM_COLS); signal rSelChnIO_E : std_logic_vector(0 to NUM_ROWS); signal rSelChnIO_W : std_logic_vector(0 to NUM_ROWS); signal rCnfChnIO_N : std_logic_vector(0 to NUM_COLS); signal rCnfChnIO_S : std_logic_vector(0 to NUM_COLS); signal rCnfChnIO_E : std_logic_vector(0 to NUM_ROWS); signal rCnfChnIO_W : std_logic_vector(0 to NUM_ROWS); -- Cluster Routing Configuration & Selection chains type CLUSTER_CNF_CHAIN_ARRAY is array (0 to NUM_COLS, Y_RANGE) of std_logic; signal rSelChnCluster : CLUSTER_CNF_CHAIN_ARRAY; signal rCnfChnCluster : CLUSTER_CNF_CHAIN_ARRAY; -- Cluster Logic Configuration & Selection chains signal lSelChnCluster : CLUSTER_CNF_CHAIN_ARRAY; signal lCnfChnCluster : CLUSTER_CNF_CHAIN_ARRAY; begin -- IO Block Routing Chains ( ->W->N->S->E-> ) rCnfChnIO_N(0) <= rCnfChnIO_W(NUM_ROWS); -- Connect north end of West IO Blocks to west end of North IO Blocks rCnfChnIO_E(0) <= rCnfChnIO_S(NUM_COLS); -- Connect east end of South IO Blocks to south end of East IO Blocks rCnfChnIO_S(0) <= rCnfChnIO_N(NUM_COLS); -- Connect east end of North IO Blocks to west end of South IO Blocks rSelChnIO_N(0) <= rSelChnIO_W(NUM_ROWS); -- Connect north end of West IO Blocks to west end of North IO Blocks rSelChnIO_E(0) <= rSelChnIO_S(NUM_COLS); -- Connect east end of South IO Blocks to south end of East IO Blocks rSelChnIO_S(0) <= rSelChnIO_N(NUM_COLS); -- Connect east end of North IO Blocks to west end of South IO Blocks -- Cluster Logic Chains lSelChnCluster(0,0) <= lSelChnDIn; lCnfChnCluster(0,0) <= lCnfChnDIn; lSelChnDOut <= lSelChnCluster(NUM_COLS, Y_RANGE'high); lCnfChnDOut <= lCnfChnCluster(NUM_COLS, Y_RANGE'high); -- Connect Cluster & IO Block Routing Chains ( Cluster->IOBlock ) rSelChnCluster(0,0) <= rSelChnDIn; -- ChnDIn -> Cluster(southwest) rCnfChnCluster(0,0) <= rCnfChnDIn; rSelChnIO_W(0) <= rSelChnCluster(NUM_COLS, Y_RANGE'high); -- Cluster(northeast) -> IOBlock_W(south) rCnfChnIO_W(0) <= rCnfChnCluster(NUM_COLS, Y_RANGE'high); rSelChnDOut <= rSelChnIO_E(NUM_ROWS); -- IOBLock_E(north) -> ChnDout rCnfChnDOut <= rCnfChnIO_E(NUM_ROWS); -- Instantiate North & South IO Blocks NorthSouthGenerate : for x in X_RANGE generate signal linkCAIn_N : std_logic; signal linkCBIn_N : std_logic; signal linkCCIn_N : std_logic; signal linkCDIn_N : std_logic; signal linkR1In_N : std_logic_vector(1 downto 0); signal linkR2In_N : std_logic; signal linkR4In_N : std_logic; signal shChnIn_N : std_logic; signal cyChnIn_N : std_logic; signal linkCAIn_S : std_logic; signal linkCBIn_S : std_logic; signal linkCCIn_S : std_logic; signal linkCDIn_S : std_logic; signal linkR1In_S : std_logic_vector(1 downto 0); signal linkR2In_S : std_logic; signal linkR4In_S : std_logic; signal shChnIn_S : std_logic; signal cyChnIn_S : std_logic; constant PADA_POS : integer := (x*2); constant PADB_POS : integer := (x*2) + 1; begin -- North Block Input Connections linkCAIn_N <= clusterOutputs(x, Y_RANGE'high ).linkCOut_N; linkCBIn_N <= clusterOutputs(x, Y_RANGE'high-1 ).linkCOut_N; CCN1 : if (x=0) generate linkCCIn_N <= clusterOutputs(x, Y_RANGE'high-2 ).linkCOut_N; end generate; CCN2 : if (x>0) generate linkCCIn_N <= clusterOutputs(x-1, Y_RANGE'high ).linkCOut_N; end generate; CDN1 : if (x=X_RANGE'high) generate linkCDIn_N <= clusterOutputs(x, Y_RANGE'high-2 ).linkCOut_N; end generate; CDN2 : if (x clk, nReset => nReset, -- Pad Connections padAIn => padIn_N(PADA_POS), padAOut => padOut_N(PADA_POS), padAOutEn => padOutEn_N(PADA_POS), padBIn => padIn_N(PADB_POS), padBOut => padOut_N(PADB_POS), padBOutEn => padOutEn_N(PADB_POS), -- Fabirc Connections linkCAIn => linkCAIn_N, linkCBIn => linkCBIn_N, linkCCIn => linkCCIn_N, linkCDIn => linkCDIn_N, linkR1In => linkR1In_N, linkR2In => linkR2In_N, linkR4In => linkR4In_N, linkPAOut => ioBlockOutputs_N(x).linkPAOut, linkPBOut => ioBlockOutputs_N(x).linkPBOut, linkIOOut => ioBlockOutputs_N(x).linkIOOut, -- Chain Connections shChnIn => shChnIn_N, shChnOut => ioBlockOutputs_N(x).shChnOut, cyChnIn => cyChnIn_N, cyChnOut => ioBlockOutputs_N(x).cyChnOut, -- Snap Connections snapDIn => snapDIn_N(x), snapDOut => snapDOut_N(x), -- Routing Selection rSelChnDIn => rSelChnIO_N(x), rSelChnDOut => rSelChnIO_N(x+1), rSelChnShiftEn => rSelChnShiftEn, -- Routing Configuration rCnfChnDIn => rCnfChnIO_N(x), rCnfChnDOut => rCnfChnIO_N(x+1), rCnfChnShiftEn => rCnfChnShiftEn, rCnfChnLoadEn => rCnfChnLoadEn, rCnfChnReadBackEn => rCnfChnReadBackEn); -- South Block Input Connections linkCAIn_S <= clusterOutputs(x, 0).linkCOut_S; linkCBIn_S <= clusterOutputs(x, 1).linkCOut_S; CCS1 : if (x=X_RANGE'high) generate linkCCIn_S <= clusterOutputs(x, 2).linkCOut_S; end generate; CCS2 : if (x0) generate linkCDIn_S <= clusterOutputs(x-1, 0).linkCOut_S; end generate; linkR1In_S(0) <= clusterOutputs(x, 0).linkROut_S(0); linkR1In_S(1) <= clusterOutputs(x, 0).linkROut_S(1); linkR2In_S <= clusterOutputs(x, 1).linkROut_S(0); linkR4In_S <= clusterOutputs(x, 3).linkROut_S(0); cyChnIn_S <= clusterOutputs(x, 0).cyChnOut_W; shChnIn_S <= clusterOutputs(x, 0).shChnOut_E; -- Instantiate South IOBlocks RISAIOBlock_S : IOBlock port map( clk => clk, nReset => nReset, -- Pad Connections padAIn => padIn_S(PADA_POS), padAOut => padOut_S(PADA_POS), padAOutEn => padOutEn_S(PADA_POS), padBIn => padIn_S(PADB_POS), padBOut => padOut_S(PADB_POS), padBOutEn => padOutEn_S(PADB_POS), -- Fabric Connections linkCAIn => linkCAIn_S, linkCBIn => linkCBIn_S, linkCCIn => linkCCIn_S, linkCDIn => linkCDIn_S, linkR1In => linkR1In_S, linkR2In => linkR2In_S, linkR4In => linkR4In_S, linkPAOut => ioBlockOutputs_S(x).linkPAOut, linkPBOut => ioBlockOutputs_S(x).linkPBOut, linkIOOut => ioBlockOutputs_S(x).linkIOOut, -- Chain Connections shChnIn => shChnIn_S, shChnOut => ioBlockOutputs_S(x).shChnOut, cyChnIn => cyChnIn_S, cyChnOut => ioBlockOutputs_S(x).cyChnOut, -- Snap Connections snapDIn => snapDIn_S(x), snapDOut => snapDOut_S(x), -- Routing Selection rSelChnDIn => rSelChnIO_S(x), rSelChnDOut => rSelChnIO_S(x+1), rSelChnShiftEn => rSelChnShiftEn, -- Routing Configuration rCnfChnDIn => rCnfChnIO_S(x), rCnfChnDOut => rCnfChnIO_S(x+1), rCnfChnShiftEn => rCnfChnShiftEn, rCnfChnLoadEn => rCnfChnLoadEn, rCnfChnReadBackEn => rCnfChnReadBackEn); end generate; -- Instantiate East & West IO Blocks EastWestGenerate : for y in Y_RANGE generate signal linkCAIn_E : std_logic; signal linkCBIn_E : std_logic; signal linkCCIn_E : std_logic; signal linkCDIn_E : std_logic; signal linkR1In_E : std_logic_vector(1 downto 0); signal linkR2In_E : std_logic; signal linkR4In_E : std_logic; signal shChnIn_E : std_logic; signal cyChnIn_E : std_logic; signal linkCAIn_W : std_logic; signal linkCBIn_W : std_logic; signal linkCCIn_W : std_logic; signal linkCDIn_W : std_logic; signal linkR1In_W : std_logic_vector(1 downto 0); signal linkR2In_W : std_logic; signal linkR4In_W : std_logic; signal shChnIn_W : std_logic; signal cyChnIn_W : std_logic; constant PADA_POS : integer := (y*2); constant PADB_POS : integer := (y*2) + 1; begin -- East Block Input Connections linkCAIn_E <= clusterOutputs(X_RANGE'high, y ).linkCOut_E; linkCBIn_E <= clusterOutputs(X_RANGE'high-1, y ).linkCOut_E; CCE1 : if (y=Y_RANGE'high) generate linkCCIn_E <= clusterOutputs(X_RANGE'high-2, y ).linkCOut_E; end generate; CCE2 : if (y0) generate linkCDIn_E <= clusterOutputs(X_RANGE'high, y-1).linkCOut_E; end generate; linkR1In_E(0) <= clusterOutputs(X_RANGE'high, y ).linkROut_E(0); linkR1In_E(1) <= clusterOutputs(X_RANGE'high, y ).linkROut_E(1); linkR2In_E <= clusterOutputs(X_RANGE'high-1, y ).linkROut_E(0); linkR4In_E <= clusterOutputs(X_RANGE'high-3, y ).linkROut_E(0); cyChnIn_E <= clusterOutputs(X_RANGE'high, y ).cyChnOut_S; shChnIn_E <= clusterOutputs(X_RANGE'high, y ).shChnOut_N; -- Instantiate East IOBlocks RISAIOBlock_E : IOBlock port map( clk => clk, nReset => nReset, -- Pad Connections padAIn => padIn_E(PADA_POS), padAOut => padOut_E(PADA_POS), padAOutEn => padOutEn_E(PADA_POS), padBIn => padIn_E(PADB_POS), padBOut => padOut_E(PADB_POS), padBOutEn => padOutEn_E(PADB_POS), -- Fabric Connections linkCAIn => linkCAIn_E, linkCBIn => linkCBIn_E, linkCCIn => linkCCIn_E, linkCDIn => linkCDIn_E, linkR1In => linkR1In_E, linkR2In => linkR2In_E, linkR4In => linkR4In_E, linkPAOut => ioBlockOutputs_E(y).linkPAOut, linkPBOut => ioBlockOutputs_E(y).linkPBOut, linkIOOut => ioBlockOutputs_E(y).linkIOOut, -- Chain Connections shChnIn => shChnIn_E, shChnOut => ioBlockOutputs_E(y).shChnOut, cyChnIn => cyChnIn_E, cyChnOut => ioBlockOutputs_E(y).cyChnOut, -- Snap Connections snapDIn => snapDIn_E(y), snapDOut => snapDOut_E(y), -- Routing Selection rSelChnDIn => rSelChnIO_E(y), rSelChnDOut => rSelChnIO_E(y+1), rSelChnShiftEn => rSelChnShiftEn, -- Routing Configuration rCnfChnDIn => rCnfChnIO_E(y), rCnfChnDOut => rCnfChnIO_E(y+1), rCnfChnShiftEn => rCnfChnShiftEn, rCnfChnLoadEn => rCnfChnLoadEn, rCnfChnReadBackEn => rCnfChnReadBackEn); -- West Block Input Connections linkCAIn_W <= clusterOutputs(0, y ).linkCOut_W; linkCBIn_W <= clusterOutputs(1, y ).linkCOut_W; CCW1 : if (y=0) generate linkCCIn_W <= clusterOutputs(2, y ).linkCOut_W; end generate; CCW2 : if (y>0) generate linkCCIn_W <= clusterOutputs(0, y-1).linkCOut_W; end generate; CDW1 : if (y=Y_RANGE'high) generate linkCDIn_W <= clusterOutputs(2, y ).linkCOut_W; end generate; CDW2 : if (y clk, nReset => nReset, -- Pad Connections padAIn => padIn_W(PADA_POS), padAOut => padOut_W(PADA_POS), padAOutEn => padOutEn_W(PADA_POS), padBIn => padIn_W(PADB_POS), padBOut => padOut_W(PADB_POS), padBOutEn => padOutEn_W(PADB_POS), -- Fabric Connections linkCAIn => linkCAIn_W, linkCBIn => linkCBIn_W, linkCCIn => linkCCIn_W, linkCDIn => linkCDIn_W, linkR1In => linkR1In_W, linkR2In => linkR2In_W, linkR4In => linkR4In_W, linkPAOut => ioBlockOutputs_W(y).linkPAOut, linkPBOut => ioBlockOutputs_W(y).linkPBOut, linkIOOut => ioBlockOutputs_W(y).linkIOOut, -- Chain Connections shChnIn => shChnIn_W, shChnOut => ioBlockOutputs_W(y).shChnOut, cyChnIn => cyChnIn_W, cyChnOut => ioBlockOutputs_W(y).cyChnOut, -- Snap Connections snapDIn => snapDIn_W(y), snapDOut => snapDOut_W(y), -- Routing Selection rSelChnDIn => rSelChnIO_W(y), rSelChnDOut => rSelChnIO_W(y+1), rSelChnShiftEn => rSelChnShiftEn, -- Routing Configuration rCnfChnDIn => rCnfChnIO_W(y), rCnfChnDOut => rCnfChnIO_W(y+1), rCnfChnShiftEn => rCnfChnShiftEn, rCnfChnLoadEn => rCnfChnLoadEn, rCnfChnReadBackEn => rCnfChnReadBackEn); end generate; -- Instantiate the Cluster Array -- Array generated from bottom left corner, instantiating along x axis, row by row RowGenerate : for y in Y_RANGE generate begin ColGenerate : for x in X_RANGE generate -- Chains signal shChnIn_N : std_logic; signal cyChnIn_N : std_logic; signal shChnIn_S : std_logic; signal cyChnIn_S : std_logic; signal shChnIn_E : std_logic; signal cyChnIn_E : std_logic; signal shChnIn_W : std_logic; signal cyChnIn_W : std_logic; -- Register Links signal linkR1In_N : std_logic_vector(1 downto 0); signal linkR1_0In_N : std_logic; signal linkR1_1In_N : std_logic; signal linkR2In_N : std_logic_vector(1 downto 0); signal linkR2_0In_N : std_logic; signal linkR2_1In_N : std_logic; signal linkR4In_N : std_logic; signal linkR1In_S : std_logic_vector(1 downto 0); signal linkR1_0In_S : std_logic; signal linkR1_1In_S : std_logic; signal linkR2In_S : std_logic_vector(1 downto 0); signal linkR2_0In_S : std_logic; signal linkR2_1In_S : std_logic; signal linkR4In_S : std_logic; signal linkR1In_E : std_logic_vector(1 downto 0); signal linkR1_0In_E : std_logic; signal linkR1_1In_E : std_logic; signal linkR2In_E : std_logic_vector(1 downto 0); signal linkR2_0In_E : std_logic; signal linkR2_1In_E : std_logic; signal linkR4In_E : std_logic; signal linkR1In_W : std_logic_vector(1 downto 0); signal linkR1_0In_W : std_logic; signal linkR1_1In_W : std_logic; signal linkR2In_W : std_logic_vector(1 downto 0); signal linkR2_0In_W : std_logic; signal linkR2_1In_W : std_logic; signal linkR4In_W : std_logic; -- Combinatorial Links signal linkCAIn_N : std_logic; signal linkCBIn_N : std_logic; signal linkCCIn_N : std_logic; signal linkCDIn_N : std_logic; signal linkCAIn_S : std_logic; signal linkCBIn_S : std_logic; signal linkCCIn_S : std_logic; signal linkCDIn_S : std_logic; signal linkCAIn_E : std_logic; signal linkCBIn_E : std_logic; signal linkCCIn_E : std_logic; signal linkCDIn_E : std_logic; signal linkCAIn_W : std_logic; signal linkCBIn_W : std_logic; signal linkCCIn_W : std_logic; signal linkCDIn_W : std_logic; begin -- North & South Chain Inputs CHNNS1 : if (x=X_RANGE'high) generate cyChnIn_N <= ioBlockOutputs_E(y).cyChnOut; shChnIn_S <= ioBlockOutputs_E(y).shChnOut; end generate; CHNNS2 : if (x0) generate shChnIn_N <= clusterOutputs(x-1,y).shChnOut_N; cyChnIn_S <= clusterOutputs(x-1,y).cyChnOut_S; end generate; -- East & West Chain Inputs CHNEW1 : if (y=Y_RANGE'high) generate shChnIn_E <= ioBlockOutputs_N(x).shChnOut; cyChnIn_W <= ioBlockOutputs_N(x).cyChnOut; end generate; CHNEW2 : if (y0) generate cyChnIn_E <= clusterOutputs(x,y-1).cyChnOut_E; shChnIn_W <= clusterOutputs(x,y-1).shChnOut_W; end generate; -- North Register Inputs (Register signals going north) /\ RN1 : if (y=0) generate linkR1_0In_N <= ioBlockOutputs_S(x).linkPAOut; -- From south (bottom) IOBlock linkR1_1In_N <= ioBlockOutputs_S(x).linkPBOut; -- From south (bottom) IOBlock linkR2_0In_N <= ioBlockOutputs_S(x).linkPAOut; -- From south (bottom) IOBlock linkR2_1In_N <= ioBlockOutputs_S(x).linkPBOut; -- From south (bottom) IOBlock end generate; RN2 : if (y>0) generate linkR1_0In_N <= clusterOutputs(x,y-1).linkROut_N(0); -- From Cluster, 1 below linkR1_1In_N <= clusterOutputs(x,y-1).linkROut_N(1); -- From Cluster, 1 below end generate; RN3 : if (y=1) generate linkR2_0In_N <= ioBlockOutputs_S(x).linkPAOut; -- From south (bottom) IOBlock linkR2_1In_N <= ioBlockOutputs_S(x).linkPBOut; -- From south (bottom) IOBlock end generate; RN4 : if (y>1) generate linkR2_0In_N <= clusterOutputs(x,y-2).linkROut_N(0); -- From Cluster, 2 below linkR2_1In_N <= clusterOutputs(x,y-2).linkROut_N(1); -- From Cluster, 2 below end generate; RN5 : if (y<4) generate linkR4In_N <= ioBlockOutputs_S(x).linkIOOut(4); -- From south (bottom) IOBlock end generate; RN6 : if (y>=4) generate linkR4In_N <= clusterOutputs(x,y-4).linkROut_N(0); -- From Cluster, 4 below end generate; linkR1In_N <= linkR1_1In_N & linkR1_0In_N; linkR2In_N <= linkR2_1In_N & linkR2_0In_N; -- South Register Inputs (Register signals going south) \/ RS1 : if (y=Y_RANGE'high) generate linkR1_0In_S <= ioBlockOutputs_N(x).linkPAOut; -- From north (top) IOBlock linkR1_1In_S <= ioBlockOutputs_N(x).linkPBOut; -- From north (top) IOBlock linkR2_0In_S <= ioBlockOutputs_N(x).linkPAOut; -- From north (top) IOBlock linkR2_1In_S <= ioBlockOutputs_N(x).linkPBOut; -- From north (top) IOBlock end generate; RS2 : if (yY_RANGE'high-4) generate linkR4In_S <= ioBlockOutputs_N(x).linkIOOut(4); -- From north (top) IOBlock end generate; RS6 : if (y<=Y_RANGE'high-4) generate linkR4In_S <= clusterOutputs(x,y+4).linkROut_S(0); -- From Cluster, 4 above end generate; linkR1In_S <= linkR1_1In_S & linkR1_0In_S; linkR2In_S <= linkR2_1In_S & linkR2_0In_S; -- East Register Inputs (Register signals going east) --> RE1 : if (x=0) generate linkR1_0In_E <= ioBlockOutputs_W(y).linkPAOut; -- From west (far left) IOBlock linkR1_1In_E <= ioBlockOutputs_W(y).linkPBOut; -- From west (far left) IOBlock linkR2_0In_E <= ioBlockOutputs_W(y).linkPAOut; -- From west (far left) IOBlock linkR2_1In_E <= ioBlockOutputs_W(y).linkPBOut; -- From west (far left) IOBlock end generate; RE2 : if (x>0) generate linkR1_0In_E <= clusterOutputs(x-1,y).linkROut_E(0); -- From Cluster, 1 to left linkR1_1In_E <= clusterOutputs(x-1,y).linkROut_E(1); -- From Cluster, 1 to left end generate; RE3 : if (x=1) generate linkR2_0In_E <= ioBlockOutputs_W(y).linkPAOut; -- From west (far left) IOBlock linkR2_1In_E <= ioBlockOutputs_W(y).linkPBOut; -- From west (far left) IOBlock end generate; RE4 : if (x>1) generate linkR2_0In_E <= clusterOutputs(x-2,y).linkROut_E(0); -- From Cluster, 2 to left linkR2_1In_E <= clusterOutputs(x-2,y).linkROut_E(1); -- From Cluster, 2 to left end generate; RE5 : if (x<4) generate linkR4In_E <= ioBlockOutputs_W(y).linkIOOut(4); -- From west (far left) IOBlock end generate; RE6 : if (x>=4) generate linkR4In_E <= clusterOutputs(x-4,y).linkROut_E(0); -- From Cluster, 4 to left end generate; linkR1In_E <= linkR1_1In_E & linkR1_0In_E; linkR2In_E <= linkR2_1In_E & linkR2_0In_E; -- West Register Inputs (Register signals going west) <-- RW1 : if (x=X_RANGE'high) generate linkR1_0In_W <= ioBlockOutputs_E(y).linkPAOut; -- From east (far right) IOBlock linkR1_1In_W <= ioBlockOutputs_E(y).linkPBOut; -- From east (far right) IOBlock linkR2_0In_W <= ioBlockOutputs_E(y).linkPAOut; -- From east (far right) IOBlock linkR2_1In_W <= ioBlockOutputs_E(y).linkPBOut; -- From east (far right) IOBlock end generate; RW2 : if (xX_RANGE'high-4) generate linkR4In_W <= ioBlockOutputs_E(y).linkIOOut(4); -- From east (far right) IOBlock end generate; RW6 : if (x<=X_RANGE'high-4) generate linkR4In_W <= clusterOutputs(x+4,y).linkROut_W(0); -- From Cluster, 4 to right end generate; linkR1In_W <= linkR1_1In_W & linkR1_0In_W; linkR2In_W <= linkR2_1In_W & linkR2_0In_W; -- North Combinatorial Inputs (Combinatorial signals going north) /\ CN1 : if (y=0) generate linkCAIn_N <= ioBlockOutputs_S(x).linkIOOut(0); -- From south (bottom) IOBlock (0, CA) linkCBIn_N <= ioBlockOutputs_S(x).linkIOOut(1); -- From south (bottom) IOBlock (1, CB) end generate; CN2 : if (y>0) generate linkCAIn_N <= clusterOutputs(x,y-1).linkCOut_N; -- From Cluster, 1 below end generate; CN3 : if (y=1) generate linkCBIn_N <= ioBlockOutputs_S(x).linkIOOut(0); -- From south (bottom) IOBlock (0, CA) end generate; CN4 : if (y>1) generate linkCBIn_N <= clusterOutputs(x,y-2).linkCOut_N; -- From Cluster, 2 below end generate; CN5 : if (x=0) generate CN5_1 : if (y=0) generate linkCCIn_N <= ioBlockOutputs_S(x).linkIOOut(3); -- From south (bottom) IOBlock (3, CD) end generate; CN5_2 : if (y=1) generate linkCCIn_N <= ioBlockOutputs_S(x).linkIOOut(3); -- From south (bottom) IOBlock (3, CD) end generate; CN5_3 : if (y=2) generate linkCCIn_N <= ioBlockOutputs_S(x).linkIOOut(0); -- From south (bottom) IOBlock (0, CA) end generate; CN5_4 : if (y>2) generate linkCCIn_N <= clusterOutputs(x,y-2).linkCOut_N; -- From Cluster, 2 below end generate; end generate; CN6 : if (x>0) generate CN6_1 : if (y=0) generate linkCCIn_N <= ioBlockOutputs_S(x-1).linkIOOut(2); -- From south (bottom) IOBlock (2, CC) end generate; CN6_2 : if (y>0) generate linkCCIn_N <= clusterOutputs(x-1,y-1).linkCOut_N; -- From Cluster, below left end generate; end generate; CN7 : if (x=X_RANGE'high) generate CN7_1 : if (y=0) generate linkCDIn_N <= ioBlockOutputs_S(x).linkIOOut(2); -- From south (bottom) IOBlock (2, CC) end generate; CN7_2 : if (y=1) generate linkCDIn_N <= ioBlockOutputs_S(x).linkIOOut(2); -- From south (bottom) IOBlock (2, CC) end generate; CN7_3 : if (y=2) generate linkCDIn_N <= ioBlockOutputs_S(x).linkIOOut(0); -- From south (bottom) IOBlock (0, CA) end generate; CN7_4 : if (y>2) generate linkCDIn_N <= clusterOutputs(x,y-2).linkCOut_N; -- From Cluster, 2 below end generate; end generate; CN8 : if (x0) generate linkCDIn_N <= clusterOutputs(x+1,y-1).linkCOut_N; -- From Cluster, below right end generate; end generate; -- South Combinatorial Inputs (Combinatorial signals going south) \/ CS1 : if (y=Y_RANGE'high) generate linkCAIn_S <= ioBlockOutputs_N(x).linkIOOut(0); -- From north (top) IOBlock (0, CA) linkCBIn_S <= ioBlockOutputs_N(x).linkIOOut(1); -- From north (top) IOBlock (1, CB) end generate; CS2 : if (y0) generate CS8_1 : if (y=Y_RANGE'high) generate linkCDIn_S <= ioBlockOutputs_N(x-1).linkIOOut(3); -- From north (top) IOBlock (3, CD) end generate; CS8_2 : if (y CE1 : if (x=0) generate linkCAIn_E <= ioBlockOutputs_W(y).linkIOOut(0); -- From west (left) IOBlock (0, CA) linkCBIn_E <= ioBlockOutputs_W(y).linkIOOut(1); -- From west (left) IOBlock (1, CB) end generate; CE2 : if (x>0) generate linkCAIn_E <= clusterOutputs(x-1,y).linkCOut_E; -- From Cluster, 1 to left end generate; CE3 : if (x=1) generate linkCBIn_E <= ioBlockOutputs_W(y).linkIOOut(0); -- From west (left) IOBlock (0, CA) end generate; CE4 : if (x>1) generate linkCBIn_E <= clusterOutputs(x-2,y).linkCOut_E; -- From Cluster, 2 to left end generate; CE5 : if (y=Y_RANGE'high) generate CE5_1 : if (x=0) generate linkCCIn_E <= ioBlockOutputs_W(y).linkIOOut(3); -- From west (left) IOBlock (3, CD) end generate; CE5_2 : if (x=1) generate linkCCIn_E <= ioBlockOutputs_W(y).linkIOOut(3); -- From west (left) IOBlock (3, CD) end generate; CE5_3 : if (x=2) generate linkCCIn_E <= ioBlockOutputs_W(y).linkIOOut(0); -- From west (left) IOBlock (0, CA) end generate; CE5_4 : if (x>2) generate linkCCIn_E <= clusterOutputs(x-2,y).linkCOut_E; -- From Cluster, 2 to left end generate; end generate; CE6 : if (y0) generate linkCCIn_E <= clusterOutputs(x-1,y+1).linkCOut_E; -- From Cluster, above left end generate; end generate; CE7 : if (y=0) generate CE7_1 : if (x=0) generate linkCDIn_E <= ioBlockOutputs_W(y).linkIOOut(2); -- From west (left) IOBlock (2, CC) end generate; CE7_2 : if (x=1) generate linkCDIn_E <= ioBlockOutputs_W(y).linkIOOut(2); -- From west (left) IOBlock (2, CC) end generate; CE7_3 : if (x=2) generate linkCDIn_E <= ioBlockOutputs_W(y).linkIOOut(0); -- From west (left) IOBlock (0, CA) end generate; CE7_4 : if (x>2) generate linkCDIn_E <= clusterOutputs(x-2,y).linkCOut_E; -- From Cluster, 2 to left end generate; end generate; CE8 : if (y>0) generate CE8_1 : if (x=0) generate linkCDIn_E <= ioBlockOutputs_W(y-1).linkIOOut(3); -- From west (left) IOBlock (3, CD) end generate; CE8_2 : if (x>0) generate linkCDIn_E <= clusterOutputs(x-1,y-1).linkCOut_E; -- From Cluster, below left end generate; end generate; -- West Combinatorial Inputs (Combinatorial signals going west) <-- CW1 : if (x=X_RANGE'high) generate linkCAIn_W <= ioBlockOutputs_E(y).linkIOOut(0); -- From east (right) IOBlock (0, CA) linkCBIn_W <= ioBlockOutputs_E(y).linkIOOut(1); -- From east (right) IOBlock (1, CB) end generate; CW2 : if (x0) generate CW6_1 : if (x=X_RANGE'high) generate linkCCIn_W <= ioBlockOutputs_E(y-1).linkIOOut(2); -- From east (right) IOBlock (2, CC) end generate; CW6_2 : if (x clk, nReset => nReset, -- Chains shChnIn_N => shChnIn_N, shChnOut_N => clusterOutputs(x,y).shChnOut_N, cyChnIn_N => cyChnIn_N, cyChnOut_N => clusterOutputs(x,y).cyChnOut_N, shChnIn_S => shChnIn_S, shChnOut_S => clusterOutputs(x,y).shChnOut_S, cyChnIn_S => cyChnIn_S, cyChnOut_S => clusterOutputs(x,y).cyChnOut_S, shChnIn_E => shChnIn_E, shChnOut_E => clusterOutputs(x,y).shChnOut_E, cyChnIn_E => cyChnIn_E, cyChnOut_E => clusterOutputs(x,y).cyChnOut_E, shChnIn_W => shChnIn_W, shChnOut_W => clusterOutputs(x,y).shChnOut_W, cyChnIn_W => cyChnIn_W, cyChnOut_W => clusterOutputs(x,y).cyChnOut_W, -- Global Links linkGIn => globalInputs, -- Register Links linkR1In_N => linkR1In_N, linkR2In_N => linkR2In_N, linkR4In_N => linkR4In_N, linkROut_N => clusterOutputs(x,y).linkROut_N, linkR1In_S => linkR1In_S, linkR2In_S => linkR2In_S, linkR4In_S => linkR4In_S, linkROut_S => clusterOutputs(x,y).linkROut_S, linkR1In_E => linkR1In_E, linkR2In_E => linkR2In_E, linkR4In_E => linkR4In_E, linkROut_E => clusterOutputs(x,y).linkROut_E, linkR1In_W => linkR1In_W, linkR2In_W => linkR2In_W, linkR4In_W => linkR4In_W, linkROut_W => clusterOutputs(x,y).linkROut_W, -- Combinatorial Links linkCAIn_N => linkCAIn_N, linkCBIn_N => linkCBIn_N, linkCCIn_N => linkCCIn_N, linkCDIn_N => linkCDIn_N, linkCOut_N => clusterOutputs(x,y).linkCOut_N, linkCAIn_S => linkCAIn_S, linkCBIn_S => linkCBIn_S, linkCCIn_S => linkCCIn_S, linkCDIn_S => linkCDIn_S, linkCOut_S => clusterOutputs(x,y).linkCOut_S, linkCAIn_E => linkCAIn_E, linkCBIn_E => linkCBIn_E, linkCCIn_E => linkCCIn_E, linkCDIn_E => linkCDIn_E, linkCOut_E => clusterOutputs(x,y).linkCOut_E, linkCAIn_W => linkCAIn_W, linkCBIn_W => linkCBIn_W, linkCCIn_W => linkCCIn_W, linkCDIn_W => linkCDIn_W, linkCOut_W => clusterOutputs(x,y).linkCOut_W, -- Logic Configuration lSelChnDIn => lSelChnCluster(x,y), lSelChnDOut => lSelChnCluster(x+1,y), lSelChnShiftEn => lSelChnShiftEn, lCnfChnDIn => lCnfChnCluster(x,y), lCnfChnDOut => lCnfChnCluster(x+1,y), lCnfChnShiftEn => lCnfChnShiftEn, lCnfChnLoadEn => lCnfChnLoadEn, lCnfChnReadBackEn => lCnfChnReadBackEn, -- Routing Configuration rSelChnDIn => rSelChnCluster(x,y), rSelChnDOut => rSelChnCluster(x+1,y), rSelChnShiftEn => rSelChnShiftEn, rCnfChnDIn => rCnfChnCluster(x,y), rCnfChnDOut => rCnfChnCluster(x+1,y), rCnfChnShiftEn => rCnfChnShiftEn, rCnfChnLoadEn => rCnfChnLoadEn, rCnfChnReadBackEn => rCnfChnReadBackEn); end generate; -- Connect the row's chain input (at the start of the row) to -- the output of row below's chain (at end of row) ChainConnnect : if (y>0) generate begin lSelChnCluster(0,y) <= lSelChnCluster(NUM_COLS, y-1); lCnfChnCluster(0,y) <= lCnfChnCluster(NUM_COLS, y-1); rSelChnCluster(0,y) <= rSelChnCluster(NUM_COLS, y-1); rCnfChnCluster(0,y) <= rCnfChnCluster(NUM_COLS, y-1); end generate; end generate; end General;