% EPF10K30ETC144-2                                                AUGUST 21'00 %
% The FEB and TTC INTERFACE TO THE DSP %

% The interface has three input ports: the FEB, the TTC, and the off-line serial data.

  The TTC data is buffered in a FIFO and written to the Dual Port Ram at address xxFE.
  
  The FEB data is de-serialized, and the gain bits are stripped off and merged into
  special words to aid the DSP. The data is checked for parity, alignment, and 
  conistency, and errors are flagged in an output word.
  
  VME parameters define the number of samples expected, 
  the number of gain scales expected, and the address MAP data. 
  
  The output port writes to 32Kx32 Dual Port Ram, which is seen as read only
  memory by the DSP. The output data address can be remapped via a look-table 
  so that the order is optimized at the DSP read port. 
  
  The Dual Port Ram is partitioned into blocks, where the event block size
  is specified by the "SIZE" parameter.
  The block address is written at DP address 00FF at the end of an FEB frame, and 
  then incremented. The DSP reads 00FF to determine how many events are left in 
  the Dual Port. The DSP sends a "busy" to Level1 if the Dual Port is almost full.
  
  Initialization is described in the initialize.tdf file. %
  
PARAMETERS   (SIZE=8,POINTER_ADD=H"7FFF",TTC_DATA_ADD=H"FE");


FUNCTION   INITIALIZE (CP,INIT)
           RETURNS   (INIT_FRAME,INIT_TTC,INIT_BLKCNT,INIT_BLKADD) ;
 
FUNCTION   FRAME   (CP,INIT_FRAME,ONES,NS[6..0],NG[2..0])
           RETURNS (FRAMEO,SYNCO,ADD[9..0],HED1,HED2,CELL,ADC,LAST,STAT) ;

FUNCTION   CHANNEL (CP,DI_E,DI_O,SYNC)
           RETURNS (DATA_OUT[11..0],GAIN_OUT[15..0],PAR_OUT,GAIN_ERR,ONES_OUT) ;
                    
FUNCTION  TTC     (CP,INIT_TTC,INIT_BLK,TTC_BCID,TTC_TYPE,TTC_D[7..0],INHIBIT)
          RETURNS (DO[31..0],BLKO[15..0],WDAT,ERR) ;

FUNCTION lpm_ram_dp (wren,data[SIZE..0],wraddress[9..0],wrclock,rdaddress[9..0],rdclock)
              WITH  (LPM_WIDTH = SIZE+1,LPM_WIDTHAD = 10,
                     LPM_RDADDRESS_CONTROL="UNREGISTERED")
           RETURNS  (q[SIZE..0]);
          
FUNCTION  SERIAL  (SCK,DL,DH,AD,FR)
          RETURNS (D[31..0],A[15..0],WEN) ;
          
FUNCTION  BITSUM  (CP,/CLR,D[7..0])
          RETURNS (ACCUM[1..0]) ;
           
