-- Serial interface to the front-end via the VME -- dataway for the standard (A24) supervisory and -- non-privileged data access. No block transfer -- as it requiers long data frames - unsafe in -- the radiation field. -- The full address = Base Address + Extension. -- channel mapping: -------------------------------------------- -- Extension = 0000...00FE - Front-end card 0; -- Extension = 0100...01FE - Front-end card 1; -- Extension = 0200...02FE - Front-end card 2; -- Extension = 0300...03FE - Front-end card 3; -- Extension = 0400...04FE - Front-end card 4; -- Extension = 0500...05FE - Front-end card 5; -- Extension = 0600...06FE - Trigger card; -------------------------------------------- -- Control registers -- (xx = 00...05): -------------------------- -- Extension = xxAA activate default settings; -- Extension = xxAC define a sequence of commands; -- Monitors -- (xx = 00...05): -------------------------- -- Extension = xx02 supply watchdogs (read only); -- Extension = xx04 r/o chip load status (read only); -- Readout steering -- (xx = 00...05): -------------------------- -- Extension = xxB4 - select the readout time -- slice in the pipeline; -- Thresholds (xx = 00...05): -------------------------- -- Extension = xx06 threshold 00; -- Extension = xx08 threshold 01; -- Extension = xx0A threshold 02; -- Extension = xx0C threshold 03; -- Extension = xx0E threshold 10; -- Extension = xx10 threshold 11; -- Extension = xx12 threshold 12; -- Extension = xx14 threshold 13; -- PRO/A settings -- (xx = 00...05): -------------------------- -- Extension = xx18 test enable pad 03; -- Extension = xx1A test enable pad 02; -- Extension = xx1C test enable pad 01; -- Extension = xx1E test enable pad 00; -- Extension = xx20 test enable pad 23; -- Extension = xx22 test enable pad 22; -- Extension = xx24 test enable pad 21; -- Extension = xx26 test enable pad 20; -- Extension = xx28 test enable pad 43; -- Extension = xx2A test enable pad 42; -- Extension = xx2C test enable pad 41; -- Extension = xx2E test enable pad 40; -- Extension = xx30 test enable pad 63; -- Extension = xx32 test enable pad 62; -- Extension = xx34 test enable pad 61; -- Extension = xx36 test enable pad 60; -- Extension = xx38 test enable pad 70; -- Extension = xx3A test enable pad 71; -- Extension = xx3C test enable pad 72; -- Extension = xx3E test enable pad 73; -- Extension = xx40 test enable pad 50; -- Extension = xx42 test enable pad 51; -- Extension = xx44 test enable pad 52; -- Extension = xx46 test enable pad 53; -- Extension = xx48 test enable pad 30; -- Extension = xx4A test enable pad 31; -- Extension = xx4C test enable pad 32; -- Extension = xx4E test enable pad 33; -- Extension = xx50 test enable pad 10; -- Extension = xx52 test enable pad 11; -- Extension = xx54 test enable pad 12; -- Extension = xx56 test enable pad 13; -- Extension = xx58 output disable pad 03; -- Extension = xx5A output disable pad 02; -- Extension = xx5C output disable pad 01; -- Extension = xx5E output disable pad 00; -- Extension = xx60 output disable pad 23; -- Extension = xx62 output disable pad 22; -- Extension = xx64 output disable pad 21; -- Extension = xx66 output disable pad 20; -- Extension = xx68 output disable pad 43; -- Extension = xx6A output disable pad 42; -- Extension = xx6C output disable pad 41; -- Extension = xx6E output disable pad 40; -- Extension = xx70 output disable pad 63; -- Extension = xx72 output disable pad 62; -- Extension = xx74 output disable pad 61; -- Extension = xx76 output disable pad 60; -- Extension = xx78 output disable pad 70; -- Extension = xx7A output disable pad 71; -- Extension = xx7C output disable pad 72; -- Extension = xx7E output disable pad 73; -- Extension = xx80 output disable pad 50; -- Extension = xx82 output disable pad 51; -- Extension = xx84 output disable pad 52; -- Extension = xx86 output disable pad 53; -- Extension = xx88 output disable pad 30; -- Extension = xx8A output disable pad 31; -- Extension = xx8C output disable pad 32; -- Extension = xx8E output disable pad 33; -- Extension = xx90 output disable pad 10; -- Extension = xx92 output disable pad 11; -- Extension = xx94 output disable pad 12; -- Extension = xx96 output disable pad 13; -- Extension = xx98 enable calibration mode; -- Extension = xx9A enable current compensation; -- Extension = xx9C gain selection bit_0; -- Extension = xx9E gain selection bit_1; -- Extension = xxA0 enable analog output; -- Extension = xxA2 enable individual mode; -- Extension = xxA4 negative signal; -- Extension = xxA6 time-over-threshold; -- Data format: -------------------------------------------- -- Control register xxAA -------------------------- Any data with a write permission; -- Control register xxAC -------------------------- -- Data = 0000 0000 0000 0BBB (binary) -- B_0 - reset PRO/A power; -- B_1 - load PRO/A; -- B_2 - read PRO/A; -- Power supply watchdogs -------------------------- -- Data = 0000 0000 PPPP PPPP (binary) -- P_7 - +5.0 V. serial interface buffer; -- P_6 - +3.3 V. ACEX / APEX shell and comparators; -- P_5 - +2.5 V. ACEX core; -- P_4 - +1.8 V. APEX core; -- P_3 - -2.0 V. PRO/A digital; -- P_2 - +2.0 V. PRO/A digital; -- P_1 - -2.0 V. PRO/A analog; -- P_0 - +2.0 V. PRO/A analog; -- PRO/A settings and load status -------------------------- -- Data = 0000 0000 CCCC CCCC (binary) -- C_7 - Pro/A 13 = Sector 1, Plane 3; -- C_6 - Pro/A 12 = Sector 1, Plane 2; -- C_5 - Pro/A 11 = Sector 1, Plane 1; -- C_4 - Pro/A 10 = Sector 1, Plane 0; -- C_3 - Pro/A 03 = Sector 0, Plane 3; -- C_2 - Pro/A 02 = Sector 0, Plane 2; -- C_1 - Pro/A 01 = Sector 0, Plane 1; -- C_0 - Pro/A 00 = Sector 0, Plane 0; -- Trigger card functions: -------------------------------------------- -- Extension = 06A0 topological pipeline depth; -- Extension = 06A2 2x front-end cable delay; -- Extension = 06A4 Clock phase adjustment; -- Extension = 06A6 Trigger mask for sectors 0...5; -- Extension = 06A8 Trigger mask for sectors 10...15; -- Extension = 06AA Rad. mon. mask for sect. 0...5; -- Extension = 06AC Rad. mon. mask for sect. 10...55; -- Extension = 06AE Pedestal subtracted from radiation -- monitor rate 0...255 kHz (1 kHz / bit); -- Extension = 06B0 Bit_0 = '1' stucks the rad. monitor rate; -- Extension = 06B2 Radiation level 0...5 MHz (16 kHz / bit); -- Topological pipeline depth -------------------------- -- Data = 0000 0000 000D EPTH (binary) -- DEPTH - encoded T0 time slice (0...31), -- 1 bunch crossing / unit, -- default value - 20 b.c.; -- Front-end cable delay -------------------------- -- Data = 0000 0000 02XD ELAY (binary) -- 2XDELAY - encoded delay (0...127), -- 1 bunch crossing / unit, -- default value - 5 b.c.; -- Clock phase -------------------------- -- Data = 0000 0000 0000 FASE (binary) -- FASE - encoded delay (0...15), 10 ns / unit -- default value - 0 ns; -- Masks of the trigger card -------------------------- -- Data = 0000 0000 00MM MMMM (binary) -- M_i - Front-end sector 'i' = 0...5 (10...15); -- Radiation monitor pedestal -------------------------- -- Data = 0000 0000 PEDE STAL (binary) -- PEDESRAL - encoded pedestal 1 kHz / unit -------------------------------------------- -- Radiation monitor level -------------------------- -- Data = 0000 0000 RADL EVEL (binary) -- RADLEVEL - encoded pedestal 16 kHz Hz / unit -------------------------------------------- -- Data frame format (inversed logics) -- for the serial interface: -------------------------------------------- -- Bit_17 - wake up = 0 (active); -- Bit_16 - write flag = 0 (active); -- -- Bit_15 - address Bit_6; -- Bit_14 - address Bit_5; -- Bit_13 - address Bit_4; -- Bit_12 - address Bit_3; -- Bit_11 - address Bit_2; -- Bit_10 - address Bit_1; -- Bit_9 - address Bit_0; -- -- Bit_8 - data Bit_7; -- Bit_7 - data Bit_6; -- Bit_6 - data Bit_5; -- Bit_5 - data Bit_4; -- Bit_4 - data Bit_3; -- Bit_3 - data Bit_2; -- Bit_2 - data Bit_1; -- Bit_1 - data Bit_0; -- -- Bit_0 - end of frame = 1 (passive); -------------------------------------------- -- Data acknowledge delay = 18 bit * 1.2 us / bit ~ 20 us. -- Time out for most controllers = 64 us ! Even if the VME -- command is interrupted, the data transmission to / from -- the front-end will complete (the detector should be -- functioning despite of the VME problems)! -------------------------------------------- -- 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 INTmod is port( -- VME signals -------------------------------------------- VME_ADD: in std_logic_vector(15 downto 1); -- VME address; nBase_Ok: in std_logic; -- Match higher Byte; VME_AM: in std_logic_vector(5 downto 0); -- Address modifier; nLWord: in std_logic; nDS0: in std_logic; -- nDS1: in std_logic; (missing in the hardware) VME_DAT: inout std_logic_vector(15 downto 0); -- VME data; nWrite: in std_logic; nDatEN: out std_logic; DTACK: out std_logic; BError: out std_logic; nAS: in std_logic; nIACK: in std_logic; nSRES: in std_logic; SysCLK: in std_logic; -------------------------------------------- -- CAN signals -------------------------------------------- RXD: in std_logic_vector(6 downto 0); -- Serial interface read; TXD: out std_logic_vector(6 downto 0) -- Serial interface write; -------------------------------------------- ); attribute pinnum: string; attribute pinnum of VME_ADD: signal is "47,46,45,44,41,40,39,38,37,36,31,30,29,28,27"; attribute pinnum of nBase_Ok: signal is "202"; attribute pinnum of VME_AM: signal is "203,204,205,206,207,208"; attribute pinnum of nLWord: signal is "126"; attribute pinnum of nDS0: signal is "78"; attribute pinnum of VME_DAT: signal is "26,25,24,19,18,17,16,15,14,13,12,11,10,9,8,7"; attribute pinnum of nWrite: signal is "80"; attribute pinnum of nDatEN: signal is "73"; attribute pinnum of DTACK: signal is "122"; attribute pinnum of BError: signal is "191"; attribute pinnum of nAS: signal is "125"; attribute pinnum of nIACK: signal is "71"; attribute pinnum of nSRES: signal is "120"; attribute pinnum of SysCLK: signal is "79"; attribute pinnum of RXD: signal is "74,99,100,101,167,113,176"; attribute pinnum of TXD: signal is "75,200,199,198,83,133,144"; end; architecture behavior of INTmod 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_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(15 downto 1); alias BRD_ADR: std_logic_vector(2 downto 0) is VMA_INP(10 downto 8); 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; -------------------------------------------- -- Front-end data -------------------------------------------- signal FRM_CNT: natural range 0 to 511; signal IAM_BSY: std_logic; signal Write: std_logic; signal BRD_OUT: std_logic_vector(14 downto 0); signal BRD_INP: std_logic_vector(7 downto 0); signal INP_BIT: std_logic; signal OUT_BIT: std_logic; signal OUT_GTE: std_logic_vector(6 downto 0); -------------------------------------------- begin -- Permanent statements -------------------------------------------- DUM_RES <= '0'; VMD_OUT(15 downto 8) <= "00000000"; -------------------------------------------- -- 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, nBase_Ok, nLWord, VME_ADD, VME_AM) begin if (nAS = '1') then BAS_ADR <= '0'; NLN_WRD <= '1'; VMA_INP <= (others => '0'); VMM_INP <= (others => '0'); elsif (SysCLK'event and SysCLK = '0') then if (nAS_CNT = 2) then BAS_ADR <= not nBase_Ok; NLN_WRD <= nLWord; VMA_INP <= VME_ADD; VMM_INP <= VME_AM; else null; end if; 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 and VMA_INP <= "000001101111111") 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; -------------------------------------------- -- Data strobe timer -------------------------------------------- process(nDS0, SysCLK, nDS_BLK) begin if (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; -------------------------------------------- -- Latch the input data (SysCLK ->) -- protected against overwriting by -- the IAM_BSY signal -------------------------------------------- process(SysCLK, nDS_CNT, MOD_ACT, nWrite, IAM_BSY, VMA_INP, VMD_INP) begin if (SysCLK'event and SysCLK = '1') then if (nDS_CNT = 3 and MOD_ACT = '1' and IAM_BSY = '0') then Write <= not nWrite; BRD_OUT(14 downto 8) <= VMA_INP(7 downto 1); BRD_OUT(7 downto 0) <= VMD_INP(7 downto 0); else null; end if; end if; end process; -------------------------------------------- -- Busy indicator (SysCLK ->) -------------------------------------------- process(RES_PUL, SysCLK, nDS_CNT, MOD_ACT, FRM_CNT) begin if (RES_PUL = '1') then IAM_BSY <= '0'; elsif (SysCLK'event and SysCLK = '1') then if (nDS_CNT = 4 and MOD_ACT = '1') then IAM_BSY <= '1'; elsif (FRM_CNT = 360) then IAM_BSY <= '0'; else null; end if; end if; end process; -------------------------------------------- -- Frame counter -------------------------------------------- process(IAM_BSY, SysCLK) begin if (IAM_BSY = '0') then FRM_CNT <= 0; elsif (SysCLK'event and SysCLK = '0') then FRM_CNT <= FRM_CNT + 1; end if; end process; -------------------------------------------- -- data acknowledge response (SysCLK ->) -------------------------------------------- process(nDS0, IAM_BSY, MOD_ACT) begin if (nDS0 = '1') then DTACK <= '0'; elsif (IAM_BSY'event and IAM_BSY = '0') then if (MOD_ACT = '1') then DTACK <= '1'; else DTACK <= '0'; end if; end if; end process; -------------------------------------------- -- Bus error response (SysCLK ->) -------------------------------------------- process(nDS0, SysCLK, nDS_CNT, BAS_ADR, ACTION, IAM_BSY) 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' or IAM_BSY = '1')) then BError <= '1'; else null; end if; end if; end process; -------------------------------------------- -- multiplexing the input data -- gating the output data -------------------------------------------- process(BRD_ADR, RXD) begin case BRD_ADR is when "000" => INP_BIT <= not RXD(0); OUT_GTE <= "0000001"; when "001" => INP_BIT <= not RXD(1); OUT_GTE <= "0000010"; when "010" => INP_BIT <= not RXD(2); OUT_GTE <= "0000100"; when "011" => INP_BIT <= not RXD(3); OUT_GTE <= "0001000"; when "100" => INP_BIT <= not RXD(4); OUT_GTE <= "0010000"; when "101" => INP_BIT <= not RXD(5); OUT_GTE <= "0100000"; when "110" => INP_BIT <= not RXD(6); OUT_GTE <= "1000000"; when others => INP_BIT <= '0'; OUT_GTE <= "0000000"; end case; end process; -------------------------------------------- -- pushing out data (SysCLK ->) -------------------------------------------- process(SysCLK, FRM_CNT, Write, BRD_OUT) begin if (SysCLK'event and SysCLK = '1') then case FRM_CNT is when 1 => OUT_BIT <= '1'; when 21 => OUT_BIT <= Write; -- ALTERA address when 41 => OUT_BIT <= BRD_OUT(14); when 61 => OUT_BIT <= BRD_OUT(13); when 81 => OUT_BIT <= BRD_OUT(12); when 101 => OUT_BIT <= BRD_OUT(11); when 121 => OUT_BIT <= BRD_OUT(10); when 141 => OUT_BIT <= BRD_OUT(9); when 161 => OUT_BIT <= BRD_OUT(8); -- ALTERA data when 181 => OUT_BIT <= (BRD_OUT(7) and Write); when 201 => OUT_BIT <= (BRD_OUT(6) and Write); when 221 => OUT_BIT <= (BRD_OUT(5) and Write); when 241 => OUT_BIT <= (BRD_OUT(4) and Write); when 261 => OUT_BIT <= (BRD_OUT(3) and Write); when 281 => OUT_BIT <= (BRD_OUT(2) and Write); when 301 => OUT_BIT <= (BRD_OUT(1) and Write); when 321 => OUT_BIT <= (BRD_OUT(0) and Write); when 341 => OUT_BIT <= '0'; when others => null; end case; end if; end process; -------------------------- TXD(0) <= not (OUT_GTE(0) and OUT_BIT); TXD(1) <= not (OUT_GTE(1) and OUT_BIT); TXD(2) <= not (OUT_GTE(2) and OUT_BIT); TXD(3) <= not (OUT_GTE(3) and OUT_BIT); TXD(4) <= not (OUT_GTE(4) and OUT_BIT); TXD(5) <= not (OUT_GTE(5) and OUT_BIT); TXD(6) <= not (OUT_GTE(6) and OUT_BIT); -------------------------------------------- -- latching readout data (SysCLK ->) -------------------------------------------- process(SysCLK, Write, FRM_CNT, INP_BIT) begin if (SysCLK'event and SysCLK = '1') then if (Write = '0') then case FRM_CNT is when 197 => BRD_INP(7) <= INP_BIT; when 217 => BRD_INP(6) <= INP_BIT; when 237 => BRD_INP(5) <= INP_BIT; when 257 => BRD_INP(4) <= INP_BIT; when 277 => BRD_INP(3) <= INP_BIT; when 297 => BRD_INP(2) <= INP_BIT; when 317 => BRD_INP(1) <= INP_BIT; when 337 => BRD_INP(0) <= INP_BIT; when others => null; end case; else null; end if; end if; end process; -------------------------------------------- -- buffering VME readout (SysCLK ->) -------------------------------------------- process(IAM_BSY, BRD_INP) begin if (IAM_BSY'event and IAM_BSY = '0') then VMD_OUT(7 downto 0) <= BRD_INP; end if; end process; -------------------------------------------- end;