diff --git a/bs/TagEngine.bs b/bs/TagEngine.bs index e1ea262..456cf28 100644 --- a/bs/TagEngine.bs +++ b/bs/TagEngine.bs @@ -7,27 +7,55 @@ import Util #define UIntLog2N(n) (UInt (TLog n)) +data Tag numTags + = Next UIntLog2N(numTags) + | Freed + | Tail + deriving (Bits, Eq, FShow) + +data TagPtr numTags + = SomeTagPtr UIntLog2N(numTags) + | None + deriving (Bits, Eq, FShow) + interface (TagEngine :: # -> *) numTags = requestTag :: ActionValue UIntLog2N(numTags) retireTag :: UIntLog2N(numTags) -> Action --- The tag engine returns a tag that is unique for the duration of --- the lifetime of the tag. Useful when you need to tag transactions --- on a bus for example. --- This implementation is stack based. +instance FShow (Reg (Tag numTags)) where + fshow value = fshow (readReg value) + +initTagNext :: Integer -> Module(Reg (Tag numTags)) +initTagNext i = do + t :: Reg (Tag numTags) + t <- mkReg (Next (fromInteger i)) + return t + +initTagTail :: Module(Reg (Tag numTags)) +initTagTail = do + t :: Reg (Tag numTags) + t <- mkReg Tail + return t + +initTagVec :: Module(Vector numTags (Reg (Tag numTags))) +initTagVec = + let + lastIdx :: Integer = (fromInteger |> valueOf numTags) - 1 + initByIdx currIdx = + if (currIdx < lastIdx) + then initTagNext (currIdx + 1) + else initTagTail + in + mapM initByIdx genVector + mkTagEngine :: Module (TagEngine numTags) mkTagEngine = do - let reifiedNumTags = fromInteger |> valueOf numTags + tagVec :: Vector numTags (Reg (Tag numTags)) + tagVec <- initTagVec - freeStackVec :: Vector numTags (Reg UIntLog2N(numTags)) - freeStackVec <- mapM (\i -> mkReg |> fromInteger i) genVector - - inUseVec :: Vector numTags (Reg Bool) - inUseVec <- replicateM |> mkReg False - - stackPtr :: (Reg (Maybe(UIntLog2N(numTags)))) - stackPtr <- mkReg |> Just |> reifiedNumTags - 1 + head :: Reg(TagPtr(numTags)) <- mkReg(SomeTagPtr(0)) + tail :: Reg(TagPtr(numTags)) <- mkReg(SomeTagPtr(lastIdx)) debugOnce <- mkReg True @@ -35,37 +63,35 @@ mkTagEngine = rules "display": when (debugOnce == True) ==> do - $display "freeStackVec : " (fshow |> readVReg freeStackVec) - $display "inUseVec : " (fshow |> readVReg inUseVec) - $display "stackPtr : " (fshow stackPtr) + $display (fshow tagVec) debugOnce := False counter <- mkReg(0 :: UIntLog2N(numTags)) return $ interface TagEngine - requestTag :: ActionValue UIntLog2N(numTags) requestTag = do - stackPtr := - if sampledStackPtr == 0 - then Nothing - else Just |> sampledStackPtr - 1 - (select inUseVec sampledStackPtr) := True - return |> readReg (select freeStackVec sampledStackPtr) + let currHeadPtr :: UIntLog2N(numTags) = + case head of + SomeTagPtr ptr -> ptr + -- we technically will never hit this arm + -- due to when guard `SomeTagPtr ptr <- head` + None -> 0 + let currHead :: (Reg (Tag numTags)) = (select tagVec currHeadPtr) + let nextHeadPtr :: UIntLog2N(numTags) = + case currHead of + Next ptr -> ptr + -- TODO : handle tail correctly + Tail -> 0 + currHead := Freed + head := SomeTagPtr(nextHeadPtr) + return nextHeadPtr when - Just sampledStackPtr <- stackPtr - + SomeTagPtr ptr <- head retireTag :: UIntLog2N(numTags) -> Action - retireTag tag = - do - let nextStackPtrUint = - case stackPtr of - Nothing -> 0 - Just n -> n + 1 - (select inUseVec tag) := False - (select freeStackVec nextStackPtrUint) := tag - stackPtr := Just nextStackPtrUint - -- when - -- tag < (reifiedNumTags - 1), - -- readReg (select inUseVec tag) + retireTag tag = do + -- placeholder + counter := 0 + where + lastIdx :: UIntLog2N(numTags) = (fromInteger |> valueOf numTags) - 1 diff --git a/bs/Util.bs b/bs/Util.bs index b2ea119..49ac04e 100644 --- a/bs/Util.bs +++ b/bs/Util.bs @@ -1,7 +1,5 @@ package Util((|>), simulate_for) where -infixr 0 |> - (|>) :: (a -> b) -> a -> b f |> x = f x;