// CSMA/CD protocol - probabilistic version of kronos model adapted to model a single station // gxn/dxp 04/12/01 nondeterministic // note made changes since cannot have strict inequalities // in digital clocks approach and suppose a station only sends one message // actual parameters const int K=4; // exponential backoff limit const int slot=2*sigma; // length of slot const int M=floor(pow(2, K)); // max number of slots to wait const int sigma=26; const int lambda=808; //---------------------------------------------------------------------------------------------------------------------------- // the bus module bus b : [0..2]; // b=0 - idle // b=1 - active // b=2 - collision // clock of bus y : [0..sigma+1]; // station starts sending [send1] (b=0) -> (b'=1) & (y'=0); // no message being sent [send2] (b=0) -> (b'=1) & (y'=0); // no message being sent [send1] (b=1) & (y (b'=2) & (y'=0); // message being sent (move to collision) [send2] (b=1) & (y (b'=2) & (y'=0); // message being sent (move to collision) // message being sent [busy1] (b=1) & (y>=sigma) -> (b'=1); [busy2] (b=1) & (y>=sigma) -> (b'=1); // station finishes [end1] (b=1) -> (b'=0) & (y'=0); [end2] (b=1) -> (b'=0) & (y'=0); // collision detected [cd] (b=2) & (y<=sigma) -> (b'=0) & (y'=0); // time transitions [time] (b=0) -> (y'=min(y+1,sigma+1)); // value of y does not matter in state 0 [time] (b=1) -> (y'=min(y+1,sigma+1)); // no invariant in state 1 [time] (b=2) & (y (y'=min(y+1,sigma+1)); // invariant in state 2 endmodule //---------------------------------------------------------------------------------------------------------------------------- // model of first sender module station1 // LOCAL STATE s1 : [0..4]; // s1=0 - initial state // s1=1 - transmit // s1=2 - collision (set backoff) // s1=3 - wait (bus busy) // s1=4 -done (since sending only one message) // LOCAL CLOCK x1 : [0..max(lambda,M*slot)+1]; // COLLISION COUNTER cd1 : [0..K]; // start sending [send1] (s1=0) -> (s1'=1) & (x1'=0); // start sending [busy1] (s1=0) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // detects channel is busy so go into backoff // transmitting [time] (s1=1) & (x1 (x1'=min(x1+1,lambda)); // let time pass [end1] (s1=1) & (x1=lambda) -> (s1'=4) & (x1'=0); // finished [cd] (s1=1) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // collision detected // set backoff (no time can pass in this state) // first retransmission [] s1=2 & cd1=1 -> 1/2 : (s1'=3) & (x1'=0*slot) + 1/2 : (s1'=3) & (x1'=1*slot); // second retransmission [] s1=2 & cd1=2 -> 1/4 : (s1'=3) & (x1'=0*slot) + 1/4 : (s1'=3) & (x1'=1*slot) + 1/4 : (s1'=3) & (x1'=2*slot) + 1/4 : (s1'=3) & (x1'=3*slot); // thrid retransmission [] s1=2 & cd1=3 -> 1/8 : (s1'=3) & (x1'=0*slot) + 1/8 : (s1'=3) & (x1'=1*slot) + 1/8 : (s1'=3) & (x1'=2*slot) + 1/8 : (s1'=3) & (x1'=3*slot) + 1/8 : (s1'=3) & (x1'=4*slot) + 1/8 : (s1'=3) & (x1'=5*slot) + 1/8 : (s1'=3) & (x1'=6*slot) + 1/8 : (s1'=3) & (x1'=7*slot); // fourth retransmission [] s1=2 & cd1=4 -> 1/16 : (s1'=3) & (x1'=0*slot) + 1/16 : (s1'=3) & (x1'=1*slot) + 1/16 : (s1'=3) & (x1'=2*slot) + 1/16 : (s1'=3) & (x1'=3*slot) + 1/16 : (s1'=3) & (x1'=4*slot) + 1/16 : (s1'=3) & (x1'=5*slot) + 1/16 : (s1'=3) & (x1'=6*slot) + 1/16 : (s1'=3) & (x1'=7*slot) + 1/16 : (s1'=3) & (x1'=8*slot) + 1/16 : (s1'=3) & (x1'=9*slot) + 1/16 : (s1'=3) & (x1'=10*slot) + 1/16 : (s1'=3) & (x1'=11*slot) + 1/16 : (s1'=3) & (x1'=12*slot) + 1/16 : (s1'=3) & (x1'=13*slot) + 1/16 : (s1'=3) & (x1'=14*slot) + 1/16 : (s1'=3) & (x1'=15*slot); // wait until backoff counter reaches 0 then send again [time] (s1=3) & (cd1=1) & (x1<2*slot) -> (x1'=x1+1); // let time pass (in slot) [time] (s1=3) & (cd1=2) & (x1<4*slot) -> (x1'=x1+1); // let time pass (in slot) [time] (s1=3) & (cd1=3) & (x1<8*slot) -> (x1'=x1+1); // let time pass (in slot) [time] (s1=3) & (cd1=4) & (x1<16*slot) -> (x1'=x1+1); // let time pass (in slot) // finished backoff [send1] (s1=3) & cd1=1 & (x1=2*slot) -> (s1'=1) & (x1'=0); // channel free [busy1] (s1=3) & cd1=1 & (x1=2*slot) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // channel busy [send1] (s1=3) & cd1=2 & (x1=4*slot) -> (s1'=1) & (x1'=0); // channel free [busy1] (s1=3) & cd1=2 & (x1=4*slot) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // channel busy [send1] (s1=3) & cd1=3 & (x1=8*slot) -> (s1'=1) & (x1'=0); // channel free [busy1] (s1=3) & cd1=3 & (x1=8*slot) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // channel busy [send1] (s1=3) & cd1=4 & (x1=16*slot) -> (s1'=1) & (x1'=0); // channel free [busy1] (s1=3) & cd1=4 & (x1=16*slot) -> (s1'=2) & (x1'=0) & (cd1'=min(K,cd1+1)); // channel busy // finished [done] (s1=4) -> true; [time] (s1=4) -> (x1'=min(x1+1,max(lambda,M*slot)+1)); endmodule //---------------------------------------------------------------------------------------------------------------------------- // construct further stations through renaming module station2=station1[s1=s2,x1=x2,cd1=cd2,bc1=bc2,send1=send2,busy1=busy2,end1=end2] endmodule