(in-package "ACL2") (include-book "utils") (include-book "basic-def") (include-book "model") (deflabel begin-table-def) ; The valid pipeline stages in this machine are latch1, latch2 and ; retire. (defun stage-p (stg) (declare (xargs :guard t)) (or (equal stg 'latch1) (equal stg 'latch2) (equal stg 'retire))) (in-theory (disable proj flushed? stage-p)) ; The definition of MAETT entry which represents an instruction. ; Only a few fields are required for this example. ; Field Description ; stg The current stage of the represented instruction. ; pre-ISA The ISA state before the execution of this instruction. ; post-ISA The ISA state after the execution of this instruction. (defstructure INST (stg (:assert (stage-p stg) :rewrite)) (pre-ISA (:assert (ISA-state-p pre-ISA) :rewrite)) (post-ISA (:assert (ISA-state-p post-ISA) :rewrite)) (:options :guards)) (deflist INST-listp (l) (declare (xargs :guard t)) INST-p) ; Definition of MAETT. It stores the initial ISA state, init-ISA, and ; a list of MAETT entries, trace. Each entry of trace represents ; a fetched and executed instruction. Trace stores the entries in ; the order that the ISA executes the represented instructions. ISA ; state init-ISA is the ISA state before executing the first ; instruction in trace. (defstructure MAETT (init-ISA (:assert (ISA-state-p init-ISA) :rewrite)) (trace (:assert (INST-listp trace) :rewrite)) (:options :guards (:conc-name MT-))) (deflabel begin-MAETT-def) ; Function init-MT constructs the initial MAETT table for an ; flushed initial MA state. Since no instructions are fetched yet, ; trace field contains an empty list. (defun init-MT (MA) (declare (xargs :guard (MA-state-p MA))) (MAETT (proj MA) nil)) ; The MAETT entry representing a newly fetched instruction. Argument ; ISA is the pre-ISA state of the newly fetched instruction. In other ; words, it is the correct ISA state before executing the newly ; fetched instruction. (defun new-inst (ISA) (declare (xargs :guard (ISA-state-p ISA))) (INST 'latch1 ISA (ISA-step ISA))) (defun step-latch1-INST (i MA) (declare (xargs :guard (and (INST-p i) (MA-state-p MA)))) (if (b1p (stall-cond? MA)) i (update-INST i :stg 'latch2))) (defun step-latch2-INST (i) (declare (xargs :guard (INST-p i))) (update-INST i :stg 'retire)) ; Function step-INST updates the MAETT entry to reflect the change of ; the state of the represented instruction. In this example, we only ; have to update the stage field as the instruction advances through the ; pipeline. (defun step-INST (i MA) (declare (xargs :guard (and (INST-p i) (MA-state-p MA)))) (cond ((equal (INST-stg i) 'latch1) (step-latch1-INST i MA)) ((equal (INST-stg i) 'latch2) (step-latch2-INST i)) (t i))) ; Function step-trace updates the field, trace, of a MAETT. If a new ; instruction is fetched, an entry corresponding to the new ; instruction is added at the end of the trace. The rest of the ; entries are updated with function step-INST. (defun step-trace (trace MA sig last-ISA) (declare (xargs :guard (and (INST-listp trace) (MA-state-p MA) (MA-sig-p sig) (ISA-state-p last-ISA)))) (if (endp trace) (if (b1p (fetch-inst? MA sig)) (list (new-inst last-ISA)) nil) (cons (step-INST (car trace) MA) (step-trace (cdr trace) MA sig (INST-post-ISA (car trace)))))) ; Function to update an MAETT. MT-step takes arguments MA and MT, ; which are the current MA state and the corresponding MAETT, and it ; returns the updated MAETT. The new MAETT represents the next MA ; state (MA-step MA sig). (defun MT-step (MT MA sig) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA) (MA-sig-p sig)))) (MAETT (MT-init-ISA MT) (step-trace (MT-trace MT) MA sig (MT-init-ISA MT)))) (deflabel end-MAETT-def) ; Function to iteratively update a MAETT, MT, for n cycles. Argument ; MA and MT are the initial MA state and the corresponding MAETT. (defun MT-stepn (MT MA sig-list n) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA) (MA-sig-listp sig-list) (integerp n) (<= 0 n)) :verify-guards nil)) (if (zp n) MT (if (endp sig-list) MT (MT-stepn (MT-step MT MA (car sig-list)) (MA-step MA (car sig-list)) (cdr sig-list) (1- n))))) (deftheory MAETT-def (non-rec-functions (set-difference-theories (function-theory 'end-MAETT-def) (function-theory 'begin-MAETT-def)) world)) (in-theory (disable MAETT-def)) ;; Type proofs (defthm ISA-state-p-proj (implies (MA-state-p MA) (ISA-state-p (proj MA))) :hints (("Goal" :in-theory (enable proj)))) (defthm MAETT-p-init-MT (implies (MA-state-p MA) (MAETT-p (init-MT MA))) :hints (("Goal" :in-theory (enable init-MT)))) (defthm inst-p-new-inst (implies (ISA-state-p ISA) (INST-p (new-inst ISA))) :hints (("Goal" :in-theory (enable new-inst)))) (defthm INST-p-step-INST (implies (INST-p i) (INST-p (step-INST i MA))) :Hints (("Goal" :in-theory (enable step-inst step-latch1-inst step-latch2-inst)))) (defthm INST-listp-step-trace (implies (and (INST-listp trace) (ISA-state-p ISA)) (INST-listp (step-trace trace MA sig ISA)))) (defthm MAETT-p-MT-step (implies (and (MAETT-p MT) (MA-state-p MA) (MA-sig-p sig)) (MAETT-p (MT-step MT MA sig))) :hints (("Goal" :in-theory (enable MT-step)))) (verify-guards MT-step) (defthm MAETT-p-MT-stepn (implies (and (MAETT-p MT) (MA-state-p MA) (MA-sig-listp sig-list) (<= n (len sig-list))) (MAETT-p (MT-stepn MT MA sig-list n)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Definition of Instruction Attributes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Various attributes of an instruction are defined as functions which ; take the MAETT entry representing the instruction. For instance, ; the opcode of an instruction represented by MAETT entry I is defined ; as (INST-op I). In the following definitions, we define many ; attributes such as instruction word, operand registers, source ; values and result value. (deflabel begin-INST-attrb) (defun INST-word (i) (declare (xargs :guard (INST-p i))) (read-mem (ISA-pc (INST-pre-ISA i)) (ISA-mem (INST-pre-ISA i)))) (defun INST-op (i) (declare (xargs :guard (INST-p i))) (op-field (INST-word i))) (defun INST-rc (i) (declare (xargs :guard (INST-p i))) (rc-field (INST-word i))) (defun INST-ra (i) (declare (xargs :guard (INST-p i))) (ra-field (INST-word i))) (defun INST-rb (i) (declare (xargs :guard (INST-p i))) (rb-field (INST-word i))) (defun INST-ra-val (i) (declare (xargs :guard (INST-p i))) (read-reg (INST-ra i) (ISA-regs (INST-pre-ISA i)))) (defun INST-rb-val (i) (declare (xargs :guard (INST-p i))) (read-reg (INST-rb i) (ISA-regs (INST-pre-ISA i)))) (defun INST-result (i) (declare (xargs :guard (INST-p i))) (ALU-output (INST-op i) (INST-ra-val i) (INST-rb-val i))) (deflabel end-INST-attrb) (deftheory INST-attrb (set-difference-theories (function-theory 'end-INST-attrb) (function-theory 'begin-INST-attrb))) (in-theory (disable INST-attrb)) (defthm word-p-INST-word (implies (INST-p i) (word-p (INST-word i))) :hints (("Goal" :in-theory (enable INST-word)))) (defthm opcd-p-INST-op (implies (INST-p i) (opcd-p (INST-op i))) :hints (("Goal" :in-theory (enable INST-op)))) (defthm rname-p-INST-rc (implies (INST-p i) (rname-p (INST-rc i))) :hints (("Goal" :in-theory (enable INST-rc)))) (defthm rname-p-INST-ra (implies (INST-p i) (rname-p (INST-ra i))) :hints (("Goal" :in-theory (enable INST-ra)))) (defthm rname-p-INST-rb (implies (INST-p i) (rname-p (INST-rb i))) :hints (("Goal" :in-theory (enable INST-rb)))) (defthm word-p-INST-ra-val (implies (INST-p i) (word-p (INST-ra-val i))) :hints (("Goal" :in-theory (enable INST-ra-val)))) (defthm word-p-INST-rb-val (implies (INST-p i) (word-p (INST-rb-val i))) :hints (("Goal" :in-theory (enable INST-rb-val)))) (defthm word-p-INST-result (implies (INST-p i) (word-p (INST-result i))) :hints (("Goal" :in-theory (enable INST-result ALU-output)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Defintion of INST-at ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INST-at returns the MAETT entry whose represented instruction is at ; a particular stage. ; ; (INST-at stg MT) is nil if there is no instruction at stage stg in ; MAETT MT. If there is one, it returns the corresponding MAETT entry ; representing the instruction. (defun trace-inst-at (stg trace) (declare (xargs :guard (and (stage-p stg) (INST-listp trace)))) (if (endp trace) nil (if (equal (INST-stg (car trace)) stg) (car trace) (trace-inst-at stg (cdr trace))))) (defun INST-at (stg MT) (declare (xargs :guard (and (stage-p stg) (MAETT-p MT)))) (trace-inst-at stg (MT-trace MT))) (in-theory (disable INST-at)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Definition of invariant conditions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Invariant conditions required for the proof of correctness diagram ; are defined here. We needed seven invariant conditions. ; ; (pc-match-p MT MA) ; The program counter holds the correct value. ; (regs-match-p MT MA) ; The register file contains correct values. ; (mem-match-p MT MA) ; The memory is in the correct state. ; (ISA-chain-p MT) ; MAETT records correct ISA execution of instructions. ; (MT-inst-invariant MT MA) ; Each instruction in the pipeline satisfies "instruction invariant". ; (MT-contains-all-insts MT MA) ; MT contains all instructions currently in the pipeline of MA. ; (MT-in-order-p MT))) ; MA pipeline executes instructions in program order. (deflabel begin-invariant-def) ; Predicate pc-match-p checks whether the program counter in the MA ; holds the correct value. The reader may ask what the correct value is. ; The answer is that the program counter should point to the ; instruction to be fetched in the next cycle. MT-pc calculates ; it from a MAETT, by first looking for the most recently fetched ; instruction I, and find the program counter value of (INST-post-ISA I). ; (INST-post-ISA I) is the ISA state after the execution of I, ; and before fetching the next instruction. (defun trace-pc (trace ISA) (declare (xargs :guard (and (INST-listp trace) (ISA-state-p ISA)))) (if (endp trace) (ISA-pc ISA) (trace-pc (cdr trace) (INST-post-ISA (car trace))))) (defun MT-pc (MT) (declare (xargs :guard (MAETT-p MT))) (trace-pc (MT-trace MT) (MT-init-ISA MT))) (defun pc-match-p (MT MA) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)))) (equal (MT-pc MT) (MA-pc MA))) ; Predicate regs-match-p checks whether the register file contains the ; correct values. MT-regs calculate the correct register file ; state from a MAETT. It first looks for the earliest non-retired ; instruction I, and returns the register file of (INST-pre-ISA I). ; The register is updated when an instruction retires. So the ; register file in the MA holds the results of all retired ; instruction, but none of the partially executed instructions, ; including I. (defun trace-regs (trace ISA) (declare (xargs :guard (and (INST-listp trace) (ISA-state-p ISA)))) (if (endp trace) (ISA-regs ISA) (if (not (equal (INST-stg (car trace)) 'retire)) (ISA-regs ISA) (trace-regs (cdr trace) (INST-post-ISA (car trace)))))) (defun MT-regs (MT) (declare (xargs :guard (MAETT-p MT))) (trace-regs (MT-trace MT) (MT-init-ISA MT))) (defun regs-match-p (MT MA) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)))) (equal (MT-regs MT) (MA-regs MA))) ; Memory state does not change in this model. The memory of the MA state ; should be equal to that of the initial ISA state. (defun mem-match-p (MT MA) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)))) (equal (MA-mem MA) (ISA-mem (MT-init-ISA MT)))) ; MAETT represents the sequence of instructions as a list, where each ; element of the list represents an instruction. Each entry ; has pre-ISA and post-ISA fields, which store the ISA state before ; and after executing the represented instruction. This ISA ; states form a sort of chain. Suppose MT has a list of instruction ; entries (I_0 I_1 I_2 ...). I_0 represents the first instruction to be ; executed, I_1 represents the second and so on. Then following ; equations hold: ; (ISA-step (INST-pre-ISA I_0)) = (INST-post-ISA I_0) ; (INST-post-ISA I_0) = (INST-pre-ISA I_1) ; (ISA-step (INST-pre-ISA I_1)) = (INST-post-ISA I_1) ; (INST-post-ISA I_1) = (INST-pre-ISA I_2) ; .... ; This relations are checked by the predicate ISA-chain-p. In other ; words, ISA-chain-p checks whether the correct sequence of ISA states ; are stored in the MAETT. Following picture may help the reader to ; understand the relations of pre-ISA and post-ISA. ; ; (INST-pre-ISA i_0) ; | execution of i_0 ; v ; (INST-post-ISA i_0) = (INST-pre-ISA i_1) ; | execution of i_1 ; v ; (INST-post-ISA i_1) = (INST-pre-ISA i_2) ; ... (defun ISA-chain-trace-p (trace ISA) (declare (xargs :guard (and (INST-listp trace) (ISA-state-p ISA)))) (if (endp trace) T (and (equal (INST-pre-ISA (car trace)) ISA) (equal (ISA-step ISA) (INST-post-ISA (car trace))) (ISA-chain-trace-p (cdr trace) (ISA-step ISA))))) (defun ISA-chain-p (MT) (declare (xargs :guard (MAETT-p MT))) (ISA-chain-trace-p (MT-trace MT) (MT-init-ISA MT))) ; Each instruction should satisfy some invariant conditions at each ; stage of the pipeline. Mostly, these conditions are about the ; intermediate values stored in the pipeline latches. ; ; For instance, field latch1-op of latch latch1 in the MA state hould ; hold the operand of instruction at stage latch1. If you see the ; definition of inst-latch1-inv, you can find the corresponding ; equation as the second conjunct of the body of the definition. ; ; Predicate inst-invariant checks whether instruction entry i and the ; corresponding MA state satisfies these stage-dependent invariant. ; MT-inst-invariant checks all instructions in the MAETT satisfies ; inst-invariant. ; The condition that instruction should satisfy at state latch1. (defun inst-latch1-inv (i MA) (declare (xargs :guard (and (INST-p i) (MA-state-p MA)))) (and (b1p (latch1-valid? (MA-latch1 MA))) (equal (latch1-op (MA-latch1 MA)) (INST-op i)) (equal (latch1-rc (MA-latch1 MA)) (INST-rc i)) (equal (latch1-ra (MA-latch1 MA)) (INST-ra i)) (equal (latch1-rb (MA-latch1 MA)) (INST-rb i)))) ; The condition that instruction should satisfy at state latch2. (defun inst-latch2-inv (i MA) (declare (xargs :guard (and (INST-p i) (MA-state-p MA)))) (and (b1p (latch2-valid? (MA-latch2 MA))) (equal (latch2-op (MA-latch2 MA)) (INST-op i)) (equal (latch2-rc (MA-latch2 MA)) (INST-rc i)) (equal (latch2-ra-val (MA-latch2 MA)) (INST-ra-val i)) (equal (latch2-rb-val (MA-latch2 MA)) (INST-rb-val i)))) ; Instruction invariant that i should satisfy regardless of its stage. (defun inst-invariant (i MA) (declare (xargs :guard (and (INST-p i) (MA-state-p MA)))) (cond ((equal (INST-stg i) 'latch1) (inst-latch1-inv i MA)) ((equal (INST-stg i) 'latch2) (inst-latch2-inv i MA)) (t t))) (defun trace-inst-invariant (trace MA) (declare (xargs :guard (and (INST-listp trace) (MA-state-p MA)))) (if (endp trace) t (and (inst-invariant (car trace) MA) (trace-inst-invariant (cdr trace) MA)))) (defun MT-inst-invariant (MT MA) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)))) (trace-inst-invariant (MT-trace MT) MA)) ; If field latch1-valid? of an MA state is on, the corresponding MAETT ; contains an entry representing the instruction at latch1. Similarly ; for latch2. (defun MT-contains-all-insts (MT MA) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)))) (and (implies (b1p (latch1-valid? (MA-latch1 MA))) (inst-at 'latch1 MT)) (implies (b1p (latch2-valid? (MA-latch2 MA))) (inst-at 'latch2 MT)))) ; This pipelined machine executes instructions in program order. ; The instruction at latch1 is younger than the instruction at latch2, ; and the instruction at latch2 is younger than any retired ; instructions. This fact is checked by MT-in-order-p, assuming that ; instructions are recorded in program order in a MAETT. (defun trace-in-order-p (trace) (declare (xargs :guard (INST-listp trace))) (if (endp trace) t (if (equal (INST-stg (car trace)) 'latch1) (endp (cdr trace)) (if (equal (INST-stg (car trace)) 'latch2) (and (not (trace-inst-at 'latch2 (cdr trace))) (not (trace-inst-at 'retire (cdr trace))) (trace-in-order-p (cdr trace))) (trace-in-order-p (cdr trace)))))) (defun MT-in-order-p (MT) (declare (xargs :guard (MAETT-p MT))) (trace-in-order-p (MT-trace MT))) ; The definition of invariant. (defun invariant (MT MA) (declare (xargs :guard (and (MAETT-p MT) (MA-state-p MA)))) (and (pc-match-p MT MA) (regs-match-p MT MA) (mem-match-p MT MA) (ISA-chain-p MT) (MT-inst-invariant MT MA) (MT-contains-all-insts MT MA) (MT-in-order-p MT))) (deflabel end-invariant-def) (deftheory invariant-def (set-difference-theories (function-theory 'end-invariant-def) (function-theory 'begin-invariant-def))) (deftheory non-rec-invariant-def (non-rec-functions (theory 'invariant-def) world)) (in-theory (disable non-rec-invariant-def))