Skip to content

Commit

Permalink
Merge pull request #2869 from clash-lang/mergify/copy/1.8/pr-2792
Browse files Browse the repository at this point in the history
Add AutoReg instance for RamOp (copy #2792)
  • Loading branch information
christiaanb authored Jan 5, 2025
2 parents 6f2b6ef + fd7f211 commit 6d78ae1
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ADDED: RamOp now has an AutoReg instance.
47 changes: 46 additions & 1 deletion clash-prelude/src/Clash/Explicit/BlockRam.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Copyright : (C) 2013-2016, University of Twente,
2017 , Google Inc.,
2021-2023, QBayLogic B.V.,
2022 , Google Inc.,
2024 , Alex Mason,
License : BSD2 (see the file LICENSE)
Maintainer : QBayLogic B.V. <[email protected]>
Expand Down Expand Up @@ -445,13 +446,16 @@ import Unsafe.Coerce (unsafeCoerce)

import Clash.Annotations.Primitive
(Primitive(InlineYamlPrimitive), HDL(..), hasBlackBox)
import Clash.Class.AutoReg (AutoReg(autoReg))
import Clash.Class.BitPack (bitToBool, msb)
import Clash.Class.Num (SaturationMode(SatBound), satSucc)
import Clash.Explicit.BlockRam.Model (TdpbramModelConfig(..), tdpbramModel)
import Clash.Explicit.Signal (KnownDomain, Enable, register, fromEnable)
import Clash.Explicit.Signal (KnownDomain, Enable, register, fromEnable, andEnable)
import Clash.Promoted.Nat (SNat(..))
import Clash.Signal.Bundle (unbundle)
import Clash.Signal.Internal
(Clock(..), Reset, Signal (..), invertReset, (.&&.), mux)
import Clash.Sized.BitVector (BitVector)
import Clash.Sized.Index (Index)
import Clash.Sized.Unsigned (Unsigned)
import Clash.Sized.Vector (Vec, replicate, iterateI)
Expand Down Expand Up @@ -1168,6 +1172,47 @@ data RamOp n a
-- ^ No operation
deriving (Generic, NFDataX, Show)

instance (AutoReg a, KnownNat n) => AutoReg (RamOp n a) where
autoReg clk rst en initVal input =
createRamOp <$> tagR <*> valAddr <*> valValue
where
tag = toTag <$> input

toTag op = case op of
RamNoOp -> 0b00 :: BitVector 2
RamRead{} -> 0b01
RamWrite{} -> 0b10

tagInit = toTag initVal
tagR = register clk rst en tagInit tag

toAddr op = case op of
RamNoOp -> deepErrorX "autoReg'.ramOpAddr"
RamRead addr -> addr
RamWrite addr _ -> addr

toValue op = case op of
RamWrite _ a -> a
_ -> deepErrorX "autoReg'.ramOpValue"


opAddr = toAddr <$> input
opValue = toValue <$> input

addrInit = toAddr initVal
valInit = toValue initVal

valAddr = autoReg clk rst (andEnable en ((/=0) <$> tag)) addrInit opAddr
valValue = autoReg clk rst (andEnable en (bitToBool . msb <$> tag)) valInit opValue

createRamOp t addr val = case t of
0b00 -> RamNoOp
0b01 -> RamRead addr
0b10 -> RamWrite addr val
_ -> deepErrorX "autoReg'.createRamOp: impossible"

{-# INLINE autoReg #-}

ramOpAddr :: RamOp n a -> Index n
ramOpAddr (RamRead addr) = addr
ramOpAddr (RamWrite addr _) = addr
Expand Down

0 comments on commit 6d78ae1

Please sign in to comment.