From 020bc5b6460dd422e2170f5466ae8c8d90174760 Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Fri, 4 Apr 2025 15:27:25 -0400 Subject: [PATCH] notable refactor with grok --- bs/TagEngine.bs | 155 ++++++++++++++++++++---------------------------- 1 file changed, 64 insertions(+), 91 deletions(-) diff --git a/bs/TagEngine.bs b/bs/TagEngine.bs index f5a00ba..0d28fce 100644 --- a/bs/TagEngine.bs +++ b/bs/TagEngine.bs @@ -20,111 +20,84 @@ interface (TagEngine :: # -> *) numTags = -- on a bus for example. -- This implementation is FIFO based. mkTagEngine :: Module (TagEngine numTags) -mkTagEngine = - do - let reifiedNumTags = fromInteger |> valueOf numTags +mkTagEngine = do + -- Constants + let maxTagCount = fromInteger (valueOf numTags) - -- we really only use tagUsageTracker after emptying out our - -- `initialTagDistributor` buffer - tagUsageTracker :: Vector numTags (Reg Bool) - tagUsageTracker <- replicateM |> mkReg False + -- State + tagUsage :: Vector numTags (Reg Bool) <- replicateM (mkReg False) -- Tracks which tags are in use + initialTagCounter <- mkReg (Just (maxTagCount - 1)) -- Distributes initial tags + retireQueue <- mkBypassFIFO -- Queue for tags being retired + freeTagQueue <- mkSizedFIFOF maxTagCount -- Queue of available tags - -- Since Bluespec doesn't allow us to initialize FIFOs with values at - -- reset, we can pretend as if the buffer within our tagFIFO is populated - -- with sequentially incrementing values(starting from 0) on reset - -- by having our tag engine effectively return the value of a decrementing - -- counter initialized to (numTags - 1) for the first n tag requests made - -- to TagEngine where `n := numTags`. - initialTagDistributor :: (Reg (Maybe UIntLog2N(numTags))) - initialTagDistributor <- mkReg |> Just |> reifiedNumTags - 1 + -- Signals + retireSignal <- mkRWire -- Signals a tag retirement + requestSignal <- mkRWire -- Signals a tag request - validatedTagToRetire :: FIFO UIntLog2N(numTags) - validatedTagToRetire <- mkBypassFIFO + -- Debug + debugOnce <- mkReg True - updateUsageRetireTag :: RWire UIntLog2N(numTags) - updateUsageRetireTag <- mkRWire + -- Rules + addRules $ + rules + "debug_initial_state": when debugOnce ==> do + $display "tagUsage: " (fshow (readVReg tagUsage)) + debugOnce := False - updateUsageRequestTag :: RWire UIntLog2N(numTags) - updateUsageRequestTag <- mkRWire + "retire_tag": when True ==> do + let tag = retireQueue.first + $display "Retiring tag: " (fshow tag) + retireQueue.deq + freeTagQueue.enq tag + retireSignal.wset tag - tagFIFO :: FIFOF UIntLog2N(numTags) - tagFIFO <- mkSizedFIFOF reifiedNumTags - - debugOnce <- mkReg True - - addRules $ - rules - "display": when (debugOnce == True) ==> - do - $display "tagUsageTracker : " (fshow |> readVReg tagUsageTracker) - debugOnce := False - - "update_usage_just_retire": when - Just tag <- updateUsageRetireTag.wget, - Nothing <- updateUsageRequestTag.wget ==> - do - $display $time " tagUsageTracker after update retire: " (fshow |> readVReg tagUsageTracker) - (select tagUsageTracker tag) := False - - "update_usage_just_request": when - Nothing <- updateUsageRetireTag.wget, - Just tag <- updateUsageRequestTag.wget ==> - do - $display $time " tagUsageTracker after update request: " (fshow |> readVReg tagUsageTracker) - (select tagUsageTracker tag) := True - - "update_usage_request_and_retire": when - Just retireTag <- updateUsageRetireTag.wget, - Just requestTag <- updateUsageRequestTag.wget ==> - do - $display $time " tagUsageTracker after update request and retire: " (fshow |> readVReg tagUsageTracker) - let - tagUsageTrackerInner = readVReg tagUsageTracker - tagUsageTracker' = update tagUsageTrackerInner requestTag True - tagUsageTracker'' = update tagUsageTracker' retireTag False - writeVReg tagUsageTracker tagUsageTracker'' - - "retire_tags": when True ==> - do - let tagToRetire = validatedTagToRetire.first - $display "firing retire_tags" (fshow tagToRetire) - validatedTagToRetire.deq - tagFIFO.enq tagToRetire - updateUsageRetireTag.wset tagToRetire - - return $ - interface TagEngine + -- Combined update rules (simplified below) + "update_usage": when True ==> do + let mRetireTag = retireSignal.wget + mRequestTag = requestSignal.wget + case (mRetireTag, mRequestTag) of + (Just retireTag, Just requestTag) -> do + let usage = readVReg tagUsage + usage' = update usage requestTag True + usage'' = update usage' retireTag False + writeVReg tagUsage usage'' + $display $time " Updated usage (request + retire): " (fshow |> readVReg tagUsage) + (Just retireTag, Nothing) -> do + (select tagUsage retireTag) := False + $display $time " Updated usage (retire): " (fshow (readVReg tagUsage)) + (Nothing, Just requestTag) -> do + (select tagUsage requestTag) := True + $display $time " Updated usage (request): " (fshow (readVReg tagUsage)) + (Nothing, Nothing) -> action {} + -- Interface + return $ + interface TagEngine requestTag :: ActionValue UIntLog2N(numTags) - requestTag = - do - case initialTagDistributor of - Just 0 -> do - initialTagDistributor := Nothing - updateUsageRequestTag.wset 0 - return 0 - Just tag -> do - initialTagDistributor := Just |> tag - 1 - updateUsageRequestTag.wset tag - return tag - Nothing -> do - let tag = tagFIFO.first - tagFIFO.deq - updateUsageRequestTag.wset tag - return tag + requestTag = do + case initialTagCounter of + Just 0 -> do + initialTagCounter := Nothing + requestSignal.wset 0 + return 0 + Just tag -> do + initialTagCounter := Just (tag - 1) + requestSignal.wset tag + return tag + Nothing -> do + let tag = freeTagQueue.first + freeTagQueue.deq + requestSignal.wset tag + return tag - -- `retireTag` isn't guarded on tag validity(this would break Bluespec's safety model) - -- so it is advisable that the caller of `retireTag` only attempt to retire valid tags. - -- Internally, the tagEngine will keep a correct and consistent state since TagEngine - -- validates tags before attempting to retire them. retireTag :: UIntLog2N(numTags) -> Action retireTag tag = do let - tagValid = tag < reifiedNumTags - tagInUse = readReg (select tagUsageTracker tag) + tagValid = tag < maxTagCount + tagInUse = readReg (select tagUsage tag) if (tagValid && tagInUse) then do - validatedTagToRetire.enq tag + retireQueue.enq tag else do action {}