diff --git a/TLAplus/TDMv5/TDMv5.tla b/TLAplus/TDMv5/TDMv5.tla
index 5644eaed32228eaac115a80c62ed022f5acdf0ec..f74d19b3074f61286ad3207edb24250efe2690b4 100644
--- a/TLAplus/TDMv5/TDMv5.tla
+++ b/TLAplus/TDMv5/TDMv5.tla
@@ -1,10 +1,13 @@
 ------------------------------- MODULE TDMv5 -------------------------------
-EXTENDS Reals, Integers
+EXTENDS Integers, FiniteSets, Sequences, SequencesExt
 
-Max(a,b) == IF a >= b THEN a ELSE b
+\* Utility predicates
+Max2Numbers(a,b) == IF a >= b THEN a ELSE b
+Max(S) == CHOOSE x \in S : \A y \in S : x >= y
+Min(S) == CHOOSE x \in S : \A y \in S : x =< y
+ModuloSum(a,b,max) == IF a + b =< max THEN a + b ELSE max - ((a+b)%max)
 
 CONSTANTS 
-    Banks,
     \* Intra-bank constraints
     t_RCD,
     t_RP,
@@ -21,30 +24,75 @@ CONSTANTS
     t_WRtoRD,
     t_CCD,
     t_WTR,
-    t_BURST
+    t_BURST,
+    \* Other constants
+    Banks,
+    CrRq,
+    NCrRq,
+    Mapping,
+    Queue_Capacity
+
+\* This creates a function that maps each requestor to a bank
+Requestors == CrRq \cup NCrRq
+tMapping == SetToSeq(Mapping)
+BankMapping == [req \in Requestors |-> tMapping[req]]
+\* Length of the TDM slot. Worst case is a write miss
+TDM_Slot == t_RCD + t_WL + t_BURST + t_WR + t_RP + 1
+\* Peridiocity of the TDM
+TDM_Period == Cardinality(CrRq)
+
+ASSUME
+    /\ Cardinality(Requestors) = Cardinality(Mapping)
 
 VARIABLES
-    state,
-    lbtimer,
-    now,
-    req_under_treatment
+    cmds_lbtimer, \* Lower bound timers, used for expressing timing constraints. There is one per bank per command type.
+    arvl_lbtimer, \* Upper bound timers, used for modelling arrival of requests. There is one per requestor. Could be any type of timer. SF required.
+    chsl_lbtimer, \* Lower bound timer, used for modelling the change in slot_owner. Coulbe be any type of timer. SF required.
+    now, \* Current time
+    bank_state, \* Used to control the issue of commands to each bank
+    queue, \* A sequence of records containing the requests that have arrived in the system
+    req_under_treatment, \* A record representing the request currently under treatment
+    request_count, \* Counts how many requests per requestor have arrived
+    slot_count, \* Counts how many TDM slots have elapsed at total
+    slot_owner, \* The requestor who currently owns the TDM slot
+    row_buffer, \* A function that maps banks to a row buffer situation, i.e open or closed
+    slack, \* A function that maps each critical request to a value of slack
+    control \* A variable that controls the general advance of the system
 
-vars == <<state,lbtimer,now,req_under_treatment>>
+vars == <<cmds_lbtimer,arvl_lbtimer,chsl_lbtimer,now,
+          bank_state,queue,req_under_treatment,request_count,slot_count,slot_owner,row_buffer,slack,control>>
 
+\* Auxiliary sets
 CMDS == {"IDLE","USEBUS","RLSBUS","ACT","RD","WR","PRE"}
-
-\* How to express the type predicate for lbtimer ? 
+CONTROL == {"INIT","ARRIVAL","TREATMENT","COMPLETED"}
+-----------------------------------------------------------------------------
+\* What is the rule for changing the slot owner ? Have to make an action for that ?
+\* How to express the type predicate for cmds_lbtimer ? 
 \* Bounding time for now
 maxtime == 100
+-----------------------------------------------------------------------------
+TimeTypeOK ==
+    \* /\ cmds_lbtimer \in [Banks \X {CMDS \{"IDLE"}} -> Int]
+    /\ arvl_lbtimer \in [Requestors -> Int]
+    /\ chsl_lbtimer \in Int
+    /\ now \in 0..maxtime
 
+\* No type invariance for now : req_under_treatment, queue  
 TypeOK ==
