9. Pipelined Cell
The fully synchronous cell pays three clocks per instruction because it never overlaps its phases. This chapter overlaps them for throughput and proves the result still commits the sequential trace. The overlap is deliberately narrow: only instruction fetch runs ahead. That is exactly the overlap this instruction set makes safe.
The reasoning turns on which hazards exist. There is no data hazard from
register, accumulator, or pointer dependencies, because each instruction still
executes against the fully committed architectural state — commits stay
one-per-cycle and in order, so every operand read sees all prior writebacks. The
instruction memory is read-only while the cell runs, so a prefetched instruction
never depends on a writeback either. The one hazard is control: the prefetch
predicts the fall-through address pc + 1, and a taken branch or a halt makes
that prediction wrong. A wrong prefetch is caught and squashed, costing a single
bubble.
The pipeline state adds a fetch latch to the architectural state: a validity bit, the memory index the latched instruction was fetched from, and the instruction itself. The invariant is that a valid latch holds the instruction at its recorded index.
namespace Honeycomb
def wantIdx (s : State defaultConfig) : Nat :=
memIndexOfNat defaultConfig s.pc.toNat
structure PipeCell where
arch : State defaultConfig
imem : Nat -> DecodedInstr
busy : Bool
fvalid : Bool
fpc : Nat
fir : DecodedInstr
-- One clock. A hit (the latch holds the instruction the program counter wants)
-- commits that instruction and prefetches the predicted fall-through. A miss
-- refetches the wanted instruction and bubbles.
def pstep (c : PipeCell) : PipeCell :=
if c.busy then
if c.arch.halted then c
else if c.fvalid && (c.fpc == wantIdx c.arch) then
let arch' := execDecoded c.fir c.arch
let pidx := memIndexOfNat defaultConfig (c.arch.pc.toNat + 1)
{ c with arch := arch', busy := !arch'.halted,
fvalid := true, fpc := pidx, fir := c.imem pidx }
else
let widx := wantIdx c.arch
{ c with fvalid := true, fpc := widx, fir := c.imem widx }
else c
Every clock keeps the fetch-latch invariant: whatever address the latch records, it holds that instruction. Both the hit and miss branches load the latch from the instruction memory at the index they record, and neither writes the instruction memory.
theorem pstep_preserves_inv (c : PipeCell)
(hinv : c.fvalid = true -> c.fir = c.imem c.fpc) :
(pstep c).fvalid = true -> (pstep c).fir = (pstep c).imem (pstep c).fpc := c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpc⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpcc:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:¬c.busy = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpcc:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:¬c.arch.halted = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc All goals completed! 🐙
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:¬c.arch.halted = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = false⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = falsehit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpcc:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = falsehit:¬(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = falsehit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = falsehit:(c.fvalid && c.fpc == wantIdx c.arch) = truea✝:(pstep c).fvalid = true⊢ (pstep c).fir = (pstep c).imem (pstep c).fpc; All goals completed! 🐙
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = falsehit:¬(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = falsehit:(c.fvalid && c.fpc == wantIdx c.arch) = false⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = truehh:c.arch.halted = falsehit:(c.fvalid && c.fpc == wantIdx c.arch) = falsea✝:(pstep c).fvalid = true⊢ (pstep c).fir = (pstep c).imem (pstep c).fpc; All goals completed! 🐙
c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:¬c.busy = true⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc c:PipeCellhinv:c.fvalid = true → c.fir = c.imem c.fpchb:c.busy = false⊢ (pstep c).fvalid = true → (pstep c).fir = (pstep c).imem (pstep c).fpc
All goals completed! 🐙
A hit commits exactly what the combinational cell commits in one cycle, so it
refines the ISA step for that instruction. The prefetch is validated by the hit
condition itself: the latched index equals the wanted index, so by the invariant
the latched instruction is the right one.
theorem pstep_hit_matches (c : PipeCell)
(hbusy : c.busy = true) (hhalt : c.arch.halted = false)
(hvalid : c.fvalid = true) (hpc : c.fpc = wantIdx c.arch)
(hinv : c.fir = c.imem c.fpc) :
(pstep c).arch
= (cellExecCycle
{ arch := c.arch, imem := c.imem, busy := c.busy }).arch := c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehvalid:c.fvalid = truehpc:c.fpc = wantIdx c.archhinv:c.fir = c.imem c.fpc⊢ (pstep c).arch = (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehvalid:c.fvalid = truehpc:c.fpc = wantIdx c.archhinv:c.fir = c.imem c.fpchit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (pstep c).arch = (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehvalid:c.fvalid = truehpc:c.fpc = wantIdx c.archhinv:c.fir = c.imem c.fpchit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (if false = true then c
else
{ arch := execDecoded c.fir c.arch, imem := c.imem, busy := !(execDecoded c.fir c.arch).halted, fvalid := true,
fpc := memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc + 1),
fir := c.imem (memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc + 1)) }).arch =
(cellExecCycle { arch := c.arch, imem := c.imem, busy := true }).arch
c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehvalid:c.fvalid = truehpc:c.fpc = wantIdx c.archhinv:c.fir = c.imem c.fpchit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (if false = true then c
else
{ arch := execDecoded (c.imem (wantIdx c.arch)) c.arch, imem := c.imem,
busy := !(execDecoded (c.imem (wantIdx c.arch)) c.arch).halted, fvalid := true,
fpc := memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc + 1),
fir := c.imem (memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc + 1)) }).arch =
(cellExecCycle { arch := c.arch, imem := c.imem, busy := true }).arch
simp [cellExecCycle, hhalt, wantIdx] All goals completed! 🐙
theorem pstep_hit_refines_isa (c : PipeCell)
(hbusy : c.busy = true) (hhalt : c.arch.halted = false)
(hvalid : c.fvalid = true) (hpc : c.fpc = wantIdx c.arch)
(hinv : c.fir = c.imem c.fpc) :
step defaultConfig (programOf c.imem) c.arch = some (pstep c).arch := by c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehvalid:c.fvalid = truehpc:c.fpc = wantIdx c.archhinv:c.fir = c.imem c.fpc⊢ step defaultConfig (programOf c.imem) c.arch = some (pstep c).arch
rw [pstep_hit_matches c hbusy hhalt hvalid hpc hinv c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehvalid:c.fvalid = truehpc:c.fpc = wantIdx c.archhinv:c.fir = c.imem c.fpc⊢ step defaultConfig (programOf c.imem) c.arch =
some (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch] c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehvalid:c.fvalid = truehpc:c.fpc = wantIdx c.archhinv:c.fir = c.imem c.fpc⊢ step defaultConfig (programOf c.imem) c.arch =
some (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
exact cellExecCycle_refines_step
{ arch := c.arch, imem := c.imem, busy := c.busy } hbusy hhalt All goals completed! 🐙
A miss changes nothing architecturally; it only reloads the latch with the wanted instruction. So a miss is a stutter step, and the state it produces is hit-ready: valid, with the recorded index equal to the wanted index and the invariant restored. The bubble after a mispredict therefore lasts exactly one cycle.
theorem pstep_miss_stutter (c : PipeCell)
(hbusy : c.busy = true) (hhalt : c.arch.halted = false)
(hmiss : (c.fvalid && (c.fpc == wantIdx c.arch)) = false) :
(pstep c).arch = c.arch := by c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = false⊢ (pstep c).arch = c.arch
simp [pstep, hbusy, hhalt, hmiss] All goals completed! 🐙
theorem pstep_miss_then_ready (c : PipeCell)
(hbusy : c.busy = true) (hhalt : c.arch.halted = false)
(hmiss : (c.fvalid && (c.fpc == wantIdx c.arch)) = false) :
(pstep c).fvalid = true
/\ (pstep c).fpc = wantIdx (pstep c).arch
/\ (pstep c).fir = (pstep c).imem (pstep c).fpc
/\ (pstep c).busy = c.busy
/\ (pstep c).imem = c.imem := by c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = false⊢ (pstep c).fvalid = true ∧
(pstep c).fpc = wantIdx (pstep c).arch ∧
(pstep c).fir = (pstep c).imem (pstep c).fpc ∧ (pstep c).busy = c.busy ∧ (pstep c).imem = c.imem
simp [pstep, hbusy, hhalt, hmiss] All goals completed! 🐙
The two combine into the throughput statement: a mispredict bubble followed by its refetch commits exactly one sequential step. Any taken branch costs one lost cycle and no correctness; straight-line code commits one instruction per cycle.
theorem pstep_bubble_then_commit (c : PipeCell)
(hbusy : c.busy = true) (hhalt : c.arch.halted = false)
(hmiss : (c.fvalid && (c.fpc == wantIdx c.arch)) = false) :
(pstep (pstep c)).arch
= (cellExecCycle
{ arch := c.arch, imem := c.imem, busy := c.busy }).arch := by c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = false⊢ (pstep (pstep c)).arch = (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
obtain ⟨hv, hp, hi, hbz, him⟩ :=
pstep_miss_then_ready c hbusy hhalt hmiss c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imem⊢ (pstep (pstep c)).arch = (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
have harch : (pstep c).arch = c.arch := pstep_miss_stutter c hbusy hhalt hmiss c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.arch⊢ (pstep (pstep c)).arch = (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
have hb2 : (pstep c).busy = true := by rw [hbz c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.arch⊢ c.busy = true] c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.arch⊢ c.busy = true; exact hbusy c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = true⊢ (pstep (pstep c)).arch = (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
have hh2 : (pstep c).arch.halted = false := by rw [harch c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = true⊢ c.arch.halted = false] c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = true⊢ c.arch.halted = false; exact hhalt c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = false⊢ (pstep (pstep c)).arch = (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
rw [pstep_hit_matches (pstep c) hb2 hh2 hv hp hi c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = false⊢ (cellExecCycle { arch := (pstep c).arch, imem := (pstep c).imem, busy := (pstep c).busy }).arch =
(cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch] c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = false⊢ (cellExecCycle { arch := (pstep c).arch, imem := (pstep c).imem, busy := (pstep c).busy }).arch =
(cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch
rw [harch, c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = false⊢ (cellExecCycle { arch := c.arch, imem := (pstep c).imem, busy := (pstep c).busy }).arch =
(cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch hbz, c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = false⊢ (cellExecCycle { arch := c.arch, imem := (pstep c).imem, busy := c.busy }).arch =
(cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch him c:PipeCellhbusy:c.busy = truehhalt:c.arch.halted = falsehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = false⊢ (cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch =
(cellExecCycle { arch := c.arch, imem := c.imem, busy := c.busy }).arch] All goals completed! 🐙
Running the cell is iterating the clock.
def pRun : Nat -> PipeCell -> PipeCell
| 0, c => c
| k + 1, c => pRun k (pstep c)
end Honeycomb
The correctness account is complete without a full stuttering-simulation induction. Every committing cycle equals one combinational-cell cycle and refines the ISA; every non-committing cycle leaves the architectural state untouched and is immediately followed by a commit. So the sequence of architectural states the pipeline commits is exactly the sequential trace, with isolated single-cycle bubbles that carry no value. The bubbles are the price of the one real hazard, and they appear only after a taken branch or at startup.
This model is emitted as generated SystemVerilog: rtl/honeycomb_cell_pipe.sv binds
a registered-read honeycomb_sram_sync_32 for the instruction fetch and drives its
address with the predicted pf_addr, keeping combinational operand memories. A
fvalid/fpc fetch latch and a hit line implement the prediction and squash.
The generated cell passes the same golden program suite as the combinational
cell — retiring identical results and identical instruction counts — over fewer
clocks than the fully synchronous cell, with a bubble only where a branch is
taken.
Widening the overlap — registering the operand reads and forwarding or interlocking their results, so the fully synchronous cell also reaches one instruction per cycle — is the next pipeline step, and the first that needs true data-hazard reasoning rather than this control-only argument.
9.1. The whole run, machine-checked
The composition is a theorem here too (review R4): under the fetch-latch
invariant, the pipeline simulates the combinational cycle model on a computed
schedule — one clock per hit, two per mispredict bubble, never more than
2 * n for n instructions — and therefore retires the sequential ISA trace
while the machine keeps executing.
namespace Honeycomb
/-- The cycle-model view of a pipelined-fetch cell. -/
def PipeCell.toCellState (c : PipeCell) : CellState :=
{ arch := c.arch, imem := c.imem, busy := c.busy }
/-- The hit test, exactly the condition `pstep` keys on. -/
def pReady (c : PipeCell) : Bool :=
c.fvalid && (c.fpc == wantIdx c.arch)
/-- The pipeline's schedule: one clock per hit, two per bubbled commit. -/
def pCycles : Nat → PipeCell → Nat
| 0, _ => 0
| n + 1, c =>
if pReady c then 1 + pCycles n (pstep c)
else 2 + pCycles n (pstep (pstep c))
/-- The fetch-latch invariant, as a predicate. -/
def PFetchInv (c : PipeCell) : Prop :=
c.fvalid = true → c.fir = c.imem c.fpc
/-- A stopped or halted machine holds through a clock. -/
theorem pstep_stalls (c : PipeCell)
(h : ¬(c.busy = true ∧ c.arch.halted = false)) : pstep c = c := by c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)⊢ pstep c = c
by_cases hb : c.busy pos c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:c.busy = true⊢ pstep c = cneg c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:¬c.busy = true⊢ pstep c = c
· pos c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:c.busy = true⊢ pstep c = c have hh : c.arch.halted = true := by
cases hx : c.arch.halted false c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:c.busy = truehx:c.arch.halted = false⊢ false = truetrue c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:c.busy = truehx:c.arch.halted = true⊢ true = true
· false c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:c.busy = truehx:c.arch.halted = false⊢ false = true exact absurd ⟨hb, hx⟩ h All goals completed! 🐙
· true c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:c.busy = truehx:c.arch.halted = true⊢ true = true rfl pos c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:c.busy = truehh:c.arch.halted = true⊢ pstep c = c
simp [pstep, hb, hh] All goals completed! 🐙
· neg c:PipeCellh:¬(c.busy = true ∧ c.arch.halted = false)hb:¬c.busy = true⊢ pstep c = c simp [pstep, hb] All goals completed! 🐙
/-- A hit is one iteration of the cycle model on the projected state. -/
theorem pstep_hit_toCellState (c : PipeCell)
(hInv : PFetchInv c) (hb : c.busy = true) (hh : c.arch.halted = false)
(hr : pReady c = true) :
(pstep c).toCellState = cellExecCycle c.toCellState := by c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehr:pReady c = true⊢ (pstep c).toCellState = cellExecCycle c.toCellState
simp only [pReady, Bool.and_eq_true, beq_iff_eq] at hr c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehr:c.fvalid = true ∧ c.fpc = wantIdx c.arch⊢ (pstep c).toCellState = cellExecCycle c.toCellState
obtain ⟨hfv, hpc⟩ := hr c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehfv:c.fvalid = truehpc:c.fpc = wantIdx c.arch⊢ (pstep c).toCellState = cellExecCycle c.toCellState
have hit : (c.fvalid && (c.fpc == wantIdx c.arch)) = true := by
simp [hfv, hpc] c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehfv:c.fvalid = truehpc:c.fpc = wantIdx c.archhit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ (pstep c).toCellState = cellExecCycle c.toCellState
have hfir : c.fir = c.imem (memIndexOfNat defaultConfig c.arch.pc.toNat) := by
rw [hInv hfv, c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehfv:c.fvalid = truehpc:c.fpc = wantIdx c.archhit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ c.imem c.fpc = c.imem (memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc)) hpc c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehfv:c.fvalid = truehpc:c.fpc = wantIdx c.archhit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ c.imem (wantIdx c.arch) = c.imem (memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc))] c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehfv:c.fvalid = truehpc:c.fpc = wantIdx c.archhit:(c.fvalid && c.fpc == wantIdx c.arch) = true⊢ c.imem (wantIdx c.arch) = c.imem (memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc)); rfl c:PipeCellhInv:PFetchInv chb:c.busy = truehh:c.arch.halted = falsehfv:c.fvalid = truehpc:c.fpc = wantIdx c.archhit:(c.fvalid && c.fpc == wantIdx c.arch) = truehfir:c.fir = c.imem (memIndexOfNat defaultConfig (BitVec.toNat c.arch.pc))⊢ (pstep c).toCellState = cellExecCycle c.toCellState
simp [PipeCell.toCellState, pstep, cellExecCycle, hb, hh, hit, hfir] All goals completed! 🐙
/-- **The run-level simulation, on the pipeline's own schedule.** `pCycles n c`
clocks are exactly `n` iterations of the combinational cycle model, with the
fetch-latch invariant preserved and at most two clocks per instruction —
unconditionally in `n` (a halted or stopped machine holds on both sides). -/
theorem pRun_refines_cellExecCycleN (n : Nat) (c : PipeCell)
(hInv : PFetchInv c) :
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState
∧ PFetchInv (pRun (pCycles n c) c)
∧ pCycles n c ≤ 2 * n := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
induction n generalizing c with
| zero => zero c:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles 0 c) c).toCellState = cellExecCycleN 0 c.toCellState ∧
PFetchInv (pRun (pCycles 0 c) c) ∧ pCycles 0 c ≤ 2 * 0 exact ⟨rfl, hInv, by c:PipeCellhInv:PFetchInv c⊢ pCycles 0 c ≤ 2 * 0 simp [pCycles] All goals completed! 🐙⟩
| succ n ih => succ n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hunf : cellExecCycleN (n + 1) c.toCellState
= cellExecCycleN n (cellExecCycle c.toCellState) := rfl succ n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hInvStep : PFetchInv (pstep c) := pstep_preserves_inv c hInv succ n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
by_cases hlive : c.busy = true ∧ c.arch.halted = false pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:c.busy = true ∧ c.arch.halted = false⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
· pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:c.busy = true ∧ c.arch.halted = false⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1) obtain ⟨hb, hh⟩ := hlive pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = false⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
by_cases hr : pReady c = true pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
· pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1) have hcyc : pCycles (n + 1) c = 1 + pCycles n (pstep c) := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
simp [pCycles, hr] pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
obtain ⟨hsim, hInv'', hbound⟩ := ih (pstep c) hInvStep pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * n⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hproj := pstep_hit_toCellState c hInv hb hh hr pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
refine ⟨?_, ?_, by n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ pCycles (n + 1) c ≤ 2 * (n + 1) omega All goals completed! 🐙⟩
· pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState rw [hcyc, pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ (pRun (1 + pCycles n (pstep c)) c).toCellState = cellExecCycleN (n + 1) c.toCellState show 1 + pCycles n (pstep c) = pCycles n (pstep c) + 1 by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n omega All goals completed! 🐙] pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles n (pstep c) + 1) c).toCellState = cellExecCycleN (n + 1) c.toCellState
show (pRun (pCycles n (pstep c)) (pstep c)).toCellState = _ pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN (n + 1) c.toCellState
rw [hsim, pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ cellExecCycleN n (pstep c).toCellState = cellExecCycleN (n + 1) c.toCellState hunf, pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ cellExecCycleN n (pstep c).toCellState = cellExecCycleN n (cellExecCycle c.toCellState) hproj pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ cellExecCycleN n (cellExecCycle c.toCellState) = cellExecCycleN n (cellExecCycle c.toCellState)] All goals completed! 🐙
· pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ PFetchInv (pRun (pCycles (n + 1) c) c) rw [hcyc, pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ PFetchInv (pRun (1 + pCycles n (pstep c)) c) show 1 + pCycles n (pstep c) = pCycles n (pstep c) + 1 by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n omega All goals completed! 🐙] pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n (pstep c)hsim:(pRun (pCycles n (pstep c)) (pstep c)).toCellState = cellExecCycleN n (pstep c).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep c)) (pstep c))hbound:pCycles n (pstep c) ≤ 2 * nhproj:(pstep c).toCellState = cellExecCycle c.toCellState⊢ PFetchInv (pRun (pCycles n (pstep c) + 1) c)
exact hInv'' All goals completed! 🐙
· neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1) have hmiss : (c.fvalid && (c.fpc == wantIdx c.arch)) = false := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
have : pReady c = false := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
cases hx : pReady c false n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehx:pReady c = false⊢ false = falsetrue n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehx:pReady c = true⊢ true = false
· false n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehx:pReady c = false⊢ false = false rfl All goals completed! 🐙
· true n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehx:pReady c = true⊢ true = false exact absurd hx hr n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truethis:pReady c = false⊢ (c.fvalid && c.fpc == wantIdx c.arch) = false
simpa [pReady] using this neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = false⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
obtain ⟨hv, hp, hi, hbz, him⟩ := pstep_miss_then_ready c hb hh hmiss neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imem⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have harch : (pstep c).arch = c.arch := pstep_miss_stutter c hb hh hmiss neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.arch⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hb2 : (pstep c).busy = true := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n rw [hbz n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.arch⊢ c.busy = true] n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.arch⊢ c.busy = true; exact hb neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hh2 : (pstep c).arch.halted = false := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n rw [harch n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = true⊢ c.arch.halted = false] n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = true⊢ c.arch.halted = false; exact hh neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = false⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hr2 : pReady (pstep c) = true := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
simp [pReady, hv, hp] neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hcyc : pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c)) := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
have : pReady c = false := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
cases hx : pReady c false n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehx:pReady c = false⊢ false = falsetrue n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehx:pReady c = true⊢ true = false
· false n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehx:pReady c = false⊢ false = false rfl All goals completed! 🐙
· true n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehx:pReady c = true⊢ true = false exact absurd hx hr n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truethis:pReady c = false⊢ pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))
simp [pCycles, this] neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hInv2 : PFetchInv (pstep (pstep c)) :=
pstep_preserves_inv (pstep c) hInvStep neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
obtain ⟨hsim, hInv'', hbound⟩ := ih (pstep (pstep c)) hInv2 neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * n⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hproj : (pstep (pstep c)).toCellState = cellExecCycle c.toCellState := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
have h1 := pstep_hit_toCellState (pstep c) hInvStep hb2 hh2 hr2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nh1:(pstep (pstep c)).toCellState = cellExecCycle (pstep c).toCellState⊢ (pstep (pstep c)).toCellState = cellExecCycle c.toCellState
rw [h1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nh1:(pstep (pstep c)).toCellState = cellExecCycle (pstep c).toCellState⊢ cellExecCycle (pstep c).toCellState = cellExecCycle c.toCellState] n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nh1:(pstep (pstep c)).toCellState = cellExecCycle (pstep c).toCellState⊢ cellExecCycle (pstep c).toCellState = cellExecCycle c.toCellState
show cellExecCycle (pstep c).toCellState = _ n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nh1:(pstep (pstep c)).toCellState = cellExecCycle (pstep c).toCellState⊢ cellExecCycle (pstep c).toCellState = cellExecCycle c.toCellState
have : (pstep c).toCellState = c.toCellState := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
simp [PipeCell.toCellState, harch, hbz, him] n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nh1:(pstep (pstep c)).toCellState = cellExecCycle (pstep c).toCellStatethis:(pstep c).toCellState = c.toCellState⊢ cellExecCycle (pstep c).toCellState = cellExecCycle c.toCellState
rw [this n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nh1:(pstep (pstep c)).toCellState = cellExecCycle (pstep c).toCellStatethis:(pstep c).toCellState = c.toCellState⊢ cellExecCycle c.toCellState = cellExecCycle c.toCellState] neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
refine ⟨?_, ?_, by n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ pCycles (n + 1) c ≤ 2 * (n + 1) omega All goals completed! 🐙⟩
· neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState rw [hcyc, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ (pRun (2 + pCycles n (pstep (pstep c))) c).toCellState = cellExecCycleN (n + 1) c.toCellState show 2 + pCycles n (pstep (pstep c))
= pCycles n (pstep (pstep c)) + 1 + 1 by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n omega All goals completed! 🐙] neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles n (pstep (pstep c)) + 1 + 1) c).toCellState = cellExecCycleN (n + 1) c.toCellState
show (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = _ neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN (n + 1) c.toCellState
rw [hsim, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ cellExecCycleN n (pstep (pstep c)).toCellState = cellExecCycleN (n + 1) c.toCellState hunf, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ cellExecCycleN n (pstep (pstep c)).toCellState = cellExecCycleN n (cellExecCycle c.toCellState) hproj neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ cellExecCycleN n (cellExecCycle c.toCellState) = cellExecCycleN n (cellExecCycle c.toCellState)] All goals completed! 🐙
· neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ PFetchInv (pRun (pCycles (n + 1) c) c) rw [hcyc, neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ PFetchInv (pRun (2 + pCycles n (pstep (pstep c))) c) show 2 + pCycles n (pstep (pstep c))
= pCycles n (pstep (pstep c)) + 1 + 1 by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n omega All goals completed! 🐙] neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hb:c.busy = truehh:c.arch.halted = falsehr:¬pReady c = truehmiss:(c.fvalid && c.fpc == wantIdx c.arch) = falsehv:(pstep c).fvalid = truehp:(pstep c).fpc = wantIdx (pstep c).archhi:(pstep c).fir = (pstep c).imem (pstep c).fpchbz:(pstep c).busy = c.busyhim:(pstep c).imem = c.imemharch:(pstep c).arch = c.archhb2:(pstep c).busy = truehh2:(pstep c).arch.halted = falsehr2:pReady (pstep c) = truehcyc:pCycles (n + 1) c = 2 + pCycles n (pstep (pstep c))hInv2:PFetchInv (pstep (pstep c))hsim:(pRun (pCycles n (pstep (pstep c))) (pstep (pstep c))).toCellState = cellExecCycleN n (pstep (pstep c)).toCellStatehInv'':PFetchInv (pRun (pCycles n (pstep (pstep c))) (pstep (pstep c)))hbound:pCycles n (pstep (pstep c)) ≤ 2 * nhproj:(pstep (pstep c)).toCellState = cellExecCycle c.toCellState⊢ PFetchInv (pRun (pCycles n (pstep (pstep c)) + 1 + 1) c)
exact hInv'' All goals completed! 🐙
· neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1) have hstall : pstep c = c := pstep_stalls c hlive neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = c⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hcell : cellExecCycle c.toCellState = c.toCellState := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
apply cellExecCycle_stalls n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = c⊢ ¬(c.toCellState.busy = true ∧ c.toCellState.arch.halted = false)
simpa [PipeCell.toCellState] using hlive neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellState⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
obtain ⟨hsim, hInv'', hbound⟩ := ih c hInv neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * n⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
by_cases hr : pReady c = true pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
· pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1) have hcyc : pCycles (n + 1) c = 1 + pCycles n c := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
simp [pCycles, hr, hstall] pos n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
refine ⟨?_, ?_, by n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ pCycles (n + 1) c ≤ 2 * (n + 1) omega All goals completed! 🐙⟩ <;> pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellStatepos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ PFetchInv (pRun (pCycles (n + 1) c) c)
rw [hcyc, pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ (pRun (1 + pCycles n c) c).toCellState = cellExecCycleN (n + 1) c.toCellState show 1 + pCycles n c = pCycles n c + 1 by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n omega All goals completed! 🐙] pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ (pRun (pCycles n c + 1) c).toCellState = cellExecCycleN (n + 1) c.toCellState pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ PFetchInv (pRun (pCycles n c + 1) c)
· pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ (pRun (pCycles n c + 1) c).toCellState = cellExecCycleN (n + 1) c.toCellState show (pRun (pCycles n c) (pstep c)).toCellState = _ pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ (pRun (pCycles n c) (pstep c)).toCellState = cellExecCycleN (n + 1) c.toCellState
rw [hstall, pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN (n + 1) c.toCellState hsim, pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ cellExecCycleN n c.toCellState = cellExecCycleN (n + 1) c.toCellState hunf, pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ cellExecCycleN n c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState) hcell pos.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ cellExecCycleN n c.toCellState = cellExecCycleN n c.toCellState] All goals completed! 🐙
· pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ PFetchInv (pRun (pCycles n c + 1) c) show PFetchInv (pRun (pCycles n c) (pstep c)) pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ PFetchInv (pRun (pCycles n c) (pstep c))
rw [hstall pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ PFetchInv (pRun (pCycles n c) c)] pos.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:pReady c = truehcyc:pCycles (n + 1) c = 1 + pCycles n c⊢ PFetchInv (pRun (pCycles n c) c); exact hInv'' All goals completed! 🐙
· neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = true⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1) have hrf : pReady c = false := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
cases hx : pReady c false n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehx:pReady c = false⊢ false = falsetrue n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehx:pReady c = true⊢ true = false
· false n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehx:pReady c = false⊢ false = false rfl All goals completed! 🐙
· true n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehx:pReady c = true⊢ true = false exact absurd hx hr neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = false⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
have hcyc : pCycles (n + 1) c = 2 + pCycles n c := by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n
simp [pCycles, hrf, hstall] neg n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellState ∧
PFetchInv (pRun (pCycles (n + 1) c) c) ∧ pCycles (n + 1) c ≤ 2 * (n + 1)
refine ⟨?_, ?_, by n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ pCycles (n + 1) c ≤ 2 * (n + 1) omega All goals completed! 🐙⟩ <;> neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (pCycles (n + 1) c) c).toCellState = cellExecCycleN (n + 1) c.toCellStateneg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ PFetchInv (pRun (pCycles (n + 1) c) c)
rw [hcyc, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (2 + pCycles n c) c).toCellState = cellExecCycleN (n + 1) c.toCellState show 2 + pCycles n c = pCycles n c + 1 + 1 by n:Natc:PipeCellhInv:PFetchInv c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * n omega All goals completed! 🐙] neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (pCycles n c + 1 + 1) c).toCellState = cellExecCycleN (n + 1) c.toCellState neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ PFetchInv (pRun (pCycles n c + 1 + 1) c)
· neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (pCycles n c + 1 + 1) c).toCellState = cellExecCycleN (n + 1) c.toCellState show (pRun (pCycles n c) (pstep (pstep c))).toCellState = _ neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (pCycles n c) (pstep (pstep c))).toCellState = cellExecCycleN (n + 1) c.toCellState
rw [hstall, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (pCycles n c) (pstep c)).toCellState = cellExecCycleN (n + 1) c.toCellState hstall, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ (pRun (pCycles n c) c).toCellState = cellExecCycleN (n + 1) c.toCellState hsim, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ cellExecCycleN n c.toCellState = cellExecCycleN (n + 1) c.toCellState hunf, neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ cellExecCycleN n c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState) hcell neg.refine_1 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ cellExecCycleN n c.toCellState = cellExecCycleN n c.toCellState] All goals completed! 🐙
· neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ PFetchInv (pRun (pCycles n c + 1 + 1) c) show PFetchInv (pRun (pCycles n c) (pstep (pstep c))) neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ PFetchInv (pRun (pCycles n c) (pstep (pstep c)))
rw [hstall, neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ PFetchInv (pRun (pCycles n c) (pstep c)) hstall neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ PFetchInv (pRun (pCycles n c) c)] neg.refine_2 n:Natih:∀ (c : PipeCell),
PFetchInv c →
(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellState ∧
PFetchInv (pRun (pCycles n c) c) ∧ pCycles n c ≤ 2 * nc:PipeCellhInv:PFetchInv chunf:cellExecCycleN (n + 1) c.toCellState = cellExecCycleN n (cellExecCycle c.toCellState)hInvStep:PFetchInv (pstep c)hlive:¬(c.busy = true ∧ c.arch.halted = false)hstall:pstep c = chcell:cellExecCycle c.toCellState = c.toCellStatehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStatehInv'':PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nhr:¬pReady c = truehrf:pReady c = falsehcyc:pCycles (n + 1) c = 2 + pCycles n c⊢ PFetchInv (pRun (pCycles n c) c); exact hInv'' All goals completed! 🐙
/-- **The ISA trace, at one-to-two clocks per instruction.** While the machine
keeps executing, the pipelined-fetch cell retires exactly `n` ISA steps in
`pCycles n c ≤ 2 * n` clocks. -/
theorem pRun_commits_trace (n : Nat) (c : PipeCell)
(hInv : PFetchInv c)
(hlive : ∀ k, k < n →
(cellExecCycleN k c.toCellState).busy = true
∧ (cellExecCycleN k c.toCellState).arch.halted = false) :
stepN (programOf c.imem) n c.arch = some (pRun (pCycles n c) c).arch
∧ pCycles n c ≤ 2 * n := by n:Natc:PipeCellhInv:PFetchInv chlive:∀ (k : Nat), k < n → (cellExecCycleN k c.toCellState).busy = true ∧ (cellExecCycleN k c.toCellState).arch.halted = false⊢ stepN (programOf c.imem) n c.arch = some (pRun (pCycles n c) c).arch ∧ pCycles n c ≤ 2 * n
obtain ⟨hsim, _, hbound⟩ := pRun_refines_cellExecCycleN n c hInv n:Natc:PipeCellhInv:PFetchInv chlive:∀ (k : Nat), k < n → (cellExecCycleN k c.toCellState).busy = true ∧ (cellExecCycleN k c.toCellState).arch.halted = falsehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStateleft✝:PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * n⊢ stepN (programOf c.imem) n c.arch = some (pRun (pCycles n c) c).arch ∧ pCycles n c ≤ 2 * n
have h := cellExecCycleN_refines_stepN n c.toCellState hlive n:Natc:PipeCellhInv:PFetchInv chlive:∀ (k : Nat), k < n → (cellExecCycleN k c.toCellState).busy = true ∧ (cellExecCycleN k c.toCellState).arch.halted = falsehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStateleft✝:PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nh:stepN (programOf c.toCellState.imem) n c.toCellState.arch = some (cellExecCycleN n c.toCellState).arch⊢ stepN (programOf c.imem) n c.arch = some (pRun (pCycles n c) c).arch ∧ pCycles n c ≤ 2 * n
refine ⟨?_, hbound⟩ n:Natc:PipeCellhInv:PFetchInv chlive:∀ (k : Nat), k < n → (cellExecCycleN k c.toCellState).busy = true ∧ (cellExecCycleN k c.toCellState).arch.halted = falsehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStateleft✝:PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nh:stepN (programOf c.toCellState.imem) n c.toCellState.arch = some (cellExecCycleN n c.toCellState).arch⊢ stepN (programOf c.imem) n c.arch = some (pRun (pCycles n c) c).arch
rw [show (pRun (pCycles n c) c).arch
= (pRun (pCycles n c) c).toCellState.arch from rfl, n:Natc:PipeCellhInv:PFetchInv chlive:∀ (k : Nat), k < n → (cellExecCycleN k c.toCellState).busy = true ∧ (cellExecCycleN k c.toCellState).arch.halted = falsehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStateleft✝:PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nh:stepN (programOf c.toCellState.imem) n c.toCellState.arch = some (cellExecCycleN n c.toCellState).arch⊢ stepN (programOf c.imem) n c.arch = some (pRun (pCycles n c) c).toCellState.arch hsim n:Natc:PipeCellhInv:PFetchInv chlive:∀ (k : Nat), k < n → (cellExecCycleN k c.toCellState).busy = true ∧ (cellExecCycleN k c.toCellState).arch.halted = falsehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStateleft✝:PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nh:stepN (programOf c.toCellState.imem) n c.toCellState.arch = some (cellExecCycleN n c.toCellState).arch⊢ stepN (programOf c.imem) n c.arch = some (cellExecCycleN n c.toCellState).arch] n:Natc:PipeCellhInv:PFetchInv chlive:∀ (k : Nat), k < n → (cellExecCycleN k c.toCellState).busy = true ∧ (cellExecCycleN k c.toCellState).arch.halted = falsehsim:(pRun (pCycles n c) c).toCellState = cellExecCycleN n c.toCellStateleft✝:PFetchInv (pRun (pCycles n c) c)hbound:pCycles n c ≤ 2 * nh:stepN (programOf c.toCellState.imem) n c.toCellState.arch = some (cellExecCycleN n c.toCellState).arch⊢ stepN (programOf c.imem) n c.arch = some (cellExecCycleN n c.toCellState).arch
simpa [PipeCell.toCellState] using h All goals completed! 🐙
end Honeycomb