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


PROC AddC(CHAN OF BUNDLE frompcpipe,fromapipe,fromlsreg,W,Wc,MA,MAc,LSMP,
          MAa,Pca,Wa,WLx,APa,LSMPa,LSMa,CHAN OF DEB.MESSAGE screen,
          VAL INT report, evaluation, preemption)

  BOOL pcparchanged, end,Ren,Wen,oldPCpar,PCpar,Nusr,Sp, Lsm, Opc, Ntrm,
       dPc,lsmpc,dPCc,ToInc,LSin:

  [32]BOOL Ctrlb, Dec1ctrlb:
  [10]BOOL Ctrl1b:

  [MESGLEN]INT Ctrl,Data:
  TIMER clock:
  VAL INT delays IS 2343:   --0.5 sec
  INT time:
  [20]INT delay:

  -------------------------------------------------------------------------
  PROC calculate.delays()
    SEQ
      delay[0]:=(XOR+ARBITER)+SELECT
      delay[1]:=ARBITER+SELECT
      delay[2]:=SELECT
      delay[3]:=CALL+CALL
      delay[4]:=(MULLERC+CALL)+CALL
      delay[5]:=CALL+CALL
      delay[6]:=((CALL+CALL)+XOR)+XOR
      delay[7]:=SELECT+XOR
      delay[8]:=(MULLERC+CALL)+CALL
      delay[9]:=((((CALL+CALL)+SELECT)+SELECT)+XOR)+XOR
      delay[10]:=MULLERC + XOR
      delay[11]:=(MULLERC+CALL)+CALL
      delay[12]:=CALL+CALL
      delay[13]:=(CALL+CALL)+XOR
      delay[14]:=XOR
  :
  -------------------------------------------------------------------------
  PROC  initialize.occup.tables()
    SEQ
      initialize.occup.table(occupancy.table[0], PCREGPIPE, PCREGPIPE.SIZE,REGISTER.DELAY)
      initialize.occup.table(occupancy.table[1], APIPE, APIPE.SIZE,REGISTER.DELAY)
      initialize.occup.table(occupancy.table[2], WRTCTRLREG,WRTCTRLREG.SIZE ,REGISTER.DELAY)
      initialize.occup.table(occupancy.table[3], LSMREG,LSMREG.SIZE ,REGISTER.DELAY)
  :
  -------------------------------------------------------------------------
  PROC mkpcc()
    SEQ
      init.hex(Ctrl[0], [PCpar,VSS,VDD, VDD, VSS, Nusr, VSS,VDD, VDD, Opc])

      int.to.bool(Ctrl[0], Ctrlb)
      Wen:=Ctrlb[7]
      Ren:=Ctrlb[6]
      Opc:=Ctrlb[3]
  :

  -----------------------------------------------------------------------------
  PROC rpcpipe()

    [MESGLEN]INT ack:

    SEQ
      IF
        pcparchanged=FALSE          --ignore the first after the parity change
          SEQ
            Data[TIME.STAMP]:=clock0 + delay[12]  --CALL+CALL
            mkpcc()                 -- make PCc
            PAR                     -- to/from the register
              MA!Data
              MAc!Ctrl
            MAa? ack
            clock0:=ack[TIME.STAMP]+delay[13]  --CALL+CALL+XOR
        TRUE
          SEQ
            clock0:=clock0+delay[14]   --XOR
            debugmsg(report,screen, "ADDINT-AddC: reject PC after pcpar changed ", Data[0])
            pcparchanged:=FALSE
      SEQ
        ack[TIME.STAMP]:=clock0
        debugmsg(report,screen, "ADDINT-AddC: waiting to send ack to pca for PC", Data[0])
        Pca!ack                   -- to the pc pipe
        debugmsg(report,screen, "ADDINT-AddC: send ack to pca for PC", Data[0])
  :
  --------------------------------------------------------------------------

  PROC mkwac()

    SEQ
      int.to.bool(Ctrl[0],Ctrlb)
      lsmpc:=(Ctrlb[8] AND dPc)
      dPCc:=(lsmpc OR Ctrlb[1])
      Ctrl1b[0]:=Ctrlb[0]
      Ctrl1b[1]:=dPCc
      [Ctrl1b FROM 2 FOR 6]:=[Ctrlb FROM 2 FOR 6]
      LSin:=(Ctrlb[8] AND Ntrm)
      ToInc:=(LSin OR  Ctrlb[3])
      Ctrl1b[8]:=ToInc
      Ctrl1b[9]:=VSS
      init.hex(Ctrl[0], Ctrl1b)

      int.to.bool(Ctrl[0], Ctrlb)
      Wen:=Ctrlb[7]
      Ren:=Ctrlb[6]
      Opc:=Ctrlb[3]

      ---initial implementation follows.....
      --get.bit(OPC, Ctrl[0],Opc)
      --get.bit(WEN, Ctrl[0],Wen)
      --get.bit(REN, Ctrl[0],Ren)
      --set.bit(LSM, INT ((Opc OR (Lsm AND Ntrm))), Ctrl[0])
      --set.bit(SP, IVSS, Ctrl[0])  --Lsm  is 1 anyway
  :


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

  PROC rwbus()

    [MESGLEN]INT ack,ackw:

    SEQ
      mkwac()                         --make Wctrl
      Data[TIME.STAMP]:=clock0
      PAR                            --to/from register
        MA!Data
        MAc!Ctrl
      MAa? ack
      ackw[TIME.STAMP]:=  ack[TIME.STAMP] +delay[6] -- CALL+CALL+XOR+XOR
      ack[TIME.STAMP]:=ack[TIME.STAMP] +delay[6] -- CALL+CALL+XOR+XOR
      calculate.occupancy(evaluate, occupancy.table[2], Ack[TIME.STAMP],Data.occ )
      PAR
        Wa!ack                      --to the wbus(wregister)
        WLx!ackw                    --to write-control
  :
  -----------------------------------------------------------------------
  PROC rapipe()

    [MESGLEN]INT  ack, ack1,ackw:
    SEQ
      fromapipe? Data        --from apipe
      mkwac()                         --make Actrl
      Data[TIME.STAMP]:= max(clock0, Data[TIME.STAMP]) +delay[4]  --MULLERC+CALL+CALL
      PAR                            --to/from the register
        MA!Data
        MAc!Ctrl
      MAa? ack

      ack1[TIME.STAMP]:= ack[TIME.STAMP] +delay[5] --CALL+CALL
      ackw[TIME.STAMP]:=  ack[TIME.STAMP] +delay[6] -- CALL+CALL+XOR+XOR
      ack[TIME.STAMP]:=ack[TIME.STAMP] +delay[6] -- CALL+CALL+XOR+XOR
      calculate.occupancy(evaluate, occupancy.table[2], ack[TIME.STAMP],Data.occ )
      calculate.occupancy(evaluate, occupancy.table[1], ack1[TIME.STAMP],Data.occ )
      PAR
        Wa!ack                    -- to the wbus for the Wc
        WLx!ackw
        APa!ack1                   -- to the apipe
  :
  -----------------------------------------------------------------------
  PROC mklsc()

    SEQ

      init.hex(Ctrl[0], [PCpar,dPc, VDD, VSS, VSS,Nusr, Ren,Wen ,Ntrm, VDD])
      int.to.bool(Ctrl[0], Ctrlb)
      Wen:=Ctrlb[7]
      Ren:=Ctrlb[6]
      Opc:=Ctrlb[3]
  :
  --------------------------------------------------------------------------

  PROC rlsmreg()

    [MESGLEN]INT  Dec1ctrl, ack, ack1,ack2,ackw :

    SEQ
      SEQ
        SEQ

          debugmsg(report,screen, "ADDINT-AddC: rlsmreg waiting  from Dec1", 0)
          LSMP? Dec1ctrl    --control from Dec1/includes Ntrm, dPc
          debugmsg(report,screen, "ADDINT-AddC rlsmreg received from Dec1", 0)
          int.to.bool(Dec1ctrl[0],Dec1ctrlb)
          Ntrm:=Dec1ctrlb[0]
          dPc:=Dec1ctrlb[1]

          mkwac()                 --use the above two values
          debugmsg(report,screen, "ADDINT-AddC rlsmreg waiting to send to MA", 0)
          Data[TIME.STAMP]:=max(clock0, Dec1ctrl[TIME.STAMP]) + delay[8]  --MULLERC+CALL+CALL
          PAR
            MA!Data
            MAc!Ctrl
          debugmsg(report,screen, "ADDINT-AddC rlsmreg sent to MA", 0)
          debugmsg(report,screen, "ADDINT-AddC rlsmreg waiting for ack from MA", 0)
          MAa?  ack
          debugmsg(report,screen, "ADDINT-AddC rlsmreg received ack from MA",0)
          debugmsg(report,screen, "ADDINT-AddC rlsmreg waiting to send LSMPa", 0)
          clock0:=ack[TIME.STAMP]
          ackw[TIME.STAMP]:=ack[TIME.STAMP] +delay[6] -- CALL+CALL+XOR+XOR
          ack[TIME.STAMP]:=ack[TIME.STAMP] +delay[6] -- CALL+CALL+XOR+XOR

          SEQ
            PAR
              Wa!ack     --send ack to WrtCtrl
              WLx!ackw
          clock0:=clock0 +delay[9] --CALL+CALL+SELECT+SELECT+XOR+XOR
          ack[TIME.STAMP]:=clock0
          LSMPa!ack  --send ack to Dec1
          debugmsg(report,screen, "ADDINT-AddC rlsmreg sent LSMPa", 0)
          WHILE Ntrm=TRUE
            SEQ
              debugmsg(report,screen, "ADDINT-AddC: rlsmreg wait from Dec1-lsmreg", 0)
              PAR
                fromlsreg? Data
                LSMP? Dec1ctrl
              clock0:=max(clock0, Data[TIME.STAMP]) + delay[10]  --MULLERC + XOR
              clock0:=max(clock0, Dec1ctrl[TIME.STAMP]) + delay[11]  --MULLERC+CALL+CALL
              debugmsg(report,screen, "ADDINT-AddC: rlsmreg received Dec1/lsmreg", 0)
              int.to.bool(Dec1ctrl[0],Dec1ctrlb)
              Ntrm:=Dec1ctrlb[0]
              dPc:=Dec1ctrlb[1]

              mklsc()               --use the above two values
              debugmsg(report,screen, "ADDINT-AddC rlsmreg waiting to send to MA", 0)
              Data[TIME.STAMP]:=clock0
              PAR
                MA!Data
                MAc!Ctrl
              debugmsg(report,screen, "ADDINT-AddC rlsmreg sent to MA", 0)
              debugmsg(report,screen, "ADDINT-AddC rlsmreg waiting for ack from MA", 0)
              MAa? ack
              debugmsg(report,screen, "ADDINT-AddC rlsmreg rec ack from MA",0)
              debugmsg(report,screen, "ADDINT-AddC rlsmreg wait to send LSMPa/LSMa", 0)
              clock0:=ack[TIME.STAMP]