-    /\ state \in [Banks -> CMDS]
-    /\ now \in 0..maxtime
+    /\ bank_state \in [Banks -> CMDS]
+    /\ request_count \in [Requestors -> Nat]
+    /\ slot_count \in Nat
+    /\ slot_owner \in 1..Cardinality(CrRq)
+    /\ row_buffer \in [Banks -> {"OPEN","CLOSED"}]
+    /\ slack \in [CrRq -> Nat]
+    /\ control \in CONTROL
 
 Init ==
-    /\ state = [b \in Banks |-> "IDLE"]
-    /\ lbtimer = [b \in Banks, c \in CMDS |-> 0]
+    /\ cmds_lbtimer = [b \in Banks, c \in CMDS\{"IDLE"} |-> 0]
+    /\ arvl_lbtimer = [req \in Requestors |-> 0]
+    /\ chsl_lbtimer = 0
     /\ now = 0
+    /\ bank_state = [b \in Banks |-> "IDLE"]
     /\ req_under_treatment = [type |-> "NONE",
                               deadline |-> 0,
                               target |-> "NONE",
@@ -53,104 +101,195 @@ Init ==
                               issue_date |-> 0,
                               delayed_issue_date |-> 0,
                               hit_miss |-> "NONE"]
-
-\* QUESTION : How could I model the request arrival and treatment with this new model ?
-\* Opt 1. By bounds as well.
+    /\ queue = <<>>
+    /\ request_count = [r \in Requestors |-> 0]
+    /\ slot_count = 1
+    /\ slot_owner = 1
+    /\ row_buffer = [b \in Banks |-> "CLOSED"]
+    /\ slack = [req \in CrRq |-> 0]
+    /\ control = "INIT"
 -----------------------------------------------------------------------------
-SetTimer(a,b,timer,value) == timer' = [timer EXCEPT ![a,b] = value]
-TimedOut(a,b,timer) == timer[a,b] = 0    
+Set2dimTimer(a,b,timer,value) == timer' = [timer EXCEPT ![a,b] = value]
+Set1dimTimer(a,timer,value) == timer' = [timer EXCEPT ![a] = value]
+TimedOut_2dim(a,b,timer) == timer[a,b] = 0
+TimedOut_1dim(a,timer) == timer[a] = 0
 -----------------------------------------------------------------------------
 IssueACT(this_bank) ==
-    /\ state[this_bank] = "ACT"
-    \* Checks if command is both intra and inter-ready
-    /\ \A bank \in Banks : TimedOut(bank,"ACT",lbtimer)
-    \* Sets intra bank timers
-    /\ SetTimer(this_bank,"RD",lbtimer,t_RCD)
-    /\ SetTimer(this_bank,"WR",lbtimer,t_RCD)
-    /\ SetTimer(this_bank,"ACT",lbtimer,t_RC)
-    /\ SetTimer(this_bank,"PRE",lbtimer,t_RAS)
-    \* Sets inter bank timers
-    /\ \A other_bank \in Banks \ {this_bank} : SetTimer(other_bank,"ACT",lbtimer,t_RRD)
-    \* Decide the next command to be issued
-    /\ state' = IF req_under_treatment.type = "RD"
-                   THEN [state EXCEPT ![this_bank] = "RD"]
-                   ELSE [state EXCEPT ![this_bank] = "WR"]
-    /\ UNCHANGED<<now,req_under_treatment>>
+    /\ bank_state[this_bank] = "ACT"
+    /\ control = "TREATMENT"
+    /\ bank_state' = [bank_state EXCEPT ![this_bank] = "RD"]
+    /\ UNCHANGED<<arvl_lbtimer,chsl_lbtimer,now,queue,req_under_treatment,request_count,slot_count,slot_owner,row_buffer,slack,control>>
     
 IssueRD(this_bank) ==
-    /\ state[this_bank] = "RD"
+    /\ bank_state[this_bank] = "RD"
+    /\ control = "TREATMENT"
     \* Checks if command is both intra and inter-ready
-    /\ \A bank \in Banks : TimedOut(bank,"RD",lbtimer)
+    /\ \A bank \in Banks : TimedOut_2dim(bank,"RD",cmds_lbtimer)
     \* Sets intra bank timers
-    /\ SetTimer(this_bank,"USEBUS",lbtimer,t_RL)
-    /\ SetTimer(this_bank,"PRE",lbtimer,t_RTP)
+    /\ Set2dimTimer(this_bank,"USEBUS",cmds_lbtimer,t_RL)
+    /\ Set2dimTimer(this_bank,"PRE",cmds_lbtimer,t_RTP)
     \* Sets inter and inter bank timers
