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


PROC Dec2(CHAN OF BUNDLE FromCtrl2,ToCtrl2A,FromDec1,
                         ToDec1,ToCtrl2D,Fromctrl2A,CHAN OF DEB.MESSAGE screen, VAL INT report, evaluate)

  CHAN OF BUNDLE FromregA,ToRegA,FromregB,ToregB:

  -------------------------------------------------------
  PROC RegA(CHAN OF BUNDLE Din, Dout, Ain, Aout)
    SEQ
      last.fifo.stage( Din, Dout, Ain, Aout)

  :
  -----------------------------------------------------
 
  PROC RegB(CHAN OF BUNDLE Din, Dout, Ain, Aout)
    SEQ
      fifo.stage(Din, Dout, Ain, Aout)

  :
  ----------------------------------------------------------------
  PROC Dec2ctrl(CHAN OF BUNDLE FromDec1,FromregA,FromregB,ToregB,ToDec1,ToRegA,CHAN OF DEB.MESSAGE screen, VAL INT report, evaluate)

    [MESGLEN]INT In2,Rs2,I0,Ackb,Ackd1,Acka:

    INT Shin,ShR,sel,sh0,sh1,sh2,sh3,SHop, clock:

    BOOL RSsh, IMror, end:


    [32]BOOL Rs2b:
    [10]BOOL Shinb:
    [32]BOOL In2b:
    [10]BOOL SHopb:
    [26]BOOL i0b:
    [30][10] INT ShfCmask:
    [30][10] INT ShfCmatch:
    [30][10] INT ShfCout:
    [8]INT delay:

    [2][OCCT.SIZE][OCCT.COL]INT occupancy.table:  --an array of occupancy tables!!!!
  


    -----------------------------------------------------
    PROC ShfC(INT In, Out)

      SEQ
        decode(ShfCout, ShfCmatch, ShfCmask, In, Out) 
   
    :
    ------------------------------------------------------

    PROC calculate.delays()
      SEQ
        delay[0]:=SELECT
        delay[1]:=MULLERC
        delay[2]:=CALLR
        delay[3]:=CALLA +XOR
        delay[4]:=CALLA
    :
    -------------------------------------------------------

    PROC  initialize.occup.tables()
      SEQ
        initialize.occup.table(occupancy.table[0], DEC1REGB, DEC1REGB.SIZE, REGISTER.DELAY)  
        initialize.occup.table(occupancy.table[1], DEC2REGA,DEC2REGA.SIZE , REGISTER.DELAY)  
    :
    ------------------------------------


    SEQ
      ShfCmask:=CShfCmask
      ShfCmatch:=CShfCmatch
      ShfCout:=CShfCout

      end:=FALSE
      Shin:=0
      Rs2[0]:=0
      calculate.delays()
      initialize.occup.tables()

      debugmsg(report, screen, "DECODE2-DEC2: Waiting for data from Dec1 ", NULL1)
      FromDec1?In2                           -- from Dec1
      debugmsg(report, screen, "DECODE2-DEC2: Received data from Dec1 ", In2)

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

      WHILE end=FALSE
        SEQ
          clock:=In2[TIME.STAMP]+delay[0]  --SELECT
          int.to.bool(In2[0], In2b)
          RSsh:= ((In2b[16]) AND (In2b[17]))
          IMror:=((In2b[12] OR In2b[13]) OR (In2b[14] OR In2b[15]))
          IF
            RSsh=TRUE
              SEQ
                debugmsg(report, screen, "DECODE2-DEC2: RSsh is TRUE!!!!", NULL1)
                FromregA? Rs2           -- from Ctrl2
                clock:=max(clock, Rs2[TIME.STAMP]) +delay[1]    --MULLERC
                
            TRUE
              SEQ
                debugmsg(report, screen, "DECODE2-DEC2: RSsh is FALSE!!!!", NULL1)
                SKIP
          clock:=clock+delay[2]   --CALLR
          -----------------------------------------------
          int.to.bool(Rs2[0], Rs2b)
          [Shinb FROM 0 FOR 8]:=[Rs2b FROM 0 FOR 8]
          [Shinb FROM 8 FOR 2]:=[In2b FROM 9 FOR 2]
          init.hex(Shin, Shinb)        
          ShfC(Shin, ShR)
          -----------------------------------------------

          init.hex(sel, [In2b[16], In2b[17]])
          init.hex(sh0, [VSS,In2b[18],VSS,VSS,VSS,VSS,VSS,VSS,VDD,VDD])
          init.hex(sh1, [In2b[11],In2b[12],In2b[13],In2b[14],In2b[15],
                      In2b[9],In2b[10],VSS,VDD,VDD])
          init.hex(sh2, [VSS,In2b[12],In2b[13],In2b[14],In2b[15],IMror,IMror,
                       VSS,VDD,VDD])
          sh3:=ShR
          mux4(sel, sh0,sh1,sh2,sh3,SHop)
          -----------------------------------------------
          int.to.bool(SHop, SHopb)
          [i0b FROM 0 FOR 9] := [In2b FROM 0 FOR 9]
          [i0b FROM 9 FOR 10]:= [SHopb FROM 0 FOR 10]
          [i0b FROM 19 FOR 7]:= [In2b FROM 19 FOR 7]
          init.hex(I0[0], i0b)
          I0[TIME.STAMP]:=clock
          I0[STALL]:=-1
          ToregB!I0  
          FromregB? Ackb
          Ackd1[TIME.STAMP]:=Ackb[TIME.STAMP]+delay[3] --CALL +XOR
          Acka[TIME.STAMP]:=Ackb[TIME.STAMP]+delay[4] --CALL
          calculate.occupancy(evaluate, occupancy.table[0], Ackd1[TIME.STAMP], In2)   
          PAR
            ToDec1!Ackd1
            IF
              RSsh=TRUE
                SEQ  
                  calculate.occupancy(evaluate, occupancy.table[1], Acka[TIME.STAMP], Rs2)           
                  ToRegA!Acka
              TRUE
                SKIP
          debugmsg(report, screen, "DECODE2-DEC2: Waiting for data from Dec1 ", NULL1)       
          FromDec1?In2
          debugmsg(report, screen, "DECODE2-DEC2: Received data from Dec1 ", NULL1) 
          IF
            In2[0]<>FINISH
              SEQ
                ---------------------------------
                WHILE (In2[0]=NULL.MESSAGE)
                  SEQ
                    PAR
                      ToDec1!Ackd1
                      SEQ
                        ToregB!In2  
                        FromregB? Ackb
                    FromDec1?In2
                ---------------------------------

            TRUE
              end:=TRUE  
      -------------------------------------------------
      terminate(evaluate, In2[TIME.STAMP],KILL,FLUSH, occupancy.table, screen, [ToregB])     
  :

  -------------------------------------------------------   
  SEQ
    PAR
      RegA(FromCtrl2, FromregA, ToCtrl2A, ToRegA)
      Dec2ctrl(FromDec1,FromregA,FromregB,ToregB,ToDec1,ToRegA,screen, report, evaluate)
      RegB(ToregB,ToCtrl2D, FromregB, Fromctrl2A)
  
:
