#INCLUDE "/home/amu5/users/georget/Phd/Simul/Defs/defs.inc"
#INCLUDE "/home/amu5/users/georget/Phd/Simul/PLA/Mode.inc"
#INCLUDE "/home/amu5/users/georget/Phd/Simul/PLA/CondC.inc"
#INCLUDE "/home/amu5/users/georget/Phd/Simul/PLA/CPmxC.inc"
#USE "/home/amu5/users/georget/Phd/Simul/library"

PROC Ctrl3(CHAN OF BUNDLE FOPregDA,FOPregDB, FromDec3D1,FromDec3D2,FromCPregD,
                           MemDabt0,MemDabt1,AIDabt0,Toctrl2D,ALUgo,
                           ToCPregA,ToOPregA,ToDec3A,ToWrregD1,
                           ToWrregD2,FWrregA,ToDec1PCp,
                           []CHAN OF DEB.MESSAGE screen, VAL INT report, evaluate, preemption) --5
  ------------------------------------------------------------

  [MESGLEN]INT  alP,Opa, Opb,C3,Cpsr,ALx,Dabt0,Dabt1,Dabtai,ALUok,
        RE,Ackcp,Ackop,Ackd3,ALfs,PCpr,Ackwr:

  INT Modin,Modout,CPmxin,ALfg,CPmxout,sel,sh0,ShCi,CP2,
      sh1,sh2,sh3,CP2A,CP2B,alu,alu0,i,aluC,aluV,mode,condin,condout, 
      clock0,clock1,clock2,clock3,clock4,clock5,Pcpar.clock:

  BOOL Usr0,Usr,pDabt1,PcPar,PrevPcPar,pass,ShC,end,DPdabt,previous.pass,DPflaten,
       DP,DPtpcp,Dabtlaten,Pflaten,Pcp1,psrV,psrC,psrZ,psrN,pcpar.updated, Cdn, ALe,
       fail.due.to.pcpar,abort0.received:

  TIMER clock:
  VAL INT delay IS 2343:   --0.5 sec
  [3][OCCT.SIZE][OCCT.COL]INT occupancy.table:  --an array of occupancy tables!!!!
  [20]INT delay:


  [14][9]INT CPmxCmask:
  [14][9]INT CPmxCmatch:
  [14][4]INT CPmxCout:
  [11][4]INT  ModeCmatch:
  [11][4]INT ModeCmask:
  [11][7]INT ModeCout:
  [25][12]INT  CondCmask:
  [25][12]INT  CondCmatch:
  [25][1]INT  CondCout:

  [17]BOOL  alPb :
  [32]BOOL  C3b :
  [32]BOOL  Cpsrb :
  [13]BOOL  CP0b :
  [11]BOOL  CPb :
  [11]BOOL  CP2b:
  [4]BOOL   CP2Ab :
  [7]BOOL   CP2Bb :
  [13]BOOL  CP1b:
  [32]BOOL  CPmxoutb :
  [32]BOOL  alub :
  [11]BOOL  alu1b:
  [32]BOOL  sh1b:
  [4]BOOL   Modinb:
  [4]BOOL   Modoutb:
  [9]BOOL   CPmxinb:
  [6]BOOL   modeb:
  [7]BOOL   ALUokb:
  [12]BOOL  condinb:
  [32]BOOL  condoutb:

  ---------------------------------------------------------  
  PROC calculate.delays()
    SEQ
      delay[0]:=MULLERC
      delay[1]:=SELECT+CALLR
      delay[2]:=(((ALU.DELAY + MULLERC) +XOR)+XOR) +TOGGLE
      delay[3]:=SELECT
      delay[4]:=SELECT
      delay[5]:=(SELECT+XOR)+EVLATCH
      delay[6]:=SELECT+XOR
      delay[7]:=XOR
      delay[8]:=SELECT+XOR
      delay[9]:=SELECT
      delay[10]:=(SELECT+CALLR)+SELECT
      delay[11]:=SELECT
      delay[12]:=DESWAIT+XOR
      delay[13]:=XOR
      delay[14]:=XOR
      delay[15]:=XOR
      delay[16]:=(MULLERC+SELECT)+XOR
      delay[17]:=(MULLERC+CALLA)+XOR
      delay[18]:=MULLERC+CALLA

  :
  -------------------------------------------------------------------------
  PROC  initialize.occup.tables()
    SEQ
      initialize.occup.table(occupancy.table[0], DEC3PIPE,DEC3.SIZE , DEC3.DELAY)  
      initialize.occup.table(occupancy.table[1], CPREG,CPSR.SIZE ,REGISTER.DELAY)  
      initialize.occup.table(occupancy.table[2], OPREG,OP.SIZE ,REGISTER.DELAY)  
  :
  -------------------------------------------------------------------------


  PROC Mode(INT In, Out)

    SEQ
      decode(ModeCout, ModeCmatch, ModeCmask, In, Out)    
  :
  ---------------------------------------------------------
  PROC CPmx(INT In, Out)

    SEQ
      decode(CPmxCout, CPmxCmatch, CPmxCmask, In, Out)    
  :
  ---------------------------------------------------------

  PROC Cond(INT In, Out)

    SEQ
      decode(CondCout, CondCmatch, CondCmask, In, Out)    
  :
  ---------------------------------------------------------
  PROC mkModin()
    SEQ
      Modinb[0]:=CP0b[5]
      [Modinb FROM 1 FOR 3] := [C3b FROM 23 FOR 3]
      init.hex(Modin,Modinb) 
  :
  ---------------------------
  PROC mkCPmxin()
    SEQ
      [CPmxinb FROM 0 FOR 6]:=[C3b FROM 16 FOR 6]
      CPmxinb[6]:=Usr0
      CPmxinb[7]:=pass
      CPmxinb[8]:=Cdn               
      init.hex(CPmxin,CPmxinb) 
  :
  ---------------------------
  PROC mkalP()
    SEQ
      alPb[0]:=PcPar
      alPb[1]:=C3b[1]
      alPb[2]:=((((C3b[18] OR C3b[17])) OR DP) AND pass) 
      alPb[3]:=C3b[2]
      alPb[4]:=C3b[3]
      alPb[5]:=Usr
      [alPb FROM 6 FOR 6]:=[C3b FROM 4 FOR 6] 
      alPb[12]:=C3b[0]
      [alPb FROM 13 FOR 4]:=[C3b FROM 26 FOR 4] 
      init.hex(alP[0], alPb)
  :
  ---------------------------
  PROC Alu(INT a1,b1,alufs,psrC,psrV,shftC,alu,Flags)
    INT c1,v1,fs,c0,alul,alue, a, b:

    INT64 alu1:
    [64]BOOL alu1b:
    SEQ
      a:=0
      b:=0
      c1:= shftC
      v1:= psrV
      fs:= ~(alufs)
      
      ---------------------------------------
      --/* input true or complement logic */
      ----------------------------------------
      -----------------------a-----------------
      IF
        ((fs/\#80)<>0)
          SEQ
            a:= a1    
            SKIP         
        ((fs/\#80)=0)       --(fs/\#80)=0
          SEQ
            IF
              ((fs/\#40)<>0)
                SEQ
                  a:=~a1  
              ((fs/\#40)=0) 
                SEQ               --WHAT IS HAPPENING WITH a HERE??
                  SKIP
      -----------------------b-----------------      
      IF
        ((fs/\#20)<>0)
          SEQ
            b:= b1
            SKIP         
        ((fs/\#20)=0)       --(fs/\#80)=0
          SEQ
            IF
              ((fs/\#10)<>0)
                SEQ
                  b:=~b1
              ((fs/\#10)=0)             --WHAT IS HAPPENING WITH b HERE??
                SKIP
      -----------------------------------------------------------------------
      --/* ALU logic:  ~ALUfs = ~c1, c0, a+, a-, b+, b-, add, and, or, xor */
      -----------------------------------------------------------------------
   
      CASE (fs/\ #F)

        #4
          SEQ
            alu:=(a/\ b)   --a and b
 
        #1
          SEQ
            alu:=( a>< b)   --a xor b

        #2
          SEQ
            alu:=( a\/ b)   --a or b


        #8                      --/* carry in logic */   a+b
          SEQ
            CASE  (fs/\#300)
              #000
                SEQ
                  c0:=1
              #300
                SEQ
                  c0:=0
              #200
                SEQ
                  c0:=psrC

            alu:=((a PLUS b) PLUS c0)   --**MODULO ARITHEMTIC TO AVOID OVERFLOW***!!!!
            --int64.to.bool(alu1, alu1b)
            --init.hex(alu, [alu1b FROM 0 FOR 32])
            IF
              ((((a<0) AND (b<0)) OR ((a<0) AND (alu>=0))) OR ((b<0) AND (alu>=0)))=TRUE
                SEQ
                  c1:=1
              TRUE
                SEQ
                  c1:=0
          
            IF
              ((((a<0) AND (b<0)) AND (alu>=0)) OR ((a>=0) AND ((b>=0) AND (alu<0))))=TRUE
                SEQ
                  v1:=1
              TRUE
                SEQ
                  v1:=0 
      IF
        alu<0
          SEQ
            alul:=1
        TRUE
          SEQ
            alul:=0
      IF
        alu=0
          SEQ
            alue:=1
        TRUE
          SEQ
            alue:=0
       
             
      Flags:= ((alul<<3)  PLUS ((alue<<2)  PLUS ((c1<<1)  PLUS v1)))
  :
  -----------------------------------------------------------------
  SEQ
    CPmxCmask:=CCPmxCmask
    CPmxCmatch:=CCPmxCmatch
    CPmxCout:=CCPmxCout
    ModeCmatch:=CModeCmatch
    ModeCmask:=CModeCmask
    ModeCout:=CModeCout
    CondCmask:=CCondCmask
    CondCmatch:=CCondCmatch
    CondCout:=CCondCout
    alu:=0
    int.to.bool(alu, alub)


    Usr0,Usr,pDabt1,PcPar,pass,ShC,end,DPdabt,DP,DPtpcp,Dabtlaten,
    Pflaten,Pcp1,psrV,psrC,psrZ,psrN,pcpar.updated:=
    FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,
    FALSE,FALSE,FALSE,FALSE,FALSE

    --*****RESET*******

    Cdn:=FALSE           --clock down
    mkCPmxin()            
    CPmx(CPmxin, CPmxout)
    int.to.bool(CPmxout, CPmxoutb) 

    --------------------------------------------------- 
    init.hex(sel, [CPmxoutb[2],CPmxoutb[3]])
    init.hex(sh0, [CP0b[7],CP0b[8],CP0b[9],CP0b[10]])
    init.hex(sh1, [alub[7],alub[8],alub[9],alub[10]])
    sh2:=ALfg
    init.hex(sh3, [VSS,VSS,VSS,VSS])                 --this is chosen in the reset phase
    mux4(sel, sh0,sh1,sh2,sh3,CP2A) 
    ----------------------------------------------------
    init.hex(sel, [CPmxoutb[0],CPmxoutb[1]])
    init.hex(sh0, [CP0b[0],CP0b[1],CP0b[2],CP0b[3],CP0b[4],CP0b[5],CP0b[6]])
    init.hex(sh1, [alub[0],alub[1],alub[2],alub[3],alub[4],alub[5],alub[6]])
    sh2:=Modout
    init.hex(sh3, [VDD,VDD,VSS,VSS,VDD,VDD,VDD])     --this is chosen in the reset phase
    mux4(sel, sh0,sh1,sh2,sh3,CP2B) 
    ----------------------------------------------------
    int.to.bool(CP2A,CP2Ab)
    int.to.bool(CP2B,CP2Bb)
    [CP2b FROM 0 FOR 7]:= [CP2Bb FROM 0 FOR 7]
    [CP2b FROM 7 FOR 4]:= [CP2Ab FROM 0 FOR 4]
    Usr:= (NOT(CP2b[0] OR CP2b[1]))

    ----------------------------------------------------------
           
    CPb:=CP2b                       --ENABLE LATCH

    psrV:=CPb[7]     --initialize flags
    psrC:=CPb[8]
    psrZ:=CPb[9]
    psrN:=CPb[10]

    [modeb FROM 0 FOR 4]:=[CPb FROM 0 FOR 4]
    [modeb FROM 4 FOR 2]:=[CPb FROM 5 FOR 2]
    init.hex(mode, modeb) 
    Usr0:= (NOT(CP1b[0] OR CP1b[1]))     --calculate new Usr0
    ---------------------------------------------------------
             
    ALUokb[0]:=FALSE
    ALUok[TIME.STAMP]:=0
    [ALUokb FROM 1 FOR 6]:=[modeb FROM 0 FOR 6]
    init.hex(ALUok[0],ALUokb)
    ALUgo!ALUok   --send initial mode(SVC) to Dec1CtrlB

    Cdn:=TRUE

    --*****END OF RESET*******
    calculate.delays()
    initialize.occup.tables()
    Ackwr[TIME.STAMP]:=0    --initially

    debugmsg(report,screen[0], "DECODE3-CTRL3: Waiting from OP register...  ", NULL1)
    FOPregDA?Opa


    IF
      Opa[0]<>FINISH          --from Ctrl2 through OP register
        SEQ
          PAR
            SEQ
              FOPregDB? Opb
              debugmsg(report,screen[0], "DECODE3-CTRL3: Received from OP register...Opa ", Opa )
              debugmsg(report,screen[0], "DECODE3-CTRL3: Received from OP register...Opb ", Opb )
            SEQ
              debugmsg(report,screen[1], "DECODE3-CTRL3: Waiting from DEC3...  ", NULL1)
              PAR
                FromDec3D1? ALfs   --from Dec3
                FromDec3D2?  C3   --from Dec3
              debugmsg(report,screen[1], "DECODE3-CTRL3: Received from DEC3...  ", ALfs )

    
            SEQ
              debugmsg(report,screen[2], "DECODE3-CTRL3: waiting for CPSR ", NULL1)
              FromCPregD? Cpsr     --from Ctrl2 through CPsr register
              debugmsg(report,screen[2], "DECODE3-CTRL3: received CPSR ", Cpsr )
 
              int.to.bool(Cpsr[0], Cpsrb)
              ShC:=Cpsrb[7]

              ------------------calculate new pass--------------
              [condinb FROM 0 FOR 4]:=[psrV,psrC,psrZ,psrN]
              condinb[4]:= Pcp1
              [condinb FROM 5 FOR 7]:=[Cpsrb FROM 0 FOR 7]                           
              init.hex(condin,condinb)
              Cond(condin,condout)
              int.to.bool(condout,condoutb)
              pass:=condoutb[0]
              debugmsg(report,screen[2], "DECODE3-CTRL3: newpass is ", NULL1)
            
              ---------------------------------------------------

              --CP0(ShC1,Pass,aluN,aluZ,aluC,aluV,Omd[6:0])
              [CP0b FROM 0 FOR 11]:=[CPb FROM 0 FOR 11] 
              CP0b[11]:=pass 
              CP0b[12]:=ShC
              
      TRUE
        end:=TRUE

    WHILE end=FALSE
      SEQ

        clock0:=max(Opa[TIME.STAMP],ALfs[TIME.STAMP])
        clock0:=max(clock0,Cpsr[TIME.STAMP]) +delay[0] --MULLERC  
        abort0.received:=FALSE
        previous.pass:=pass
        DPdabt:=DP 
        DPtpcp:=DP
        Dabtlaten:=FALSE
        DPflaten:=FALSE

        int.to.bool(C3[0], C3b)

        PAR     --*A*
          --------------------------A.1
          SEQ

            clock1:= clock0 + delay[1]         --SELECT+CALL

            mkModin()
            mkCPmxin()            
            Mode(Modin, Modout) 
            int.to.bool(Modout,Modoutb)
            CPmx(CPmxin, CPmxout)
            debugmsg(report,screen[3], "DECODE3-CTRL3: Output of CPmx ", [CPmxout,0,0,0] )
            int.to.bool(CPmxout, CPmxoutb) 

            clock2:=max(clock1, Ackwr[TIME.STAMP]) +delay[2]                  -- ALU.DELAY + MULLERC +XOR+XOR +TOGGLE

            --**always activate ALe, and call ALU
            ALe:=TRUE
            aluC:=INT (CP0b[8])
            aluV:=INT (CP0b[7])
            ShCi := INT (ShC)     
            Alu(Opa[0],Opb[0],ALfs[0],aluC,aluV, ShCi,alu0,ALfg) 
            debugmsg(report,screen[3], "DECODE3-CTRL3: calling ALU  new flags are ", [ALfg,0,0,0] )
            ---------------------------------------------------------
            CP1b:=CP0b                           --enable lat0 in cpsr
            Usr0:= (NOT(CP1b[0] OR CP1b[1]))     --calculate new Usr0
            ---------------------------------------------------------

            --*****get ALd*****

            --**Now check if ALU output latch should be activated 

            IF 
              (NOT((NOT(C3b[18] OR C3b[17])) AND DP))=TRUE
                --** ALe1 call ALU and latch output**
                SEQ 
                  debugmsg(report,screen[3], "DECODE3-CTRL3: latch ALU  new result  ", [alu0,0,0,0])
                  alu:=alu0

              TRUE     -- don't latch
                SEQ
                  debugmsg(report,screen[3], "DECODE3-CTRL3: do not latch ALU  new result ", [alu0,0,0,0] )
                  --ALe:=FALSE
                  SKIP 

            debugmsg(report,screen[3], "DECODE3-CTRL3: calling ALU  new result is ", [alu,0,0,0] )
            int.to.bool(alu, alub)
            [alu1b FROM 0 FOR 5]:=[alub FROM 0 FOR 5]
            [alu1b FROM 5 FOR 2]:=[alub FROM 6 FOR 2]
            [alu1b FROM 7 FOR 4]:=[alub FROM 28 FOR 4]


             --the multiplexers of CPSR **use the new output of the alu to calculate new CP2 **
            --------------------------------------------------- 
            init.hex(sel, [CPmxoutb[2],CPmxoutb[3]])
            init.hex(sh0, [CP0b[7],CP0b[8],CP0b[9],CP0b[10]])
            init.hex(sh1, [alu1b[7],alu1b[8],alu1b[9],alu1b[10]])
            sh2:=ALfg
            init.hex(sh3, [VSS,VSS,VSS,VSS])
            mux4(sel, sh0,sh1,sh2,sh3,CP2A) 
            ----------------------------------------------------
            init.hex(sel, [CPmxoutb[0],CPmxoutb[1]])
            init.hex(sh0, [CP0b[0],CP0b[1],CP0b[2],CP0b[3],CP0b[4],CP0b[5],CP0b[6]])
            init.hex(sh1, [alu1b[0],alu1b[1],alu1b[2],alu1b[3],alu1b[4],alu1b[5],alu1b[6]])
            sh2:=Modout
            init.hex(sh3, [VDD,VDD,VSS,VSS,VDD,VDD,VDD])
            mux4(sel, sh0,sh1,sh2,sh3,CP2B) 
            ----------------------------------------------------
            int.to.bool(CP2A,CP2Ab)
            int.to.bool(CP2B,CP2Bb)
            [CP2b FROM 0 FOR 7]:= [CP2Bb FROM 0 FOR 7]
            [CP2b FROM 7 FOR 4]:= [CP2Ab FROM 0 FOR 4]
            init.hex(CP2,CP2b)

            debugmsg(report,screen[3], "DECODE3-CTRL3: new CP2 is  ", [CP2,0,0,0]  )

            Usr:= (NOT(CP2b[0] OR CP2b[1]))

            ----------------------------------------------------------
            IF
              ((ALe=TRUE) AND (((CPmxoutb[0] OR CPmxoutb[1]) OR (CPmxoutb[2] OR CPmxoutb[3]))=TRUE))
                SEQ
                  CPb:=CP2b                       --enable lat1 in cpsr  latch the new value of CP2
                  

                  psrV:=CPb[7]
                  psrC:=CPb[8]
                  psrZ:=CPb[9]
                  psrN:=CPb[10]

                  [modeb FROM 0 FOR 4]:=[CPb FROM 0 FOR 4]
                  [modeb FROM 4 FOR 2]:=[CPb FROM 5 FOR 2]
                  init.hex(mode, modeb)
                  
              TRUE
                SKIP            
         
            --MULLER-C: produce ALx1, clear ALe/ALe1, disable latches
            --------------------------
            SEQ
              clock3:=clock1+delay[3]   --SELECT
              IF   --4
                (NOT(pass AND C3b[10]))=FALSE
                  SEQ
                    debugmsg(report,screen[3], "DECODE3-CTRL3:  (NOT(pass AND C3b[10]))=FALSE ", NULL1)
                    clock3:=clock3+delay[4]   --SELECT
                    Pcpar.clock:=clock3+delay[5]   --SELECT+XOR+EVLATCH
                    IF   --5
                      DP=TRUE
                        SEQ
                          DPtpcp:= (NOT DP)
                          debugmsg(report,screen[3], "DECODE3-CTRL3: DP IS TRUE changing the value of  DPtpcp", [(INT DPtpcp), 0,0,0] )
                          clock3:=clock3+delay[6]   --SELECT+XOR
    
                      DP=FALSE
                        SEQ
                          debugmsg(report,screen[3], "DP IS FALSE changing  PcPar...",  NULL1)
                          DPflaten:=TRUE     --enable latch to get new pcpar
                                                 --might have the same value
                          PrevPcPar:=PcPar
                          PcPar:=NOT Pcp1
                          pcpar.updated:=TRUE
                          clock3:=clock3+delay[6]   --SELECT+XOR

                (NOT(pass AND C3b[10]))=TRUE
                  SEQ
                    debugmsg(report,screen[3], "DECODE3-CTRL3: (NOT(pass AND C3b[10]))=TRUE ", NULL1)
                    SKIP
              clock3:=clock3+delay[7]  --XOR

            mkalP()
            -------------------rmux------------------

            sel:=INT(alPb[12])
            sh0:=alu
            [sh1b FROM 0 FOR 5]:=[CP1b FROM 0 FOR 5]
            sh1b[5]:=VSS
            [sh1b FROM 6 FOR 2]:=[CP1b FROM 5 FOR 2]
            SEQ i=0 FOR 20
              SEQ
                sh1b[8+i]:=VSS
            [sh1b FROM 28 FOR 4]:=[CP1b FROM 7 FOR 4]
            init.hex(sh1, sh1b)

            mux2(sel, sh0, sh1, RE[0]) 



            PAR
              ----------------------------------------------------------------
              SEQ
                ALx[TIME.STAMP]:=clock2
                --debugmsg(report,screen[1], "DECODE3-CTRL3: Waiting to send ALx ", NULL1)
                ALx[0]:=INT CPb[8]
                
                Toctrl2D!ALx   --signal to ctrl2-carry for the shifter
                --debugmsg(report,screen[1], "DECODE3-CTRL3: sent ALx ", ALx )
              ----------------------------------------------------------------
              SEQ  
                clock4:= clock2 + delay[8]  --SELECT+XOR                     
                IF
                  C3b[13]=FALSE
                    SEQ
                      ALUok[TIME.STAMP]:=clock2 + delay[9]  --SELECT
                      ALUokb[0]:=alPb[2]
                      [ALUokb FROM 1 FOR 6]:=[modeb FROM 0 FOR 6]
                      init.hex(ALUok[0],ALUokb)
                      debugmsg(report,screen[2], "DECODE3-CTRL3: Waiting to send ALUgo to Dec1 ", NULL1)
                      ALUgo!ALUok  
                      debugmsg(report,screen[2], "DECODE3-CTRL3: ALUgo sent to Dec1 ", NULL1)                  
                  C3b[13]=TRUE
                    SEQ
                      SKIP
              ----------------------------------------------------------------
              SEQ

                RE[TIME.STAMP]:=clock2+delay[9]   --SELECT
                RE[STALL]:=(-1)   --SELECT

                IF --7
                  ((pass AND C3b[14]) OR C3b[15])=TRUE
                    SEQ
                      
                      debugmsg(report,screen[1], "DECODE3-CTRL3: waiting to send to WrtCtrl ", NULL1) 
                      --clock? AFTER delay
                      PAR
                        ToWrregD1!RE
                        ToWrregD2!alP 
                      debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  RE ", RE )
                      debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  alP ", alP )
                      debugmsg(report,screen[3], "DECODE3-CTRL3: waiting for ack from Wreg ", NULL1)
                      FWrregA? Ackwr
                      debugmsg(report,screen[3], "DECODE3-CTRL3: received ack from Wreg ", NULL1)

   
                  ((pass AND C3b[14]) OR C3b[15])=FALSE 
                    SEQ
                      SKIP
          --------------------------A.2
          SEQ
            clock5:=clock0 + delay[10]         --SELECT+CALL+SELECT
            IF                --2
              C3b[12]=FALSE  
                SEQ
                  clock5:=clock5+delay[11] --SELECT

                  IF     --3
                    pass=TRUE     --FIRE Decision/wait element!!
                      SEQ
                        debugmsg(report,screen[0], "DECODE3-CTRL3: pass=TRUE,waiting to receive abort from memory", NULL1)
                        ALT
                          MemDabt0? Dabt0
                            SEQ
                              clock5:=max(clock5,Dabt0[TIME.STAMP])+delay[12]  --DESWAIT+XOR
                              debugmsg(report,screen[0], "DECODE3-CTRL3: pass=TRUE, received Dabt0 from memory  ",Dabt0 )
                              abort0.received:=TRUE
                              
                              SKIP
                          MemDabt1? Dabt1
                            SEQ
                              clock5:=max(clock5,Dabt1[TIME.STAMP])+delay[12]  --DESWAIT+XOR

                              debugmsg(report,screen[0], "DECODE3-CTRL3: pass=TRUE, received Dabt1 from memory  ", NULL1)
                              Dabtlaten:=TRUE     --enable latch to get new pcpar
                                                  --may have the same value 
                              DPdabt:= (NOT DP)   --we use DP for the alp-latch
                    pass=FALSE
                      SEQ
                        debugmsg(report,screen[0], "DECODE3-CTRL3: pass=FALSE... ", NULL1)
                        debugmsg(report,screen[0], "DECODE3-CTRL3: waiting to send abort to AddInt... ", NULL1)
                        Dabtai[TIME.STAMP]:= clock5+delay[13] --XOR
                        AIDabt0!Dabtai
                        debugmsg(report,screen[0], "DECODE3-CTRL3: sent abort to AddInt... ", NULL1)
                        
                        clock5:=clock5+delay[14]  --XOR
                        

              C3b[12]=TRUE
                SEQ
                  debugmsg(report,screen[0], "DECODE3-CTRL3: C3[12] is TRUE, not reading Dabt from memory  ", NULL1)
                  SKIP

            clock5:=clock5+delay[15]   -- XOR

        -------------------------------------------end of *A*
        SEQ

          -----------------------CHANGE DP, PCPAR
          IF
            ((DPdabt<>DP) OR  (DPtpcp<>DP))=TRUE     --change DP
              SEQ
                DP:=NOT DP
                debugmsg(report,screen[4], "DECODE3-CTRL3: changing  the value of DP into  ", [(INT DP),0,0,0])


            TRUE
              SKIP
          IF
            ((Dabtlaten=TRUE) OR (DPflaten=TRUE))   --enable PcPar latch
              SEQ
                IF
                  pcpar.updated=FALSE
                    SEQ
                      PrevPcPar:=PcPar
                      PcPar:=NOT Pcp1
                  pcpar.updated=TRUE
                    SEQ
                      pcpar.updated:=FALSE
                IF
                  (PrevPcPar<>PcPar)                    --change PcPar?
                    SEQ 

                      --Dabtlaten will inform Dec1CtrlA the reason of the PcPar change
                      debugmsg(report,screen[0], "DECODE3-CTRL3: PCpar has changed.... ", PCpr )
                      init.hex(PCpr[0], [PcPar,Dabtlaten]) 
                      PCpr[TIME.STAMP]:=Pcpar.clock 
                      ToDec1PCp!PCpr
                      debugmsg(report,screen[0], "DECODE3-CTRL3: PCpar sent to Dec1.... ", PCpr )
                  TRUE
                    SKIP

            TRUE
              SEQ
                debugmsg(report,screen[0], "DECODE3-CTRL3: PCpar not sent.... ", PCpr )
                SKIP 
              


          PAR  --*B*
            ----------------------------------B.1   
            SEQ
              IF
                preemption=PREEMPTION.OFF
                  SEQ
                    IF
                      (pass=FALSE) AND (C3b[31]=TRUE) AND (fail.due.to.pcpar=FALSE)
                        SEQ
                          SEQ
                            SEQ
                              alP[0]:=#00000400    --alp[10]=TRUE   alp[11]=FALSE (do not send to regbank)
                              RE[0]:=NULL.MESSAGE
                              ToWrregD1!RE
                              ToWrregD2!alP 
                                  
                              debugmsg(report,screen[1], "DECODE3-CTRL3: CONDITION CODES FAILED sending second NULL.MESSAGE.... ", NULL1)
                              debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  RE ", RE )
                              debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  alP ", alP )
                              debugmsg(report,screen[1], "DECODE3-CTRL3: waiting for ack from Wreg ", NULL1)
                              FWrregA? Ackwr
                              debugmsg(report,screen[1], "DECODE3-CTRL3: received ack from Wreg ", NULL1)

                      TRUE
                        SEQ
                          SKIP

                preemption=PREEMPTION.ON
                  SEQ
                    SKIP
              ---------------------------------------------------

              IF
                abort0.received=TRUE
                  SEQ
                    SEQ
                      IF
                        preemption=PREEMPTION.OFF
                          SEQ 
                            IF 
                              C3b[30]=FALSE     
                                SEQ

                                  alP[0]:=#00000400    --alp[10]=TRUE   alp[11]=FALSE (do not send to regbank)
                                  RE[0]:=NULL.MESSAGE
                                  ToWrregD1!RE
                                  ToWrregD2!alP                                  
                                  debugmsg(report,screen[1], "DECODE3-CTRL3: sending NULL.MESSAGE for ABORT.... ", NULL1)
                                  debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  RE ", RE )
                                  debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  alP ", alP )
                                  debugmsg(report,screen[3], "DECODE3-CTRL3: waiting for ack from Wreg ", NULL1)
                                  FWrregA? Ackwr
                                  debugmsg(report,screen[3], "DECODE3-CTRL3: received ack from Wreg ", NULL1)

                              TRUE
                                SEQ
                                  SKIP
                                  debugmsg(report,screen[1], "DECODE3-CTRL3: C3b[30] TRUE not sending NULL.MESSAGE for ABORT.... ", NULL1)


                        preemption=PREEMPTION.ON
                          SEQ
                            SKIP
                abort0.received=FALSE
                  SEQ
                    SKIP

            ----------------------------------                       
            SEQ
              IF
                C3b[11] = TRUE
                  SEQ
                    Pcp1:=PcPar    --enable latch
                C3b[11] = FALSE
                  SEQ
                    SKIP  
              -------------------------------------
              SEQ
                Ackop[TIME.STAMP]:= max ((max(clock3, clock5) + delay[16]), clock4) +delay[17]            --MULLERC+SELECT+XOR ,  MULLERC+CALL+XOR
                Ackd3[TIME.STAMP]:=max ((max(clock3, clock5) + delay[16]), clock4) +delay[17]            --MULLERC+SELECT+XOR ,  MULLERC+CALL+XOR
                Ackcp[TIME.STAMP]:=max ((max(clock3, clock5) + delay[16]), clock4) +delay[18]     --MULLERC+SELECT+XOR ,  MULLERC+CALL
                calculate.occupancy(evaluate, occupancy.table[0], Ackd3[TIME.STAMP],ALfs )  
                calculate.occupancy(evaluate, occupancy.table[2], Ackop[TIME.STAMP],Opa )  

                PAR
                  IF --1
                    ((NOT pass) OR C3b[22])=TRUE
                      SEQ
                        calculate.occupancy(evaluate, occupancy.table[1], Ackcp[TIME.STAMP],Cpsr )  
                        ToCPregA!Ackcp 
                    ((NOT pass) OR C3b[22])=FALSE
                      SEQ
                        SKIP
                  ToOPregA!Ackop
                  ToDec3A!Ackd3                       
        -------------------------------------------end of *B*
        PAR 
          SEQ
            debugmsg(report,screen[0], "DECODE3-CTRL3: Waiting from OP register...  ", NULL1)
            FOPregDA?Opa
            IF
              Opa[0]<>FINISH          --from Ctrl2 through OP register
                SEQ
                  -------------------------------------------------------------
                  WHILE (Opa[0]=NULL.MESSAGE)
                    SEQ
                      FOPregDB? Opb
                      PAR
                        ToOPregA!Ackop
                        SEQ
                          alP[0]:=#00000400    --alp[10]=TRUE   alp[11]=FALSE (do not send to regbank)
                          RE[0]:=NULL.MESSAGE
                          ToWrregD1!RE
                          ToWrregD2!alP 
                          debugmsg(report,screen[1], "DECODE3-CTRL3: received NULL from OPreg !!", NULL1)
                          debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  RE ", RE )
                          debugmsg(report,screen[1], "DECODE3-CTRL3: sent to WrtCtrl  alP ", alP )
                          debugmsg(report,screen[1], "DECODE3-CTRL3: waiting for ack from Wreg ", NULL1)
                          FWrregA? Ackwr
                      FOPregDA?Opa
                  -------------------------------------------------------------

                  PAR
                    SEQ
                      FOPregDB? Opb
                      debugmsg(report,screen[0], "DECODE3-CTRL3: Received from OP register...Opa", Opa )
                      debugmsg(report,screen[0], "DECODE3-CTRL3: Received from OP register...Opb ", Opb )

                    SEQ
                      debugmsg(report,screen[1], "DECODE3-CTRL3: Waiting from Dec3...  ", NULL1)
                      FromDec3D1? ALfs   --from Dec3
                      FromDec3D2? C3   --from Dec3  
                      debugmsg(report,screen[1], "DECODE3-CTRL3: Received from Dec3... ALfs  ", ALfs )
                      debugmsg(report,screen[1], "DECODE3-CTRL3: Received from Dec3... C3 ", C3 )                 
                    IF --1      --read from CPsr reg only if ack has been sent 
                      ((NOT pass) OR C3b[22])=TRUE
                        SEQ
                          debugmsg(report,screen[2], "DECODE3-CTRL3: Waiting from CPSR register...  ", NULL1) 
                          debugmsg(report,screen[2], "DECODE3-CTRL3: pass was...  ", [(INT pass),0,0,0])
                          debugmsg(report,screen[2], "DECODE3-CTRL3:  C3b[22] was...  ", [(INT C3b[22]),0,0,0])

 
                          FromCPregD? Cpsr 
                          debugmsg(report,screen[2], "DECODE3-CTRL3: Received from CPSR register...  ", Cpsr )                  
                          int.to.bool(Cpsr[0], Cpsrb)
                          ShC:=Cpsrb[7]
                          ------------------calculate new pass--------------
                          [condinb FROM 0 FOR 4]:=[psrV,psrC,psrZ,psrN]
                          condinb[4]:= Pcp1
                          [condinb FROM 5 FOR 7]:=[Cpsrb FROM 0 FOR 7]                  
                          init.hex(condin,condinb)
                          Cond(condin,condout)
                          int.to.bool(condout,condoutb)
                          pass:=condoutb[0]
                          debugmsg(report,screen[2], "DECODE3-CTRL3: new pass is...  ", [(INT pass), 0,0,0])
                          -----------------NULL MESSAGES????-----------------
                          IF
                            Pcp1<>Cpsrb[4]
                              SEQ
                                fail.due.to.pcpar:=TRUE
                            Pcp1=Cpsrb[4]
                              SEQ
                                fail.due.to.pcpar:=FALSE                      
                          ---------------------------------------------------

                          --CP0(ShC1,Pass,aluN,aluZ,aluC,aluV,Omd[6:0])
                          [CP0b FROM 0 FOR 11]:=[CPb  FROM 0 FOR 11] 
                          CP0b[11]:=pass 
                          CP0b[12]:=ShC

                      ((NOT pass) OR C3b[22])=FALSE
                        SEQ
                          debugmsg(report,screen[2], "DECODE3-CTRL3: Not receiving from CPSR register...  ", NULL1) 

                          SKIP
              TRUE
                end:=TRUE
          --IF
            --(NOT((previous.pass AND C3b[14]) OR C3b[15]))=FALSE
              --SEQ
                --debugmsg(report,screen[3], "DECODE3-CTRL3: waiting for ack from Wreg ", NULL1)
                --FWrregA? Ackwr
                --debugmsg(report,screen[3], "DECODE3-CTRL3: received ack from Wreg ", NULL1)
            --(NOT((previous.pass AND C3b[14]) OR C3b[15]))=TRUE
             -- SEQ
                --debugmsg(report,screen[3], "DECODE3-CTRL3: do not wait for ack from Wreg ", NULL1)
                --SKIP
    ------------------------------------------------------------------
    PAR
      FWrregA? Ackwr
      terminate(evaluate, Opa[TIME.STAMP],KILL,FLUSH, occupancy.table, screen[0], [ToWrregD1,Toctrl2D,ALUgo,ToDec1PCp,AIDabt0])


:
