{-# OPTIONS --safe --cubical #-}
module Spartan6.Primitive.RAM64X1S where
open import Spartan6.Prelude
open import Spartan6.Evidence
open import Spartan6.Semantics.Design using (Event; idle; risingEdge)
import Spartan6.Foundation.Memory as Memory
import Spartan6.Primitive.LUT as LUT
ug615RAM64X1SSource : PinnedSource
ug615RAM64X1SSource =
pinSource UG615 (revision "v14.7" (just "2013-10-02"))
ug615RAM64X1SLocator : SourceLocator
ug615RAM64X1SLocator =
locate ug615RAM64X1SSource "RAM64X1S"
"printed pages 270-271: introduction, logic table, INIT attribute, and HDL templates"
ug384DistributedRAMSource : PinnedSource
ug384DistributedRAMSource =
pinSource UG384 (revision "v1.1" (just "2010-02-22"))
ug384DistributedRAMLocator : SourceLocator
ug384DistributedRAMLocator =
locate ug384DistributedRAMSource "Distributed RAM"
"Figure 10 on printed page 19; synchronous write and asynchronous read on printed page 25"
ram64x1sTrace : RuleTraceability
ram64x1sTrace =
traceRule "primitive.RAM64X1S.two-valued"
officialDocumentation
(just ug615RAM64X1SLocator)
partiallySupported
guaranteed
"Executable two-valued addressed read, hold, enabled rising-edge write, post-write O=D, and all-zero default INIT; physical timing and raw hexadecimal INIT decoding are outside this module."
ram64x1sDataFlowTrace : RuleTraceability
ram64x1sDataFlowTrace =
traceRule "primitive.RAM64X1S.distributed-data-flow"
officialDocumentation
(just ug384DistributedRAMLocator)
fullySupported
guaranteed
"The admitted subset models a single-edge active-high-WE write and a clock-independent asynchronous addressed read."
RAM64X1SState : Type₀
RAM64X1SState = Memory.Memory 64 1
RAM64X1SAddress : Type₀
RAM64X1SAddress = Vec Bit 6
addressIndex : RAM64X1SAddress → Fin 64
addressIndex = LUT.address
wordBit : Word 1 → Bit
wordBit (bit ∷ []) = bit
readRAM64X1S : RAM64X1SState → RAM64X1SAddress → Bit
readRAM64X1S state address =
wordBit (Memory.read (addressIndex address) state)
updateRAM64X1S :
Event → Bit → RAM64X1SAddress → Bit → RAM64X1SState → RAM64X1SState
updateRAM64X1S idle write-enable address data-in state = state
updateRAM64X1S risingEdge write-enable address data-in state =
Memory.writeIf write-enable (addressIndex address) (data-in ∷ []) state
defaultInitialState : RAM64X1SState
defaultInitialState = replicate (low ∷ [])
data RAM64X1SBoundary : Type₀ where
sameAddressReadDuringWrite : RAM64X1SBoundary
defaultINIT : RAM64X1SBoundary
rawHexINITDecoding : RAM64X1SBoundary
unstableWriteEdgeInputs : RAM64X1SBoundary
boundarySupport : RAM64X1SBoundary → SupportStatus
boundarySupport sameAddressReadDuringWrite = fullySupported
boundarySupport defaultINIT = fullySupported
boundarySupport rawHexINITDecoding = planned
boundarySupport unstableWriteEdgeInputs = unsupportedFeature
boundarySemantics : RAM64X1SBoundary → SemanticStatus
boundarySemantics sameAddressReadDuringWrite = guaranteed
boundarySemantics defaultINIT = guaranteed
boundarySemantics rawHexINITDecoding = unsupportedSemantics
boundarySemantics unstableWriteEdgeInputs = insufficientEvidence
boundaryNote : RAM64X1SBoundary → String
boundaryNote sameAddressReadDuringWrite =
"UG615 page 270 gives O=D on the enabled rising-edge write row; the model exposes that post-edge value."
boundaryNote defaultINIT =
"UG615 page 271 gives all zeros as the default value of the 64-bit INIT attribute."
boundaryNote rawHexINITDecoding =
"The cited sections do not provide a raw hexadecimal bit-to-address decoding table; admission must supply address-indexed contents."
boundaryNote unstableWriteEdgeInputs =
"Setup/hold violations and physical edge collisions are outside the untimed model and have no invented two-valued result."
allLowAddress : RAM64X1SAddress
allLowAddress = low ∷ low ∷ low ∷ low ∷ low ∷ low ∷ []
onlyA0HighAddress : RAM64X1SAddress
onlyA0HighAddress = high ∷ low ∷ low ∷ low ∷ low ∷ low ∷ []
A0-is-least-significant : addressIndex onlyA0HighAddress ≡ fsuc fzero
A0-is-least-significant = refl
all-low-is-address-zero : addressIndex allLowAddress ≡ fzero
all-low-is-address-zero = refl
no-rising-edge-holds : ∀ write-enable address data-in state
→ updateRAM64X1S idle write-enable address data-in state ≡ state
no-rising-edge-holds write-enable address data-in state = refl
disabled-rising-edge-holds : ∀ address data-in state
→ updateRAM64X1S risingEdge low address data-in state ≡ state
disabled-rising-edge-holds address data-in state = refl
disabled-rising-edge-preserves-read : ∀ read-address write-address data-in state
→ readRAM64X1S
(updateRAM64X1S risingEdge low write-address data-in state)
read-address
≡ readRAM64X1S state read-address
disabled-rising-edge-preserves-read read-address write-address data-in state =
refl
enabled-rising-edge-writes : ∀ address data-in state
→ updateRAM64X1S risingEdge high address data-in state
≡ Memory.write (addressIndex address) (data-in ∷ []) state
enabled-rising-edge-writes address data-in state = refl
write-edge-output-is-D : ∀ address data-in state
→ readRAM64X1S
(updateRAM64X1S risingEdge high address data-in state)
address
≡ data-in
write-edge-output-is-D address data-in state =
cong wordBit
(Memory.read-after-write-same
(addressIndex address) (data-in ∷ []) state)
lookup-replicate : ∀ {ℓ n} {A : Type ℓ} (index : Fin n) (value : A)
→ lookup index (replicate value) ≡ value
lookup-replicate fzero value = refl
lookup-replicate (fsuc index) value = lookup-replicate index value
default-output-is-low : ∀ address
→ readRAM64X1S defaultInitialState address ≡ low
default-output-is-low address =
cong wordBit
(lookup-replicate (addressIndex address) (low ∷ []))
exampleState : RAM64X1SState
exampleState =
Memory.write (addressIndex onlyA0HighAddress) (high ∷ [])
defaultInitialState
asynchronous-read-address-zero :
readRAM64X1S exampleState allLowAddress ≡ low
asynchronous-read-address-zero = refl
asynchronous-read-address-one :
readRAM64X1S exampleState onlyA0HighAddress ≡ high
asynchronous-read-address-one = refl
write-address-one-read-after-write :
readRAM64X1S
(updateRAM64X1S risingEdge high onlyA0HighAddress high
defaultInitialState)
onlyA0HighAddress
≡ high
write-address-one-read-after-write = refl
same-address-write-read-is-supported :
fullySupported? (boundarySupport sameAddressReadDuringWrite) ≡ true
same-address-write-read-is-supported = refl
raw-INIT-decoding-is-not-executable :
executable? (boundarySemantics rawHexINITDecoding) ≡ false
raw-INIT-decoding-is-not-executable = refl