SUBDESIGN   DSPINFPGA
                   (CP,                 % the TTC global clock                     % 
                    EXT,                % selects the serial port                  %  
                    DL,DH,AD,FR,        % the serial port                          %
                    INIT,               % initialize                               %
                    FEB_D[15..0],       % the FEB data for 64 signals              %
                    FEB_CLK,            % the FEB clock                            %
                    TTC_BCID,           % valid TTC_BCID byte                      %
                    TTC_TYPE,           % valid TTC_TYPE byte                      %
                    TTC_D[7..0]         %       TTC data byte                      %
                    :INPUT;
                    DO[31..0],          % the 32 bit data         to the DP Buffer %
                    ADD[14..0],         % the 15 bit address      to the DP Buffer %
                    /AWE,               % the write enable        to the DP Buffer %
                    CE1R                % the read port enable    to the DP Buffer %
                    :OUTPUT;
                    
                    LINKRST,            % unused input  %
                    FEB_LNKST,          % unused input  %
                    TTC_RSTN            % unused input  %
                    :INPUT;
                    INT_DSP,            % unused output %
                    TP[8..1]            % test points   %
                    :OUTPUT;)
                    
             VARIABLE
                    INT           :INITIALIZE ; 
                    FRM           :FRAME      ;  % the FEB data sequence          %
                    CHA           :CHANNEL    ;  % ch's 0  to 7                   %
                    CHB           :CHANNEL    ;  % ch's 8  to 15                  %
                    CHC           :CHANNEL    ;  % ch's 16 to 23                  %
                    CHD           :CHANNEL    ;  % ch's 24 to 31                  %
                    CHE           :CHANNEL    ;  % ch's 32 to 39                  %
                    CHF           :CHANNEL    ;  % ch's 40 to 47                  %
                    CHG           :CHANNEL    ;  % ch's 48 to 55                  %
                    CHH           :CHANNEL    ;  % ch's 56 to 63                  %
                    TC            :TTC        ;  % the TTC port                   %
                    ROM           :lpm_ram_dp ;  % the address map                %
                    SER           :SERIAL     ;  % serial input data port         %
                    PAR           :BITSUM     ;  % accumulate parity errors       %
                    
                    MAPQ           :DFFE  ;   % use the mapped addresses from VME %
                    NS[6..0]       :DFFE  ;   % the # samples            from VME %
                    NG[2..0]       :DFFE  ;   % the # gains              from VME %
                    ROT[4..0]      :DFFE  ;   % rotates the ADC data     from VME %
                    
                    PH_ADJ         :DFFE  ;   % adjust the FEB data phase for cp  %
                    QFEB[15..0]    :DFF   ;   % the FEB input register            %
                    QZERO[15..0]   :DFF   ;   % zero detection register           %
                    QNEG[15..0]    :DFF   ;   % deskews the input with !CP        %
                    FEB[15..0]     :DFF   ;   % FEB data to the deserializers     %
                    
                    PH[8..1]       :DFF   ;   % 8 clock phases                    %
                    DEL_FRM        :DFF   ;   % stores the TTC BCN                %
                    DREG_L[11..0]  :DFF   ;
                    DREG_U[11..0]  :DFF   ;
                    COMP           :DFF   ;
                    COMP_L         :LCELL ;
                    COMP_U         :LCELL ;
                    DEL_L[11..0]   :DFF   ;
                    DEL_U[11..0]   :DFF   ;
                    GAIN_L[15..0]  :DFF   ;
                    GAIN_U[15..0]  :DFF   ;
                    GAIN           :DFF   ;
                    ERRD           :DFF   ;
                    FEBD           :DFF   ;
                    ADCD           :DFF   ;
                    
                    ONES_REG[7..0] :DFF   ;
                    ONES_ERR       :DFF   ;
                    PAR_REG[7..0]  :DFF%E%;
                    GAIN_REG[7..0] :DFFE  ;
                    TEST_GAIN      :DFFE  ;
                    TEST_PAR       :DFFE  ;
                   %PARITY_ERR     :LCELL ;%
                    PEN            :LCELL ;
                    GAIN_ERR       :LCELL ;
                    HED1_ERR       :DFFE  ;
                    HED2_ERR       :DFFE  ;
                    CELL_ERR       :DFFE  ;
                    STAT_ERR       :DFFE  ;
                    TTC_ERR        :DFF   ;
                    ERR[15..0]     :LCELL ;
                    DAT[31..0]     :DFF   ;
                    
                    EOB            :DFF   ;      % the end of block             %
                    ADDREG[14..0]  :DFF   ;      % output address register      %
                    DATREG[31..0]  :DFF   ;      % output data register         %
                    WREN           :DFF   ;      % output write enable          %
                    STRB[2..1]     :LCELL ;      % strobe for the async  wren   %
                    
                    ROM_ADD[SIZE..0]     :DFF  ; % the DP address from the ROM  %
                    BLK_CNT[15..0]       :DFF  ; % the DP block address counter %
                    WD_CNT[SIZE-1..0]    :DFF  ; % the DP word address counter  %
                    WD_INC               :DFF  ; % increments the word counter  %
                    WENQ                 :DFF  ; % output write FF              %
                    
                    REGOUT[31..0]        :DFF  ; % the output data register     %
                    ADDOUT[14..0]        :DFF  ; % the output address register  %
                    
                    POINTER              :NODE;
                    
             BEGIN 
    %______________________ VME PARAMETERS _____________________________________%
             % the serial port from dspoutfpga: %
                   SER.DL  = DL      ;
                   SER.DH  = DH      ;
                   SER.AD  = AD      ;
                   SER.FR  = FR      ;
                   SER.SCK = CP      ;
                   
                   % H"8XXX" enable the address map:%    
                   MAPQ.ENA = EXT & SER.WEN & (SER.A[15..12]==8) ;
                   MAPQ.D   = SER.D[0]                           ;
                   
                   % H"9XXX" write the number of FEB samples:%
                   NS[].ENA = EXT & SER.WEN & (SER.A[15..12]==9) ;
                   NS[].D   = SER.D[6..0]                        ;
                   FRM.NS[] = NS[]                               ;
                   
                   % H"AXXX" write the number of FEB gains: %
                   NG[].ENA = EXT & SER.WEN & (SER.A[15..12]==10) ;
                   NG[].D   = SER.D[2..0]                         ;
                   FRM.NG[] = NG[]                                ;
                   
                   % H"BXXX" write the address map data: %
                   ROM.wren        = EXT & SER.WEN & (SER.A[15..12]==11) ;
                   ROM.wraddress[] = SER.A[9..0]                         ;
                   ROM.data[]      = SER.D[SIZE..0]                      ;
                   ROM.wrclock     = CP                                  ;
                   
                   % H"CXXX" write the adc data rotation: %
                   ROT[].CLK = CP;
                   ROT[].ENA = EXT & SER.WEN & (SER.A[15..12]==12) ;
                   ROT[0].D = (SER.D[2..0]==0) ;
                   ROT[1].D = (SER.D[2..0]==1) ;
                   ROT[2].D = (SER.D[2..0]==2) ;
                   ROT[3].D = (SER.D[2..0]==3) ;
                   ROT[4].D = (SER.D[2..0]==4) ;
                   
                 % B"0XXX XXXX XXXX XXXX" RESERVED FOR OFFLINE DATA TO THE DP BUFFER%
  %__________________________________________________________________________________%
  
  
  
  %_____________ PROCESS THE INPUT DATA AND WRITE TO THE DUAL PORT BUFFER ___________%
            % INITIALIZE THE FPGA AND DP: %
                   INT.CP          = CP               ;
                   INT.INIT        = INIT             ;
                   FRM.INIT_FRAME  = INT.INIT_FRAME   ;
                   TC.INIT_TTC     = INT.INIT_TTC     ;
                   TC.INIT_BLK     = INT.INIT_BLKCNT  ;  
            %___________________________________________________________%    
             % RE-PHASE THE FEB INPUT DATA WITH THE GLOBAL TTC CLOCK (CP): %
                  QFEB[].CLK  = FEB_CLK ;
                  QFEB[].D    = FEB_D[] ;
                  
                % ZERO DETECTION: %
                  QZERO[].CLK    = FEB_CLK      ;
                  QZERO[0].D     = FEB_D[0]     ;
                  QZERO[8].D     = FEB_D[1]     ;
                  QZERO[7..1].D  = QZERO[6..0]  ;
                  QZERO[15..9].D = QZERO[14..8] ;
                  
                % DURING ALL ZERO'S, CHOOSE CP OR !CP TO RETIME THE FEB DATA:%
                  PH_ADJ.CLK = FEB_CLK                    ;
                  PH_ADJ.ENA = (QZERO[]==0) & !FRM.FRAMEO ;
                  PH_ADJ.D   = CP                         ;
                  
                  QNEG[].CLK = !FEB_CLK ;
                  QNEG[].D   = QFEB[]   ;
                  
                  FEB[].CLK  = CP              ;                  
                  FEB[].D    = PH_ADJ & QFEB[] #
                              !PH_ADJ & QNEG[] ;
            %___________________________________________________________%                 
             
             % START THE FRAME SEQUENCE FROM ALL ONES RECOGNITION: %
                  FRM.ONES = CHA.ONES_OUT ;
              
             % CONVERT THE FEB SERIAL WORDS TO PARALLEL WORDS: % 
               CHA.DI_E = FEB0 ; CHA.DI_O = FEB1 ; CHA.SYNC = FRM.SYNCO;
               CHB.DI_E = FEB2 ; CHB.DI_O = FEB3 ; CHB.SYNC = FRM.SYNCO;
               CHC.DI_E = FEB4 ; CHC.DI_O = FEB5 ; CHC.SYNC = FRM.SYNCO;
               CHD.DI_E = FEB6 ; CHD.DI_O = FEB7 ; CHD.SYNC = FRM.SYNCO;
               CHE.DI_E = FEB8 ; CHE.DI_O = FEB9 ; CHE.SYNC = FRM.SYNCO;
               CHF.DI_E = FEB10; CHF.DI_O = FEB11; CHF.SYNC = FRM.SYNCO;
               CHG.DI_E = FEB12; CHG.DI_O = FEB13; CHG.SYNC = FRM.SYNCO;
               CHH.DI_E = FEB14; CHH.DI_O = FEB15; CHH.SYNC = FRM.SYNCO;

             %_______________________________________________________%            
              % MERGE THE 64 FEB CHANNELS : %
              
              % ASSIGN THE 12 BIT DATA WORDS TO CLOCK PHASES:
                ASSIGN CH'S 0-7   AND 32-39 TO TIME PHASE PH1
                ASSIGN CH'S 8-15  AND 40-47 TO TIME PHASE PH2
                ASSIGN CH'S 16-23 AND 48-55 TO TIME PHASE PH3
                ASSIGN CH'S 24-31 AND 56-63 TO TIME PHASE PH4
                ASSIGN OUTPUT BITS[15..0] TO CH'S 0-31
                ASSIGN OUTPUT BITS[31..0] TO CH'S 32-63 %
                
                   DEL_FRM.D  = FRM.FRAMEO ;
                   PH[].CLRN  = DEL_FRM    ;
                   
                   PH[1].D    = FRM.SYNCO  ;
                   PH[8..2].D = PH[7..1]   ;
                
                   DREG_L[].D =  CHA.DATA_OUT[] & (PH1) #
                                 CHB.DATA_OUT[] & (PH2) #
                                 CHC.DATA_OUT[] & (PH3) #
                                 CHD.DATA_OUT[] & (PH4) ;
                                
                   DREG_U[].D =  CHE.DATA_OUT[] & (PH1) #
                                 CHF.DATA_OUT[] & (PH2) #
                                 CHG.DATA_OUT[] & (PH3) #
                                 CHH.DATA_OUT[] & (PH4) ;
                                 
               % ASSIGN THE GAIN WORDS TO TIME PHASES PH5-PH8 : %
                   GAIN_L[].D =  CHA.GAIN_OUT[] & (PH5) #
                                 CHB.GAIN_OUT[] & (PH6) #
                                 CHC.GAIN_OUT[] & (PH7) #
                                 CHD.GAIN_OUT[] & (PH8) ;
                                
                   GAIN_U[].D =  CHE.GAIN_OUT[] & (PH5) #
                                 CHF.GAIN_OUT[] & (PH6) #
                                 CHG.GAIN_OUT[] & (PH7) #
                                 CHH.GAIN_OUT[] & (PH8) ;
             %___________________________________________________________________%                              
              % ROTATE THE ADC WORDS, AND MERGE THE FEB, GAIN, AND ERROR DATA : %
                   FEBD.D = !FRM.ADC  & (PH1 # PH2 # PH3 # PH4) ;
                   ADCD.D =  FRM.ADC  & (PH1 # PH2 # PH3 # PH4) ;
                   GAIN.D =  FRM.LAST & (PH5 # PH6 # PH7 # PH8) ; 
                   ERRD.D =  FRM.STAT &        PH6              ;                   
                                      
                   DAT[11..0].D  = FEBD & DREG_L[11..0] ;
                   DAT[27..16].D = FEBD & DREG_U[11..0] ;
                   
                   DAT[11..0].D  = ADCD & ROT0 & DREG_L[] ;
                   DAT[12..1].D  = ADCD & ROT1 & DREG_L[] ;
                   DAT[13..2].D  = ADCD & ROT2 & DREG_L[] ;
                   DAT[14..3].D  = ADCD & ROT3 & DREG_L[] ;
                   DAT[15..4].D  = ADCD & ROT4 & DREG_L[] ;
                   
                   DAT[27..16].D = ADCD & ROT0 & DREG_U[] ;
                   DAT[28..17].D = ADCD & ROT1 & DREG_U[] ;
                   DAT[29..18].D = ADCD & ROT2 & DREG_U[] ;
                   DAT[30..19].D = ADCD & ROT3 & DREG_U[] ;
                   DAT[31..20].D = ADCD & ROT4 & DREG_U[] ;
                   
                   DAT[15..0].D  = GAIN & GAIN_L[15..0] ;
                   DAT[31..16].D = GAIN & GAIN_U[15..0] ;
                   DAT[15..0].D  = ERRD &    ERR[15..0] ;
                   
           %___________________________________________________________________%
            % THE ADDRESS MAP LOGIC: %   
                   ROM.rdaddress[]    = FRM.ADD[9..0] ;
                   ROM.rdclock        = CP            ;
                   ROM_ADD[SIZE..0].D = ROM.q[]       ;
                   
            % THE NON MAPPED DATA ADDRESS GENERATION: % 
             WD_CNT[].CLRN = FRM.FRAMEO ;
                      
             WD_INC.D = FRM.HED1 &  PH1  #  % FEB CONTROL WORD   %
                        FRM.HED2 &  PH1  #  % FEB BUNCH CROSSING %
                        FRM.CELL &  PH1  #  % CELL NUMBER        %
                        FRM.ADC  & (PH1  #  % CH 0-7    32-39    %
                                    PH2  #  % CH 8-15   40-47    %
                                    PH3  #  % CH 16-23  48-55    %
                                    PH4) #  % CH 24-31  56-63    %
                        FRM.LAST & (PH5  #  % GAIN 0-7   32-39   %
                                    PH6  #  % GAIN 8-15  40-47   %
                                    PH7  #  % GAIN 16-23 48-55   %
                                    PH8) #  % GAIN 24-31 56-63   %
                        FRM.STAT &  PH1  #  % FEB STATUS WORD    %
                        FRM.STAT &  PH6  ;  % ERROR WORD         %
                                                
                 IF   WD_INC
                 THEN WD_CNT[].D = WD_CNT[] + 1 ;
                 ELSE WD_CNT[].D = WD_CNT[]     ;
                 END IF ;
                 
                 WENQ.D = WD_INC ; 
                 
              %_________________________________________________________________%
               % DEFINE THE END OF THE FEB BLOCK: %
                 EOB.D = DEL_FRM & !FRM.FRAMEO ;
                 
               % THE FEB DATA TO THE DP BUFFER: %
                 DATREG[31..0].D  = FRM.FRAMEO & DAT[31..0]     ;
                 
               % STORE THE BLOCK ADDRESS AT THE "POINTER_ADD" AND INC THE BLOCK COUNTER: %
                 BLK_CNT[].CLRN   = !INT.INIT_BLKCNT      ;
                 IF  EOB
                 THEN BLK_CNT[].D = BLK_CNT[] + 1         ;       
                 ELSE BLK_CNT[].D = BLK_CNT[]             ; 
                 END IF ;
                   
               % THE FEB DATA ADDRESS AND WREN FOR THE DUAL PORT BUFFER: %
                 ADDREG[14..SIZE].D  =                 DEL_FRM & BLK_CNT[14-SIZE..0] ;
                 ADDREG[SIZE-1..0].D =          MAPQ & DEL_FRM & ROM_ADD[SIZE-1..0]  ;
                 ADDREG[SIZE-1..0].D =         !MAPQ & DEL_FRM & WD_CNT[SIZE-1..0]   ;
                 
                 WREN.D =  MAPQ & DEL_FRM & ROM_ADD[SIZE] #
                          !MAPQ & DEL_FRM & WENQ          ;
                           
                 POINTER = !(WREN # TC.WDAT %# TTC.WADD%);
       %________________________________________________________________________________%
                                  
                           
                           
       %____________WRITE THE TTC AND FEB DATA STREAMS TO THE DP BUFFER ________________%
           % THE TTC PORT: %
              TC.TTC_BCID  = TTC_BCID ;
              TC.TTC_TYPE  = TTC_TYPE ;
              TC.TTC_D[]   = TTC_D[]  ;
       
           % DEFINE AVAILABLE WRITE TIME FOR THE TTC DATA: %                 
              TC.INHIBIT = MAPQ & DEL_FRM & ROM_ADD[SIZE] #
                          !MAPQ & DEL_FRM & WENQ          #
                           EOB                            ;
                             
            % WRITE THE FEB AND THE TTC DATA STREAMS TO THE DUAL PORT BUFFER: %
              REGOUT[31..0].D     =    WREN & DATREG[31..0]  # 
                                    TC.WDAT & TC.DO[31..0]   ;
              REGOUT[31..16].D    = POINTER & TC.BLKO[15..0] ;
              REGOUT[15..0].D     = POINTER & BLK_CNT[15..0] ;
              
              ADDOUT[14..0].D     =    WREN & ADDREG[14..0]       #
                                    POINTER & POINTER_ADD         ;
              ADDOUT[14..SIZE].D  = TC.WDAT & TC.BLKO[14-SIZE..0] ;
              ADDOUT[SIZE-1..0].D = TC.WDAT & TTC_DATA_ADD        ;
                                     
                     STRB1=CP    ;
                     STRB2=STRB1 ; 
                 
                  DO[] =             !EXT & REGOUT[] # EXT & SER.D[] ;
                 ADD[] =             !EXT & ADDOUT[] # EXT & SER.A[14..0] ;                           
                 /AWE  =  !(STRB2 & (!EXT            # EXT & SER.WEN & !SER.A[15]));
                 
     %______________________________________________________________________________%  
     
     
      
                
     %__________________   ERROR CHECKING SECTION   _________________________________% 
              % CHECK THE DATA FOR ERRORS AND DEFINE THE WORD ERR[8..0]: %
             
              % STORE THE TTC ERROR FLAG: %
                   TTC_ERR.CLRN = !INT.INIT_TTC    ;
                   TTC_ERR.D    = TC.ERR # TTC_ERR ;
                                
              % STORE THE FRAME ALIGNMENT ERROR: %                  
                   ONES_REG0.D = CHA.ONES_OUT ;
                   ONES_REG1.D = CHB.ONES_OUT ;
                   ONES_REG2.D = CHC.ONES_OUT ;
                   ONES_REG3.D = CHD.ONES_OUT ;
                   ONES_REG4.D = CHE.ONES_OUT ;
                   ONES_REG5.D = CHF.ONES_OUT ;
                   ONES_REG6.D = CHG.ONES_OUT ;
                   ONES_REG7.D = CHH.ONES_OUT ;
                   
                   ONES_ERR.CLRN = FRM.FRAMEO ;
                   ONES_ERR.D    = FRM.FRAMEO & !DEL_FRM & (ONES_REG[] !=H"FF" ) #
                                   ONES_ERR   ;
                                    
              % COMPARE SPECIAL WORDS AND STORE THE ERRORS: %
                   COMP.D = PH2 # PH3 # PH4 ;
              
                   DEL_L[11..0].D = DREG_L[11..0]   ;
                   DEL_U[11..0].D = DREG_U[11..0]   ;
                   
                   COMP_L = (DEL_L[11..0]==DREG_L[11..0]) ;
                   COMP_U = (DEL_U[11..0]==DREG_U[11..0]) ;
                   
                   HED1_ERR.ENA = COMP ;
                   HED2_ERR.ENA = COMP ;
                   CELL_ERR.ENA = COMP ;
                   STAT_ERR.ENA = COMP ;
                   
                   HED1_ERR.D = FRM.HED1 & !(COMP_L & COMP_U)   # HED1_ERR ;
                   HED2_ERR.D = FRM.HED2 & !(COMP_L & COMP_U)   # HED2_ERR ;
                   CELL_ERR.D = FRM.CELL & !(COMP_L & COMP_U)   # CELL_ERR ;
                   STAT_ERR.D = FRM.STAT & !(COMP_L & COMP_U)   # STAT_ERR ;
              
                   HED1_ERR.CLRN = FRM.FRAMEO ; 
                   HED2_ERR.CLRN = FRM.FRAMEO ; 
                   CELL_ERR.CLRN = FRM.FRAMEO ; 
                   STAT_ERR.CLRN = FRM.FRAMEO ; 
                   
              % STORE THE PARITY ERROR: %
                 TEST_PAR.CLRN = FRM.FRAMEO ;
                 TEST_PAR.ENA  = FRM.SYNCO  ;
                 TEST_PAR.D    = FRM.FRAMEO ;
              
                 PAR_REG[].CLRN = FRM.FRAMEO             ;
           %PAR_REG[].ENA% PEN  = FRM.SYNCO & TEST_PAR   ;
                 
                 PAR_REG0.D     = CHA.PAR_OUT & PEN %# PAR_REG0% ;
                 PAR_REG1.D     = CHB.PAR_OUT & PEN %# PAR_REG1% ; 
                 PAR_REG2.D     = CHC.PAR_OUT & PEN %# PAR_REG2% ;
                 PAR_REG3.D     = CHD.PAR_OUT & PEN %# PAR_REG3% ;
                 PAR_REG4.D     = CHE.PAR_OUT & PEN %# PAR_REG4% ;
                 PAR_REG5.D     = CHF.PAR_OUT & PEN %# PAR_REG5% ;
                 PAR_REG6.D     = CHG.PAR_OUT & PEN %# PAR_REG6% ;
                 PAR_REG7.D     = CHH.PAR_OUT & PEN %# PAR_REG7% ;
                %PARITY_ERR     = (PAR_REG[] != 0 )      ;%
                 
                 PAR.D[]  = PAR_REG[]  ;
                 PAR./CLR = FRM.FRAMEO ;
                 PAR.CP   = CP         ;
                 
              % STORE THE GAIN ERROR: %
                 GAIN_REG[].CLRN = FRM.FRAMEO                      ;
                 TEST_GAIN.CLRN  = FRM.FRAMEO                      ;
                 TEST_GAIN.ENA   = FRM.SYNCO                       ;
                 TEST_GAIN.D     = FRM.LAST  # TEST_GAIN           ;
                  GAIN_REG[].ENA = FRM.SYNCO & FRM.ADC & TEST_GAIN ;
                 
                 GAIN_REG0.D     = CHA.GAIN_ERR # GAIN_REG0 ;
                 GAIN_REG1.D     = CHB.GAIN_ERR # GAIN_REG1 ;
                 GAIN_REG2.D     = CHC.GAIN_ERR # GAIN_REG2 ;
                 GAIN_REG3.D     = CHD.GAIN_ERR # GAIN_REG3 ;
                 GAIN_REG4.D     = CHE.GAIN_ERR # GAIN_REG4 ;
                 GAIN_REG5.D     = CHF.GAIN_ERR # GAIN_REG5 ;
                 GAIN_REG6.D     = CHG.GAIN_ERR # GAIN_REG6 ;
                 GAIN_REG7.D     = CHH.GAIN_ERR # GAIN_REG7 ;
                 GAIN_ERR        = (GAIN_REG[] != 0)        ;
               
              % COMBINE THE ERROR FLAGS IN THE ERR[] WORD: %
                 ERR0      = ONES_ERR    ;
                 ERR1      = HED1_ERR    ;
                 ERR2      = HED2_ERR    ;
                 ERR3      = CELL_ERR    ;
                 ERR4      = GAIN_ERR    ;
                 ERR5      = STAT_ERR    ;
                 ERR[7..6] = PAR.ACCUM[] ;
                %ERR6 = PARITY_ERR ;
                 ERR7 = TTC_ERR    ;%
                 
                 ERR8  = ONES_REG0 # PAR_REG0 # GAIN_REG0 ;
                 ERR9  = ONES_REG1 # PAR_REG1 # GAIN_REG1 ;
                 ERR10 = ONES_REG2 # PAR_REG2 # GAIN_REG2 ;
                 ERR11 = ONES_REG3 # PAR_REG3 # GAIN_REG3 ;
                 ERR12 = ONES_REG4 # PAR_REG4 # GAIN_REG4 ;
                 ERR13 = ONES_REG5 # PAR_REG5 # GAIN_REG5 ;
                 ERR14 = ONES_REG6 # PAR_REG6 # GAIN_REG6 ;
                 ERR15 = ONES_REG7 # PAR_REG7 # GAIN_REG7 ;
   %______________________________________________________________________% 
   
   
   
   %______________________________________________________________________%  
                 INT_DSP = GND; % spare output to the fpgaout         %
                 CE1R    = VCC; % read enable to the DUAL PORT buffer %
    
    
        % DIAGNOSTIC TEST POINT OUTPUTS: %
        TP1 = /AWE       ;
        TP2 = FRM.FRAMEO ;
        TP3 = TTC_BCID   ;
        TP4 = TTC_TYPE   ;
        TP5 = TC.WDAT    ;
        TP6 = INIT       ;
        TP7 = FEB_D3     ;
        TP8 = FEB_CLK    ;

   %_________________________________________________________________________%                    
              % CLOCKS: %
                   MAPQ.CLK       = CP ;
                   NS[].CLK       = CP ;
                   NG[].CLK       = CP ;
                   DREG_L[].CLK   = CP ;
                   DREG_U[].CLK   = CP ;
                   DEL_FRM.CLK    = CP ;
                   COMP.CLK       = CP ;
                   DEL_L[].CLK    = CP ;
                   DEL_U[].CLK    = CP ;
                   HED1_ERR.CLK   = CP ;
                   HED2_ERR.CLK   = CP ;
                   CELL_ERR.CLK   = CP ;
                   STAT_ERR.CLK   = CP ;
                   ONES_REG[].CLK = CP ;
                   PAR_REG[].CLK  = CP ;
                   GAIN_REG[].CLK = CP ;
                   TEST_GAIN.CLK  = CP ;
                   ONES_ERR.CLK   = CP ;
                   PH[].CLK       = CP ; 
                   GAIN_L[].CLK   = CP ;
                   GAIN_U[].CLK   = CP ;
                   GAIN.CLK       = CP ;
                   ERRD.CLK       = CP ;
                   EOB.CLK        = CP ;
                   ADDREG[].CLK   = CP ;
                   DATREG[].CLK   = CP ;
                   WREN.CLK       = CP ;
                   FEBD.CLK       = CP ;
                   ADCD.CLK       = CP ;
                   BLK_CNT[].CLK  = CP ;
                   WD_CNT[].CLK   = CP ;
                   WD_INC.CLK     = CP ;
                   WENQ.CLK       = CP ;
                   DAT[].CLK      = CP ;
                   ROM_ADD[].CLK  = CP ;
                   REGOUT[].CLK   = CP ;
                   ADDOUT[].CLK   = CP ;
                   TTC_ERR.CLK    = CP ;
                   TEST_PAR.CLK   = CP ;
              
                   FRM.CP  = CP ;
                   CHA.CP  = CP ;
                   CHB.CP  = CP ;
                   CHC.CP  = CP ;
                   CHD.CP  = CP ;
                   CHE.CP  = CP ;
                   CHF.CP  = CP ;
                   CHG.CP  = CP ;
                   CHH.CP  = CP ;
                   TC.CP   = CP ;
                                
                   END;