type state = Invalid | Shared | Exclusive
type msg = Empty | Reqs | Reqe | Inv | Invack | Gnts | Gnte
type data
var Exgntd : bool
var Curcmd : msg
var CurClient : proc
var MemData : data
var AuxData : data
var Store_data : data
array Chan1Cmd[proc] : msg
array Chan1Data[proc] : data
array Chan2Cmd[proc] : msg
array Chan2Data[proc] : data
array Chan3Cmd[proc] : msg
array Chan3Data[proc] : data
array CacheState[proc] : state
array CacheData[proc] : data
array Invset[proc] : bool
array Shrset[proc] : bool
init (z) {
Chan1Cmd[z] = Empty &&
Chan2Cmd[z] = Empty &&
Chan3Cmd[z] = Empty &&
CacheState[z] = Invalid &&
Invset[z] = False &&
Shrset[z] = False &&
Curcmd = Empty &&
Exgntd = False &&
MemData = AuxData
}
unsafe (z1 z2) { CacheState[z1] = Exclusive && CacheState[z2] <> Invalid }
unsafe () { Exgntd = False && MemData <> AuxData }
unsafe (z) { CacheState[z] <> Invalid && CacheData[z] <> AuxData }
transition store (n)
requires { CacheState[n] = Exclusive }
{
AuxData := Store_data;
CacheData[j] := case
| j = n : Store_data
| _ : CacheData[j];
Store_data := .;
}
transition sendReqs (i)
requires { Chan1Cmd[i] = Empty && CacheState[i] = Invalid }
{
Chan1Cmd[i] := Reqs;
}
transition sendReqe (i)
requires { Chan1Cmd[i] = Empty && CacheState[i] <> Exclusive }
{
Chan1Cmd[i] := Reqe;
}
transition recvReqs (i)
requires { Curcmd = Empty && Chan1Cmd[i] = Reqs }
{
Curcmd := Reqs;
CurClient := i;
Chan1Cmd[i] := Empty;
Invset[j] := case | _ : Shrset[j];
}
transition recvReqe (i)
requires { Curcmd = Empty && Chan1Cmd[i] = Reqe }
{
Curcmd := Reqe;
CurClient := i;
Chan1Cmd[i] := Empty;
Invset[j] := case | _ : Shrset[j];
}
transition sendInv1 (i)
requires { Chan2Cmd[i] = Empty && Invset[i] = True && Curcmd = Reqe }
{
Chan2Cmd[i] := Inv;
Invset[i] := False;
}
transition sendInv2 (i)
requires { Chan2Cmd[i] = Empty && Invset[i] = True && Curcmd = Reqs &&
Exgntd = True }
{
Chan2Cmd[i] := Inv;
Invset[i] := False;
}
transition sendInvack (i)
requires { Chan2Cmd[i] = Inv && Chan3Cmd[i] = Empty }
{
Chan2Cmd[i] := Empty;
Chan3Cmd[i] := Invack;
Chan3Data[j] := case
| j = i && CacheState[i] = Exclusive : CacheData[i]
| _ : Chan3Data[j];
CacheState[i] := Invalid;
}
transition recvInvack1 (i)
requires { Chan3Cmd[i] = Invack && Curcmd <> Empty && Exgntd = False }
{
Chan3Cmd[i] := Empty;
Shrset[i] := False;
}
transition recvInvack2 (i)
requires { Chan3Cmd[i] = Invack && Curcmd <> Empty && Exgntd = True }
{
Chan3Cmd[i] := Empty;
Shrset[i] := False;
Exgntd := False;
MemData := Chan3Data[i];
}
transition sendGnts (i)
requires { Curcmd = Reqs && CurClient = i && Chan2Cmd[i] = Empty && Exgntd = False }
{
Chan2Cmd[i] := Gnts;
Chan2Data[i] := MemData;
Shrset[i] := True;
Curcmd := Empty;
}
transition sendGnte (i)
requires { Curcmd = Reqe && CurClient = i && Chan2Cmd[i] = Empty && Exgntd = False &&
Shrset[i] = False && forall_other j. Shrset[j] = False }
{
Chan2Cmd[i] := Gnte;
Chan2Data[i] := MemData;
Shrset[i] := True;
Curcmd := Empty;
Exgntd := True;
}
transition recvGnts (i)
requires { Chan2Cmd[i] = Gnts }
{
CacheState[i] := Shared;
CacheData[i] := Chan2Data[i];
Chan2Cmd[i] := Empty;
}
transition recvGnte (i)
requires { Chan2Cmd[i] = Gnte }
{
CacheState[i] := Exclusive;
CacheData[i] := Chan2Data[i];
Chan2Cmd[i] := Empty;
}