{-# OPTIONS --safe --cubical #-}
module Spartan6.Netlist.NormalizeMixed where
open import Spartan6.Prelude
import Spartan6.Architecture.Primitive as Architecture
import Spartan6.Netlist.Checked as Checked
import Spartan6.Netlist.GenericBuilder as Generic
import Spartan6.Netlist.NormalizeRegisters as Registers
import Spartan6.Netlist.Raw as Raw
import Spartan6.Netlist.RegisterMode as Single
import Spartan6.Netlist.Schedule as Schedule
import Spartan6.Netlist.TopInterface as TopInterface
import Spartan6.Validation.Diagnostic as Diagnostic
import Spartan6.Validation.Raw as Validation
singleton : Diagnostic.Diagnostic → Diagnostic.Diagnostics
singleton item = item ∷ᴸ []ᴸ
issue : Diagnostic.DiagnosticCode → String → String → String → String
→ Diagnostic.Diagnostic
issue code subject expected observed detail =
Diagnostic.diagnostic code Diagnostic.reject subject expected observed detail
record InstancePartition : Type₀ where
constructor instancePartition
field
partitionRegisters : List Registers.RegisterDescriptor
partitionCombinational : List Raw.RawInstance
open InstancePartition public
prependRegister : Registers.RegisterDescriptor
→ Diagnostic.CheckResult InstancePartition
→ Diagnostic.CheckResult InstancePartition
prependRegister descriptor (Diagnostic.rejected diagnostics) =
Diagnostic.rejected diagnostics
prependRegister descriptor
(Diagnostic.accepted (instancePartition registers combinational)) =
Diagnostic.accepted
(instancePartition (descriptor ∷ᴸ registers) combinational)
prependCombinational : Raw.RawInstance
→ Diagnostic.CheckResult InstancePartition
→ Diagnostic.CheckResult InstancePartition
prependCombinational item (Diagnostic.rejected diagnostics) =
Diagnostic.rejected diagnostics
prependCombinational item
(Diagnostic.accepted (instancePartition registers combinational)) =
Diagnostic.accepted
(instancePartition registers (item ∷ᴸ combinational))
mutual
partitionRegisterItem : Raw.RawInstance → List Raw.RawInstance
→ Diagnostic.CheckResult InstancePartition
partitionRegisterItem item items with Registers.normaliseDescriptor item
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted descriptor =
prependRegister descriptor (partitionInstances items)
partitionInstances : List Raw.RawInstance
→ Diagnostic.CheckResult InstancePartition
partitionInstances []ᴸ =
Diagnostic.accepted (instancePartition []ᴸ []ᴸ)
partitionInstances (item ∷ᴸ items) with Raw.rawInstanceKind item
... | Raw.knownPrimitive Architecture.FDRE =
partitionRegisterItem item items
... | Raw.knownPrimitive Architecture.FDSE =
partitionRegisterItem item items
... | kind = prependCombinational item (partitionInstances items)
registerQNets : List Registers.RegisterDescriptor → List Raw.NetId
registerQNets []ᴸ = []ᴸ
registerQNets (descriptor ∷ᴸ descriptors) =
Registers.descriptorQNet descriptor ∷ᴸ registerQNets descriptors
descriptorBindings : ∀ {inputCount}
→ (descriptors : List Registers.RegisterDescriptor)
→ Generic.Bindings inputCount (lengthList descriptors) 0
descriptorBindings []ᴸ = []ᴸ
descriptorBindings (descriptor ∷ᴸ descriptors) =
Generic.bindNet
(Registers.descriptorQNet descriptor)
(Checked.storedWire fzero)
∷ᴸ Generic.liftRegisterBindings (descriptorBindings descriptors)
mixedInitialBuilder :
(input-nets : List Raw.NetId)
→ (registers : List Registers.RegisterDescriptor)
→ Generic.Builder (lengthList input-nets) (lengthList registers)
mixedInitialBuilder input-nets registers =
Generic.builder 0 Checked.noNodes
(descriptorBindings registers
++ᴸ Generic.inputBindings input-nets)
appendAnonymous : ∀ {inputCount registerCount}
→ (current : Generic.Builder inputCount registerCount)
→ Checked.Node inputCount registerCount
(Generic.builderLocalCount current)
→ Generic.Builder inputCount registerCount
appendAnonymous (Generic.builder local-count nodes bindings) node =
Generic.builder
(suc local-count)
(nodes Checked.▻ node)
(Generic.liftLocalBindings bindings)
liftTwice : ∀ {inputCount registerCount localCount}
→ Checked.Wire inputCount registerCount localCount
→ Checked.Wire inputCount registerCount (suc (suc localCount))
liftTwice (Checked.externalWire index) = Checked.externalWire index
liftTwice (Checked.storedWire index) = Checked.storedWire index
liftTwice (Checked.localWire index) =
Checked.localWire (fsuc (fsuc index))
liftTwice (Checked.literalWire bit) = Checked.literalWire bit
liftNextTwice : ∀ {inputCount registerCount localCount count}
→ Vec (Checked.Wire inputCount registerCount localCount) count
→ Vec
(Checked.Wire inputCount registerCount (suc (suc localCount)))
count
liftNextTwice [] = []
liftNextTwice (wire ∷ wires) = liftTwice wire ∷ liftNextTwice wires
record BuiltRegisters
(inputCount registerCount nextCount : ℕ) : Type₀ where
constructor builtRegisters
field
builtBuilder : Generic.Builder inputCount registerCount
builtNext :
Vec
(Checked.Wire inputCount registerCount
(Generic.builderLocalCount builtBuilder))
nextCount
open BuiltRegisters public
finishRegisterNodes : ∀ {inputCount registerCount nextCount}
→ Registers.RegisterDescriptor
→ BuiltRegisters inputCount registerCount nextCount
→ Diagnostic.CheckResult
(BuiltRegisters inputCount registerCount (suc nextCount))
finishRegisterNodes {inputCount = inputCount} {registerCount = registerCount}
descriptor (builtRegisters current next-wires)
with Generic.resolveOneConnection
"register.Q" (Generic.builderBindings current)
(Raw.net (Registers.descriptorQNet descriptor))
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted current-wire
with Generic.resolveScalarPort
"register.D" (Generic.builderBindings current)
(Single.registerD (Registers.descriptorPorts descriptor))
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted data-wire
with Generic.resolveScalarPort
"register.CE" (Generic.builderBindings current)
(Single.registerCE (Registers.descriptorPorts descriptor))
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted enable-wire
with Generic.resolveScalarPort
"register.control" (Generic.builderBindings current)
(Single.registerControl (Registers.descriptorPorts descriptor))
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted control-wire =
Diagnostic.accepted
(builtRegisters after-control
(Checked.localWire fzero ∷ liftNextTwice next-wires))
where
after-enable : Generic.Builder inputCount registerCount
after-enable =
appendAnonymous current
(Checked.muxNode enable-wire current-wire data-wire)
after-control : Generic.Builder inputCount registerCount
after-control =
appendAnonymous after-enable
(Checked.muxNode
(Generic.liftLocalWire control-wire)
(Checked.localWire fzero)
(Checked.literalWire
(Single.modeForcedValue (Registers.descriptorMode descriptor))))
buildRegisterNodes : ∀ {inputCount registerCount}
→ (descriptors : List Registers.RegisterDescriptor)
→ Generic.Builder inputCount registerCount
→ Diagnostic.CheckResult
(BuiltRegisters inputCount registerCount
(lengthList descriptors))
buildRegisterNodes []ᴸ current =
Diagnostic.accepted (builtRegisters current [])
buildRegisterNodes (descriptor ∷ᴸ descriptors) current with
buildRegisterNodes descriptors current
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted built = finishRegisterNodes descriptor built
initialValues : (descriptors : List Registers.RegisterDescriptor)
→ Vec Bit (lengthList descriptors)
initialValues []ᴸ = []
initialValues (descriptor ∷ᴸ descriptors) =
Single.modeInitial (Registers.descriptorMode descriptor)
∷ initialValues descriptors
resolveOutputConnections : ∀ {inputCount registerCount localCount}
→ String
→ Generic.Bindings inputCount registerCount localCount
→ List Raw.Connection
→ Diagnostic.CheckResult
(List (Checked.Wire inputCount registerCount localCount))
resolveOutputConnections = TopInterface.resolveOutputConnections
collectOutputWires : ∀ {inputCount registerCount}
→ List Raw.RawTopPort
→ (current : Generic.Builder inputCount registerCount)
→ Diagnostic.CheckResult
(List
(Checked.Wire inputCount registerCount
(Generic.builderLocalCount current)))
collectOutputWires = TopInterface.collectBuilderOutputWires
record CheckedMixedCandidate : Type₀ where
constructor checkedMixedCandidate
field
candidateSource : Raw.RawDesign
candidateStructuralProof : Validation.StructurallyValid candidateSource
candidateInputCount : ℕ
candidateOutputCount : ℕ
candidateRegisterCount : ℕ
candidateLocalCount : ℕ
candidateClockInput : Fin candidateInputCount
candidateNetlist :
Checked.CheckedNetlist
candidateInputCount candidateOutputCount
candidateRegisterCount candidateLocalCount
open CheckedMixedCandidate public
finishCandidate :
(design : Raw.RawDesign)
→ Validation.StructurallyValid design
→ (input-nets : List Raw.NetId)
→ (registers : List Registers.RegisterDescriptor)
→ Fin (lengthList input-nets)
→ (built :
BuiltRegisters
(lengthList input-nets) (lengthList registers)
(lengthList registers))
→ (outputs :
List
(Checked.Wire
(lengthList input-nets) (lengthList registers)
(Generic.builderLocalCount (builtBuilder built))))
→ CheckedMixedCandidate
finishCandidate design structural-proof input-nets registers clock-index
built outputs =
checkedMixedCandidate
design structural-proof
(lengthList input-nets)
(lengthList outputs)
(lengthList registers)
(Generic.builderLocalCount (builtBuilder built))
clock-index
(Checked.checkedNetlist
(initialValues registers)
(Generic.builderNodes (builtBuilder built))
(TopInterface.listToVec outputs)
(builtNext built))
normaliseBuiltCombinational :
(design : Raw.RawDesign)
→ Validation.StructurallyValid design
→ (input-nets : List Raw.NetId)
→ (registers : List Registers.RegisterDescriptor)
→ Fin (lengthList input-nets)
→ Generic.Builder (lengthList input-nets) (lengthList registers)
→ Diagnostic.CheckResult CheckedMixedCandidate
normaliseBuiltCombinational design structural-proof input-nets registers
clock-index combinational-builder with
buildRegisterNodes registers combinational-builder
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted built with
collectOutputWires (Raw.rawTopPorts design) (builtBuilder built)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted outputs =
Diagnostic.accepted
(finishCandidate
design structural-proof input-nets registers clock-index built outputs)
normalisePartition :
(design : Raw.RawDesign)
→ Validation.StructurallyValid design
→ List Raw.NetId
→ InstancePartition
→ Diagnostic.CheckResult CheckedMixedCandidate
normalisePartition design structural-proof input-nets partition with
Registers.commonClock input-nets (partitionRegisters partition)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted clock-index with
Schedule.scheduleInstances
(mixedInitialBuilder input-nets (partitionRegisters partition))
(partitionCombinational partition)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted scheduled =
normaliseBuiltCombinational
design structural-proof input-nets (partitionRegisters partition)
clock-index (Schedule.finalBuilder scheduled)
normaliseMixed : Validation.StructurallyChecked
→ Diagnostic.CheckResult CheckedMixedCandidate
normaliseMixed (design , structural-proof) with
TopInterface.checkDevelopmentTarget design
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted tt with
TopInterface.collectInputNets (Raw.rawTopPorts design)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted input-nets with
partitionInstances (Raw.rawInstances design)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted partition =
normalisePartition design structural-proof input-nets partition