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

PROC Reg(CHAN OF BUNDLE FWCtrlD, FWCtrlC,ToWrtCtrlA,Iinstr,IPc,Iack,
                         OAout,OBout,Oack,
         []CHAN OF DEB.MESSAGE screen, VAL INT report,evaluate)  --6

  CHAN OF BUNDLE FIRegD,FIRegPC, FORegA1, FWRegA,FWrtCtrl,
                  ToRLckA,ToRLckB,ToRLckPC,ToWRegD, ToIRegA,
                  FORegA2, FWReg, FALkFA,FMLkFA,ToALkFW,
                  ToALkFPs, ToMLkFW, ToMLkFPs,ToWRegA,WfromAf,AfromAf,
                  AfromMf,WfromMf, ToRegsA,ToRegsB,ToMultiA,ToMultiB,
                  FALkFW,FALkFSl,FMLkFW,FMLkFSl,ToALkFa,ToMLkFa, Abus,Bbus,WCRddone:



  ----------------------------------------------------------------
  PROC fifo.stage.2ack(CHAN OF BUNDLE DAin, DBin, DAout, DBout,Ain1, Ain2,Aout)

    [MESGLEN]INT Adata,Bdata,Ack1,Ack2, ack:
    BOOL end:
    INT data.TIME.STAMP, clock:
    VAL INT delay IS MULLERC+TOGGLE:
    SEQ
      end:=FALSE
      ack[TIME.STAMP]:=0   --initially
      PAR
        DAin?Adata
        DBin? Bdata
      IF
        Adata[0]<>FINISH
          SEQ
            SKIP
        TRUE
          end:=TRUE

      WHILE NOT end
        SEQ
          data.TIME.STAMP:=max(Adata[TIME.STAMP], Bdata[TIME.STAMP])+delay  --MULLERc+TOGGLE

          --------check for stalls-------------
          IF
            Adata[STALL]=(-1)     --I am the first register in the pipe
              SEQ  
                IF
                  ack[TIME.STAMP] > data.TIME.STAMP
                    SEQ
                      Adata[STALL]:= (ack[TIME.STAMP] - Adata[TIME.STAMP])
                  TRUE
                    SEQ
                      Adata[STALL]:= 0

                      SKIP
                Adata[TIME.IN]:=(max(ack[TIME.STAMP], data.TIME.STAMP)) 

            TRUE
              SKIP

          --------calculate timestamps---------------
          clock:=(max(ack[TIME.STAMP], data.TIME.STAMP)) + REGISTER.DELAY
          Adata[TIME.STAMP]:=clock

          IF
            ack[TIME.STAMP] >  data.TIME.STAMP
              SEQ
                clock:=clock+REGISTER.DELAY.ASU
            ack[TIME.STAMP] <=  data.TIME.STAMP
              SEQ
                SKIP     

          Ack1[TIME.STAMP]:=clock
          Ack2[TIME.STAMP]:=clock

          --------send messages---------------
          PAR
            Ain1 ! Ack1
            Ain2 ! Ack2
            DAout! Adata
            DBout! Bdata
          PAR
            SEQ
              PAR
                DAin?Adata
                DBin? Bdata
              IF
                Adata[0]<>FINISH
                  SEQ
                    SKIP
                TRUE
                  end:=TRUE
            Aout ?  ack
  :
  -----------------------------------
  PROC IReg(CHAN OF BUNDLE DAin, DBin, DAout, DBout,Ain,Aout)
    SEQ
      two.input.stage(DAin, DBin, DAout, DBout,Ain,Aout )

  :
  -----------------------------------
  PROC WReg(CHAN OF BUNDLE DAin, DAout,Ain,Aout)
    SEQ
      fifo.stage(DAin, DAout,Ain,Aout )
  :
  -----------------------------------
  PROC OReg(CHAN OF BUNDLE DAin, DBin, DAout, DBout, Ain1, Ain2, Aout)
    SEQ
      fifo.stage.2ack(DAin, DBin, DAout, DBout, Ain1, Ain2, Aout)
  :
  -----------------------------------

  PROC LkFifos(CHAN OF BUNDLE ADAin,ADBin,ADAout,ADBout,AAin,AAout,
               AToRdLockD,AToRdLkOK ,
               MDAin,MDBin,MDAout,MDBout,MAin,MAout,MToRdLockD,MToRdLkOK)

    ------------------------------------------
    PROC first.stage.lk(CHAN OF BUNDLE DAin, DBin, DAout, DBout,Ain,Aout,
                        ToRdLockA)

      [MESGLEN]INT Adata,Bdata,ack:
      BOOL end:
      INT clock:


      SEQ
        end:=FALSE
        ack[TIME.STAMP]:=0  --initially
        DAin?Adata
        IF
          Adata[0]<>FINISH
            SEQ
              DBin? Bdata
          TRUE
            end:=TRUE
        WHILE NOT end
          SEQ
            --------check for stalls-------------
            ------Adata carries timing information
            IF
              Adata[STALL]=(-1)     --I am the first register in the pipe
                SEQ  
                  IF
                    ack[TIME.STAMP] > Adata [TIME.STAMP]   --stall
                      SEQ
                        Adata[STALL]:= (ack[TIME.STAMP] - Adata [TIME.STAMP])
                    TRUE
                      SEQ
                        Adata[STALL]:= 0
                        SKIP      
                  Adata[TIME.IN]:=(max(ack[TIME.STAMP], Adata[TIME.STAMP]))
 
              TRUE
                SKIP        

            --------calculate timestamps---------------
            clock:=(max (ack[TIME.STAMP], Adata[TIME.STAMP])) + REGISTER.DELAY
            Adata[TIME.STAMP]:=clock
            IF
              ack[TIME.STAMP] > Adata[TIME.STAMP]
                SEQ
                  clock:=clock+REGISTER.DELAY.ASU
              ack[TIME.STAMP] <= Adata[TIME.STAMP]
                SEQ
                  SKIP     
            ack[TIME.STAMP]:=clock
            --------send messages---------------
            ToRdLockA!Adata
            PAR
              DAout! Adata
              DBout! Bdata
              Ain ! ack

            PAR
              SEQ
                DAin?Adata
                IF
                  Adata[0]<>FINISH
                    SEQ
                      DBin? Bdata
                  TRUE
                    end:=TRUE
              Aout ?  ack
        -----------------------------------
        DAout!Adata

    :
    ----------------------------------------
    PROC last.stage.alk(CHAN OF BUNDLE DAin, DBin, DAout, DBout,Ain,Aout,
                        ToRdLkOK )

      [MESGLEN]INT Adata,Bdata,ack:
      BOOL end:
      INT clock:

      SEQ
        end:=FALSE

        ack[TIME.STAMP]:=0  --initially
        DAin?Adata
        IF
          Adata[0]<>FINISH
            SEQ
              DBin? Bdata
          TRUE
            end:=TRUE

        WHILE NOT end
          SEQ

            --------check for stalls-------------
            ------Adata carries timing information
            IF
              Adata[STALL]=(-1)     --I am the first register in the pipe
                SEQ  
                  IF
                    ack[TIME.STAMP] > Adata [TIME.STAMP]   --stall
                      SEQ
                        Adata[STALL]:= (ack[TIME.STAMP] - Adata [TIME.STAMP])
                    TRUE
                      SEQ
                        Adata[STALL]:= 0
                        SKIP      
                  Adata[TIME.IN]:=(max(ack[TIME.STAMP], Adata[TIME.STAMP])) 
 
              TRUE
                SKIP        


            --------calculate timestamps---------------
            clock:=(max (ack[TIME.STAMP], Adata[TIME.STAMP])) + REGISTER.DELAY
            Adata[TIME.STAMP]:=clock

            IF
              ack[TIME.STAMP] > Adata[TIME.STAMP]
                SEQ
                  clock:=clock+REGISTER.DELAY.ASU
              ack[TIME.STAMP] <= Adata[TIME.STAMP]
                SEQ
                  SKIP     

            ack[TIME.STAMP]:=clock

            --------send messages---------------
            PAR
              Ain!ack
              DAout! Adata
              DBout! Bdata
            PAR
              SEQ
                DAin?Adata
                IF
                  Adata[0]<>FINISH
                    SEQ
                      DBin? Bdata
                  TRUE
                    end:=TRUE
              SEQ
                Aout ?  ack
                ToRdLkOK!ack
        --------------------------------  
        PAR           
          ToRdLkOK!Adata    --kill readlock  
          --DAout! Adata   --kill registers/write

    :
    -----------------------------------------------
    PROC last.stage.mlk(CHAN OF BUNDLE DAin, DBin, DAout, DBout,Ain,Aout,
                        ToRdLkOK )

      [MESGLEN]INT Adata,Bdata,ack:
      BOOL end:
      INT clock:

      SEQ
        end:=FALSE

        ack[TIME.STAMP]:=0  --initially
        DAin?Adata
        IF
          Adata[0]<>FINISH
            SEQ
              DBin? Bdata
          TRUE
            end:=TRUE

        WHILE NOT end
          SEQ

            --------check for stalls-------------
            ------Adata carries timing information
            IF
              Adata[STALL]=(-1)     --I am the first register in the pipe
                SEQ  
                  IF
                    ack[TIME.STAMP] > Adata [TIME.STAMP]   --stall
                      SEQ
                        Adata[STALL]:= (ack[TIME.STAMP] - Adata [TIME.STAMP])
                    TRUE
                      SEQ
                        Adata[STALL]:= 0
                        SKIP      
                  Adata[TIME.IN]:=(max(ack[TIME.STAMP], Adata[TIME.STAMP]))
 
              TRUE
                SKIP        

            --------calculate timestamps---------------
            clock:=(max (ack[TIME.STAMP], Adata[TIME.STAMP])) + REGISTER.DELAY
            Adata[TIME.STAMP]:=clock

            IF
              ack[TIME.STAMP] > Adata[TIME.STAMP]
                SEQ
                  clock:=clock+REGISTER.DELAY.ASU
              ack[TIME.STAMP] <= Adata[TIME.STAMP]
                SEQ
                  SKIP     

            ack[TIME.STAMP]:=clock

            --------send messages---------------
            PAR
              Ain!ack
              DAout! Adata
              DBout! Bdata
            PAR
              SEQ
                DAin?Adata
                IF
                  Adata[0]<>FINISH
                    SEQ
                      DBin? Bdata
                  TRUE
                    end:=TRUE
              SEQ
                Aout ?  ack
                ToRdLkOK!ack
        --------------------------------  
        PAR           
          --ToRdLkOK!Adata    --kill readlock  
          --DAout! Adata   --kill registers/write

    :
    -----------------------------------------------
    PROC ALkFifo(CHAN OF BUNDLE DAin,DBin,DAout,DBout,Ain,Aout,
                 AToRdLockD,AToRdLkOK)

      VAL INT num.of.stages IS RBALKFIFO.SIZE:
      [num.of.stages]CHAN OF BUNDLE DA,DB, Ack:
      INT i:
      PAR
        first.stage.lk(DAin,DBin, DA[0], DB[0],
                         Ain, Ack[0], AToRdLockD)

        PAR i=0 FOR num.of.stages-2
          two.input.stage(DA[i],DB[i],DA[i+1], DB[i+1], Ack[i], Ack[i+1])

        last.stage.alk(DA[num.of.stages-2],DB[num.of.stages-2],
                     DAout,DBout, Ack[num.of.stages-2], Aout, AToRdLkOK)
    :

    --------------------------------------------------------------------------
    PROC MLkFifo(CHAN OF BUNDLE DAin,DBin,DAout,DBout,Ain,Aout,
                 MToRdLockD,MToRdLkOK)

      VAL INT num.of.stages IS RBMLKFIFO.SIZE:
      [num.of.stages]CHAN OF BUNDLE DA,DB, Ack:
      INT i:
      PAR
        first.stage.lk(DAin,DBin, DA[0], DB[0],
                         Ain, Ack[0],MToRdLockD)

        PAR i=0 FOR num.of.stages-2
          two.input.stage(DA[i],DB[i],DA[i+1], DB[i+1], Ack[i], Ack[i+1])

        last.stage.mlk(DA[num.of.stages-2],DB[num.of.stages-2],
                     DAout,DBout, Ack[num.of.stages-2],Aout, MToRdLkOK)
    :

    --------------------------------------------------

    PAR
      ALkFifo( ADAin,ADBin,ADAout,ADBout,AAin,AAout,
                 AToRdLockD,AToRdLkOK )

      MLkFifo( MDAin,MDBin,MDAout,MDBout,MAin,MAout,
                 MToRdLockD,MToRdLkOK )
  :
  --------------------------------------------------------------
  PROC ReadLock(CHAN OF BUNDLE AfromAf,AfromMf,WfromAf,WfromMf,FRdCtrlA,
                FRdCtrlB,FRdCtlPC,ToRegsA,ToRegsB,ToMultiA,ToMultiB,
                []CHAN OF DEB.MESSAGE screen,VAL INT report )

    VAL INT AfSize IS 3:
    VAL INT MfSize IS 4:
    [AfSize]INT Abuffer:
    [MfSize]INT Mbuffer:

    INT Atop, Abase, Mtop, Mbase, aaddr,baddr,i,pc,acontents,mcontents:
    BOOL awaits, bwaits, acango, bcango,aOK,bOK, end, afinish, mfinish:

    [MESGLEN]INT  Signal,Aaddr,Baddr,Waddr,PC:
    [3]INT delay:
    ----------------------------------------------------------
    PROC calculate.delays()
      SEQ
        delay[0]:=AND.GATE
        delay[1]:=AND.GATE+XOR
    :
    -----------------------------------------------------------      
  

    SEQ
      calculate.delays()
      Atop:=0
      Mtop:=0
      Abase:=0
      Mbase:=0
      acontents:=0
      mcontents:=0
      awaits:=FALSE
      bwaits:=FALSE
      end:=FALSE
      afinish:=FALSE
      mfinish:=FALSE
    
      SEQ i=0 FOR SIZE Abuffer
        SEQ
          Abuffer[i]:=UNDEF

      SEQ i=0 FOR SIZE Mbuffer
        SEQ
          Mbuffer[i]:=UNDEF

      WHILE ((mfinish=FALSE) OR (afinish=FALSE))
        ----------------------------------------------------------------
        PRI ALT

          AfromAf? Signal    --unlock from A Fifo
            SEQ
              IF
                Signal[0]=FINISH
                  SEQ
                    afinish:=TRUE
                TRUE
                  SEQ
                    debugmsg(report,screen[0], "REG-READLOCK: Received unlock signal from Afifo ",NULL1)
                    Abase:=(Abase+1) REM AfSize
                    acontents:=acontents-1
                    --------------------------------------Check A address
                    IF
                      (awaits=TRUE)
                        SEQ
                          acango:=TRUE
                          --------------------   search A Fifo
                          i:=Abase
                          WHILE (i<>Atop)
                            SEQ
                              IF
                                ((Abuffer[i]=aaddr))
                                  acango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM AfSize

                          --------------------   search M Fifo
                          i:=Mbase
                          WHILE (i<>Mtop)
                            SEQ
                              IF
                                ((Mbuffer[i]=aaddr))
                                  acango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM MfSize
                      TRUE
                        SKIP
                    --------------------------------------Check B address

                    IF
                      (bwaits=TRUE)
                        SEQ
                          bcango:=TRUE

                          i:=Abase
                          WHILE (i<>Atop)
                            SEQ
                              IF
                                (Abuffer[i]=baddr)
                                  bcango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM AfSize

                          i:=Mbase
                          WHILE (i<>Mtop)
                            SEQ
                              IF
                                (Mbuffer[i]=baddr)
                                  bcango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM MfSize
                      TRUE
                        SKIP

                    --------------------------------------------------------
                    PAR
                      --------------------------------A address
                      IF
                        (acango=TRUE) AND (awaits=TRUE)
                          SEQ
                            Aaddr[TIME.STAMP]:=Signal[TIME.STAMP]+delay[1] --AND+XOR
                            ToRegsA!Aaddr
                            awaits:=FALSE
                            debugmsg(report,screen[0], "REG-READLOCK: sent to ReadCtrl Aaddress ",Aaddr)
                        TRUE
                          SKIP
                      --------------------------------B address

                      IF
                        (bcango=TRUE) AND (bwaits=TRUE)
                          SEQ
                            Baddr[TIME.STAMP]:=Signal[TIME.STAMP]+delay[1] --AND+XOR

                            ToRegsB!Baddr
                            bwaits:=FALSE
                            debugmsg(report,screen[1], "REG-READLOCK: sent to ReadCtrl Baddress ",Baddr)
                        TRUE
                          SKIP


          ------------------------------------------------------
          AfromMf? Signal    --unlock from M Fifo
            SEQ
              IF
                Signal[0]=FINISH
                  SEQ
                    mfinish:=TRUE
                TRUE
                  SEQ
                    debugmsg(report,screen[0], "REG-READLOCK: Receiced unlock signal from Mfifo ",NULL1)
                    Mbase:=(Mbase+1) REM MfSize
                    mcontents:=mcontents-1
                    --------------------------------------Check A address
                    IF
                      (awaits=TRUE)
                        SEQ
                          acango:=TRUE
                          --------------------   search A Fifo
                          i:=Abase
                          WHILE (i<>Atop)
                            SEQ
                              IF
                                ((Abuffer[i]=aaddr) )
                                  acango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM AfSize

                          --------------------   search M Fifo
                          i:=Mbase
                          WHILE (i<>Mtop)
                            SEQ
                              IF
                                ((Mbuffer[i]=aaddr) )
                                  acango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM MfSize
                      TRUE
                        SKIP
                    --------------------------------------Check B address

                    IF
                      (bwaits=TRUE)
                        SEQ
                          bcango:=TRUE

                          i:=Abase
                          WHILE (i<>Atop)
                            SEQ
                              IF
                                (Abuffer[i]=baddr)
                                  bcango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM AfSize

                          i:=Mbase
                          WHILE (i<>Mtop)
                            SEQ
                              IF
                                (Mbuffer[i]=baddr)
                                  bcango:=FALSE
                                TRUE
                                  SKIP
                              i:=(i+1) REM MfSize
                      TRUE
                        SKIP

                    --------------------------------------------------------
                    PAR
                      --------------------------------A address
                      IF
                        (acango=TRUE) AND (awaits=TRUE)
                          SEQ
                            Aaddr[TIME.STAMP]:=Signal[TIME.STAMP]+delay[1] --AND+XOR
                            ToRegsA!Aaddr
                            awaits:=FALSE
                            debugmsg(report,screen[0], "REG-READLOCK: unlock: sent to Registers/Read  Aaddress",Aaddr)
                        TRUE
                          SKIP
                      --------------------------------B address

                      IF
                        (bcango=TRUE) AND (bwaits=TRUE)
                          SEQ
                            Baddr[TIME.STAMP]:=Signal[TIME.STAMP]+delay[1] --AND+XOR
                            ToRegsB!Baddr
                            bwaits:=FALSE
                            debugmsg(report,screen[1], "REG-READLOCK: unlock: sent toRegisters/Read  Baddress ",Baddr)
                        TRUE
                          SKIP

          -----------------------------------------------------------
          acontents < (SIZE Abuffer) & WfromAf?Waddr               --Get new lock address from A Fifo
            SEQ
              debugmsg(report,screen[0], "REG-READLOCK: Receiced new lock address from Afifo ",Waddr)
              IF
                Waddr[0]<>FINISH
                  SEQ
                    Abuffer[Atop]:=Waddr[0]
                    Atop:=(Atop+1) REM AfSize
                    acontents:=acontents+1
                TRUE
                  SKIP
          -----------------------------------------------------------
          mcontents < (SIZE Mbuffer) & WfromMf?Waddr               --Get new lock addresses from M Fifo
            SEQ
              debugmsg(report,screen[0], "REG-READLOCK: Receiced new lock address from Mfifo ",Waddr)
              IF
                Waddr[0]<>FINISH
                  SEQ
                    Mbuffer[Mtop]:=Waddr[0]
                    Mtop:=(Mtop+1) REM MfSize
                    mcontents:=mcontents+1

                TRUE
                  SKIP
          -----------------------------------------------------------
          FRdCtrlA?Aaddr             --Get read addresses from the Read control

            SEQ

              IF
                Aaddr[0]<>FINISH

                  SEQ
                    aOK:=FALSE
                    bOK:=FALSE
                    PAR
                      FRdCtrlB? Baddr
                      FRdCtlPC? PC
                    debugmsg(report,screen[0], "REG-READLOCK: Received read addresses from Read Control A: ",Aaddr)
                    debugmsg(report,screen[0], "REG-READLOCK: Received read addresses from Read Control B: ",Baddr)
                    debugmsg(report,screen[0], "REG-READLOCK: Received read addresses from Read Control PC: ",PC)
                    aaddr:=Aaddr[0]
                    baddr:=Baddr[0]
                    --In The ASIM model the PC that is sent to the Reg Bank
                    --from the AddInt(PCpipe or Xpipe), is PC[31:2],ie
                    --the first 2 bits of the PC produced by the PC loop are
                    --ignored. In the regbank the PC is shifted left, so
                    --that is becomes a 32-bit integer again, with the first
                    --two digits 0.
                    PC[0]:=(PC[0]>>2)
                    PC[0]:=(PC[0]<<2)
                    PC[STALL]:=(-1)
                    IF                  --check if PC is to be read
                      (aaddr=30)
                        SEQ
                          debugmsg(report,screen[0], "REG-READLOCK: Aaddress is 30 for PC: ",PC)
                          PAR
                            ToMultiA!PC
                            ToRegsA!Aaddr
                          debugmsg(report,screen[0], "REG-READLOCK: Aaddress has been forwarded to Multiplex: ",Aaddr)
                          aOK:=TRUE
                      TRUE
                        SKIP
                    IF                  --check if PC is to be read
                      (baddr=30)
                        SEQ
                          debugmsg(report,screen[0], "REG-READLOCK: Baddress is 30 for PC: ",PC)
                          PAR
                            ToMultiB!PC
                            ToRegsB!Baddr
                          bOK:=TRUE
                          debugmsg(report,screen[0], "REG-READLOCK: Baddress has been forwarded to Multiplex: ",Baddr)

                      TRUE
                        SKIP
                    -----------------------------search A Fifo
                    i:=Abase
                    WHILE (i<>Atop)
                      SEQ
                        IF                        --A address
                          ((Abuffer[i]=aaddr) )
                            SEQ
                              awaits:=TRUE
                              debugmsg(report,screen[0], "REG-READLOCK: Aaddress is waiting in Afifo ",[aaddr, 0,0,0])
                          TRUE
                            SKIP
                        IF                        --B address
                          (Abuffer[i]=baddr)
                            SEQ
                              bwaits:=TRUE
                              debugmsg(report,screen[0], "REG-READLOCK: Baddress is waiting in Afifo ",[baddr,0,0,0])

                          TRUE
                            SKIP
                        i:=(i+1) REM AfSize

                    -----------------------------search M Fifo

                    i:=Mbase
                    WHILE (i<>Mtop)
                      SEQ
                        IF                        --A address
                          ((Mbuffer[i]=aaddr) )
                            SEQ
                              awaits:=TRUE
                              debugmsg(report,screen[0], "REG-READLOCK: Aaddress is waiting in Mfifo ",[aaddr,0,0,0])

                          TRUE
                            SKIP
                        IF                        --B address
                          (Mbuffer[i]=baddr)
                            SEQ
                              bwaits:=TRUE
                              debugmsg(report,screen[0], "REG-READLOCK: Baddress is waiting in Afifo ",[baddr,0,0,0])

                          TRUE
                            SKIP

                        i:=(i+1) REM MfSize

                    --------------------------------------
                    PAR
                      ----------------------
                      IF
                        (awaits=FALSE) AND (aOK=FALSE)
                          SEQ
                            Aaddr[TIME.STAMP]:=Aaddr[TIME.STAMP]+delay[0]  --AND
                            ToRegsA!Aaddr

                        TRUE
                          SEQ

                            SKIP
                      ----------------------
                      IF
                        (bwaits=FALSE) AND (bOK=FALSE)
                          SEQ
                            Baddr[TIME.STAMP]:=Baddr[TIME.STAMP]+delay[0]  --AND
                            ToRegsB!Baddr

                        TRUE
                          SEQ

                            SKIP

                TRUE
                  SEQ
                    end:=TRUE
      ------------------------------------------------
      --kill mux, read
      PC[0]:=FINISH
      PAR
        ToRegsA!PC
        ToMultiA!PC
  :
  -----------------------------------
  PROC Registers (CHAN OF BUNDLE FRdLkA, FRdLkB, FWCtrlD, FWCtrlC, FALkFW,
                                  FALkFSl, FMLkFW,FMLkFSl,ToALkFa,ToMLkFa,
                                  ToWrtCtrlA, Abus, Bbus, FRdLkPCA, FRdLkPCB,
                  CHAN OF DEB.MESSAGE screen,VAL INT report,evaluate)
    [num.of.reg]CHAN OF BUNDLE Rdenact,WrtEnM,CtoA,CtoB,WrtEnW:

    -------------------------------------------------------------------
    PROC Read([]CHAN OF BUNDLE Rdenact, CHAN OF BUNDLE FRdLkA, FRdLkB)

      [MESGLEN]INT addra, addrb, Abus, Bbus:
      BOOL end:

      SEQ
        end:=FALSE
        PAR
          FRdLkA?addra
          FRdLkB?addrb

        IF
          addra[0]<>FINISH
            SEQ
              SKIP
          TRUE
            SEQ
              end:=TRUE

        WHILE NOT end
          SEQ

            Abus[0]:=ABUS
            Bbus[0]:=BBUS
            Abus[TIME.STAMP]:=addra[TIME.STAMP]
            Bbus[TIME.STAMP]:=addrb[TIME.STAMP]

            IF
              addra[0]<>30        --if PC ignore it, it has been sent by ReadLock
                SEQ
                  Rdenact[addra[0]]!Abus
              TRUE
                SKIP
            IF
              addrb[0]<>30
                SEQ
                  Rdenact[addrb[0]]!Bbus
              TRUE
                SKIP
            PAR
              FRdLkA?addra
              FRdLkB?addrb

            IF
              addra[0]<>FINISH
                SEQ
                  SKIP
              TRUE
                SEQ
                  end:=TRUE

    :
    --------------------------------------------------------------------
    PROC Write([]CHAN OF BUNDLE WrtEnW, WrtEnM,
               CHAN OF BUNDLE  FWCtrlD,FWCtrlC,FALkFW,FALkFSl,
               FMLkFW,FMLkFSl,ToALkFa,ToMLkFa,ToWrtCtrlA,CHAN OF DEB.MESSAGE screen )


      [MESGLEN]INT  W, Wctrl,Psel,Wa, Mask,Acklf,Ackwc:
      BOOL end:
      INT reg,i,clock:
      [32]BOOL Wctrlb, Pselb:
      [4]INT delay:
      [2][OCCT.SIZE][OCCT.COL]INT occupancy.table:  --an array of occupancy tables!!!!

      -------------------------------------------------------------------------
      PROC calculate.delays()
        SEQ
          delay[0]:=(((MULLERC+SELECT)+CALLR)+SELECT)
          delay[1]:=(((((XOR+WRITE.ENABLE)+WRITE.COMPLETE)+TOGGLE)+CALLR)+XOR)
          delay[2]:=XOR+CALLA
      :
      ------------------------------------------------------------------
      PROC  initialize.occup.tables()
        SEQ
          initialize.occup.table(occupancy.table[0], RBALKFIFO, RBALKFIFO.SIZE,REGISTER.DELAY)  
          initialize.occup.table(occupancy.table[1], RBMLKFIFO, RBMLKFIFO.SIZE,NGEN.DELAY)
      :
      ------------------------------------------------------------------       


      SEQ
        calculate.delays()
        initialize.occup.tables()
        end:=FALSE
        debugmsg(report,screen, "REG-WRITE: Waiting for Write data and Control ", NULL1)
        FWCtrlD?W
        IF
          W[0]<>FINISH
            SEQ
              FWCtrlC? Wctrl
              debugmsg(report,screen, "REG-WRITE: Received Write data and Control ", W)

          TRUE
            SEQ
              end:=TRUE
        WHILE end=FALSE
          SEQ

            int.to.bool(Wctrl[0], Wctrlb)     --[Ma, valid]
            IF
              Wctrlb[0]=TRUE    --Read from A Lk Fifo
                SEQ
                  debugmsg(report,screen, "REG-WRITE:  Waiting for Write Address from A fifo ", W)
                  PAR
                    FALkFW? Wa
                    FALkFSl? Psel
                  debugmsg(report,screen, "REG-WRITE:  Received Write Address from A fifo ", Wa)


              Wctrlb[0]=FALSE    --Read from M Lk Fifo
                SEQ
                  debugmsg(report,screen, "REG-WRITE:  Waiting for Write Address from M fifo ", W)
                  PAR
                    FMLkFW? Wa
                    FMLkFSl? Psel
                  debugmsg(report,screen, "REG-WRITE:  Received Write Address from M fifo ", Wa)

            clock:=max(Wa[TIME.STAMP], W[TIME.STAMP]) + delay[0] --MULLERC+SELECT+CALL+SELECT

            IF
              Wctrlb[1]=TRUE                  --valid
                SEQ
                  Mask[0]:=0
                  reg:=Wa[0]
                  IF
                    (reg <32)     --register
                      SEQ
                        Mask[0]:=(Mask[0] \/ #FFFFFFFF)
                    TRUE            --SPSR
                      SEQ
                        ---------------------------------------
                        int.to.bool(Psel[0], Pselb)
                        IF
                          Pselb[1]=TRUE       --mode
                            SEQ
                              Mask[0]:=(Mask[0] \/ #000000DF)
                          TRUE
                            SEQ
                              SKIP
                        ---------------------------------------
                        IF
                          Pselb[0]=TRUE       --flag
                            SEQ
                              Mask[0]:=(Mask[0] \/ #F0000000)
                          TRUE
                            SEQ
                              SKIP
                   ---------------------------------------
                  debugmsg(report,screen, "REG-WRITE: writing into register ", [reg,0,0,0])
                  debugmsg(report,screen, "REG-WRITE: data... ", W)
                  debugmsg(report,screen, "REG-WRITE: with Mask ", Mask)

                  WrtEnW[reg]!W
                  WrtEnM[reg]!Mask
                  clock:=clock+delay[1] --XOR+WRITE.ENABLE+WRITE.COMPLETE+TOGGLE+CALL+XOR
              Wctrlb[1]=FALSE                  -- NOT valid
                SEQ
                  debugmsg(report,screen, "REG-WRITE: VALID is FALSE- for data... ", W)
                  clock:=clock+delay[2] --XOR+CALL

                  SKIP
            Acklf[TIME.STAMP]:=clock
            Ackwc[TIME.STAMP]:=clock


            PAR
              ----------------------------------------------------------------
              IF
                Wctrlb[0]=TRUE     -- A Lk Fifo
                  SEQ
                    calculate.occupancy(evaluate, occupancy.table[0], Acklf[TIME.STAMP], Wa) 
                    --debugmsg(report,screen, "REG-WRITE: Waiting to send ack to Alkfifo ", NULL1)
 
                    ToALkFa!Acklf
                    --debugmsg(report,screen, "REG-WRITE: sent ack to Alkfifo ", NULL1)

                Wctrlb[0]=FALSE    -- M Lk Fifo
                  SEQ
                    calculate.occupancy(evaluate, occupancy.table[1], Acklf[TIME.STAMP], Wa)
                    --debugmsg(report,screen, "REG-WRITE: Waiting to send ack to Mlkfifo ", NULL1)
  
                    ToMLkFa!Acklf
                    --debugmsg(report,screen, "REG-WRITE: sent ack to Mlkfifo ", NULL1)

              -----------------------------------------------------------------
              ToWrtCtrlA!Ackwc
              SEQ
                debugmsg(report,screen, "REG-WRITE: Waiting for Write data and Control ", NULL1)
                FWCtrlD?W
                debugmsg(report,screen, "REG-WRITE: Received Write data", W)

                IF
                  W[0]<>FINISH
                    SEQ
                      FWCtrlC? Wctrl
                      debugmsg(report,screen, "REG-WRITE: Received Control ", Wctrl)
                  TRUE
                    SEQ
                      end:=TRUE
        
        ----------------------------------------
        --terminate(evaluate, W[TIME.STAMP],NO.KILL,FLUSH, occupancy.table,screen,WrtEnW)
        --terminate(evaluate, W[TIME.STAMP],NO.KILL,FLUSH, occupancy.table,screen,WrtEnW)
        terminate(evaluate, W[TIME.STAMP],KILL,FLUSH, occupancy.table,screen,WrtEnW)
    :
    --------------------------------------------------------------------------
    PROC Registercells ([]CHAN OF BUNDLE Rdenact, WrtEnW, WrtEnM, Abus, Bbus)

      INT i:
      [num.of.reg]INT init:
      ------------------------------------------------------------------------
      PROC Cell(INT i, CHAN OF BUNDLE FromRd,ToORega,ToORegb,FromWrtW,FromWrtM)

        INT contents, writen:
        BOOL end:
        [MESGLEN]INT  Enact, Contents,Wa, Mask:

        SEQ
          writen:=0
          contents:=i     --initial contents of the registers
          WHILE end=FALSE
            ALT
              -----------------------------------
              FromRd?Enact
                SEQ
                  Contents[TIME.STAMP]:=Enact[TIME.STAMP]+REG.CELL.DELAY     --for timestamp
                  Contents[0]:=contents
                  Contents[STALL]:=(-1)
                  IF
                    Enact[0] = ABUS
                      SEQ
                        ToORega!Contents
                    Enact[0] = BBUS
                      SEQ
                        ToORegb!Contents
              ------------------------------------
              FromWrtW? Wa
                SEQ
                  IF
                    Wa[0]<>FINISH
                      SEQ           
                        FromWrtM? Mask
                        writen:=1
                        contents:=((Wa[0] /\ Mask[0]) \/ (contents /\ (~(Mask[0]))))
                    Wa[0]=FINISH
                      SEQ
                        end:=TRUE


      :
      ------------------------------------------------------------------------
      SEQ
        PAR i=0 FOR num.of.reg
          SEQ
            init[i]:=i

        PAR i=0 FOR num.of.reg
          SEQ

            Cell(init[i], Rdenact[i], Abus[i], Bbus[i], WrtEnW[i], WrtEnM[i])

    :
    ----------------------------------------------------------------------------
    PROC Multiplex([]CHAN OF BUNDLE CtoA, CtoB,  CHAN OF BUNDLE Abus, Bbus,
                   FRdLkPCA,FRdLkPCB )

      [MESGLEN]INT Adata, Bdata,Adata1, Bdata1:
      INT i,j:
      BOOL end,ab,bb,pca,pcb:
      SEQ
        end:=FALSE
        ab,bb,pca,pcb:=FALSE,FALSE,FALSE,FALSE
        WHILE  end=FALSE
          SEQ
            ALT
              ALT i = 0 FOR num.of.reg
                CtoA[i]?Adata
                  SEQ
                    Abus!Adata
              ALT j = 0 FOR num.of.reg
                CtoB[j]?Bdata
                  SEQ
                    Bbus!Bdata

              FRdLkPCA? Adata               --Read PC  From Read Lock
                SEQ
                  IF
                    Adata[0]<>FINISH
                      SEQ
                        Abus!Adata
                    TRUE
                      end:=TRUE
              FRdLkPCB?Bdata
                SEQ
                  Bbus!Bdata


    :
    ---------------------------------------------------------------------------
    SEQ
      PAR
        Read(Rdenact, FRdLkA, FRdLkB)

        Write(WrtEnW, WrtEnM, FWCtrlD,FWCtrlC,FALkFW,FALkFSl,
            FMLkFW,FMLkFSl,ToALkFa,ToMLkFa,ToWrtCtrlA, screen)

        Registercells (Rdenact, WrtEnW, WrtEnM,  CtoA, CtoB)

        Multiplex(CtoA, CtoB, Abus, Bbus, FRdLkPCA,FRdLkPCB )

  :
  -----------------------------------------------------------

  PROC Decode(INT A, VAL INT Nbs, INT dcA, VAL BOOL rNp)
    SEQ

      IF
        rNp=TRUE
          SEQ
            IF
              (A=15)
                SEQ
                  dcA:=30
              TRUE
                SEQ
                  CASE Nbs
                    --------------------
                    #6E
                      SEQ
                        dcA:=A
                    ---------------------
                    #7D
                      SEQ
                        IF
                          (A>7)
                            SEQ
                              dcA:=A+7
                          TRUE
                            SEQ
                              dcA:=A
                    ---------------------
                    #7A
                      SEQ
                        IF
                          (A>12)
                            SEQ
                              dcA:=A+9
                          TRUE
                            SEQ
                              dcA:=A
                    ---------------------
                    #76
                      SEQ
                        IF
                          (A>12)
                            SEQ
                              dcA:=A+11
                          TRUE
                            SEQ
                              dcA:=A
                    ---------------------
                    #5E
                      SEQ
                        IF
                          (A>12)
                            SEQ
                              dcA:=A+13
                          TRUE
                            SEQ
                              dcA:=A
                    ---------------------
                    #3E
                      SEQ
                        IF
                          (A>12)
                            SEQ
                              dcA:=A+15
                          TRUE
                            SEQ
                              dcA:=A

        rNp=FALSE
          SEQ
            CASE Nbs
              --------------------
              #7D                 --FIQ SPSR
                SEQ
                  dcA:=0+32
              --------------------
              #7A                 --IRQ SPSR
                SEQ
                  dcA:=1+32
              --------------------
              #76                 --SVC SPSR
                SEQ
                  dcA:=2+32
              --------------------
              #5E                 --ABORT SPSR
                SEQ
                  dcA:=3+32
              --------------------
              #3E                 --UNDEF SPSR
                SEQ
                  dcA:=4+32


  :
  -----------------------------------------------------------
  PROC ReadCtrl(CHAN OF BUNDLE FIRegD,FIRegPC,FORegA1,FWRegA,FWrtCtrl,
                                ToRLckA,ToRLckB,ToRLckPC,ToWRegD,ToIRegA,WCRddone,
                          CHAN OF DEB.MESSAGE screen,VAL INT report,evaluate)

    [MESGLEN]INT Instr, PC,Aaddr, Baddr,Rdn,Ackw,Acki, Lkx,Instr.occ:
    BOOL end, ArNp,temp:
    INT adec, bdec, nbs, clock0,clock1,clock2:
    [32]BOOL Instrb:
    [4]BOOL adecb,bdecb:
    [7]BOOL nbsb:
    [6]INT delay:
    [1][OCCT.SIZE][OCCT.COL]INT occupancy.table:  --an array of occupancy tables!!!!

    -------------------------------------------------------------------------
    PROC calculate.delays()
      SEQ
        delay[0]:=MULLERC
        delay[1]:=SELECT
        delay[2]:=XOR+RB.DEC.DELAY
        delay[3]:=XOR
        delay[4]:=MULLERC
    :
    -------------------------------------------------------------------
    PROC  initialize.occup.tables()
      SEQ
        initialize.occup.table(occupancy.table[0], RBIREG, RBIREG.SIZE,REGISTER.DELAY) 
    :
    ------------------------------------------------------------------- 

    SEQ
      calculate.delays()
      initialize.occup.tables()
      end:=FALSE
      debugmsg(report,screen, "REG-RDCTRL: Waiting for Instr+PC ", NULL1)
      FIRegD?Instr
      debugmsg(report,screen, "REG-RDCTRL: Received Instr ", Instr)
      IF
        Instr[0]<>FINISH
          SEQ
            FIRegPC? PC
            debugmsg(report,screen, "REG-RDCTRL: Received PC ", PC)

        TRUE
          end:=TRUE

      Lkx[TIME.STAMP]:=0      --initially
      Rdn[TIME.STAMP]:=0      --initially

      WHILE end=FALSE
        SEQ
          Instr.occ:=Instr
          clock0:= max(Instr[TIME.STAMP], Lkx[TIME.STAMP])
          clock0:=max( clock0, Rdn[TIME.STAMP]) +delay[0]   --MULLERC

          int.to.bool(Instr[0], Instrb)
          [adecb FROM 0 FOR 4]:=[Instrb FROM 22 FOR 4]
          [bdecb FROM 0 FOR 4]:=[Instrb FROM 18 FOR 4]
          [nbsb FROM 0 FOR 7]:=[Instrb FROM 0 FOR 7]
          init.hex(adec,adecb)
          init.hex(bdec,bdecb)
          init.hex(nbs,nbsb)
          ArNp:=Instrb[26]
          debugmsg(report,screen, "REG-RDCTRL: Adec= is ", [adec,0,0,0])


          PAR
            -------------------------------------------------
            SEQ

              clock1:=clock0

              Aaddr[0]:=0
              Baddr[0]:=0
              clock1:=clock1+delay[1]  --SELECT
              IF
                Instrb[27]=TRUE                    --RdEn
                  SEQ
                    Decode(adec,nbs,Aaddr[0],ArNp)
                    temp:= VDD
                    Decode(bdec,nbs,Baddr[0],temp)
                    debugmsg(report,screen, "REG-RDCTRL: A-address is ", Aaddr)
                    debugmsg(report,screen, "REG-RDCTRL: B-address is ", Baddr)
                    debugmsg(report,screen, "REG-RDCTRL: Waiting to send to ReadLock ", PC)
                    clock1:= clock1+ delay[2]    --XOR+  RB.DEC.DELAY
                    Aaddr[TIME.STAMP]:=clock1
                    Baddr[TIME.STAMP]:=clock1
                    PC[TIME.STAMP]:=clock1
                    PAR                      --to Read-Lock
                      ToRLckA!Aaddr
                      ToRLckB!Baddr
                      ToRLckPC!PC
                    debugmsg(report,screen, "REG-RDCTRL: sent to ReadLock ", NULL1)
                    debugmsg(report,screen, "REG-RDCTRL: Waiting for Read done signal ", PC)
                    FORegA1? Rdn
                    debugmsg(report,screen, "REG-RDCTRL: Received Read done signal ", PC)


                Instrb[27]=FALSE   -- NO READ
                  SEQ
                    debugmsg(report,screen, "REG-RDCTRL: waiting to send no read signal to wrtctrl ", PC)
                    Rdn[TIME.STAMP]:=clock1+delay[3]  --XOR
                    WCRddone!Rdn
                    debugmsg(report,screen, "REG-RDCTRL: sent no read signal to wrtctrl ", PC)

                    SKIP
            -------------------------------------------------
            SEQ
              clock2:=clock0
              Instr[TIME.STAMP]:=clock2
              Instr[STALL]:=(-1)
              ToWRegD!Instr           --To/From W Register
              FWRegA? Ackw
              clock2:=Ackw[TIME.STAMP]
            -------------------------------------------------
          Acki[TIME.STAMP]:=max(clock1, clock2) +delay[4] --MULLERC
          calculate.occupancy(evaluate, occupancy.table[0], Acki[TIME.STAMP],Instr.occ )  

          PAR
            ToIRegA!Acki
            SEQ
              --debugmsg(report,screen, "REG-RDCTRL: Waiting for Write done signal ", NULL1)
              FWrtCtrl? Lkx     --from Write Ctrl(lock done)
              --debugmsg(report,screen, "REG-RDCTRL: Received Write done signal ", NULL1)
            SEQ
              debugmsg(report,screen, "REG-RDCTRL: Waiting for Instr+PC ", NULL1)
              FIRegD?Instr
              debugmsg(report,screen, "REG-RDCTRL: Received Instr ", Instr)
              IF
                Instr[0]<>FINISH
                  SEQ
                    FIRegPC? PC
                    debugmsg(report,screen, "REG-RDCTRL: Received PC ", PC)

                TRUE
                  SEQ
                    debugmsg(report,screen, "REG-RDCTRL: FINISH!!!!!", PC)
                    end:=TRUE
      ----------------------------------------------------------------
      PAR
        WCRddone!Rdn
        terminate(evaluate, Instr[TIME.STAMP],KILL,FLUSH, occupancy.table, screen, [ToWRegD])
  :
  ------------------------------------------------
  PROC WriteCtrl(CHAN OF BUNDLE FORegA2,FWReg,FALkFA,FMLkFA,ToALkFW,ToALkFPs,
                 ToMLkFW,ToMLkFPs,ToRdCtrl,ToWRegA,WCRddone, []CHAN OF DEB.MESSAGE screen,VAL INT report,evaluate)

    [MESGLEN]INT Rddn,Instr,AWaddr,MWaddr,Ackmf, Lkx, Ackw, Psel, Ackaf:
    INT aldec, mldec, nbs, clock0,clock1,clock2, clock3,clock4 :
    BOOL end, LrNp:
    [32]BOOL Instrb:
    [4]BOOL aldecb, mldecb:
    [7]BOOL nbsb:
    [2]BOOL Pselb:
    [1][OCCT.SIZE][OCCT.COL]INT occupancy.table:  --an occupancy table!!!!
    [10]INT delay:
    -------------------------------------------------------------------------
    PROC calculate.delays()
      SEQ
        delay[0]:=MULLERC
        delay[1]:=SELECT
        delay[2]:=XOR+TOGGLE
        delay[3]:=XOR
        delay[4]:=TOGGLE+XOR
        delay[5]:=XOR
        delay[6]:=MULLERC
    :
    -------------------------------------------------------------------------
    -------------------------------------------------------------------
    PROC  initialize.occup.tables()
      SEQ
        initialize.occup.table(occupancy.table[0], RBWREG, RBWREG.SIZE,REGISTER.DELAY) 
    :
    ------------------------------------------------------------------- 


    SEQ
      calculate.delays()
      initialize.occup.tables()
      end:=FALSE
      PAR
        SEQ
          debugmsg(report,screen[0], "REG-WRITECTRL: Waiting for Read done signal ",NULL1)
          ALT
            FORegA2?Rddn    --From Out Register
              SKIP
            WCRddone?Rddn    --from ReadCtrl   NO READ
              SKIP
          debugmsg(report,screen[0], "REG-WRITECTRL: Received Read done signal  ",NULL1)
        SEQ
          debugmsg(report,screen[1], "REG-WRITECTRL: Waiting for new data from W register",NULL1)
          FWReg?Instr      --From Write Register
          debugmsg(report,screen[1], "REG-WRITECTRL: Received new data from W register",Instr)

          IF
            Instr[0]<>FINISH
              SEQ
                SKIP
            TRUE
              end:=TRUE

      WHILE end=FALSE
        SEQ
          clock0:=max(Instr[TIME.STAMP], Rddn[TIME.STAMP]) +delay[0] --MULLERC

          int.to.bool(Instr[0], Instrb)
          [aldecb FROM 0 FOR 4]:=[Instrb FROM 7 FOR 4]  --A fifo
          [mldecb FROM 0 FOR 4]:=[Instrb FROM 11 FOR 4]  --M fifo
          [nbsb FROM 0 FOR 7]:=[Instrb FROM 0 FOR 7]
          [Pselb FROM 0 FOR 2]:=[Instrb FROM 16 FOR 2]
          init.hex(aldec,aldecb)
          init.hex(mldec,mldecb)
          init.hex(nbs,nbsb)
          init.hex(Psel[0],Pselb)

          LrNp:=Instrb[15]


          PAR
            ------------------------------------------------------------------------
            SEQ
              clock1:=clock0+ delay[1]   --SELECT
              IF
                (NOT(((Instrb[7] AND Instrb[8]) AND (Instrb[9] AND Instrb[10]))))=TRUE
                  SEQ
                    Decode(aldec, nbs, AWaddr[0], LrNp ) --Calculate Lock address for A-Fifo
                    debugmsg(report,screen[0], "REG-WRITECTRL: Waiting to send lock address to A fifo ", AWaddr)
                    AWaddr[TIME.STAMP]:=clock1+delay[2]  --XOR+TOGGLE
                    AWaddr[STALL]:=(-1)

                    PAR
                      ToALkFW!AWaddr   --write address
                      ToALkFPs!Psel   --mode/flag select
                    FALkFA? Ackaf
                    debugmsg(report,screen[0], "REG-WRITECTRL: sent lock address to A fifo ", AWaddr)
                    clock1:=Ackaf[TIME.STAMP]+delay[3]    --XOR
                    clock2:=clock1 +  delay[4]    --TOGGLE+XOR
                (NOT(((Instrb[7] AND Instrb[8]) AND (Instrb[9] AND Instrb[10]))))=FALSE
                  SEQ
                    clock1:=clock1+delay[5]  --XOR
                    clock2:=clock1
                    SKIP

            ------------------------------------------------------------------------
            SEQ
              clock3:=clock0+ delay[1]   --SELECT
              IF
                (NOT(((Instrb[11] AND Instrb[12]) AND (Instrb[13] AND Instrb[14]))))=TRUE
                  SEQ
                    Decode(mldec, nbs, MWaddr[0], LrNp)   --Calculate Lock address for M-Fifo
                    debugmsg(report,screen[1], "REG-WRITECTRL: Waiting to send lock address to M fifo ", MWaddr)

                    MWaddr[TIME.STAMP]:=clock3+delay[2]   --XOR+TOGGLE
                    MWaddr[STALL]:=(-1)
                    PAR
                      ToMLkFW!MWaddr   --write address
                      ToMLkFPs!Psel   --mode/flag select
                    FMLkFA? Ackmf
                    clock3:=Ackmf[TIME.STAMP]+delay[3]    --XOR
                    clock4:=clock3 +  delay[4]    --TOGGLE+XOR

                    debugmsg(report,screen[1], "REG-WRITECTRL: sent lock address to M fifo ", MWaddr)
                (NOT(((Instrb[11] AND Instrb[12]) AND (Instrb[13] AND Instrb[14]))))=FALSE

                  SEQ
                    clock3:=clock3+delay[3]  --XOR
                    clock4:=clock3

                    SKIP

          ------------------------------------------------------------------------
          debugmsg(report,screen[1], "REG-WRITECTRL: Waiting to send Lock done signal ", Instr)

          Lkx[TIME.STAMP]:=max(clock2, clock4)  + delay[6] --MULLERC
          Ackw[TIME.STAMP]:=max(clock1, clock3)  + delay[6] --MULLERC
          calculate.occupancy(evaluate, occupancy.table[0], Ackw[TIME.STAMP],Instr)  

          PAR
            ToRdCtrl!Lkx
            ToWRegA!Ackw
          debugmsg(report,screen[1], "REG-WRITECTRL: sent Lock done signal ", Instr)

          PAR
            SEQ
              debugmsg(report,screen[0], "REG-WRITECTRL: Waiting for Read done signal ",NULL1)
              ALT
                FORegA2?Rddn    --From Out Register
                  SKIP
                WCRddone?Rddn    --from ReadCtrl   NO READ
                  SKIP
              debugmsg(report,screen[0], "REG-WRITECTRL: Received Read done signal  ",NULL1)


            SEQ
              debugmsg(report,screen[1], "REG-WRITECTRL: Waiting for new data from W register",Instr)
              FWReg?Instr      --From Write Register
              debugmsg(report,screen[1], "REG-WRITECTRL: Received new data from W register",Instr)
              IF
                Instr[0]<>FINISH
                  SEQ
                    SKIP
                TRUE
                  end:=TRUE
      ---------------------------------
      --kill lock fifos
      terminate(evaluate, Instr[TIME.STAMP],KILL,FLUSH, occupancy.table, screen[0], [ToALkFW, ToMLkFW])
      
  :
  --------------------------------------
  PAR


    IReg(Iinstr, IPc,FIRegD,FIRegPC,Iack,ToIRegA) --ok

    ReadCtrl(FIRegD,FIRegPC,FORegA1,FWRegA,FWrtCtrl,
           ToRLckA,ToRLckB,ToRLckPC,ToWRegD,ToIRegA, WCRddone,screen[0],  report,evaluate)  --ok

    WriteCtrl(FORegA2,FWReg,FALkFA,FMLkFA,ToALkFW,ToALkFPs,
            ToMLkFW,ToMLkFPs,FWrtCtrl,ToWRegA,WCRddone,
            [screen FROM 3 FOR 2], report,evaluate )  --ok

    LkFifos (ToALkFW,ToALkFPs,FALkFW,FALkFSl,FALkFA,ToALkFa,
           WfromAf,AfromAf,
           ToMLkFW,ToMLkFPs,FMLkFW,FMLkFSl,FMLkFA,ToMLkFa,
           WfromMf,AfromMf)          --ok

    Registers (ToRegsA, ToRegsB, FWCtrlD, FWCtrlC, FALkFW,
             FALkFSl, FMLkFW,FMLkFSl,ToALkFa,ToMLkFa,
             ToWrtCtrlA, Abus, Bbus, ToMultiA, ToMultiB, screen[5],report,evaluate)  --ok

    ReadLock(AfromAf,AfromMf,WfromAf,WfromMf,ToRLckA,
            ToRLckB,ToRLckPC,ToRegsA,ToRegsB,ToMultiA,ToMultiB, [screen FROM 1 FOR 2], report)  --ok

    WReg(ToWRegD, FWReg,FWRegA,ToWRegA)   --ok

    OReg(Abus, Bbus, OAout, OBout, FORegA1, FORegA2, Oack) --ok

:


