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

#INCLUDE "hostio.inc"


PROC IOprocess(CHAN OF SP fs,ts, CHAN OF LINK.TO.LINK screen, To.memory,CHAN OF BYTE Out.Char, CHAN OF [3]INT Read.Write, VAL INT report, evaluate)

  #USE "hostio.lib"
  #USE "debug.lib"
  #USE "string.lib"
  #USE "convert.lib"
  #USE "/home/amu5/users/georget/Phd/Simul/library"

  [3]INT address,last.timestamp, current.timestamp, last.message:
  [MEMSIZE]INT memory.array:
  [4]BYTE instr, data:
  INT32 fileid,fileoutid,traceid,proutid, position, status, termid, occupid,preempt0.id,preempt0a.id,preempt0b.id, preempt1.id,preempt1a.id,preempt1b.id,preempt2.id,preempt2a.id,preempt2b.id:
  INT i,length,len, hex.instr, temp,x,found, len, j, duration, start,finish, num.of.addresses, Time:
  BYTE result,result1,temp0,temp1, xbyte,char:
  REAL32 percent.stall,percent.occu, percent.idle, utilization, throughput,aver.stall:
  [PREEMPT.SIZE]INT preemption:
  BOOL e.o.f,end,val :
  [32]BOOL bolean:
  [DEBMESG]BYTE message:
  [9]INT32 flid.array:
  [7]BYTE filename:
  [OCCT.SIZE][OCCT.COL]INT occupancy.table:

  VAL [][]BYTE trace.file.array IS ["DEC1   ", "IMMPIPE", "DECODE2", "DECODE3", 
                             "REG    ", "WRTCTRL", "ADDINT ", "DATINT ", "MEMORY "]:

  VAL []BYTE directory IS "/tmp_mnt/import/amu5/users/georget/Phd/Simul/":

  [55]BYTE trace.file: 
  TIMER clock:
  ------------------------------------------------------------
  PROC which.file(VAL []BYTE message, []BYTE filename)
    BOOL found:
    INT i:
    SEQ
      found:=FALSE
      

      SEQ i=0 FOR SIZE filename
        SEQ
          filename[i]:=' '

      i:=0
 
      WHILE NOT found
        SEQ
          IF 
            (((message[i]<>' ') AND (message[i]<> '-')) AND (message[i]<> ':'))
              SEQ
                filename[i]:=message[i]
                i:=i+1
            TRUE
              SEQ
                found:=TRUE
  :
  ------------------------------------------------------------
  SEQ

    --init.memory()
    so.write.string.nl(fs,ts,"IOprocess: OPENING PROGRAM FILE.....")

    so.open(fs,ts,"/home/amu5/users/georget/Phd/Simul/Dhry/robsvdhry",spt.binary, spm.existing.update, fileid, result)
    IF
      result<>spr.ok 
        SEQ
          so.write.string.nl(fs,ts,"IOprocess: CANNOT OPEN READ FILE....")
      TRUE
        SKIP
            

    so.write.string.nl(fs,ts,"IOprocess: OPEN FILE....OK")


    SEQ i=0 FOR 9
      SEQ
        ----------------------------------make filename 
        SEQ j=0 FOR SIZE trace.file
          SEQ
            trace.file[j]:=' '
        len:=0
        append.text(len, trace.file, directory)
        len:=SIZE directory
        append.text(len, trace.file, trace.file.array[i]) 
        ----------------------------------------------------------- 

        so.open(fs,ts, trace.file ,spt.text, spm.output, flid.array[i], result)
        IF
          result<>spr.ok 
            SEQ
              so.write.string.nl(fs,ts,"IOprocess: CANNOT OPEN DEBUG FILE...")
             
          TRUE
            SKIP
            

    so.open(fs,ts, "occarm.termination" ,spt.text, spm.output, termid, result)

    so.open(fs,ts, "occarm.occupancy" ,spt.text, spm.output, occupid, result)               
    so.open(fs,ts, "occarm.output" ,spt.text, spm.output, proutid, result)
    so.open(fs,ts, "occarm.wrtctrl.preempt" ,spt.text, spm.output, preempt0.id, result)  --count
    so.open(fs,ts, "occarm.addint.preempt" ,spt.text, spm.output, preempt1.id, result)
    so.open(fs,ts, "occarm.dec1.preempt" ,spt.text, spm.output, preempt2.id, result)
    so.open(fs,ts, "occarm.wrtctrla.preempt" ,spt.text, spm.output, preempt0a.id, result)  --magnitude 
    so.open(fs,ts, "occarm.addinta.preempt" ,spt.text, spm.output, preempt1a.id, result)
    so.open(fs,ts, "occarm.dec1a.preempt" ,spt.text, spm.output, preempt2a.id, result)
    so.open(fs,ts, "occarm.wrtctrlb.preempt" ,spt.text, spm.output, preempt0b.id, result)  --accumulated error 
    so.open(fs,ts, "occarm.addintb.preempt" ,spt.text, spm.output, preempt1b.id, result)
    so.open(fs,ts, "occarm.dec1b.preempt" ,spt.text, spm.output, preempt2b.id, result)




    so.write.string.nl(fs,ts,"IOprocess: waiting for messages from the model....")
    end:=FALSE
    num.of.addresses:=0
    clock?Time
    WHILE end=FALSE
      SEQ 
        SEQ
          ALT
            ---------------------------------------------------
            screen? CASE
              trace1;message
                SEQ
                  --so.write.string.nl(fs,ts,"IOprocess: message")
                  which.file(message, filename)
                  SEQ i=0 FOR 9
                    SEQ
                      IF
                        eqstr( filename, trace.file.array[i]) = TRUE 
                          SEQ                     
                            so.fwrite.string.nl(fs,ts, flid.array[i], message, result)
                        eqstr(filename, trace.file.array[i]) = FALSE
                          SEQ
                            SKIP

                  --so.fwrite.string.nl(fs,ts, traceid, message, result)  
                  --so.write.string.nl(fs,ts,message)
                  clock?Time

              ---------------------------------------------------
              eval1; occupancy.table
                SEQ
                  -------------occupancy file format ---------------------------------------------
                  --pipeline id| total # of messages| size| occupancy ...|

                  -- time.in time.out ....???

                  --stalls:  |  prop delay   | full |
                  --stalls:  | average   |  min  max    
                  --idle: # of idles, idle period

                  ----------------------------------------------------------------------------------
                  so.fwrite.int(fs,ts, occupid, occupancy.table[PIPE.ID][3],0, result) -- pipe id
                  so.fwrite.string(fs,ts,occupid,"   ", result)

                  so.fwrite.int(fs,ts, occupid, occupancy.table[9][3],0, result) -- total # of messages
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  so.fwrite.int(fs,ts, occupid, occupancy.table[PIPE.SIZE][3],0, result) -- pipe size
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  SEQ i=0 FOR occupancy.table[PIPE.SIZE][3]     --size
                    SEQ
                      so.fwrite.int(fs,ts, occupid, occupancy.table[i][2],0, result)  --occupancies
                      so.fwrite.string(fs,ts,occupid,"   ", result)
                      so.fwrite.string(fs,ts,occupid,"   ", result)
                      percent.occu:= (REAL32 ROUND ((occupancy.table[i][2]) * 100)) / (REAL32 ROUND (last.timestamp[0]))
                      so.fwrite.string(fs,ts,occupid,"   ", result)
                      so.fwrite.real32(fs,ts, occupid,percent.occu, 2,2, result)
                      so.fwrite.string(fs,ts,occupid,"   ", result)

                  so.fwrite.string.nl(fs,ts,occupid,"", result)
                  --------------------------------------------------------------
                  --SEQ i=0 FOR occupancy.table[PIPE.SIZE][3]     --size
                    --SEQ
                      --so.fwrite.int(fs,ts, occupid, occupancy.table[i][0],0, result)  -- t.in
                      --so.fwrite.string(fs,ts,occupid,"   ", result)
                      --so.fwrite.int(fs,ts, occupid, occupancy.table[i][1],0, result)  -- t.out
                      --so.fwrite.string(fs,ts,occupid,"   ", result)
                  --so.fwrite.string.nl(fs,ts,occupid,"", result)
                  ----------------stalls----------------------------------------
                  ---------------due to register propagation delays-------------
                  so.fwrite.int(fs,ts, occupid, occupancy.table[5][3],0, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  so.fwrite.int(fs,ts, occupid, occupancy.table[6][3],0, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)


                  percent.stall:= (REAL32 ROUND ((occupancy.table[6][3]) * 100)) / (REAL32 ROUND (last.timestamp[0]))
                  so.fwrite.real32(fs,ts, occupid, percent.stall, 2,2, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)

  
                  ---------------due to pipeline being full-------------
                  so.fwrite.int(fs,ts, occupid, occupancy.table[7][3], 0, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  so.fwrite.int(fs,ts, occupid, occupancy.table[8][3], 0,result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)
  
                  percent.stall:= (REAL32 ROUND ((occupancy.table[8][3]) * 100)) / (REAL32 ROUND (last.timestamp[0]))


                  so.fwrite.real32(fs,ts, occupid,percent.stall, 2,2, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  so.fwrite.string.nl(fs,ts,occupid,"", result)

                  ---------------stalls: average, min, max -------------
                  aver.stall:= ((REAL32 ROUND ((occupancy.table[6][3] + occupancy.table[8][3]))) / ((REAL32 ROUND ((occupancy.table[5][3] + occupancy.table[7][3]) + 1))))
                  so.fwrite.real32(fs,ts, occupid,aver.stall, 2,2, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)



                  so.fwrite.int(fs,ts, occupid, occupancy.table[13][3], 0, result)  --min 
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  so.fwrite.int(fs,ts, occupid, occupancy.table[14][3], 0,result)  --max
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  so.fwrite.string.nl(fs,ts,occupid,"", result)



                  ----------------idle----------------------------------------

                  so.fwrite.int(fs,ts, occupid, occupancy.table[3][3],0, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)
                  so.fwrite.int(fs,ts, occupid, occupancy.table[4][3],0, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)

                  percent.idle:= (REAL32 ROUND ((occupancy.table[4][3]) * 100)) / (REAL32 ROUND (last.timestamp[0]))


                  so.fwrite.real32(fs,ts, occupid,percent.idle, 2,2, result)
                  so.fwrite.string.nl(fs,ts,occupid,"   ",result)

                  ----------------utilization-----------------------------------
                  utilization:= (REAL32 ROUND ((occupancy.table[9][3]) * (occupancy.table[11][3]))) / (REAL32 ROUND (last.timestamp[0])) --n*d/T

                  so.fwrite.real32(fs,ts, occupid,utilization, 2,2, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)

                  ----------------throughput-----------------------------------
                  throughput:= ((REAL32 ROUND (occupancy.table[9][3])) / (REAL32 ROUND (last.timestamp[0]))) --n/T

                  so.fwrite.real32(fs,ts, occupid,throughput, 2,2, result)
                  so.fwrite.string(fs,ts,occupid,"   ", result)


                  so.fwrite.string.nl(fs,ts,occupid,"", result)
                  so.fwrite.string.nl(fs,ts,occupid,"------------------------------------", result)
                  clock?Time     
              ---------------------------------------------------
              preempt1; preemption
                SEQ               
                  IF
                    preemption[0]=0              -- Write Control
                      SEQ
                        -------------- COUNT -------------------------

                        so.fwrite.int(fs,ts, preempt0.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt0.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt0.id,preemption[2] ,0, result)     --frequency
                        so.fwrite.string.nl(fs,ts,preempt0.id,"",result)


                        -------------- MAGNITUDE -------------------------

                        so.fwrite.int(fs,ts, preempt0a.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt0a.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt0a.id,preemption[3],0 , result)     --magnitude
                        so.fwrite.string.nl(fs,ts,preempt0a.id,"",result)

                        -------------- ACCUMULATED ERROR -------------------------

                        so.fwrite.int(fs,ts, preempt0b.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt0b.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt0b.id,preemption[4],0 , result)     --accumulated error
                        so.fwrite.string.nl(fs,ts,preempt0b.id,"",result)





                        --so.fwrite.int(fs,ts, preempt0.id,preemption[1],0 , result)     --num.of.messages
                        --so.fwrite.string(fs,ts,preempt0.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt0.id,preemption[2] ,0, result)     --frequency
                        --so.fwrite.string(fs,ts,preempt0.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt0.id,preemption[3],0 , result)     --magnitude
                        --so.fwrite.string(fs,ts,preempt0.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt0.id,preemption[4],0 , result)     --accumulated error
                        --so.fwrite.string(fs,ts,preempt0.id,"   ",result)
                        --so.fwrite.string.nl(fs,ts,preempt0.id,"",result)



                    preemption[0]=1              -- Address Interface
                      SEQ

                        -------------- COUNT -------------------------

                        so.fwrite.int(fs,ts, preempt1.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt1.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt1.id,preemption[2] ,0, result)     --frequency
                        so.fwrite.string.nl(fs,ts,preempt1.id,"",result)


                        -------------- MAGNITUDE -------------------------

                        so.fwrite.int(fs,ts, preempt1a.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt1a.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt1a.id,preemption[3],0 , result)     --magnitude
                        so.fwrite.string.nl(fs,ts,preempt1a.id,"",result)

                        -------------- ACCUMULATED ERROR -------------------------

                        so.fwrite.int(fs,ts, preempt1b.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt1b.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt1b.id,preemption[4],0 , result)     --accumulated error
                        so.fwrite.string.nl(fs,ts,preempt1b.id,"",result)




                        --so.fwrite.int(fs,ts, preempt1.id,preemption[1],0 , result)     --num.of.messages
                        --so.fwrite.string(fs,ts,preempt1.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt1.id,preemption[2] ,0, result)     --frequency
                        --so.fwrite.string(fs,ts,preempt1.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt1.id,preemption[3],0 , result)     --magnitude
                        --so.fwrite.string(fs,ts,preempt1.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt1.id,preemption[4],0 , result)     --accumulated error
                        --so.fwrite.string(fs,ts,preempt1.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt1.id,preemption[5],0 , result)     --current sim time
                        --so.fwrite.string.nl(fs,ts,preempt1.id,"",result)


                    preemption[0]=2              -- Decode1
                      SEQ
                        -------------- COUNT -------------------------

                        so.fwrite.int(fs,ts, preempt2.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt2.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt2.id,preemption[2] ,0, result)     --frequency
                        so.fwrite.string.nl(fs,ts,preempt2.id,"",result)


                        -------------- MAGNITUDE -------------------------

                        so.fwrite.int(fs,ts, preempt2a.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt2a.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt2a.id,preemption[3],0 , result)     --magnitude
                        so.fwrite.string.nl(fs,ts,preempt2a.id,"",result)

                        -------------- ACCUMULATED ERROR -------------------------

                        so.fwrite.int(fs,ts, preempt2b.id,preemption[5],0 , result)     --current sim time
                        so.fwrite.string(fs,ts,preempt2b.id,"   ",result)
                        so.fwrite.int(fs,ts, preempt2b.id,preemption[4],0 , result)     --accumulated error
                        so.fwrite.string.nl(fs,ts,preempt2b.id,"",result)






                        --so.fwrite.int(fs,ts, preempt2.id,preemption[1],0 , result)     --num.of.messages
                        --so.fwrite.string(fs,ts,preempt2.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt2.id,preemption[2] ,0, result)     --frequency
                        --so.fwrite.string(fs,ts,preempt2.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt2.id,preemption[3],0 , result)     --magnitude
                        --so.fwrite.string(fs,ts,preempt2.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt2.id,preemption[4],0 , result)     --accumulated error
                        --so.fwrite.string(fs,ts,preempt2.id,"   ",result)
                        --so.fwrite.int(fs,ts, preempt2.id,preemption[5],0 , result)     --current sim time
                        --so.fwrite.string.nl(fs,ts,preempt2.id,"",result)





                  clock?Time
            ---------------------------------------------------
            Read.Write?address      
              SEQ                   --address[R/W, address, data]
                IF
                  num.of.addresses = 0
                    SEQ
                      clock?start
                      num.of.addresses := 1
                  num.of.addresses = 1
                    SEQ
                      SKIP       
                IF
                  address[0]=READ
                    SEQ
                      so.tell(fs,ts,fileid,position, result)
                      so.write.hex.int(fs,ts, address[1], 8)
                      so.write.nl(fs,ts)
                      so.write.int32(fs,ts, INT32 address[1], 0)
                      so.write.nl(fs,ts)
                      so.seek(fs,ts,fileid, INT32 (address[1]) ,spo.start, result)  --go to address
                      so.tell(fs,ts,fileid,position, result)
                      so.write.int32(fs,ts, position, 0)
                      so.write.nl(fs,ts)
                      so.read(fs, ts, fileid, length, instr)        --read from that address 4 bytes
                      IF
                        length <> (SIZE instr)
                          SEQ
                            e.o.f:=TRUE
                            so.write.string.nl(fs,ts,"IOprocess: ERROR ADDRESS OUT OF RANGE....")
              
                        length = (SIZE instr)
                          SEQ                       --reverse order ????
                  
                            --temp0:=instr[0]
                            --temp1:=instr[1]
                            --instr[0]:=instr[3]
                            --instr[1]:=instr[2]
                            --instr[2]:=temp1    
                            --instr[3]:=temp0
                
                            bytes.to.int(instr, hex.instr)     --convert to integer
                            --so.write.hex.int(fs,ts,hex.instr, 0)
                            --so.write.nl(fs,ts)

                            To.memory!to.memory;hex.instr                --send to memory            
                      clock?Time               

                  address[0]=WRITE
                    SEQ
                      --so.tell(fs,ts,fileid,position, result)
                      so.seek(fs,ts,fileid, INT32 (address[1]) ,spo.start, result)  --go to address
                      int.to.bytes(address[2], data)
                      so.fwrite.string(fs,ts, fileid, data, result)
                      clock?Time

            ---------------------------------------------------
            Out.Char?char
              SEQ
                IF
                  ((INT char) /\ #000000FF) = 4   --- END OF SIMULATION
                    ----------------------------------------------------
                    SEQ
                      Read.Write? last.timestamp
                      Read.Write? last.message
                      To.memory!to.memory;hex.instr
                      duration:=last.timestamp[1]
                      -----------message to the screen--------------------------------
                      so.write.string.nl(fs,ts,"IOprocess: PROGRAM TERMINATED AFTER ....")
                      so.write.int(fs,ts, duration , 0)
                      so.write.string.nl(fs,ts,"LAST TIMESTAMP WAS: ")
                      so.write.int(fs,ts, last.timestamp[0] , 0)
                      -----------message to the termination file--------------------------------
                      so.fwrite.string(fs,ts, termid, "OCCARM Execution Time:     " , result)
                      so.fwrite.int(fs,ts, termid, duration , 0,  result)
                      so.fwrite.nl(fs,ts,termid,result)

                      so.fwrite.string(fs,ts, termid, "OCCARM Simulated Time:     " , result)
                      so.fwrite.int(fs,ts, termid,last.timestamp[0] ,0,  result)
                      so.fwrite.nl(fs,ts,termid,result)

                      so.fwrite.string(fs,ts, termid, "Total # of Instructions:   " , result)
                      so.fwrite.int(fs,ts, termid, last.timestamp[2] ,0,  result)
                      so.fwrite.nl(fs,ts,termid,result)

                      so.fwrite.string(fs,ts, termid, "Total # of Mem. Accesses:  " , result)
                      so.fwrite.int(fs,ts, termid, last.message[0] ,0, result)
                      so.fwrite.nl(fs,ts,termid,result)


                  ((INT char) /\ #000000FF) = 5   --PRINT SIMULATED TIME
                    SEQ
                      Read.Write?current.timestamp
                      so.fwrite.int(fs,ts,proutid, current.timestamp[0],0, result)
                      so.fwrite.nl(fs,ts,proutid,result)
                      so.fwrite.nl(fs,ts,proutid,result)


                  (char='*c')  OR (char='*n')              --carriage return
                    SEQ
                      so.fwrite.nl(fs,ts,proutid,result)
                  TRUE
                    SEQ
                      so.fwrite.char(fs,ts,proutid, char,result)
                clock?Time
            ---------------------------------------------------
            clock? AFTER Time PLUS IOTIMEOUT      --- deadlock or other system problem
              SEQ

                so.exit(fs,ts, status)

:
