{-# OPTIONS --safe --cubical #-}
module Spartan6.Validation.ParameterSoundness where
open import Spartan6.Prelude
import Spartan6.Architecture.Primitive as Architecture
import Spartan6.Foundation.Hex as Hex
import Spartan6.Netlist.Raw as Raw
import Spartan6.Primitive.LUT as LUT
open import Spartan6.Validation.CheckResult public
using (accepted?; rejected≢accepted; accepted-injective)
import Spartan6.Validation.Diagnostic as Diagnostic
import Spartan6.Validation.Parameter as Parameter
open import Agda.Builtin.String using (primStringEquality)
open import Cubical.Data.Bool.Properties using (false≢true)
open import Cubical.Foundations.Path using (inspect; [_]ᵢ)
import Cubical.Data.Empty as Empty
just? : ∀ {ℓ} {A : Type ℓ} → Maybe A → Bool
just? nothing = false
just? (just value) = true
nothing≢just : ∀ {ℓ} {A : Type ℓ} {value : A}
→ nothing ≡ just value
→ Empty.⊥
nothing≢just path = false≢true (cong just? path)
just-injective : ∀ {ℓ} {A : Type ℓ} {left right : A}
→ just left ≡ just right
→ left ≡ right
just-injective {left = left} path =
cong (fromMaybe left) path
where
fromMaybe : ∀ {ℓ} {A : Type ℓ} → A → Maybe A → A
fromMaybe fallback nothing = fallback
fromMaybe fallback (just value) = value
data CanonicalLUT6
: List Raw.RawParameter → Maybe Bit → LUT.LUT6Table → Type₀ where
canonicalLUT6Default :
CanonicalLUT6 []ᴸ nothing Parameter.defaultLUT6INIT
canonicalLUT6Explicit : ∀ {name text table}
→ primStringEquality name "INIT" ≡ true
→ Hex.decodeHexINITFixed 64 text ≡ just table
→ CanonicalLUT6
(Raw.rawParameter name text ∷ᴸ []ᴸ)
nothing
table
normaliseLUT6Parameters-sound :
∀ subject parameters initial-bit table
→ Parameter.normaliseLUT6Parameters
subject parameters initial-bit
≡ Diagnostic.accepted table
→ CanonicalLUT6 parameters initial-bit table
normaliseLUT6Parameters-sound
subject []ᴸ nothing table result
with accepted-injective result
... | default-is-table =
subst
(CanonicalLUT6 []ᴸ nothing)
default-is-table
canonicalLUT6Default
normaliseLUT6Parameters-sound
subject []ᴸ (just bit) table result =
Empty.rec (rejected≢accepted result)
normaliseLUT6Parameters-sound
subject (Raw.rawParameter name text ∷ᴸ []ᴸ) nothing table result
with primStringEquality name "INIT"
| inspect (λ candidate → primStringEquality candidate "INIT") name
... | false | [ name-test ]ᵢ =
Empty.rec (rejected≢accepted result)
... | true | [ name-test ]ᵢ
with Hex.decodeHexINITFixed 64 text
| inspect (Hex.decodeHexINITFixed 64) text
... | nothing | [ decode-test ]ᵢ =
Empty.rec (rejected≢accepted result)
... | just decoded | [ decode-test ]ᵢ
with accepted-injective result
... | decoded-is-table =
subst
(CanonicalLUT6
(Raw.rawParameter name text ∷ᴸ []ᴸ)
nothing)
decoded-is-table
(canonicalLUT6Explicit {name = name} {text = text} {table = decoded}
name-test
decode-test)
normaliseLUT6Parameters-sound
subject (Raw.rawParameter name text ∷ᴸ []ᴸ) (just bit) table result
with primStringEquality name "INIT"
... | false = Empty.rec (rejected≢accepted result)
... | true with Hex.decodeHexINITFixed 64 text
... | nothing = Empty.rec (rejected≢accepted result)
... | just decoded = Empty.rec (rejected≢accepted result)
normaliseLUT6Parameters-sound
subject (first ∷ᴸ second ∷ᴸ rest) nothing table result =
Empty.rec (rejected≢accepted result)
normaliseLUT6Parameters-sound
subject (first ∷ᴸ second ∷ᴸ rest) (just bit) table result =
Empty.rec (rejected≢accepted result)
normaliseLUT6Parameters-complete :
∀ subject {parameters initial-bit table}
→ CanonicalLUT6 parameters initial-bit table
→ Parameter.normaliseLUT6Parameters
subject parameters initial-bit
≡ Diagnostic.accepted table
normaliseLUT6Parameters-complete
subject canonicalLUT6Default = refl
normaliseLUT6Parameters-complete
subject (canonicalLUT6Explicit {name} {text} {table}
name-test decode-test)
with primStringEquality name "INIT"
... | false = Empty.rec (false≢true name-test)
... | true with Hex.decodeHexINITFixed 64 text
... | nothing = Empty.rec (nothing≢just decode-test)
... | just decoded =
cong Diagnostic.accepted (just-injective decode-test)
accepted-LUT6-has-no-scalar-INIT :
∀ {parameters initial-bit table}
→ CanonicalLUT6 parameters initial-bit table
→ initial-bit ≡ nothing
accepted-LUT6-has-no-scalar-INIT canonicalLUT6Default = refl
accepted-LUT6-has-no-scalar-INIT
(canonicalLUT6Explicit name-test decode-test) = refl
literal-LUT6-INIT-complete : ∀ subject text table
→ Hex.decodeHexINITFixed 64 text ≡ just table
→ Parameter.normaliseLUT6Parameters
subject
(Raw.rawParameter "INIT" text ∷ᴸ []ᴸ)
nothing
≡ Diagnostic.accepted table
literal-LUT6-INIT-complete subject text table decode-test =
normaliseLUT6Parameters-complete subject
(canonicalLUT6Explicit
{name = "INIT"} {text = text} {table = table}
refl decode-test)
data ScalarInitial (default : Bit) : Maybe Bit → Bit → Type₀ where
scalarDefault : ScalarInitial default nothing default
scalarExplicit : ∀ bit → ScalarInitial default (just bit) bit
normaliseFDREInitialBit-sound : ∀ initial-bit value
→ Parameter.normaliseFDREInitialBit initial-bit
≡ Diagnostic.accepted value
→ ScalarInitial low initial-bit value
normaliseFDREInitialBit-sound nothing value result
with accepted-injective result
... | default-is-value =
subst (ScalarInitial low nothing) default-is-value scalarDefault
normaliseFDREInitialBit-sound (just bit) value result
with accepted-injective result
... | bit-is-value =
subst (ScalarInitial low (just bit)) bit-is-value (scalarExplicit bit)
normaliseFDREInitialBit-complete : ∀ {initial-bit value}
→ ScalarInitial low initial-bit value
→ Parameter.normaliseFDREInitialBit initial-bit
≡ Diagnostic.accepted value
normaliseFDREInitialBit-complete scalarDefault = refl
normaliseFDREInitialBit-complete (scalarExplicit bit) = refl
normaliseFDSEInitialBit-sound : ∀ initial-bit value
→ Parameter.normaliseFDSEInitialBit initial-bit
≡ Diagnostic.accepted value
→ ScalarInitial high initial-bit value
normaliseFDSEInitialBit-sound nothing value result
with accepted-injective result
... | default-is-value =
subst (ScalarInitial high nothing) default-is-value scalarDefault
normaliseFDSEInitialBit-sound (just bit) value result
with accepted-injective result
... | bit-is-value =
subst (ScalarInitial high (just bit)) bit-is-value (scalarExplicit bit)
normaliseFDSEInitialBit-complete : ∀ {initial-bit value}
→ ScalarInitial high initial-bit value
→ Parameter.normaliseFDSEInitialBit initial-bit
≡ Diagnostic.accepted value
normaliseFDSEInitialBit-complete scalarDefault = refl
normaliseFDSEInitialBit-complete (scalarExplicit bit) = refl
data CanonicalScalarParameters (default : Bit)
: List Raw.RawParameter → Maybe Bit → Bit → Type₀ where
canonicalScalarParameters : ∀ {initial-bit value}
→ ScalarInitial default initial-bit value
→ CanonicalScalarParameters default []ᴸ initial-bit value
CanonicalFDREParameters :
List Raw.RawParameter → Maybe Bit → Bit → Type₀
CanonicalFDREParameters = CanonicalScalarParameters low
CanonicalFDSEParameters :
List Raw.RawParameter → Maybe Bit → Bit → Type₀
CanonicalFDSEParameters = CanonicalScalarParameters high
normaliseFDREParameters-sound :
∀ subject parameters initial-bit value
→ Parameter.normaliseFDREParameters subject parameters initial-bit
≡ Diagnostic.accepted value
→ CanonicalFDREParameters parameters initial-bit value
normaliseFDREParameters-sound subject []ᴸ nothing value result
with accepted-injective result
... | default-is-value =
subst
(CanonicalFDREParameters []ᴸ nothing)
default-is-value
(canonicalScalarParameters scalarDefault)
normaliseFDREParameters-sound subject []ᴸ (just bit) value result
with accepted-injective result
... | bit-is-value =
subst
(CanonicalFDREParameters []ᴸ (just bit))
bit-is-value
(canonicalScalarParameters (scalarExplicit bit))
normaliseFDREParameters-sound
subject (parameter ∷ᴸ parameters) nothing value result =
Empty.rec (rejected≢accepted result)
normaliseFDREParameters-sound
subject (parameter ∷ᴸ parameters) (just bit) value result =
Empty.rec (rejected≢accepted result)
normaliseFDREParameters-complete :
∀ subject {parameters initial-bit value}
→ CanonicalFDREParameters parameters initial-bit value
→ Parameter.normaliseFDREParameters subject parameters initial-bit
≡ Diagnostic.accepted value
normaliseFDREParameters-complete
subject (canonicalScalarParameters scalarDefault) = refl
normaliseFDREParameters-complete
subject (canonicalScalarParameters (scalarExplicit bit)) = refl
fdseParameterValue : Parameter.CoreParameters Architecture.FDSE → Bit
fdseParameterValue (Parameter.fdseParameters bit) = bit
fdseParameters-injective : ∀ {left right}
→ Parameter.fdseParameters left ≡ Parameter.fdseParameters right
→ left ≡ right
fdseParameters-injective path = cong fdseParameterValue path
normaliseFDSEParameters-sound :
∀ subject parameters initial-bit value
→ Parameter.normaliseCoreParameters
Architecture.FDSE subject parameters initial-bit
≡ Diagnostic.accepted (Parameter.fdseParameters value)
→ CanonicalFDSEParameters parameters initial-bit value
normaliseFDSEParameters-sound subject []ᴸ nothing value result
with accepted-injective result
... | wrapped-path =
subst
(CanonicalFDSEParameters []ᴸ nothing)
(fdseParameters-injective wrapped-path)
(canonicalScalarParameters scalarDefault)
normaliseFDSEParameters-sound subject []ᴸ (just bit) value result
with accepted-injective result
... | wrapped-path =
subst
(CanonicalFDSEParameters []ᴸ (just bit))
(fdseParameters-injective wrapped-path)
(canonicalScalarParameters (scalarExplicit bit))
normaliseFDSEParameters-sound
subject (parameter ∷ᴸ parameters) nothing value result =
Empty.rec (rejected≢accepted result)
normaliseFDSEParameters-sound
subject (parameter ∷ᴸ parameters) (just bit) value result =
Empty.rec (rejected≢accepted result)
normaliseFDSEParameters-complete :
∀ subject {parameters initial-bit value}
→ CanonicalFDSEParameters parameters initial-bit value
→ Parameter.normaliseCoreParameters
Architecture.FDSE subject parameters initial-bit
≡ Diagnostic.accepted (Parameter.fdseParameters value)
normaliseFDSEParameters-complete
subject (canonicalScalarParameters scalarDefault) = refl
normaliseFDSEParameters-complete
subject (canonicalScalarParameters (scalarExplicit bit)) = refl
explicit-FDRE-high-is-canonical :
CanonicalFDREParameters []ᴸ (just high) high
explicit-FDRE-high-is-canonical =
canonicalScalarParameters (scalarExplicit high)
default-FDSE-high-is-canonical :
CanonicalFDSEParameters []ᴸ nothing high
default-FDSE-high-is-canonical =
canonicalScalarParameters scalarDefault
literal-zero-LUT6-is-canonical :
CanonicalLUT6
(Raw.rawParameter "INIT" "0000000000000000" ∷ᴸ []ᴸ)
nothing
Parameter.defaultLUT6INIT
literal-zero-LUT6-is-canonical =
canonicalLUT6Explicit
{name = "INIT"}
{text = "0000000000000000"}
{table = Parameter.defaultLUT6INIT}
refl refl