-- VME interface program for the standard (A24) -- supervisory and non-privileged data access. -- !!! Attention !!! The SiDAQ reads B16 words -- and moves them one by one to the to event -- builder, whose memory is segmented onto B32 -- (long) words. The early B16 word is placed -- into bits 15...0 of this memory and the late -- one - into bits 31...16. To keep the defined -- FTIR bank structure (which is well established -- and seems logical/natural and convenient for -- the offline) i swap the order of every two -- VME addresses. -- The full address = Base Address + Extension -- Read functions: -------------------------------------------- -- FTI_0 raw data: --------------------------- -- Extension = 0002 - T0-2 b.c., diodes 31...16; -- Extension = 0000 - T0-2 b.c., diodes 15...00; -- Extension = 0006 - T0-1 b.c., diodes 31...16; -- Extension = 0004 - T0-1 b.c., diodes 15...00; -- Extension = 000A - T0 b.c., diodes 31...16; -- Extension = 0008 - T0 b.c., diodes 15...00; -- Extension = 000E - T0+1 b.c., diodes 31...16; -- Extension = 000C - T0+1 b.c., diodes 15...00; -- Extension = 0012 - T0+2 b.c., diodes 31...16; -- Extension = 0010 - T0+2 b.c., diodes 15...00; -- FTI_2 raw data: --------------------------- -- Extension = 0016 - T0-2 b.c., PMTs 31...16; -- Extension = 0014 - T0-2 b.c., PMTs 15...00; -- Extension = 001A - T0-1 b.c., PMTs 31...16; -- Extension = 0018 - T0-1 b.c., PMTs 15...00; -- Extension = 001E - T0 b.c., PMTs 31...16; -- Extension = 001C - T0 b.c., PMTs 15...00; -- Extension = 0022 - T0+1 b.c., PMTs 31...16; -- Extension = 0020 - T0+1 b.c., PMTs 15...00; -- Extension = 0026 - T0+2 b.c., PMTs 31...16; -- Extension = 0024 - T0+2 b.c., PMTs 15...00; -------------------------------------------- -- Copyright I.Tsurin, University of Antwerpen, -- on behalf of DESY. -------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.numeric_std.all; -- OK. Here the entity starts... -------------------------------------------- entity VMEinter is port( SysCLK: in std_logic; SEL_ADD: in std_logic_vector(7 downto 0); RXD: in std_logic; TXD: in std_logic; Rdata: in std_logic_vector(7 downto 0); RDstb: in std_logic; Spare: out std_logic_vector(7 downto 0); nSetFER: in std_logic; L2KPul: in std_logic; FERout: out std_logic; VME_ADD: in std_logic_vector(23 downto 1); nLWord: in std_logic; nWrite: in std_logic; VME_DAT: inout std_logic_vector(15 downto 0); DTACK: out std_logic; BError: out std_logic; VME_AM: in std_logic_vector(5 downto 0); nAS: in std_logic; nIACK: in std_logic; nSRes: in std_logic; Direct: out std_logic; nDatEN: out std_logic; nDS0: in std_logic; nDS1: in std_logic; Quartz: in std_logic; LAM0: in std_logic_vector(2 downto 0); LAM1: in std_logic_vector(2 downto 0); FERin: in std_logic_vector(1 downto 0); P18_Ok: in std_logic; P25_Ok: in std_logic; P33_Ok: in std_logic; N50_Ok: in std_logic; P50_Ok: in std_logic ); attribute pinnum: string; attribute pinnum of SysCLK: signal is "7"; attribute pinnum of SEL_ADD: signal is "10,9,8,144,14,13,12,11"; attribute pinnum of RXD: signal is "17"; attribute pinnum of TXD: signal is "18"; attribute pinnum of Rdata: signal is "20,21,22,23,26,27,28,29"; attribute pinnum of RDstb: signal is "19"; attribute pinnum of Spare: signal is "30,31,32,33,36,37,38,39"; attribute pinnum of nSetFER: signal is "41"; attribute pinnum of L2KPul: signal is "42"; attribute pinnum of FERout: signal is "43"; attribute pinnum of VME_ADD: signal is "82,81,80,79,78,73,72,70,69,68,67,65,64,63,62,60,59,51,49,48,47,46,44"; attribute pinnum of nLWord: signal is "54"; attribute pinnum of nWrite: signal is "56"; attribute pinnum of VME_DAT: signal is "83,86,87,88,89,90,91,92,95,96,97,98,99,100,101,102"; attribute pinnum of DTACK: signal is "119"; attribute pinnum of BError: signal is "120"; attribute pinnum of VME_AM: signal is "114,113,112,111,110,109"; attribute pinnum of nAS: signal is "116"; attribute pinnum of nIACK: signal is "117"; attribute pinnum of nSRes: signal is "118"; attribute pinnum of Direct: signal is "121"; attribute pinnum of nDatEN: signal is "122"; attribute pinnum of nDS1: signal is "126"; attribute pinnum of nDS0: signal is "124"; attribute pinnum of Quartz: signal is "125"; attribute pinnum of LAM0: signal is "131,130,128"; attribute pinnum of LAM1: signal is "135,133,132"; attribute pinnum of FERin: signal is "137,136"; attribute pinnum of P18_Ok: signal is "138"; attribute pinnum of P25_Ok: signal is "140"; attribute pinnum of P33_Ok: signal is "141"; attribute pinnum of N50_Ok: signal is "142"; attribute pinnum of P50_Ok: signal is "143"; end; architecture behavior of VMEinter is -- Initialization -------------------------------------------- signal DUM_RES: std_logic; signal RES_PUL: std_logic; signal INI_CNT: natural range 0 to 524287; -------------------------------------------- -- VME variables -------------------------------------------- signal nAS_CNT: natural range 0 to 3; signal nDS_CNT: natural range 0 to 7; signal nAS_BLK: std_logic; signal nDS_BLK: std_logic; signal BAS_SEL: std_logic_vector(7 downto 0); signal BAS_ADR: std_logic; signal VMD_INP: std_logic_vector(15 downto 0); signal VMD_OUT: std_logic_vector(15 downto 0); signal VMA_INP: std_logic_vector(23 downto 1); alias REG_ADR: std_logic_vector(5 downto 1) is VMA_INP(5 downto 1); signal VMM_INP: std_logic_vector(5 downto 0); signal NLN_WRD: std_logic; signal DAT_ACC: std_logic; signal RDY_EXE: std_logic; signal ACTION: std_logic; signal MOD_ACT: std_logic; signal DAT_ACK: std_logic; -------------------------------------------- -- Raw data pipeline -------------------------------------------- signal D43: std_logic_vector(7 downto 0); signal D42: std_logic_vector(7 downto 0); signal D41: std_logic_vector(7 downto 0); signal D40: std_logic_vector(7 downto 0); signal D33: std_logic_vector(7 downto 0); signal D32: std_logic_vector(7 downto 0); signal D31: std_logic_vector(7 downto 0); signal D30: std_logic_vector(7 downto 0); signal D23: std_logic_vector(7 downto 0); signal D22: std_logic_vector(7 downto 0); signal D21: std_logic_vector(7 downto 0); signal D20: std_logic_vector(7 downto 0); signal D13: std_logic_vector(7 downto 0); signal D12: std_logic_vector(7 downto 0); signal D11: std_logic_vector(7 downto 0); signal D10: std_logic_vector(7 downto 0); signal D03: std_logic_vector(7 downto 0); signal D02: std_logic_vector(7 downto 0); signal D01: std_logic_vector(7 downto 0); signal D00: std_logic_vector(7 downto 0); -------------------------- signal P43: std_logic_vector(7 downto 0); signal P42: std_logic_vector(7 downto 0); signal P41: std_logic_vector(7 downto 0); signal P40: std_logic_vector(7 downto 0); signal P33: std_logic_vector(7 downto 0); signal P32: std_logic_vector(7 downto 0); signal P31: std_logic_vector(7 downto 0); signal P30: std_logic_vector(7 downto 0); signal P23: std_logic_vector(7 downto 0); signal P22: std_logic_vector(7 downto 0); signal P21: std_logic_vector(7 downto 0); signal P20: std_logic_vector(7 downto 0); signal P13: std_logic_vector(7 downto 0); signal P12: std_logic_vector(7 downto 0); signal P11: std_logic_vector(7 downto 0); signal P10: std_logic_vector(7 downto 0); signal P03: std_logic_vector(7 downto 0); signal P02: std_logic_vector(7 downto 0); signal P01: std_logic_vector(7 downto 0); signal P00: std_logic_vector(7 downto 0); -------------------------- -- Buffers -------------------------- signal B42: std_logic_vector(7 downto 0); signal B41: std_logic_vector(7 downto 0); signal B40: std_logic_vector(7 downto 0); signal B33: std_logic_vector(7 downto 0); signal B32: std_logic_vector(7 downto 0); signal B31: std_logic_vector(7 downto 0); signal B30: std_logic_vector(7 downto 0); signal B23: std_logic_vector(7 downto 0); signal B22: std_logic_vector(7 downto 0); signal B21: std_logic_vector(7 downto 0); signal B20: std_logic_vector(7 downto 0); signal B13: std_logic_vector(7 downto 0); signal B12: std_logic_vector(7 downto 0); signal B11: std_logic_vector(7 downto 0); signal B10: std_logic_vector(7 downto 0); signal B03: std_logic_vector(7 downto 0); signal B02: std_logic_vector(7 downto 0); signal B01: std_logic_vector(7 downto 0); signal B00: std_logic_vector(7 downto 0); -------------------------- signal R43: std_logic_vector(7 downto 0); signal R412: std_logic_vector(7 downto 0); signal R411: std_logic_vector(7 downto 0); signal R40: std_logic_vector(7 downto 0); signal R33: std_logic_vector(7 downto 0); signal R32: std_logic_vector(7 downto 0); signal R31: std_logic_vector(7 downto 0); signal R30: std_logic_vector(7 downto 0); signal R23: std_logic_vector(7 downto 0); signal R22: std_logic_vector(7 downto 0); signal R21: std_logic_vector(7 downto 0); signal R20: std_logic_vector(7 downto 0); signal R13: std_logic_vector(7 downto 0); signal R12: std_logic_vector(7 downto 0); signal R11: std_logic_vector(7 downto 0); signal R10: std_logic_vector(7 downto 0); signal R03: std_logic_vector(7 downto 0); signal R02: std_logic_vector(7 downto 0); signal R01: std_logic_vector(7 downto 0); signal R00: std_logic_vector(7 downto 0); -------------------------------------------- begin -- Permanent statements -------------------------------------------- DUM_RES <= '0'; ------------------------- BAS_SEL(7) <= not SEL_ADD(7); BAS_SEL(6) <= not SEL_ADD(6); BAS_SEL(5) <= not SEL_ADD(5); BAS_SEL(4) <= not SEL_ADD(4); BAS_SEL(3) <= not SEL_ADD(3); BAS_SEL(2) <= not SEL_ADD(2); BAS_SEL(1) <= not SEL_ADD(1); BAS_SEL(0) <= not SEL_ADD(0); ------------------------- FERout <= '0'; Spare <= (others => '1'); -------------------------------------------- -- Start-up counter -------------------------------------------- process(DUM_RES, SysCLK, RES_PUL) begin if (DUM_RES = '1') then INI_CNT <= 0; elsif (SysCLK'event and SysCLK = '1') then if (RES_PUL = '1') then INI_CNT <= INI_CNT + 1; else null; end if; end if; end process; -------------------------------------------- -- Start-up reset pulse (SysCLK <-) -------------------------------------------- process(DUM_RES, SysCLK, INI_CNT) begin if (DUM_RES = '1') then RES_PUL <= '1'; elsif (SysCLK'event and SysCLK = '0') then if (INI_CNT = 524287) then RES_PUL <= '0'; else RES_PUL <= '1'; end if; end if; end process; -------------------------------------------- -- Bidirectional port for the VME interface: -------------------------------------------- process(nWrite, VMD_OUT) begin if (nWrite = '0') then VME_DAT <= (others => 'Z'); else VME_DAT <= VMD_OUT; end if; end process; -------------------------- VMD_INP <= VME_DAT; -------------------------------------------- -- Address strobe timer -------------------------------------------- process(RES_PUL, nAS, SysCLK, nAS_BLK) begin if (RES_PUL = '1' or nAS = '1') then nAS_CNT <= 0; elsif (SysCLK'event and SysCLK = '1') then if (nAS_BLK = '0') then nAS_CNT <= nAS_CNT + 1; else null; end if; end if; end process; -------------------------- process(nAS, SysCLK, nAS_CNT) begin if (nAS = '1') then nAS_BLK <= '0'; elsif (SysCLK'event and SysCLK = '0') then if (nAS_CNT = 3) then nAS_BLK <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Latching the input address and modifier -------------------------------------------- process(nAS, SysCLK, nAS_CNT, nLWord, VME_ADD, VME_AM) begin if (nAS = '1') then NLN_WRD <= '1'; VMA_INP <= (others => '0'); VMM_INP <= (others => '0'); elsif (SysCLK'event and SysCLK = '0') then if (nAS_CNT = 2) then NLN_WRD <= nLWord; VMA_INP <= VME_ADD; VMM_INP <= VME_AM; else null; end if; end if; end process; -------------------------------------------- -- Check for the base address matching -------------------------------------------- process(VMA_INP, BAS_SEL) begin if (VMA_INP(23 downto 16) = BAS_SEL(7 downto 0)) then BAS_ADR <= '1'; else BAS_ADR <= '0'; end if; end process; -------------------------------------------- -- Data access regime (SysCLK <-) -------------------------------------------- process(VMM_INP) begin case VMM_INP is when "111101" => DAT_ACC <= '1'; when "111001" => DAT_ACC <= '1'; when others => DAT_ACC <= '0'; end case; end process; -------------------------------------------- -- Operation decoding (SysCLK <-) -------------------------------------------- process(VMA_INP) begin if ("000000000000000" <= VMA_INP(15 downto 1) and VMA_INP(15 downto 1) <= "000000000010011") then RDY_EXE <= '1'; else RDY_EXE <= '0'; end if; end process; -------------------------------------------- -- VME module activation (SysCLK <-) -------------------------------------------- ACTION <= NLN_WRD and RDY_EXE and DAT_ACC; MOD_ACT <= BAS_ADR and ACTION and nIACK; -------------------------------------------- -- Enable data operation (SysCLK <-) -------------------------------------------- process(MOD_ACT, nDS0) begin if (MOD_ACT = '1' and nDS0 = '0') then nDatEN <= '0'; else nDatEN <= '1'; end if; end process; -------------------------------------------- -- VME data flow direction -------------------------------------------- process(nWrite) begin if (nWrite = '0') then Direct <= '0'; else Direct <= '1'; end if; end process; -------------------------------------------- -- Data strobe timer -------------------------------------------- process(RDstb, nDS0, SysCLK, nDS_BLK) begin if (RDstb = '1' or nDS0 = '1') then nDS_CNT <= 0; elsif (SysCLK'event and SysCLK = '0') then if (nDS_BLK = '0') then nDS_CNT <= nDS_CNT + 1; else null; end if; end if; end process; -------------------------- process(nDS0, SysCLK, nDS_CNT) begin if (nDS0 = '1') then nDS_BLK <= '0'; elsif (SysCLK'event and SysCLK = '1') then if (nDS_CNT = 5) then nDS_BLK <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Forming the output data -------------------------------------------- process(REG_ADR, D03, D02, D01, D00, D13, D12, D11, D10, D23, D22, D21, D20, D33, D32, D31, D30, D43, D42, D41, D40, P03, P02, P01, P00, P13, P12, P11, P10, P23, P22, P21, P20, P33, P32, P31, P30, P43, P42, P41, P40) begin case REG_ADR is when "00001" => VMD_OUT(15 downto 8) <= D03(7 downto 0); VMD_OUT(7 downto 0) <= D02(7 downto 0); when "00000" => VMD_OUT(15 downto 8) <= D01(7 downto 0); VMD_OUT(7 downto 0) <= D00(7 downto 0); when "00011" => VMD_OUT(15 downto 8) <= D13(7 downto 0); VMD_OUT(7 downto 0) <= D12(7 downto 0); when "00010" => VMD_OUT(15 downto 8) <= D11(7 downto 0); VMD_OUT(7 downto 0) <= D10(7 downto 0); when "00101" => VMD_OUT(15 downto 8) <= D23(7 downto 0); VMD_OUT(7 downto 0) <= D22(7 downto 0); when "00100" => VMD_OUT(15 downto 8) <= D21(7 downto 0); VMD_OUT(7 downto 0) <= D20(7 downto 0); when "00111" => VMD_OUT(15 downto 8) <= D33(7 downto 0); VMD_OUT(7 downto 0) <= D32(7 downto 0); when "00110" => VMD_OUT(15 downto 8) <= D31(7 downto 0); VMD_OUT(7 downto 0) <= D30(7 downto 0); when "01001" => VMD_OUT(15 downto 8) <= D43(7 downto 0); VMD_OUT(7 downto 0) <= D42(7 downto 0); when "01000" => VMD_OUT(15 downto 8) <= D41(7 downto 0); VMD_OUT(7 downto 0) <= D40(7 downto 0); when "01011" => VMD_OUT(15 downto 8) <= P03(7 downto 0); VMD_OUT(7 downto 0) <= P02(7 downto 0); when "01010" => VMD_OUT(15 downto 8) <= P01(7 downto 0); VMD_OUT(7 downto 0) <= P00(7 downto 0); when "01101" => VMD_OUT(15 downto 8) <= P13(7 downto 0); VMD_OUT(7 downto 0) <= P12(7 downto 0); when "01100" => VMD_OUT(15 downto 8) <= P11(7 downto 0); VMD_OUT(7 downto 0) <= P10(7 downto 0); when "01111" => VMD_OUT(15 downto 8) <= P23(7 downto 0); VMD_OUT(7 downto 0) <= P22(7 downto 0); when "01110" => VMD_OUT(15 downto 8) <= P21(7 downto 0); VMD_OUT(7 downto 0) <= P20(7 downto 0); when "10001" => VMD_OUT(15 downto 8) <= P33(7 downto 0); VMD_OUT(7 downto 0) <= P32(7 downto 0); when "10000" => VMD_OUT(15 downto 8) <= P31(7 downto 0); VMD_OUT(7 downto 0) <= P30(7 downto 0); when "10011" => VMD_OUT(15 downto 8) <= P43(7 downto 0); VMD_OUT(7 downto 0) <= P42(7 downto 0); when "10010" => VMD_OUT(15 downto 8) <= P41(7 downto 0); VMD_OUT(7 downto 0) <= P40(7 downto 0); when others => VMD_OUT <= (others => '0'); end case; end process; -------------------------------------------- -- Data acknowledge response (SysCLK ->) -------------------------------------------- process(nDS0, SysCLK, nDS_CNT, MOD_ACT) begin if (nDS0 = '1') then DAT_ACK <= '0'; elsif (SysCLK'event and SysCLK = '1') then if (nDS_CNT = 4 and MOD_ACT = '1') then DAT_ACK <= '1'; else null; end if; end if; end process; -------------------------- DTACK <= DAT_ACK; -------------------------------------------- -- Bus error response (SysCLK ->) -------------------------------------------- process(nDS0, SysCLK, nDS_CNT, BAS_ADR, ACTION) begin if (nDS0 = '1') then BError <= '0'; elsif (SysCLK'event and SysCLK = '1') then if (nDS_CNT = 3 and BAS_ADR = '1' and ACTION = '0') then BError <= '1'; else null; end if; end if; end process; -------------------------------------------- -- Buffering the raw data -------------------------------------------- process(RDstb, D42, D41, D40, D33, D32, D31, D30, D23, D22, D21, D20, D13, D12, D11, D10, D03, D02, D01, D00, P43, P42, P41, P40, P33, P32, P31, P30, P23, P22, P21, P20, P13, P12, P11, P10, P03, P02, P01, P00) begin if (RDstb'event and RDstb = '0') then B42 <= D42; B41 <= D41; B40 <= D40; B33 <= D33; B32 <= D32; B31 <= D31; B30 <= D30; B23 <= D23; B22 <= D22; B21 <= D21; B20 <= D20; B13 <= D13; B12 <= D12; B11 <= D11; B10 <= D10; B03 <= D03; B02 <= D02; B01 <= D01; B00 <= D00; -------------------------- R43 <= P43; R42 <= P42; R41 <= P41; R40 <= P40; R33 <= P33; R32 <= P32; R31 <= P31; R30 <= P30; R23 <= P23; R22 <= P22; R21 <= P21; R20 <= P20; R13 <= P13; R12 <= P12; R11 <= P11; R10 <= P10; R03 <= P03; R02 <= P02; R01 <= P01; R00 <= P00; end if; end process; -------------------------------------------- -- Pipelining the raw data -------------------------------------------- process(RDstb, B42, B41, B40, B33, B32, B31, B30, B23, B22, B21, B20, B13, B12, B11, B10, B03, B02, B01, B00, R43, R42, R41, R40, R33, R32, R31, R300, R23, R22, R21, R20, R13, R12, R11, R10, R03, R02, R01, R00, Rdata) begin if (RDstb'event and RDstb = '1') then D43 <= B42; D42 <= B41; D41 <= B40; D40 <= B33; D33 <= B32; D32 <= B31; D31 <= B30; D30 <= B23; D23 <= B22; D22 <= B21; D21 <= B20; D20 <= B13; D13 <= B12; D12 <= B11; D11 <= B10; D10 <= B03; D03 <= B02; D02 <= B01; D01 <= B00; D00 <= R43; -------------------------- P43 <= R42; P42 <= R41; P41 <= R40; P40 <= R33; P33 <= R32; P32 <= R31; P31 <= R30; P30 <= R23; P23 <= R22; P22 <= R21; P21 <= R20; P20 <= R23; P13 <= R12; P12 <= R11; P11 <= R10; P10 <= R03; P03 <= R02; P02 <= R01; P01 <= R00; P00 <= Rdata; end if; end process; -------------------------------------------- end;