-    /\ \A bank \in Banks : /\ SetTimer(bank,"WR",lbtimer,t_RTW)
-                           /\ SetTimer(bank,"RD",lbtimer,t_CCD)
-    /\ state' = [state EXCEPT ![this_bank] = "USEBUS"]
-    /\ UNCHANGED<<now,req_under_treatment>>
+    /\ \A bank \in Banks : /\ Set2dimTimer(bank,"WR",cmds_lbtimer,t_RTW)
+                           /\ Set2dimTimer(bank,"RD",cmds_lbtimer,t_CCD)
+    /\ bank_state' = [bank_state EXCEPT ![this_bank] = "USEBUS"]
+    /\ UNCHANGED<<arvl_lbtimer,chsl_lbtimer,now,queue,req_under_treatment,request_count,
+                  slot_count,slot_owner,row_buffer,slack,control>>
 
 IssueWR(this_bank) ==
-    /\ state[this_bank] = "WR"
+    /\ bank_state[this_bank] = "WR"
+    /\ control = "TREATMENT"
     \* Checks if command is both intra and inter-ready
-    /\ \A bank \in Banks : TimedOut(bank,"RD",lbtimer)
+    /\ \A bank \in Banks : TimedOut_2dim(bank,"RD",cmds_lbtimer)
     \* Sets intra bank timers
-    /\ SetTimer(this_bank,"USEBUS",lbtimer,t_WL)
-    /\ SetTimer(this_bank,"PRE",lbtimer,t_RTP)
+    /\ Set2dimTimer(this_bank,"USEBUS",cmds_lbtimer,t_WL)
+    /\ Set2dimTimer(this_bank,"PRE",cmds_lbtimer,t_RTP)
     \* Sets inter bank timers
-    /\ \A other_bank \in Banks \ {this_bank} : SetTimer(other_bank,"RD",lbtimer,t_WRtoRD)
-    /\ state' = [state EXCEPT ![this_bank] = "USEBUS"]
-    /\ UNCHANGED<<now,req_under_treatment>>
+    /\ \A other_bank \in Banks \ {this_bank} : Set2dimTimer(other_bank,"RD",cmds_lbtimer,t_WRtoRD)
+    /\ bank_state' = [bank_state EXCEPT ![this_bank] = "USEBUS"]
+    /\ UNCHANGED<<arvl_lbtimer,chsl_lbtimer,now,queue,req_under_treatment,request_count,
+                  slot_count,slot_owner,row_buffer,slack,control>>
     
 UseBus(this_bank) ==
-    /\ state[this_bank] = "USEBUS"
-    /\ \A bank \in Banks : TimedOut(bank,"USEBUS",lbtimer)
-    /\ \A bank \in Banks : SetTimer(bank,"RLSBUS",lbtimer,t_BURST)
-    /\ state' = [state EXCEPT ![this_bank] = "RLSBUS"]
-    /\ UNCHANGED<<now,req_under_treatment>>
+    /\ bank_state[this_bank] = "USEBUS"
+    /\ control = "TREATMENT"
+    /\ \A bank \in Banks : TimedOut_2dim(bank,"USEBUS",cmds_lbtimer)
+    /\ \A bank \in Banks : Set2dimTimer(bank,"RLSBUS",cmds_lbtimer,t_BURST)
+    /\ bank_state' = [bank_state EXCEPT ![this_bank] = "RLSBUS"]
+    /\ UNCHANGED<<arvl_lbtimer,chsl_lbtimer,now,queue,req_under_treatment,request_count,
+                  slot_count,slot_owner,row_buffer,slack,control>>
     
 ReleaseBus(this_bank) ==
-    /\ state[this_bank] = "RLSBUS"
-    /\ \A bank \in Banks : TimedOut(bank,"RLSBUS",lbtimer)
+    /\ bank_state[this_bank] = "RLSBUS"
+    /\ control = "TREATMENT"
+    /\ \A bank \in Banks : TimedOut_2dim(bank,"RLSBUS",cmds_lbtimer)
     /\ IF req_under_treatment.type = "WR"
-          THEN SetTimer(this_bank,"PRE",lbtimer,t_WR)
+          THEN Set2dimTimer(this_bank,"PRE",cmds_lbtimer,t_WR)
           ELSE TRUE
     /\ \A bank \in Banks : IF req_under_treatment.type = "WR"
