{-# OPTIONS --safe --cubical #-}
module Spartan6.Netlist.Expression where
open import Spartan6.Prelude
open import Spartan6.Primitive.LUT using (TruthTable; evalLUT)
infixr 7 _andE_
infixr 6 _xorE_
infixr 5 _orE_
data Expr (inputs registers : ℕ) : Type₀ where
input : Fin inputs → Expr inputs registers
register : Fin registers → Expr inputs registers
constant : Bit → Expr inputs registers
invert : Expr inputs registers → Expr inputs registers
_andE_ : Expr inputs registers → Expr inputs registers → Expr inputs registers
_orE_ : Expr inputs registers → Expr inputs registers → Expr inputs registers
_xorE_ : Expr inputs registers → Expr inputs registers → Expr inputs registers
select : Expr inputs registers → Expr inputs registers → Expr inputs registers
→ Expr inputs registers
lut : ∀ {arity} → TruthTable arity → Vec (Expr inputs registers) arity
→ Expr inputs registers
mutual
eval : ∀ {inputs registers}
→ Vec Bit inputs
→ Vec Bit registers
→ Expr inputs registers
→ Bit
eval external state (input i) = lookup i external
eval external state (register i) = lookup i state
eval external state (constant bit) = bit
eval external state (invert expression) = not (eval external state expression)
eval external state (left andE right) =
eval external state left and eval external state right
eval external state (left orE right) =
eval external state left or eval external state right
eval external state (left xorE right) =
eval external state left ⊕ eval external state right
eval external state (select selector when-false when-true) =
mux (eval external state selector)
(eval external state when-false)
(eval external state when-true)
eval external state (lut table arguments) =
evalLUT table (evalAll external state arguments)
evalAll : ∀ {inputs registers arity}
→ Vec Bit inputs
→ Vec Bit registers
→ Vec (Expr inputs registers) arity
→ Vec Bit arity
evalAll external state [] = []
evalAll external state (expression ∷ expressions) =
eval external state expression ∷ evalAll external state expressions
evalConstant : ∀ {inputs registers} external state bit
→ eval {inputs} {registers} external state (constant bit) ≡ bit
evalConstant external state bit = refl
evalSelect-low : ∀ {inputs registers} external state when-false when-true
→ eval {inputs} {registers} external state
(select (constant low) when-false when-true)
≡ eval external state when-false
evalSelect-low external state when-false when-true = refl
evalSelect-high : ∀ {inputs registers} external state when-false when-true
→ eval {inputs} {registers} external state
(select (constant high) when-false when-true)
≡ eval external state when-true
evalSelect-high external state when-false when-true = refl