{-# OPTIONS --safe --cubical #-}
module Spartan6.Netlist.Checked where
open import Spartan6.Prelude
open import Spartan6.Primitive.LUT using (TruthTable)
open import Spartan6.Netlist.Expression
open import Spartan6.Semantics.Design
data Wire (inputCount registerCount localCount : ℕ) : Type₀ where
externalWire : Fin inputCount → Wire inputCount registerCount localCount
storedWire : Fin registerCount → Wire inputCount registerCount localCount
localWire : Fin localCount → Wire inputCount registerCount localCount
literalWire : Bit → Wire inputCount registerCount localCount
data Node (inputCount registerCount localCount : ℕ) : Type₀ where
invertNode : Wire inputCount registerCount localCount
→ Node inputCount registerCount localCount
andNode : Wire inputCount registerCount localCount
→ Wire inputCount registerCount localCount
→ Node inputCount registerCount localCount
orNode : Wire inputCount registerCount localCount
→ Wire inputCount registerCount localCount
→ Node inputCount registerCount localCount
xorNode : Wire inputCount registerCount localCount
→ Wire inputCount registerCount localCount
→ Node inputCount registerCount localCount
muxNode : Wire inputCount registerCount localCount
→ Wire inputCount registerCount localCount
→ Wire inputCount registerCount localCount
→ Node inputCount registerCount localCount
lutNode : ∀ {arity}
→ TruthTable arity
→ Vec (Wire inputCount registerCount localCount) arity
→ Node inputCount registerCount localCount
infixl 4 _▻_
data Nodes (inputCount registerCount : ℕ) : ℕ → Type₀ where
noNodes : Nodes inputCount registerCount 0
_▻_ : ∀ {localCount}
→ Nodes inputCount registerCount localCount
→ Node inputCount registerCount localCount
→ Nodes inputCount registerCount (suc localCount)
compileWire : ∀ {inputCount registerCount localCount}
→ Vec (Expr inputCount registerCount) localCount
→ Wire inputCount registerCount localCount
→ Expr inputCount registerCount
compileWire locals (externalWire index) = input index
compileWire locals (storedWire index) = register index
compileWire locals (localWire index) = lookup index locals
compileWire locals (literalWire bit) = constant bit
compileWires : ∀ {inputCount registerCount localCount arity}
→ Vec (Expr inputCount registerCount) localCount
→ Vec (Wire inputCount registerCount localCount) arity
→ Vec (Expr inputCount registerCount) arity
compileWires locals [] = []
compileWires locals (wire ∷ wires) =
compileWire locals wire ∷ compileWires locals wires
compileNode : ∀ {inputCount registerCount localCount}
→ Vec (Expr inputCount registerCount) localCount
→ Node inputCount registerCount localCount
→ Expr inputCount registerCount
compileNode locals (invertNode wire) = invert (compileWire locals wire)
compileNode locals (andNode left right) =
compileWire locals left andE compileWire locals right
compileNode locals (orNode left right) =
compileWire locals left orE compileWire locals right
compileNode locals (xorNode left right) =
compileWire locals left xorE compileWire locals right
compileNode locals (muxNode selector when-false when-true) =
select (compileWire locals selector)
(compileWire locals when-false)
(compileWire locals when-true)
compileNode locals (lutNode table arguments) =
lut table (compileWires locals arguments)
compileNodes : ∀ {inputCount registerCount localCount}
→ Nodes inputCount registerCount localCount
→ Vec (Expr inputCount registerCount) localCount
compileNodes noNodes = []
compileNodes (nodes ▻ node) =
compileNode compiled node ∷ compiled
where
compiled = compileNodes nodes
record CheckedNetlist
(inputCount outputCount registerCount localCount : ℕ) : Type₀ where
constructor checkedNetlist
field
checkedInitial : Vec Bit registerCount
checkedNodes : Nodes inputCount registerCount localCount
checkedOutputs : Vec (Wire inputCount registerCount localCount) outputCount
checkedNext : Vec (Wire inputCount registerCount localCount) registerCount
open CheckedNetlist public
compileNetlist : ∀ {inputCount outputCount registerCount localCount}
→ CheckedNetlist inputCount outputCount registerCount localCount
→ Design inputCount outputCount registerCount
compileNetlist netlist =
mkDesign
(checkedInitial netlist)
(compileWires locals (checkedOutputs netlist))
(compileWires locals (checkedNext netlist))
where
locals = compileNodes (checkedNodes netlist)
compile-preserves-initial :
∀ {inputCount outputCount registerCount localCount}
(netlist : CheckedNetlist inputCount outputCount registerCount localCount)
→ initial (compileNetlist netlist) ≡ checkedInitial netlist
compile-preserves-initial netlist = refl