A simple arbitration circuit for VIS TTC Yuji Kukimoto kukimoto@eecs.berkeley.edu STG: see figures.ps circuit structure: see figures.ps Overall picture: Three requesting modules (called clients) are competing to get a bus access. At any point, only one module is allowed to get a bus access. Each client has a controller attached to it, from which an acknowledgment is given. All the controllers communicate with an arbiter so that at any time at most one controller gives an acknowledgment. The arbiter is a simple three-state machine. It has a single output indicating which controller can be selected among the three at each time tick. If the "active" input of the controller is 0, the output is X, meaning that no one is selected. The protocol here is that a controller takes a control from the arbiter if it is selected by the arbiter and it has a request. Otherwise, the control is passed to the next controller. A signal pass_ctrl is set to one iff the controller needs to pass a control to another controller. There are two cases: 1) when the controller is done processing a request, 2) when the controller has no request waiting, but is selected. In both cases, the variable is set to one in the next clock so that another controller waiting for an access can take a control. The "active" signal of the arbiter is set to one iff one of the pass_ctrl is set to one. A client has to keep a request signal high until an acknowledgment is given. Even after an acknowledgment is returned from the corresponding controller, req can be high for a finite amount of time. This means that different requests take different time to complete. Fairness constraints arise here since we do not want to keep req high for infinite time. I. CTL Model Checking A. Property: 1. mutual exclusion 2. AG(req->AF(ack)) # safety: mutual exclusion AG ( !(ackA = 1 * ackB = 1 + ackB = 1 * ackC = 1 + ackC = 1 * ackA=1) ); # liveness: AG( (reqA = 1) -> AF(ackA = 1) ); AG( (reqB = 1) -> AF(ackB = 1) ); AG( (reqC = 1) -> AF(ackC = 1) ); B. Fairness: !(clientA.state=HAVE_TOKEN); !(clientB.state=HAVE_TOKEN); !(clientC.state=HAVE_TOKEN); C. Files: arbiter.v: a fair arbiter. the liveness property passes under fairness constraints. arbiter_bug.v is another version of arbiter.v, where the state transition graph of the arbiter is slightly different. This is not a fair arbiter. arbiter.fair: fairness constraints arbiter.ctl: ctl files II. Language emptiness check: A. File: arbiter_le.v An observer is added to check if the liveness property for clientA is satisfied. The observer is a non-deterministic machine which represents the complement of the liveness property. Ending up in state BAD in the observer means that the behavior is bad. Thus, observer.state=BAD is added to the fairness constraints. The corresponding fairness file is arbiter_le.fair. The language emptiness check passes, implying that the design is correct. B. Note: Complementing the liveness property is not so intuitive even though the property is very simple. It turned out that we really need a non-deterministic machine to representing this property under Buchi constraint.