{-# OPTIONS --safe --cubical #-}
module Spartan6.Netlist.GenericBuilder where
open import Spartan6.Prelude
import Spartan6.Architecture.Primitive as Architecture
import Spartan6.Netlist.BuildOBUFDS as OBUFDS
open import Spartan6.Netlist.BuilderCore public
import Spartan6.Netlist.Carry4Builder as Carry4
import Spartan6.Netlist.Checked as Checked
import Spartan6.Netlist.PortDecode as PortDecode
import Spartan6.Netlist.Raw as Raw
import Spartan6.Primitive.LUT as LUT
import Spartan6.Validation.Diagnostic as Diagnostic
import Spartan6.Validation.Parameter as Parameter
resolveLUTInputPorts :
∀ {inputCount registerCount localCount arity}
→ String
→ Bindings inputCount registerCount localCount
→ Vec Raw.RawPort arity
→ Diagnostic.CheckResult
(Vec
(Checked.Wire inputCount registerCount localCount)
arity)
resolveLUTInputPorts subject bindings [] = Diagnostic.accepted []
resolveLUTInputPorts subject bindings (port ∷ ports)
with resolveScalarPort subject bindings port
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted wire
with resolveLUTInputPorts subject bindings ports
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted wires = Diagnostic.accepted (wire ∷ wires)
processLUTBundle : ∀ {inputCount registerCount arity}
→ Raw.RawInstance
→ LUT.TruthTable arity
→ PortDecode.LUTPortBundle arity
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processLUTBundle item table bundle current
with resolveLUTInputPorts
"LUT input"
(builderBindings current)
(PortDecode.lutInputPorts bundle)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted wires
with PortDecode.outputNet
(Raw.rawInstanceName item)
(PortDecode.lutOutputPort bundle)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted net-id =
Diagnostic.accepted
(extendBuilder current net-id (Checked.lutNode table wires))
processFixedLUT : ∀ {inputCount registerCount}
→ (arity : ℕ)
→ Raw.RawInstance
→ LUT.TruthTable arity
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processFixedLUT arity item table current
with PortDecode.parseLUTPortBundle
arity (Raw.rawInstancePorts item)
... | just bundle = processLUTBundle item table bundle current
... | nothing =
Diagnostic.rejected
(singleton
(issue Diagnostic.widthMismatch
(Raw.rawInstanceName item)
"the canonical ordered LUT input ports followed by O"
"a different raw LUT port list"
"StructurallyValid should make this branch unreachable for the selected LUT arity."))
processLUT1 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processLUT1 item current
with Parameter.normaliseCoreParameters Architecture.LUT1
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted (Parameter.lut1Parameters table) =
processFixedLUT 1 item table current
processLUT2 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processLUT2 item current
with Parameter.normaliseCoreParameters Architecture.LUT2
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted (Parameter.lut2Parameters table) =
processFixedLUT 2 item table current
processLUT3 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processLUT3 item current
with Parameter.normaliseCoreParameters Architecture.LUT3
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted (Parameter.lut3Parameters table) =
processFixedLUT 3 item table current
processLUT4 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processLUT4 item current
with Parameter.normaliseCoreParameters Architecture.LUT4
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted (Parameter.lut4Parameters table) =
processFixedLUT 4 item table current
processLUT5 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processLUT5 item current
with Parameter.normaliseCoreParameters Architecture.LUT5
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted (Parameter.lut5Parameters table) =
processFixedLUT 5 item table current
processLUT6 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processLUT6 item current
with Parameter.normaliseCoreParameters Architecture.LUT6
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted (Parameter.lut6Parameters table) =
processFixedLUT 6 item table current
processParsedMux : ∀ {inputCount registerCount}
→ String
→ PortDecode.MuxPorts
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processParsedMux subject ports current
with resolveScalarPort
"mux.I0" (builderBindings current)
(PortDecode.muxI0 ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted input0
with resolveScalarPort
"mux.I1" (builderBindings current)
(PortDecode.muxI1 ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted input1
with resolveScalarPort
"mux.S" (builderBindings current)
(PortDecode.muxS ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted select
with PortDecode.outputNet subject (PortDecode.muxO ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted net-id =
Diagnostic.accepted
(extendBuilder current net-id
(Checked.muxNode select input0 input1))
processMuxPorts : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processMuxPorts item current
with PortDecode.parseMuxPorts (Raw.rawInstancePorts item)
... | just ports =
processParsedMux (Raw.rawInstanceName item) ports current
... | nothing =
Diagnostic.rejected
(singleton
(issue Diagnostic.widthMismatch
(Raw.rawInstanceName item)
"canonical scalar I0, I1, S, and O ports"
"a different raw mux port list"
"StructurallyValid should make this branch unreachable for MUXF7/MUXF8."))
processMUXF7 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processMUXF7 item current
with Parameter.normaliseCoreParameters Architecture.MUXF7
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted Parameter.muxf7Parameters =
processMuxPorts item current
processMUXF8 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processMUXF8 item current
with Parameter.normaliseCoreParameters Architecture.MUXF8
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted Parameter.muxf8Parameters =
processMuxPorts item current
processBufferPorts : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ PortDecode.BufferPorts
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processBufferPorts item ports current
with resolveScalarPort
"buffer.I" (builderBindings current)
(PortDecode.bufferI ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted input-wire
with PortDecode.outputNet
(Raw.rawInstanceName item) (PortDecode.bufferO ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted net-id =
Diagnostic.accepted (aliasBuilder current net-id input-wire)
processAliasBuffer : ∀ {inputCount registerCount}
→ Architecture.PrimitiveKind
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processAliasBuffer kind item current
with Parameter.normaliseCoreParameters kind
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted parameters
with PortDecode.parseBufferPorts (Raw.rawInstancePorts item)
... | nothing =
Diagnostic.rejected
(singleton
(issue Diagnostic.widthMismatch
(Raw.rawInstanceName item)
"canonical scalar I and O ports"
"a different raw buffer port list"
"StructurallyValid should make this branch unreachable for alias buffers."))
... | just ports = processBufferPorts item ports current
processEnabledBufferPorts : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ PortDecode.EnabledBufferPorts
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processEnabledBufferPorts item ports current
with resolveScalarPort
"BUFGCE.I" (builderBindings current)
(PortDecode.enabledBufferI ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted input-wire
with resolveScalarPort
"BUFGCE.CE" (builderBindings current)
(PortDecode.enabledBufferCE ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted enable-wire
with PortDecode.outputNet
(Raw.rawInstanceName item)
(PortDecode.enabledBufferO ports)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted net-id =
Diagnostic.accepted
(extendBuilder current net-id
(Checked.muxNode
enable-wire (Checked.literalWire low) input-wire))
processBUFGCE : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processBUFGCE item current
with Parameter.normaliseCoreParameters Architecture.BUFGCE
(Raw.rawInstanceName item)
(Raw.rawInstanceParameters item)
(Raw.rawInstanceInitialBit item)
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted Parameter.bufgceParameters
with PortDecode.parseEnabledBufferPorts
(Raw.rawInstancePorts item)
... | nothing =
Diagnostic.rejected
(singleton
(issue Diagnostic.widthMismatch
(Raw.rawInstanceName item)
"canonical scalar I, CE, and O ports"
"a different raw BUFGCE port list"
"StructurallyValid should make this branch unreachable for BUFGCE."))
... | just ports = processEnabledBufferPorts item ports current
processCARRY4 : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processCARRY4 item current =
Diagnostic.mapResult Carry4.carryBuilder
(Carry4.processCARRY4 item current)
processOBUFDS : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processOBUFDS = OBUFDS.processOBUFDS
processKnownInstance : ∀ {inputCount registerCount}
→ Architecture.PrimitiveKind
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processKnownInstance Architecture.LUT1 item current =
processLUT1 item current
processKnownInstance Architecture.LUT2 item current =
processLUT2 item current
processKnownInstance Architecture.LUT3 item current =
processLUT3 item current
processKnownInstance Architecture.LUT4 item current =
processLUT4 item current
processKnownInstance Architecture.LUT5 item current =
processLUT5 item current
processKnownInstance Architecture.LUT6 item current =
processLUT6 item current
processKnownInstance Architecture.MUXF7 item current =
processMUXF7 item current
processKnownInstance Architecture.MUXF8 item current =
processMUXF8 item current
processKnownInstance Architecture.CARRY4 item current =
processCARRY4 item current
processKnownInstance Architecture.IBUF item current =
processAliasBuffer Architecture.IBUF item current
processKnownInstance Architecture.OBUF item current =
processAliasBuffer Architecture.OBUF item current
processKnownInstance Architecture.OBUFDS item current =
processOBUFDS item current
processKnownInstance Architecture.BUFG item current =
processAliasBuffer Architecture.BUFG item current
processKnownInstance Architecture.BUFGCE item current =
processBUFGCE item current
processKnownInstance kind item current =
Diagnostic.rejected
(singleton
(issue Diagnostic.unsupportedMode
(Raw.rawInstanceName item)
"LUT1-LUT6, MUXF7/MUXF8, CARRY4, IBUF/OBUF/OBUFDS/BUFG, or BUFGCE"
"another primitive kind"
"This builder only constructs the established combinational checked-node slice."))
processInstance : ∀ {inputCount registerCount}
→ Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processInstance item current with Raw.rawInstanceKind item
... | Raw.unknownPrimitive name =
Diagnostic.rejected
(singleton
(issue Diagnostic.unknownPrimitive
(Raw.rawInstanceName item)
"a supported known combinational primitive"
name
"Unknown cells never receive checked semantics."))
... | Raw.knownPrimitive kind = processKnownInstance kind item current
processInstances : ∀ {inputCount registerCount}
→ List Raw.RawInstance
→ Builder inputCount registerCount
→ Diagnostic.CheckResult (Builder inputCount registerCount)
processInstances []ᴸ current = Diagnostic.accepted current
processInstances (item ∷ᴸ items) current
with processInstance item current
... | Diagnostic.rejected diagnostics = Diagnostic.rejected diagnostics
... | Diagnostic.accepted next = processInstances items next