зеркало из https://github.com/microsoft/ivy.git
327 строки
9.2 KiB
Plaintext
327 строки
9.2 KiB
Plaintext
|
#lang ivy1.7
|
||
|
|
||
|
################################################################################
|
||
|
#
|
||
|
################################################################################
|
||
|
|
||
|
type proc
|
||
|
|
||
|
type p_state_type = {_I, # invalid
|
||
|
_E
|
||
|
}
|
||
|
|
||
|
type dir_state_type = {dir_I,
|
||
|
dir_E # Exclusive
|
||
|
}
|
||
|
|
||
|
# Request
|
||
|
|
||
|
type net_req_type = {
|
||
|
_READE, # Coherent Read Exclusive
|
||
|
_NOP_req}
|
||
|
|
||
|
# Completion
|
||
|
|
||
|
type net_completion_type = {
|
||
|
_ERESP, # Fill data in exclusive state
|
||
|
_NOP_cmp}
|
||
|
# Snoop
|
||
|
|
||
|
type net_snoop_type = {
|
||
|
_IRDEX,
|
||
|
_NOP_snp}
|
||
|
|
||
|
module prb_type = {
|
||
|
individual v : bool
|
||
|
}
|
||
|
|
||
|
module irb_type = {
|
||
|
individual v : bool
|
||
|
individual src : proc
|
||
|
}
|
||
|
|
||
|
type ph_type = {p_req_ph,dir_rec_ph,p_rec_ph,snp_ph}
|
||
|
|
||
|
type send_type = {send_READS,send_READE,send_none}
|
||
|
|
||
|
module net_req_type_msg = {
|
||
|
individual kind : net_req_type
|
||
|
}
|
||
|
|
||
|
module net_cmp_type_msg = {
|
||
|
individual kind : net_completion_type
|
||
|
individual src : proc
|
||
|
individual dst : proc
|
||
|
}
|
||
|
|
||
|
module net_snp_type_msg = {
|
||
|
individual kind : net_snoop_type
|
||
|
individual src : proc
|
||
|
}
|
||
|
|
||
|
################################################################################
|
||
|
# issues net requests and receives completions
|
||
|
################################################################################
|
||
|
|
||
|
module p_mod = {
|
||
|
individual state : p_state_type
|
||
|
instantiate prb : prb_type
|
||
|
instantiate irb : irb_type
|
||
|
individual wr : bool
|
||
|
|
||
|
individual error : bool
|
||
|
|
||
|
action p_rec(p:proc,ph:ph_type,send:send_type) = {
|
||
|
|
||
|
error := true;
|
||
|
|
||
|
if ph=p_req_ph & ~prb.v & ~irb.v & state=_I & send=send_READS {
|
||
|
prb.v := true;
|
||
|
net.req(p).kind := _READE;
|
||
|
error := false;
|
||
|
}
|
||
|
else if ph=p_req_ph & ~prb.v & ~irb.v & state=_I & send=send_READE {
|
||
|
prb.v := true;
|
||
|
net.req(p).kind := _READE;
|
||
|
error := false;
|
||
|
}
|
||
|
else if ph=p_rec_ph & prb.v & ~irb.v & net.cmp.kind=_ERESP & net.cmp.dst=p {
|
||
|
state := _E;
|
||
|
prb.v := false;
|
||
|
net.cmp.kind := _NOP_cmp;
|
||
|
error := false;
|
||
|
}
|
||
|
else if ph=p_rec_ph & prb.v & irb.v & net.cmp.kind=_ERESP & net.cmp.dst=p {
|
||
|
net.cmp.kind := _ERESP;
|
||
|
net.cmp.dst := irb.src;
|
||
|
|
||
|
irb.v := false;
|
||
|
prb.v := false;
|
||
|
|
||
|
dir.oldest_OwnerPtr := irb.src;
|
||
|
|
||
|
net.cmp.kind := _ERESP;
|
||
|
net.cmp.dst := irb.src;
|
||
|
|
||
|
error := false;
|
||
|
}
|
||
|
else if ph=snp_ph & ~prb.v & net.snp(p).kind=_IRDEX {
|
||
|
state := _I;
|
||
|
net.cmp.kind := _ERESP;
|
||
|
net.cmp.dst := net.snp(p).src;
|
||
|
|
||
|
dir.oldest_OwnerPtr := net.snp(p).src;
|
||
|
|
||
|
net.snp(p).kind := _NOP_snp;
|
||
|
error := false;
|
||
|
}
|
||
|
else if ph=snp_ph & prb.v & net.snp(p).kind=_IRDEX {
|
||
|
irb.v := true;
|
||
|
irb.src := net.snp(p).src;
|
||
|
|
||
|
net.snp(p).kind := _NOP_snp;
|
||
|
error := false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
## ****
|
||
|
|
||
|
module dir_mod = {
|
||
|
individual _State : dir_state_type
|
||
|
individual _OwnerPtrValid : bool
|
||
|
|
||
|
individual _OwnerPtr : proc
|
||
|
individual oldest_OwnerPtr : proc
|
||
|
|
||
|
individual error : bool
|
||
|
|
||
|
################################################################################
|
||
|
#
|
||
|
################################################################################
|
||
|
|
||
|
action dir_rec(p:proc,ph:ph_type) = {
|
||
|
error := true;
|
||
|
|
||
|
if ph=dir_rec_ph & net.req(p).kind=_READE & _State=dir_I {
|
||
|
net.cmp.kind := _ERESP;
|
||
|
net.cmp.dst := p;
|
||
|
|
||
|
_State := dir_E;
|
||
|
|
||
|
_OwnerPtrValid := true;
|
||
|
_OwnerPtr := p;
|
||
|
oldest_OwnerPtr := p;
|
||
|
|
||
|
net.req(p).kind := _NOP_req;
|
||
|
error := false;
|
||
|
}
|
||
|
else if ph=dir_rec_ph & net.req(p).kind=_READE & _State=dir_E {
|
||
|
net.snp(_OwnerPtr).kind := _IRDEX;
|
||
|
net.snp(_OwnerPtr).src := p;
|
||
|
|
||
|
_OwnerPtrValid := true;
|
||
|
_OwnerPtr := p;
|
||
|
|
||
|
net.req(p).kind := _NOP_req;
|
||
|
error := false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
## ****
|
||
|
|
||
|
################################################################################
|
||
|
#
|
||
|
################################################################################
|
||
|
|
||
|
module net_fabric = {
|
||
|
instantiate req(P:proc) : net_req_type_msg
|
||
|
instantiate cmp : net_cmp_type_msg
|
||
|
instantiate snp(P:proc) : net_snp_type_msg
|
||
|
|
||
|
action step(p:proc,ph:ph_type,send:send_type) = {
|
||
|
if ph=p_req_ph { # pi issues new request
|
||
|
call pi(p).p_rec(p,ph,send)
|
||
|
} else if ph=dir_rec_ph { # dir receives request/owner-ship transfer
|
||
|
call dir.dir_rec(p,ph)
|
||
|
} else if ph=p_rec_ph { # pi receives response
|
||
|
call pi(p).p_rec(p,ph,send)
|
||
|
} else if ph=snp_ph { # proc receives intervention/invalidate request
|
||
|
if (net.cmp.kind=_NOP_cmp | net.cmp.dst~=p) {
|
||
|
call pi(p).p_rec(p,ph,send)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
after init {
|
||
|
net.req(P).kind := _NOP_req;
|
||
|
net.cmp.kind := _NOP_cmp;
|
||
|
net.snp(P).kind := _NOP_snp;
|
||
|
|
||
|
pi(P).state := _I;
|
||
|
pi(P).prb.v := false;
|
||
|
pi(P).irb.v := false;
|
||
|
|
||
|
pi(P).error := false;
|
||
|
dir.error := false;
|
||
|
dir._State := dir_I;
|
||
|
dir._OwnerPtrValid := false;
|
||
|
}
|
||
|
|
||
|
################################################################################
|
||
|
#
|
||
|
################################################################################
|
||
|
|
||
|
instantiate pi(X:proc) : p_mod
|
||
|
instantiate dir : dir_mod
|
||
|
instantiate net : net_fabric
|
||
|
|
||
|
################################################################################
|
||
|
# Proofs
|
||
|
################################################################################
|
||
|
|
||
|
conjecture net.cmp.kind=_ERESP
|
||
|
->
|
||
|
(
|
||
|
dir._State=dir_E & (net.cmp.dst=dir._OwnerPtr & dir._OwnerPtr=dir.oldest_OwnerPtr | net.cmp.dst=dir.oldest_OwnerPtr)
|
||
|
)
|
||
|
|
||
|
conjecture dir._State=dir_E
|
||
|
->
|
||
|
(
|
||
|
pi(dir.oldest_OwnerPtr).state=_E & net.cmp.kind=_NOP_cmp |
|
||
|
net.cmp.kind=_ERESP & net.cmp.dst=dir.oldest_OwnerPtr
|
||
|
)
|
||
|
|
||
|
conjecture dir._State=dir_E -> (~pi(dir._OwnerPtr).irb.v & net.snp(dir._OwnerPtr).kind=_NOP_snp)
|
||
|
|
||
|
|
||
|
conjecture (net.snp(P).kind=_IRDEX | pi(P).irb.v) -> dir._State=dir_E
|
||
|
|
||
|
conjecture ~(net.snp(P).kind=_IRDEX & pi(P).irb.v)
|
||
|
|
||
|
conjecture (dir._OwnerPtrValid & (dir.oldest_OwnerPtr~=dir._OwnerPtr)) -> pi(dir._OwnerPtr).prb.v
|
||
|
|
||
|
conjecture net.snp(P).kind=_IRDEX
|
||
|
->
|
||
|
((pi(P).prb.v | pi(P).state=_E) & ~(dir._OwnerPtr=dir.oldest_OwnerPtr))
|
||
|
|
||
|
|
||
|
conjecture (dir._OwnerPtrValid & (dir.oldest_OwnerPtr ~= dir._OwnerPtr))
|
||
|
->
|
||
|
(
|
||
|
net.snp(dir.oldest_OwnerPtr).kind=_IRDEX |
|
||
|
pi(dir.oldest_OwnerPtr).irb.v
|
||
|
)
|
||
|
|
||
|
conjecture ~pi(P).prb.v -> (net.req(P).kind=_NOP_req & ~pi(P).irb.v)
|
||
|
|
||
|
conjecture pi(P).irb.v
|
||
|
->
|
||
|
(
|
||
|
dir.oldest_OwnerPtr~=dir._OwnerPtr
|
||
|
)
|
||
|
|
||
|
conjecture pi(P).state=_I |
|
||
|
pi(P).state=_E & ~pi(P).prb.v & net.cmp.kind=_NOP_cmp & (
|
||
|
dir._State=dir_E & dir._OwnerPtr=P |
|
||
|
dir._State=dir_E & dir._OwnerPtr~=P & (net.snp(P).kind=_IRDEX | pi(P).irb.v)
|
||
|
)
|
||
|
|
||
|
conjecture net.req(P).kind~=_NOP_req -> ~(net.cmp.kind~=_NOP_cmp & net.cmp.dst=P | net.snp(P).kind~=_NOP_snp | pi(P).irb.v)
|
||
|
conjecture net.cmp.kind~=_NOP_cmp -> ~(net.req(net.cmp.dst).kind~=_NOP_req)
|
||
|
|
||
|
|
||
|
conjecture dir._State=dir_I & ~dir._OwnerPtrValid |
|
||
|
dir._State=dir_E & dir._OwnerPtrValid & (
|
||
|
pi(dir.oldest_OwnerPtr).state=_E |
|
||
|
net.cmp.kind=_ERESP & net.cmp.dst=dir.oldest_OwnerPtr
|
||
|
)
|
||
|
|
||
|
conjecture (net.req(P).kind~=_NOP_req & dir._OwnerPtrValid) -> (dir._OwnerPtr ~= P)
|
||
|
|
||
|
conjecture dir._State=dir_E -> dir._OwnerPtrValid
|
||
|
|
||
|
conjecture pi(P).prb.v
|
||
|
->
|
||
|
(
|
||
|
(
|
||
|
net.req(P).kind~=_NOP_req |
|
||
|
net.cmp.kind~=_NOP_cmp & net.cmp.dst=P |
|
||
|
(exists X. net.snp(X).kind=_IRDEX & net.snp(X).src=P)
|
||
|
)
|
||
|
& (pi(P).state=_I)
|
||
|
)
|
||
|
|
||
|
conjecture ((net.req(P).kind~=_NOP_req | net.cmp.kind~=_NOP_cmp & net.cmp.dst=P) & (pi(P).state=_I))
|
||
|
->
|
||
|
pi(P).prb.v
|
||
|
|
||
|
conjecture net.req(P).kind = _READE | net.req(P).kind = _NOP_req
|
||
|
conjecture net.cmp.kind = _ERESP | net.cmp.kind = _NOP_cmp
|
||
|
|
||
|
conjecture pi(P).state = _I | pi(P).state = _E
|
||
|
conjecture dir._State = dir_I | dir._State = dir_E
|
||
|
|
||
|
################################################################################
|
||
|
# no errors
|
||
|
################################################################################
|
||
|
|
||
|
conjecture ~pi(P).error
|
||
|
conjecture ~dir.error
|
||
|
|
||
|
|
||
|
################################################################################
|
||
|
# coherence properties
|
||
|
################################################################################
|
||
|
|
||
|
conjecture (pi(P).state=_E) -> dir.oldest_OwnerPtr=P
|
||
|
|
||
|
export net.step
|
||
|
|
||
|
|