diff --git a/bs/TagEngine.bs b/bs/TagEngine.bs index e1ea262..5b0e5a6 100644 --- a/bs/TagEngine.bs +++ b/bs/TagEngine.bs @@ -9,7 +9,8 @@ import Util interface (TagEngine :: # -> *) numTags = requestTag :: ActionValue UIntLog2N(numTags) - retireTag :: UIntLog2N(numTags) -> Action + setTagToRetire :: UIntLog2N(numTags) -> Action + retireTag :: 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 @@ -29,6 +30,9 @@ mkTagEngine = stackPtr :: (Reg (Maybe(UIntLog2N(numTags)))) stackPtr <- mkReg |> Just |> reifiedNumTags - 1 + tagToRetire :: RWire (UIntLog2N(numTags)) + tagToRetire <- mkRWireSBR + debugOnce <- mkReg True addRules $ @@ -47,7 +51,7 @@ mkTagEngine = requestTag :: ActionValue UIntLog2N(numTags) requestTag = do - stackPtr := + stackPtr := if sampledStackPtr == 0 then Nothing else Just |> sampledStackPtr - 1 @@ -56,16 +60,27 @@ mkTagEngine = when Just sampledStackPtr <- stackPtr - retireTag :: UIntLog2N(numTags) -> Action - retireTag tag = + setTagToRetire :: UIntLog2N(numTags) -> Action + setTagToRetire tag = + let + tagValid = tag < (reifiedNumTags - 1) + tagInUse = readReg (select inUseVec tag) + in + do + if (tagValid && tagInUse) + then do tagToRetire.wset tag + else do action {} + + retireTag :: Action + retireTag = do - let nextStackPtrUint = + 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) + (select inUseVec tag) := False + when + Valid tag <- tagToRetire.wget