{-# OPTIONS --safe --cubical #-}
module Spartan6.Netlist.StableBuilder where
open import Spartan6.Prelude
open import Cubical.Data.FinData.Base using (fromℕ)
import Spartan6.Netlist.Raw as Raw
import Spartan6.Netlist.StableDAG as Stable
data BuilderReference (inputCount stateCount : ℕ) : Type₀ where
externalReference : Fin inputCount → BuilderReference inputCount stateCount
storedReference : Fin stateCount → BuilderReference inputCount stateCount
localReference : ℕ → BuilderReference inputCount stateCount
literalReference : Bit → BuilderReference inputCount stateCount
record StableBinding (inputCount stateCount : ℕ) : Type₀ where
constructor bindStable
field
bindingNet : Raw.NetId
bindingReference : BuilderReference inputCount stateCount
open StableBinding public
StableBindings : ℕ → ℕ → Type₀
StableBindings inputCount stateCount =
List (StableBinding inputCount stateCount)
record StableBuilder (inputCount stateCount : ℕ) : Type₀ where
constructor stableBuilder
field
builderLocalCount : ℕ
builderNodes : Stable.StableNodes
inputCount stateCount builderLocalCount
builderBindings : StableBindings inputCount stateCount
open StableBuilder public
emptyBuilder : ∀ inputCount stateCount → StableBuilder inputCount stateCount
emptyBuilder inputCount stateCount =
stableBuilder 0 Stable.stableNoNodes []ᴸ
extendBuilder : ∀ {inputCount stateCount}
→ (current : StableBuilder inputCount stateCount)
→ Raw.NetId
→ Stable.StableNode inputCount stateCount
(builderLocalCount current)
→ StableBuilder inputCount stateCount
extendBuilder (stableBuilder localCount nodes bindings) net-id node =
stableBuilder
(suc localCount)
(nodes Stable.▹ node)
(bindStable net-id (localReference localCount) ∷ᴸ bindings)
mapMaybe : ∀ {ℓ ℓ'} {A : Type ℓ} {B : Type ℓ'}
→ (A → B) → Maybe A → Maybe B
mapMaybe function nothing = nothing
mapMaybe function (just value) = just (function value)
boundedIndex : (ordinal bound : ℕ) → Maybe (Fin bound)
boundedIndex zero zero = nothing
boundedIndex zero (suc bound) = just fzero
boundedIndex (suc ordinal) zero = nothing
boundedIndex (suc ordinal) (suc bound) =
mapMaybe fsuc (boundedIndex ordinal bound)
materializeReference : ∀ {inputCount stateCount}
→ (localCount : ℕ)
→ BuilderReference inputCount stateCount
→ Maybe (Stable.StableWire inputCount stateCount localCount)
materializeReference localCount (externalReference index) =
just (Stable.stableExternal index)
materializeReference localCount (storedReference index) =
just (Stable.stableStored index)
materializeReference localCount (localReference ordinal) =
mapMaybe Stable.stableLocal (boundedIndex ordinal localCount)
materializeReference localCount (literalReference bit) =
just (Stable.stableLiteral bit)
boundedIndex-self : ∀ ordinal
→ boundedIndex ordinal (suc ordinal) ≡ just (fromℕ ordinal)
boundedIndex-self zero = refl
boundedIndex-self (suc ordinal) =
cong (mapMaybe fsuc) (boundedIndex-self ordinal)
new-reference-materializes : ∀ {inputCount stateCount} localCount
→ materializeReference {inputCount} {stateCount}
(suc localCount) (localReference localCount)
≡ just (Stable.stableLocal (fromℕ localCount))
new-reference-materializes localCount =
cong (mapMaybe Stable.stableLocal) (boundedIndex-self localCount)
extension-retains-bindings : ∀ {inputCount stateCount}
(current : StableBuilder inputCount stateCount)
(net-id : Raw.NetId)
(node : Stable.StableNode inputCount stateCount
(builderLocalCount current))
→ builderBindings (extendBuilder current net-id node)
≡ bindStable net-id (localReference (builderLocalCount current))
∷ᴸ builderBindings current
extension-retains-bindings
(stableBuilder localCount nodes bindings) net-id node = refl
extension-adds-one-node : ∀ {inputCount stateCount}
(current : StableBuilder inputCount stateCount)
(net-id : Raw.NetId)
(node : Stable.StableNode inputCount stateCount
(builderLocalCount current))
→ builderLocalCount (extendBuilder current net-id node)
≡ suc (builderLocalCount current)
extension-adds-one-node
(stableBuilder localCount nodes bindings) net-id node = refl