Skip to content

Commit c97194e

Browse files
Merge pull request #2792 from axman6/ramop-autoreg
Add AutoReg instance for RamOp
2 parents ba12a37 + def5f54 commit c97194e

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ADDED: RamOp now has an AutoReg instance.

clash-prelude/src/Clash/Explicit/BlockRam.hs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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,
78
License : BSD2 (see the file LICENSE)
89
Maintainer : QBayLogic B.V. <devops@qbaylogic.com>
910
@@ -445,13 +446,16 @@ import Unsafe.Coerce (unsafeCoerce)
445446

446447
import Clash.Annotations.Primitive
447448
(Primitive(InlineYamlPrimitive), HDL(..), hasBlackBox)
449+
import Clash.Class.AutoReg (AutoReg(autoReg))
450+
import Clash.Class.BitPack (bitToBool, msb)
448451
import Clash.Class.Num (SaturationMode(SatBound), satSucc)
449452
import 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)
451454
import Clash.Promoted.Nat (SNat(..))
452455
import Clash.Signal.Bundle (unbundle)
453456
import Clash.Signal.Internal
454457
(Clock(..), Reset, Signal (..), invertReset, (.&&.), mux)
458+
import Clash.Sized.BitVector (BitVector)
455459
import Clash.Sized.Index (Index)
456460
import Clash.Sized.Unsigned (Unsigned)
457461
import 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+
11711216
ramOpAddr :: RamOp n a -> Index n
11721217
ramOpAddr (RamRead addr) = addr
11731218
ramOpAddr (RamWrite addr _) = addr

0 commit comments

Comments
 (0)