"$Id: pld4a.src,v 1.24 2002/01/16 16:51:33 warren Exp $
"==============================================================================
#TITLE    'ATLAS SCT TIM, PLD4a: L1ID Registers';
#ENGINEER 'Martin Postranecky / Dominic Hayes / John Lane / Matthew Warren';
#COMPANY  'University College London';
#COMMENT  '';


"==============================================================================
"CVS Update Log
"==============================================================================
"$Log: pld4a.src,v $
"Revision 1.24  2002/01/16 16:51:33  warren
"fixed enL1ID problem, tidied tabs
"
"Revision 1.23  2001/12/21 16:18:10  warren
"Changed logic for runmode strobes - fixed stand-alone issues
"
"Revision 1.22  2001/12/19 19:39:50  warren
"Removed Strobe_Rst from L1_Strobe OUTPUT FF
"
"Revision 1.21  2001/12/18 13:52:08  warren
"Figed timing on IDs - now use clk4
"
"Revision 1.20  2001/11/20 16:54:36  warren
"removed all sgb assignments
"
"Revision 1.19  2001/11/14 20:11:29  warren
"Improved signal timing
"
"Revision 1.17  2001/09/14 15:55:17  warren
"Improved timing of Strobes
"
"Revision 1.16  2001/09/10 17:51:20  warren
"added more clocking to idTRIG, L1ID
"
"Revision 1.15  2001/08/30 12:20:40  warren
"Tidied, Capitalization
"
"Revision 1.14  2001/08/08 18:40:38  warren
"signal name upper/lower case standardization
"
"Revision 1.13  2001/08/03 09:13:18  warren
"added read-back to registers
"
"Revision 1.12  2001/07/23 11:18:36  warren
"renamed signals with proper polarity n prefixes and removed LOW_TRUEs
"
"Revision 1.11  2001/07/19 10:44:40  warren
"removed unused spare bus lines
"added SA mode strobes
"
"Revision 1.10  2001/07/16 13:13:31  warren
"*** empty log message ***
"
"Revision 1.9  2001/06/22 13:07:17  warren
"Work on sim and functionality -- I think it may actually work now!
"
"Revision 1.8  2001/06/15 17:01:11  warren
"Cleaned up and simulated
"
"Revision 1.7  2001/06/13 16:49:32  warren
"re-organised code, changed L1IDcounter/bWriteb logic
"fixed some inverted sigs in the stm
"  "Revision 1.6  2001/04/03 15:44:02  warren
"Set  Event ID to reset to 1
"
"Revision 1.5  2001/03/21 14:50:04  warren
"Added ID and log info
"


"==============================================================================
"Mods Log
"==============================================================================
"14jan00 nLEb2 -> /nLEb2
"        ** ensure vme -> cnt -> reg occurs in correct order! **
"22mar00 name: rega regb --> reg10 reg12.
"        RunMode, vmemode o/ps added.  removed vmemode 18may00
"        BCID_offset[3..0], clk4, and shiftAB2[15..0], delayAB2 added.
"16may00 BCID_offset "hardwired" in code.
"18may00 name: to_master -> L1IDL/H, from_master (24) -> BCnt (12)
"           BCntIn[12] i/p in place of L1IDl/H[24] decoding now by pld4a/b.
"           ** NB ** clocking and enabling not complete yet.
"        removed vmemode, RunMode o/ps, run i/p -> RunMode.
"23may00 delayAB2 and BCID_offset delay removed (transFERed to 4b)
"26may00 name: clockAB1/2 -> idTRIG.
"        i/p: idECR, enL1ID, o/p: L1_strobe, SAECR2 added.
"        resetAB -> idECR.
"31may00 SAECR2 defined.  new i/p ENSAECR2.
"        new INPUT StrobeRst to reset q1/q2. *actual signal still to be defined

