{-# OPTIONS --safe --cubical #-}
module Spartan6.Primitive.RAM128X1D where
open import Spartan6.Prelude
open import Spartan6.Evidence
open import Spartan6.Semantics.Design using (Event; idle; risingEdge)
import Spartan6.Foundation.Memory as Memory
ram128x1dPinnedSource : PinnedSource
ram128x1dPinnedSource =
pinSource UG615 (revision "v14.7" (just "2013-10-02"))
ram128x1dLocator : SourceLocator
ram128x1dLocator =
locate ram128x1dPinnedSource "RAM128X1D"
"printed page 245: introduction, port descriptions, positive-edge write, asynchronous SPO/DPO reads, and default INIT; printed page 246: INIT attribute and HDL templates"
ram128x1dTrace : RuleTraceability
ram128x1dTrace =
traceRule "primitive.RAM128X1D.stable-two-valued"
officialDocumentation
(just ram128x1dLocator)
partiallySupported
guaranteed
"Executable stable-state dual asynchronous read, hold, enabled rising-edge single write, post-write outputs, and all-zero default INIT; physical write/read collision transients, raw address/INIT decoding, and timing are not modelled."
RAM128X1DState : Type₀
RAM128X1DState = Memory.Memory 128 1
RAM128X1DAddress : Type₀
RAM128X1DAddress = Fin 128
RAM128X1DAAddress : Type₀
RAM128X1DAAddress = RAM128X1DAddress
RAM128X1DDPRAAddress : Type₀
RAM128X1DDPRAAddress = RAM128X1DAddress
wordBit : Word 1 → Bit
wordBit (bit ∷ []) = bit
readSPO : RAM128X1DState → RAM128X1DAAddress → Bit
readSPO state address = wordBit (Memory.read address state)
readDPO : RAM128X1DState → RAM128X1DDPRAAddress → Bit
readDPO state dual-port-read-address =
wordBit (Memory.read dual-port-read-address state)
updateRAM128X1D :
Event → Bit → RAM128X1DAAddress → Bit → RAM128X1DState
→ RAM128X1DState
updateRAM128X1D idle write-enable address data-in state = state
updateRAM128X1D risingEdge write-enable address data-in state =
Memory.writeIf write-enable address (data-in ∷ []) state
defaultInitialState : RAM128X1DState
defaultInitialState = replicate (low ∷ [])
data RAM128X1DBoundary : Type₀ where
stableSPOAfterWrite : RAM128X1DBoundary
stableDPOAfterWrite : RAM128X1DBoundary
defaultINIT : RAM128X1DBoundary
writeReadCollisionInstant : RAM128X1DBoundary
rawAddressBusDecoding : RAM128X1DBoundary
rawHexINITDecoding : RAM128X1DBoundary
physicalWriteTiming : RAM128X1DBoundary
boundarySupport : RAM128X1DBoundary → SupportStatus
boundarySupport stableSPOAfterWrite = fullySupported
boundarySupport stableDPOAfterWrite = fullySupported
boundarySupport defaultINIT = fullySupported
boundarySupport writeReadCollisionInstant = unsupportedFeature
boundarySupport rawAddressBusDecoding = unsupportedFeature
boundarySupport rawHexINITDecoding = unsupportedFeature
boundarySupport physicalWriteTiming = unsupportedFeature
boundarySemantics : RAM128X1DBoundary → SemanticStatus
boundarySemantics stableSPOAfterWrite = guaranteed
boundarySemantics stableDPOAfterWrite = guaranteed
boundarySemantics defaultINIT = guaranteed
boundarySemantics writeReadCollisionInstant = insufficientEvidence
boundarySemantics rawAddressBusDecoding = unsupportedSemantics
boundarySemantics rawHexINITDecoding = unsupportedSemantics
boundarySemantics physicalWriteTiming = insufficientEvidence
boundaryNote : RAM128X1DBoundary → String
boundaryNote stableSPOAfterWrite =
"UG615 printed page 245 explicitly says the written D value is reflected on SPO after the write."
boundaryNote stableDPOAfterWrite =
"After a completed write, the documented asynchronous DPRA read observes the stable contents at DPRA; this is not a claim about the write instant."
boundaryNote defaultINIT =
"UG615 printed pages 245-246 give all zeros as the default 128-bit INIT value."
boundaryNote writeReadCollisionInstant =
"UG615 gives no two-valued DPO result during a physical write with A equal to DPRA; only stable pre/post states are executable."
boundaryNote rawAddressBusDecoding =
"The entry gives two seven-bit buses but no individual bit weights; callers supply decoded Fin 128 addresses."
boundaryNote rawHexINITDecoding =
"The entry gives no raw hexadecimal bit-to-address table; callers supply already address-indexed contents."
boundaryNote physicalWriteTiming =
"The physical 'shortly after' delay and setup/hold behavior are outside this untimed event model."
addressZero : RAM128X1DAddress
addressZero = fzero
addressOne : RAM128X1DAddress
addressOne = fsuc fzero
addressTwo : RAM128X1DAddress
addressTwo = fsuc (fsuc fzero)
address-one-is-successor-zero : addressOne ≡ fsuc fzero
address-one-is-successor-zero = refl
address-two-is-double-successor-zero : addressTwo ≡ fsuc (fsuc fzero)
address-two-is-double-successor-zero = refl
no-rising-edge-holds : ∀ write-enable address data-in state
→ updateRAM128X1D 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
→ updateRAM128X1D risingEdge low address data-in state ≡ state
disabled-rising-edge-holds address data-in state = refl
disabled-rising-edge-preserves-SPO : ∀ read-address write-address data-in state
→ readSPO
(updateRAM128X1D risingEdge low write-address data-in state)
read-address
≡ readSPO state read-address
disabled-rising-edge-preserves-SPO read-address write-address data-in state =
refl
disabled-rising-edge-preserves-DPO : ∀ read-address write-address data-in state
→ readDPO
(updateRAM128X1D risingEdge low write-address data-in state)
read-address
≡ readDPO state read-address
disabled-rising-edge-preserves-DPO read-address write-address data-in state =
refl
enabled-rising-edge-writes-at-A : ∀ address data-in state
→ updateRAM128X1D risingEdge high address data-in state
≡ Memory.write address (data-in ∷ []) state
enabled-rising-edge-writes-at-A address data-in state = refl
same-A-SPO-after-write-is-D : ∀ address data-in state
→ readSPO
(updateRAM128X1D risingEdge high address data-in state)
address
≡ data-in
same-A-SPO-after-write-is-D address data-in state =
cong wordBit
(Memory.read-after-write-same address (data-in ∷ []) state)
same-DPRA-after-completed-write-is-D : ∀ address data-in state
→ readDPO
(updateRAM128X1D risingEdge high address data-in state)
address
≡ data-in
same-DPRA-after-completed-write-is-D address data-in state =
cong wordBit
(Memory.read-after-write-same 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-SPO-is-low : ∀ address
→ readSPO defaultInitialState address ≡ low
default-SPO-is-low address =
cong wordBit (lookup-replicate address (low ∷ []))
default-DPO-is-low : ∀ address
→ readDPO defaultInitialState address ≡ low
default-DPO-is-low address =
cong wordBit (lookup-replicate address (low ∷ []))
exampleState : RAM128X1DState
exampleState = Memory.write addressOne (high ∷ []) defaultInitialState
asynchronous-SPO-at-address-zero :
readSPO exampleState addressZero ≡ low
asynchronous-SPO-at-address-zero = refl
asynchronous-SPO-at-address-one :
readSPO exampleState addressOne ≡ high
asynchronous-SPO-at-address-one = refl
independent-asynchronous-DPO-at-address-one :
readDPO exampleState addressOne ≡ high
independent-asynchronous-DPO-at-address-one = refl
independent-asynchronous-DPO-at-address-two :
readDPO exampleState addressTwo ≡ low
independent-asynchronous-DPO-at-address-two = refl
stable-SPO-sees-completed-write :
readSPO
(updateRAM128X1D risingEdge high addressOne high defaultInitialState)
addressOne
≡ high
stable-SPO-sees-completed-write = refl
stable-DPO-sees-completed-write :
readDPO
(updateRAM128X1D risingEdge high addressOne high defaultInitialState)
addressOne
≡ high
stable-DPO-sees-completed-write = refl
stable-SPO-post-write-is-supported :
fullySupported? (boundarySupport stableSPOAfterWrite) ≡ true
stable-SPO-post-write-is-supported = refl
write-read-collision-instant-is-not-executable :
executable? (boundarySemantics writeReadCollisionInstant) ≡ false
write-read-collision-instant-is-not-executable = refl
raw-INIT-decoding-is-not-executable :
executable? (boundarySemantics rawHexINITDecoding) ≡ false
raw-INIT-decoding-is-not-executable = refl