-                              THEN SetTimer(bank,"RD",lbtimer,t_WTR)
+                              THEN Set2dimTimer(bank,"RD",cmds_lbtimer,t_WTR)
                               ELSE TRUE
-    /\ state' = [state EXCEPT ![this_bank] = "PRE"]
-    /\ UNCHANGED<<now,req_under_treatment>> 
+    /\ bank_state' = [bank_state EXCEPT ![this_bank] = "PRE"]
+    /\ UNCHANGED<<arvl_lbtimer,chsl_lbtimer,now,queue,req_under_treatment,request_count,
+                  slot_count,slot_owner,row_buffer,slack,control>> 
 
 IssuePRE(this_bank) ==
-    /\ state[this_bank] = "PRE"
-    /\ \A bank \in Banks : TimedOut(bank,"PRE",lbtimer)
+    /\ bank_state[this_bank] = "PRE"
+    /\ control = "TREATMENT"
+    /\ \A bank \in Banks : TimedOut_2dim(bank,"PRE",cmds_lbtimer)
     \* Intra-bank : PRE to ACT
-    /\ SetTimer(this_bank,"ACT",lbtimer,t_RP)
+    /\ Set2dimTimer(this_bank,"ACT",cmds_lbtimer,t_RP)
     \* Complection : bank becomes idle again
-    /\ state' = [state EXCEPT ![this_bank] = "IDLE"]
-    /\ UNCHANGED<<now,req_under_treatment>>
+    /\ bank_state' = [bank_state EXCEPT ![this_bank] = "IDLE"]
+    /\ UNCHANGED<<arvl_lbtimer,chsl_lbtimer,now,queue,req_under_treatment,request_count,
+                  slot_count,slot_owner,row_buffer,slack,control>>
+-----------------------------------------------------------------------------
+treat_request ==
+LET deadlines == {queue[n].deadline : n \in 1..Len(queue)}
+    min_deadline == Min(deadlines)
+    selected_req == SelectSeq(queue, LAMBDA elem: elem.deadline = min_deadline)[1]
+    StartTreatment == /\ queue' = Remove(queue,selected_req)
+                      /\ req_under_treatment' = selected_req
+                      /\ bank_state' = [bank_state EXCEPT ![selected_req.target] = "ACT"]
+    ResumeTreatment == UNCHANGED<<queue,req_under_treatment,bank_state>>
+IN /\ (control = "ARRIVAL") \/ (control = "COMPLETE" /\ queue /= <<>>)
+   /\ control' = "TREATMENT"
+   /\ IF req_under_treatment.owner = 0
+         THEN StartTreatment
+         ELSE ResumeTreatment
+   /\ UNCHANGED<<arvl_lbtimer,cmds_lbtimer,chsl_lbtimer,now,request_count,slot_count,slot_owner,
+                 row_buffer,slack>>
+-----------------------------------------------------------------------------                  
+\* so_did : slot owner considering the delayed issue date
+\* dist : distance to the next slot owned by the requestor
+request_arrival(req,ty,hm,arrival_rate) ==
+LET so_did == IF slack[req] >= (slot_count*TDM_Slot - now)
+                 THEN ModuloSum((slack[req]%TDM_Slot)+1,slot_owner,TDM_Period)
+                 ELSE slot_owner
+    dist == IF (now = TDM_Slot*(slot_count - 1)) /\ (req = slot_owner)
+               THEN 0
+               ELSE IF req = so_did
+                       THEN TDM_Period
+                       ELSE IF req - so_did >= 0 
+                               THEN req - so_did 
+                               ELSE so_did - req
+    calc_deadline == IF req \in CrRq
+                        THEN TDM_Slot*(slot_count + dist)
+                        ELSE TDM_Slot*(slot_count + 1)
+    request_instance == [number |-> request_count[req] + 1,
+                         owner |-> req,
+                         target |-> BankMapping[req],
+                         issue_date |-> now,
+                         delayed_issue_date |-> now + slack[req],
+                         deadline |-> calc_deadline,
+                         type |-> ty,
+                         hit_miss |-> hm,
+                         period |-> arrival_rate]
+IN  \* Only one request per requestor in the queue
+    /\ req \notin {queue[n].owner : n \in 1..Len(queue)}
+    \* No consecutive arrivals
+    /\ control \in CONTROL \{"ARRIVAL"}
+    \* Sets up the timer for the next TDM slot
+    /\ IF control = "INIT" THEN chsl_lbtimer' = TDM_Slot ELSE UNCHANGED<<chsl_lbtimer>>
+    \* The next arrival should happen at max arrival_rate cycles after this
+    /\ TimedOut_1dim(req,arvl_lbtimer)
+    /\ Set1dimTimer(req,arvl_lbtimer,arrival_rate)
+    /\ control' = "ARRIVAL"
+    /\ request_count' = [request_count EXCEPT ![req] = request_count[req] + 1]
+    /\ queue' = Append(queue,request_instance)
+    /\ UNCHANGED<<cmds_lbtimer,now,bank_state,req_under_treatment,
+                  slot_count,slot_owner,row_buffer,slack>>
+-----------------------------------------------------------------------------
+SlotChange ==
+    /\ control /= "INIT"
+    \* Checks if the timer has timed_out
+    /\ chsl_lbtimer = 0
+    \* Sets it aggain
+    /\ chsl_lbtimer' = TDM_Slot
+    /\ slot_count' = slot_count + 1
+    /\ slot_owner' = ModuloSum(slot_owner,1,TDM_Period)
+    /\ UNCHANGED<<cmds_lbtimer,arvl_lbtimer,now,bank_state,queue,req_under_treatment,request_count,row_buffer,slack,control>>
 -----------------------------------------------------------------------------