"        This version now has single L1IDcounter   (original saved as pld4a_orig.src)
"         CntA/BClk -> CntABClk
"        Definition of CntABClk changed to IF-THEN construct.
"           (one extra Pterm device usage)
"08jun00 name: clkC -> clk4.
"28jun00 L1IDcounter clocked by /CntABClk.
"        CntABClk uses nLEb2 instead   of /nLEb2.
"        Input StrobeRst removed.  q1 and q2 reset by new NODE StrobeRst
"         (NB not INPUT).
"29jun00 nLEb2 reverts to LOW_TRUE definition.
"11sep00 nLEb2 reverts to HIGH_TRUE,   CntABClk uses /nLEb2 instead of nLEb2.
"21Mar01 removed LOW_TRUE from nOA_rst and fixed resuting mismatches
"        Added OA_rst (= /nOA_rst) for legibility only
"        Added cvs version/update logging
"21Mar01 Cleaned up nOA_rst legibity (added OA_rst = /nOA_rst)
"13Jun01 Extensively re-organised layout (and bWriteb/L1IDcounter logic a little)
"        Found some code inside the IF RunMode ... END IF that made nonsense
"14Jun01 Added clocking to max_count (L1ID roll-over)
"         and set pulsewidth to 1/2 clock period (for safe L1IDcounter reset).
"21Jun01 Removed async resets from L1IDcounter
"18Jul01 Added logic to gen strobes in SA mode
"14Aug01 Renamed  counter   --> L1IDcounter
"                 RegisterA --> RegisterL1IDL
"                 RegisterB --> RegisterL1IDH
"10Sep01 idTRIG is now clocked as qidTRIG
"        L1ID are now clocked (clk4)
"13Sep01 L1_Strobe, BCntIn are now clocked (via qL1CntLowStrobe etc) by clk4
"        L1ID now clocked by /clk4
"23Oct01 Added clocking to L1_Strobe OUTPUT.
"        re-worked merging of low and hi strobes from PLD9
"        Changed Strobe clocking to /clk4 for better timing
"        L1_strobe run-mode logic set to only work with L then H order of strobes
"18Dec01 Fixed timing proper = REMOVED /clks - works in stand alone, need to chk RM
"19Dec01 Removed Strobe_Rst from L1_Strobe OUTPUT FF.
"21Dec01 Re-worked RUNMODE strobes
"15Jan01 Tidied L1IDCounterClk assignment


"
"==============================================================================
"GLOBAL DECLARATIONS
"==============================================================================

INPUT    nOA_rst;                   "Board reset.
NODE     OA_rst;
         OA_rst = /nOA_rst;

INPUT    clk4;

INPUT    bReadb;                    "BufFERed VME read.
INPUT    bWriteb;                   "BufFERed VME write.

INPUT    Reg10, Reg12;              "Register enables.
INPUT    nLEb2;                        "VME register clock.



BIPUT    db[15..0]                  "VME databus.
            ENABLED_BY dboe;
NODE     dboe;

INPUT    BCntIn[11..0];

INPUT    RunMode;                   "Run mode = 1, vmemode = 0;


"------------------------------------------------------------------------------
"STROBES
"-------

"Run Mode
"--------

INPUT    enL1ID;  " from PLD6

INPUT    L1CntLowStrobe,
         L1CntHighStrobe;

NODE     qL1CntLowStrobe,
         qL1CntHighStrobe
            CLOCKED_BY clk4
            RESET_BY OA_rst;

         qL1CntLowStrobe = L1CntLowStrobe;
         qL1CntHighStrobe = L1CntHighStrobe;


NODE     catchLow
            CLOCKED_BY L1CntLowStrobe
            RESET_BY qRunModeStrobe OR OA_rst;
         catchLow  = 1;

NODE     catchHigh
            CLOCKED_BY L1CntHighStrobe
            RESET_BY qRunModeStrobe OR OA_rst;

         catchHigh = catchLow; " Ensure pairs if signals are synced with data
                                 "*** needs more testing in runmode


NODE     qRunModeStrobe
            CLOCKED_BY clk4
            RESET_BY OA_rst;

         qRunModeStrobe = catchHigh AND enL1ID;


"Stand-Alone Mode
"----------------

INPUT    idTRIG;

NODE     qidTRIG
            CLOCKED_BY clk4
            RESET_BY OA_rst;
         qidTRIG = idTRIG;


"Both
"----
OUTPUT   L1_strobe
            CLOCKED_BY clk4
            RESET_BY OA_rst;

         IF (RunMode) THEN
            L1_Strobe = qRunModeStrobe AND enL1ID;

         ELSE
            L1_Strobe = qidTRIG AND enL1ID;

         END IF;


"------------------------------------------------------------------------------
"THE L1IDcounter
"---------------


INPUT    idECR;


INPUT    ENSAECR2;
OUTPUT   SAECR2;

NODE     L1IDcounter[23..0]      " See count logic in VME section below
            CLOCKED_BY L1IDcounterClk
            RESET_BY idECR OR OA_rst; "*** added idECR - not sure if good
            
