@@ -4,6 +4,7 @@ Copyright : (C) 2013-2016, University of Twente,
44 2017 , Google Inc.,
55 2021-2023, QBayLogic B.V.,
66 2022 , Google Inc.,
7+ 2024 , Alex Mason,
78License : BSD2 (see the file LICENSE)
89Maintainer : QBayLogic B.V. <devops@qbaylogic.com>
910
@@ -445,13 +446,16 @@ import Unsafe.Coerce (unsafeCoerce)
445446
446447import Clash.Annotations.Primitive
447448 (Primitive (InlineYamlPrimitive ), HDL (.. ), hasBlackBox )
449+ import Clash.Class.AutoReg (AutoReg (autoReg ))
450+ import Clash.Class.BitPack (bitToBool , msb )
448451import Clash.Class.Num (SaturationMode (SatBound ), satSucc )
449452import Clash.Explicit.BlockRam.Model (TdpbramModelConfig (.. ), tdpbramModel )
450- import Clash.Explicit.Signal (KnownDomain , Enable , register , fromEnable )
453+ import Clash.Explicit.Signal (KnownDomain , Enable , register , fromEnable , andEnable )
451454import Clash.Promoted.Nat (SNat (.. ))
452455import Clash.Signal.Bundle (unbundle )
453456import Clash.Signal.Internal
454457 (Clock (.. ), Reset , Signal (.. ), invertReset , (.&&.) , mux )
458+ import Clash.Sized.BitVector (BitVector )
455459import Clash.Sized.Index (Index )
456460import Clash.Sized.Unsigned (Unsigned )
457461import Clash.Sized.Vector (Vec , replicate , iterateI )
@@ -1168,6 +1172,47 @@ data RamOp n a
11681172 -- ^ No operation
11691173 deriving (Generic , NFDataX , Show )
11701174
1175+ instance (AutoReg a , KnownNat n ) => AutoReg (RamOp n a ) where
1176+ autoReg clk rst en initVal input =
1177+ createRamOp <$> tagR <*> valAddr <*> valValue
1178+ where
1179+ tag = toTag <$> input
1180+
1181+ toTag op = case op of
1182+ RamNoOp -> 0b00 :: BitVector 2
1183+ RamRead {} -> 0b01
1184+ RamWrite {} -> 0b10
1185+
1186+ tagInit = toTag initVal
1187+ tagR = register clk rst en tagInit tag
1188+
1189+ toAddr op = case op of
1190+ RamNoOp -> deepErrorX " autoReg'.ramOpAddr"
1191+ RamRead addr -> addr
1192+ RamWrite addr _ -> addr
1193+
1194+ toValue op = case op of
1195+ RamWrite _ a -> a
1196+ _ -> deepErrorX " autoReg'.ramOpValue"
1197+
1198+
1199+ opAddr = toAddr <$> input
1200+ opValue = toValue <$> input
1201+
1202+ addrInit = toAddr initVal
1203+ valInit = toValue initVal
1204+
1205+ valAddr = autoReg clk rst (andEnable en ((/= 0 ) <$> tag)) addrInit opAddr
1206+ valValue = autoReg clk rst (andEnable en (bitToBool . msb <$> tag)) valInit opValue
1207+
1208+ createRamOp t addr val = case t of
1209+ 0b00 -> RamNoOp
1210+ 0b01 -> RamRead addr
1211+ 0b10 -> RamWrite addr val
1212+ _ -> deepErrorX " autoReg'.createRamOp: impossible"
1213+
1214+ {-# INLINE autoReg #-}
1215+
11711216ramOpAddr :: RamOp n a -> Index n
11721217ramOpAddr (RamRead addr) = addr
11731218ramOpAddr (RamWrite addr _) = addr
0 commit comments