-Tick ==
-    \E d \in {r \in Real: r > 0}:
-        /\ now' = now + d
-        /\ lbtimer' = [b \in Banks, c \in CMDS |-> Max(0,lbtimer[b,c]-d)]
-        /\ UNCHANGED<<state,req_under_treatment>>
-        
 TNext(bank) == \/ IssueACT(bank)
                \/ IssueRD(bank)
                \/ IssueWR(bank)
                \/ UseBus(bank)
                \/ ReleaseBus(bank)
                \/ IssuePRE(bank)
-       
-Next == Tick \/ (\E bank \in Banks : TNext(bank))
+               
+Tick == LET d == 1 IN
+        /\ ~\E bank \in Banks : TNext(bank)
+        /\ \neg ENABLED (treat_request \/ request_arrival(1,"RD","HIT",10) \/ request_arrival(2,"WR","MISS",15) \/ SlotChange)
+        /\ now' = now + d
+        /\ arvl_lbtimer' = [req \in Requestors |-> Max2Numbers(0,arvl_lbtimer[req]-d)]                                                                 
+        /\ cmds_lbtimer' = [b \in Banks, c \in CMDS \{"IDLE"} |-> Max2Numbers(0,cmds_lbtimer[b,c]-d)]
+        /\ chsl_lbtimer' = Max2Numbers(0,chsl_lbtimer-d) 
+        /\ UNCHANGED<<bank_state,queue,req_under_treatment,request_count,slot_count,slot_owner,row_buffer,slack,control>>
+-----------------------------------------------------------------------------
+Next == \/ Tick 
+        \/ \E bank \in Banks : TNext(bank)
+        \/ treat_request
+        \/ SlotChange
+        \/ request_arrival(1,"RD","HIT",10)
+        \/ request_arrival(2,"WR","MISS",15)
 -----------------------------------------------------------------------------
 SafetySpec == Init /\ [][Next]_vars
+FullQueue == Len(queue) =< Queue_Capacity
+THEOREM SafetySpec => FullQueue
 -----------------------------------------------------------------------------
-Liveness == /\ \A bank \in Banks : WF_vars(TNext(bank))
-            /\ \A r \in Real : <>(now > r)
-Spec == SafetySpec /\ Liveness
+Fairness == /\ \A b \in Banks : 
+                /\ SF_vars(IssueACT(b))
+                /\ SF_vars(IssueRD(b))
+                /\ SF_vars(IssueWR(b))
+                /\ SF_vars(IssuePRE(b))
+                /\ SF_vars(UseBus(b))
+                /\ SF_vars(ReleaseBus(b))
+            /\ WF_vars(SlotChange)
+            /\ WF_vars(treat_request)
+            /\ WF_vars(request_arrival(1,"RD","HIT",10))
+            /\ WF_vars(request_arrival(2,"WR","MISS",15))
+            
+Spec == SafetySpec /\ Fairness
 =============================================================================
 \* Modification History
-\* Last modified Wed Mar 03 23:08:30 CET 2021 by felipe
+\* Last modified Fri Mar 05 10:32:19 CET 2021 by felipe
 \* Created Wed Mar 03 20:37:54 CET 2021 by felipe