NODE     L1IDcounterClk;

NODE     MaxCount
            DEFAULT_TO 0;

         IF (L1IDcounter   = 0ffffffh) THEN       "#### SET MaxCount here ####
            MaxCount = 1;
         END IF;


         SAECR2 = ENSAECR2 AND MaxCount;


         "L1IDcounter assignment func
         "------------------------------

         IF (MaxCount) THEN
            L1IDcounter = 0;
            L1IDcounterClk = qidTRIG;

         ELSIF (bWriteb AND Reg10 AND /RunMode) THEN
            L1IDcounter[11..0]  = db[11..0];      "L1IDL pre-load from VME.
            L1IDcounter[23..12] = L1IDcounter[23..12];
            L1IDcounterClk = nLEb2;

         ELSIF (bWriteb AND Reg12 AND /RunMode) THEN
            L1IDcounter[11..0]  = L1IDcounter[11..0];
            L1IDcounter[23..12] = db[11..0];      "L1IDH pre-load from VME.
            L1IDcounterClk = nLEb2;

         ELSE
            L1IDcounter    = L1IDcounter .+.  1;
            L1IDcounterClk = qidTRIG;

         END IF;



"------------------------------------------------------------------------------
" RegisterL1IDL/RegisterL1IDH       (COUNTER/TIM W,VME R)
"--------------------


NODE     RegisterL1IDL[11..0]
            CLOCKED_BY regL1IDL_clk
            RESET_BY idECR OR OA_rst;  "*** added idECR

NODE     RegisterL1IDH[11..0]
            CLOCKED_BY regL1IDH_clk
            RESET_BY idECR OR OA_rst;  "*** added idECR

NODE     regL1IDL_clk,   
         regL1IDH_clk;
            

OUTPUT   L1IDL[11..0],
         L1IDH[11..0]
            CLOCKED_BY clk4
            RESET_BY OA_rst;

         L1IDL[11..0] = RegisterL1IDL;
         L1IDH[11..0] = RegisterL1IDH;


         IF (RunMode) THEN                " --- RUN MODE ---

            regL1IDL_clk         = qL1CntLowStrobe;
            regL1IDH_clk         = qL1CntHighStrobe;
            RegisterL1IDL[11..0] = BCntIn[11..0];
            RegisterL1IDH[11..0] = BCntIn[11..0];

         ELSIF (bWriteb AND Reg10) THEN   " --- VME MODE ---
            regL1IDL_clk = nLEb2;
            RegisterL1IDL[11..0] = db[11..0];

         ELSIF (bWriteb AND Reg12) THEN
            regL1IDH_clk = nLEb2;
            RegisterL1IDH[11..0] = db[11..0];

         ELSE
            regL1IDL_clk = /qidTRIG;
            regL1IDH_clk = /qidTRIG;

            RegisterL1IDL[11..0] = L1IDcounter[11..0];
            RegisterL1IDH[11..0] = L1IDcounter[23..12];

         END IF; "



"------------------------------------------------------------------------------
"VME Read I/O
"------------


         IF (bReadb) THEN

            IF (Reg10) THEN
               db[15..12] = 0;
               db[11..0] = RegisterL1IDL;              "VME READs RegisterL1IDL.
               
            ELSIF (Reg12) THEN
               db[15..12] = 0;
               db[11..0]  = RegisterL1IDH;              "VME READs RegisterL1IDH.
                              
            END IF;
         END IF;

         dboe = bReadb AND (Reg10 OR Reg12);



"------------------------------------------------------------------------------
"SPARE I/O
"---------
         "OUTPUT  sgbA[7..0];

         "sgbA[7] = idECR;
         "sgbA[6] = Reg10;
         "sgbA[5] = L1CntHighStrobe;
         "sgbA[4] = L1CntLowStrobe;
         "sgbA[3] = qL1CntHighStrobe;
         "sgbA[2] = qL1CntLowStrobe;
         "sgbA[1] = regL1IDH_clk;
         "sgbA[0] = regL1IDL_clk;


         INPUT sgbA[7..0];     "Spare global bus A
         INPUT sgbB[7..0];     "Spare global bus B
         INPUT sgbC[7..0];     "Spare global bus C
         INPUT sgbD[5..0];     "Spare global bus D

         INPUT s2_4a[7..0];    "Spare loCAL bus   connect bus from pld2 to 4a.
         INPUT s4a_4b[7..0];   "Spare loCAL bus


"==============================================================================