diff --git a/TLAplus/TDMv6/TDMv6.tla b/TLAplus/TDMv6/TDMv6.tla
new file mode 100644
index 0000000000000000000000000000000000000000..20064c3daaa5cee866d357df887e41053ce3459b
--- /dev/null
+++ b/TLAplus/TDMv6/TDMv6.tla
@@ -0,0 +1,225 @@
+------------------------------- MODULE TDMv6 -------------------------------
+EXTENDS Integers, FiniteSets, Sequences, SequencesExt
+
+-----------------------------------------------------------------------------
+Max2Numbers(a,b) == IF a >= b THEN a ELSE b
+Max(S) == CHOOSE x \in S : \A y \in S : x >= y
+Min(S) == CHOOSE x \in S : \A y \in S : x =< y
+ModuloSum(a,b,max) == IF a + b =< max THEN a + b ELSE max - ((a+b)%max)
+-----------------------------------------------------------------------------
+Infinity == 1000
+Real == 0..100 \cup Infinity
+-----------------------------------------------------------------------------
+
+CONSTANTS 
+    \* Intra-bank constraints
+    t_RCD,
+    t_RP,
+    t_RC,
+    t_RAS,
+    t_RL,
+    t_WL,
+    t_RTP,
+    t_WR,
+    \* Inter-bank constraints
+    t_RRD,
+    \* Inter- and intra-bank constraints
+    t_RTW,
+    t_WRtoRD,
+    t_CCD,
+    t_WTR,
+    t_BURST,
+    \* Other constants
+    Banks,
+    CrRq,
+    NCrRq,
+    Mapping,
+    Queue_Capacity
+
+\* This creates a function that maps each requestor to a bank
+Requestors == CrRq \cup NCrRq
+tMapping == SetToSeq(Mapping)
+BankMapping == [req \in Requestors |-> tMapping[req]]
+\* Length of the TDM slot. Worst case is a write miss
+TDM_Slot == t_RCD + t_WL + t_BURST + t_WR + t_RP + 1
+\* Peridiocity of the TDM
+TDM_Period == Cardinality(CrRq)
+
+ASSUME
+    /\ Cardinality(Requestors) = Cardinality(Mapping)
+
+VARIABLES
+    now,
+    ACT_lbtimer,
+    RD_lbtimer,
+    WR_lbtimer,
+    PRE_lbtimer,
+    USEBUS_lbtimer,
+    RLSBUS_lbtimer,
+    ARV_lbtimer,
+    SLOT_lbtimer,
+    bank_state,
+    queue,
+    req_under_treatment,
+    request_count,
+    slot_count,
+    slot_owner,
+    row_buffer,
+    slack,
+    control
+
+vars == <<now,ACT_lbtimer,RD_lbtimer,WR_lbtimer,PRE_lbtimer,USEBUS_lbtimer,RLSBUS_lbtimer,ARV_lbtimer,SLOT_lbtimer,
+          bank_state,queue,req_under_treatment,request_count,slot_count,slot_owner,row_buffer,slack,control>>        
+-----------------------------------------------------------------------------
+CMDS == {"ACT","RD","WR","PRE","IDLE","USEBUS","RLSBUS"}
+CONTROL == {"INIT","ARRIVAL","TREATMENT","COMPLETED"}
+-----------------------------------------------------------------------------
+TimeTypeOK ==
+    /\ now \in Real
+    /\ ACT_lbtimer \in [Banks -> Real]
+    /\ RD_lbtimer \in [Banks -> Real]
+    /\ WR_lbtimer \in [Banks -> Real]
+    /\ PRE_lbtimer \in [Banks -> Real]
+    /\ USEBUS_lbtimer \in [Banks -> Real]
+    /\ RLSBUS_lbtimer \in [Banks -> Real]
+    /\ ARV_lbtimer \in [Requestors -> Real]
+    /\ SLOT_lbtimer \in Real
+
+\* No type invariance for now : req_under_treatment, queue  
+TypeOK ==
+    /\ bank_state \in [Banks -> CMDS]
+    /\ request_count \in [Requestors -> Nat]
+    /\ slot_count \in Nat
+    /\ slot_owner \in 1..Cardinality(CrRq)
+    /\ row_buffer \in [Banks -> {"OPEN","CLOSED"}]
+    /\ slack \in [CrRq -> Nat]
+    /\ control \in CONTROL
+
+Init ==
+    /\ now = 0
+    /\ ACT_lbtimer = [b \in Banks |-> 0]
+    /\ RD_lbtimer = [b \in Banks |-> 0]
+    /\ WR_lbtimer = [b \in Banks |-> 0]
+    /\ PRE_lbtimer = [b \in Banks |-> 0]
+    /\ USEBUS_lbtimer = [b \in Banks |-> 0]
+    /\ RLSBUS_lbtimer = [b \in Banks |-> 0]
+    /\ ARV_lbtimer = [req \in Requestors |-> 0]
+    /\ SLOT_lbtimer = 0
+    /\ bank_state = [b \in Banks |-> "IDLE"]
+    /\ queue = <<>>
+    /\ req_under_treatment = [type |-> "NONE",deadline |-> 0,target |-> "NONE",number |-> 0,owner |-> 0,
+                              issue_date |-> 0,delayed_issue_date |-> 0,hit_miss |-> "NONE"]
+    /\ request_count = [r \in Requestors |-> 0]
+    /\ slot_count = 1
+    /\ slot_owner = 1
+    /\ row_buffer = [b \in Banks |-> "CLOSED"]
+    /\ slack = [req \in CrRq |-> 0]
+    /\ control = "INIT"
+-----------------------------------------------------------------------------
+TimedOut(timer,index) == timer[index] = 0
+SetLBTimer(timer,index,value) == timer' = [timer EXCEPT ![index] = value]
+-----------------------------------------------------------------------------
+IssueACT(bank) ==
+    /\ control = "TREATMENT"
+    /\ bank_state[bank] = "ACT"
+    /\ ACT_lbtimer["N1"] = 0
+    /\ ACT_lbtimer["N2"] = 0
+    /\ control' = "INIT"
+    /\ UNCHANGED<<now,ACT_lbtimer,RD_lbtimer,WR_lbtimer,PRE_lbtimer,USEBUS_lbtimer,RLSBUS_lbtimer,ARV_lbtimer,SLOT_lbtimer,
+                  bank_state,queue,req_under_treatment,request_count,slot_count,slot_owner,row_buffer,slack>>   
+-----------------------------------------------------------------------------
+treat_request ==
+LET deadlines == {queue[n].deadline : n \in 1..Len(queue)}
+    min_deadline == Min(deadlines)
+    selected_req == SelectSeq(queue, LAMBDA elem: elem.deadline = min_deadline)[1]
+IN /\ (control = "ARRIVAL") \/ (control = "COMPLETE" /\ queue /= <<>>)
+   /\ control' = "TREATMENT"
+   /\ queue' = IF req_under_treatment.owner = 0 THEN Remove(queue,selected_req) ELSE queue
+   /\ req_under_treatment' = IF req_under_treatment.owner = 0 THEN selected_req ELSE req_under_treatment
+   /\ bank_state' = IF req_under_treatment.owner = 0 THEN [bank_state EXCEPT ![selected_req.target] = "ACT"] ELSE bank_state
+   /\ UNCHANGED<<now,ACT_lbtimer,RD_lbtimer,WR_lbtimer,PRE_lbtimer,USEBUS_lbtimer,RLSBUS_lbtimer,ARV_lbtimer,SLOT_lbtimer,
+                 request_count,slot_count,slot_owner,row_buffer,slack>>
+-----------------------------------------------------------------------------                  
+request_arrival(req,ty,hm,arrival_rate) ==
+LET so_did == IF slack[req] >= (slot_count*TDM_Slot - now)
+                 THEN ModuloSum((slack[req]%TDM_Slot)+1,slot_owner,TDM_Period)
+                 ELSE slot_owner
+    dist == IF (now = TDM_Slot*(slot_count - 1)) /\ (req = slot_owner)
+               THEN 0
+               ELSE IF req = so_did
+                       THEN TDM_Period
+                       ELSE IF req - so_did >= 0 
+                               THEN req - so_did 
+                               ELSE so_did - req
+    calc_deadline == IF req \in CrRq
+                        THEN TDM_Slot*(slot_count + dist)
+                        ELSE TDM_Slot*(slot_count + 1)
+    request_instance == [number |-> request_count[req] + 1,
+                         owner |-> req,
+                         target |-> BankMapping[req],
+                         issue_date |-> now,
+                         delayed_issue_date |-> now + slack[req],
+                         deadline |-> calc_deadline,
+                         type |-> ty,
+                         hit_miss |-> hm,
+                         period |-> arrival_rate]
+IN  /\ req \notin {queue[n].owner : n \in 1..Len(queue)}
+    /\ control \in CONTROL \{"ARRIVAL"}
+    /\ TimedOut(ARV_lbtimer,req)
+    \* Primed
+    /\ SLOT_lbtimer' = IF control = "INIT" THEN TDM_Slot ELSE SLOT_lbtimer
+    /\ SetLBTimer(ARV_lbtimer,req,arrival_rate)
+    /\ control' = "ARRIVAL"
+    /\ request_count' = [request_count EXCEPT ![req] = request_count[req] + 1]
+    /\ queue' = Append(queue,request_instance)
+    /\ UNCHANGED<<now,ACT_lbtimer,RD_lbtimer,WR_lbtimer,PRE_lbtimer,USEBUS_lbtimer,RLSBUS_lbtimer,
+                  bank_state,req_under_treatment,slot_count,slot_owner,row_buffer,slack>>
+-----------------------------------------------------------------------------
+SlotChange ==
+    /\ control /= "INIT"
+    /\ SLOT_lbtimer = 0
+    /\ SLOT_lbtimer' = TDM_Slot
+    /\ slot_count' = slot_count + 1
+    /\ slot_owner' = ModuloSum(slot_owner,1,TDM_Period)
+    /\ UNCHANGED<<now,ACT_lbtimer,RD_lbtimer,WR_lbtimer,PRE_lbtimer,USEBUS_lbtimer,RLSBUS_lbtimer,ARV_lbtimer,
+                  bank_state,queue,req_under_treatment,request_count,row_buffer,slack,control>>         
+-----------------------------------------------------------------------------
+\*TNext(bank) == IssueACT(bank)
+-----------------------------------------------------------------------------
+\*Tick == \E d \in 0..100:
+\*            \* The Tick action is only allowed to happen when other decision actions are not possible
+\*            /\ ~\E bank \in Banks : IssueACT(bank)
+\*            /\ \neg ENABLED (treat_request \/ request_arrival(1,"RD","HIT",10) \/ request_arrival(2,"WR","MISS",15) \/ SlotChange)
+\*            /\ now' = now + d
+\*            /\ ACT_lbtimer' = [b \in Banks |-> Max2Numbers(0,ACT_lbtimer[b]-d)]
+\*            /\ RD_lbtimer' = [b \in Banks |-> Max2Numbers(0,RD_lbtimer[b]-d)]     
+\*            /\ WR_lbtimer' = [b \in Banks |-> Max2Numbers(0,WR_lbtimer[b]-d)]     
+\*            /\ PRE_lbtimer' = [b \in Banks |-> Max2Numbers(0,PRE_lbtimer[b]-d)]     
+\*            /\ USEBUS_lbtimer' = [b \in Banks |-> Max2Numbers(0,USEBUS_lbtimer[b]-d)]     
+\*            /\ RLSBUS_lbtimer' = [b \in Banks |-> Max2Numbers(0,RLSBUS_lbtimer[b]-d)]
+\*            /\ ARV_lbtimer' = [b \in Banks |-> Max2Numbers(0,ARV_lbtimer[b]-d)]
+\*            /\ SLOT_lbtimer' = Max2Numbers(0,SLOT_lbtimer-d)                                                             
+\*            /\ UNCHANGED<<bank_state,queue,req_under_treatment,request_count,slot_count,slot_owner,row_buffer,slack,control>>
+-----------------------------------------------------------------------------
+Next == \/ request_arrival(1,"RD","HIT",10)
+        \/ request_arrival(2,"WR","MISS",15)
+        \*\/ Tick
+        \/ treat_request
+        \/ SlotChange
+        \/ \E bank \in Banks : IssueACT(bank)
+-----------------------------------------------------------------------------
+SafetySpec == Init /\ [][Next]_vars
+FullQueue == Len(queue) =< Queue_Capacity
+THEOREM SafetySpec => FullQueue
+-----------------------------------------------------------------------------
+Fairness == /\ SF_vars(SlotChange)
+            /\ SF_vars(treat_request)
+            /\ SF_vars(request_arrival(1,"RD","HIT",10))
+            /\ SF_vars(request_arrival(2,"WR","MISS",15))
+            /\ \A b \in Banks : SF_vars(IssueACT(b))
+            
+Spec == SafetySpec /\ Fairness
+=============================================================================
+\* Modification History
+\* Last modified Fri Mar 05 14:21:57 CET 2021 by felipe
+\* Created Wed Mar 03 20:37:54 CET 2021 by felipe
\ No newline at end of file