diff --git a/bs/TagEngine.bs b/bs/TagEngine.bs index d8e0736..f5a00ba 100644 --- a/bs/TagEngine.bs +++ b/bs/TagEngine.bs @@ -7,6 +7,7 @@ import Vector import Util import FIFO import FIFOF +import SpecialFIFOs #define UIntLog2N(n) (UInt (TLog n)) @@ -23,7 +24,7 @@ mkTagEngine = do let reifiedNumTags = fromInteger |> valueOf numTags - -- we really only use tagUsageTracker after emptying out our + -- we really only use tagUsageTracker after emptying out our -- `initialTagDistributor` buffer tagUsageTracker :: Vector numTags (Reg Bool) tagUsageTracker <- replicateM |> mkReg False @@ -32,13 +33,19 @@ mkTagEngine = -- 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 + -- 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 - retireTag :: Wire UIntLog2N(numTags) - retireTag <- mkWire + validatedTagToRetire :: FIFO UIntLog2N(numTags) + validatedTagToRetire <- mkBypassFIFO + + updateUsageRetireTag :: RWire UIntLog2N(numTags) + updateUsageRetireTag <- mkRWire + + updateUsageRequestTag :: RWire UIntLog2N(numTags) + updateUsageRequestTag <- mkRWire tagFIFO :: FIFOF UIntLog2N(numTags) tagFIFO <- mkSizedFIFOF reifiedNumTags @@ -51,12 +58,39 @@ mkTagEngine = 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 - $display "firing retire_tags" (fshow retireTag) - tagFIFO.enq retireTag - (select tagUsageTracker retireTag) := False + let tagToRetire = validatedTagToRetire.first + $display "firing retire_tags" (fshow tagToRetire) + validatedTagToRetire.deq + tagFIFO.enq tagToRetire + updateUsageRetireTag.wset tagToRetire return $ interface TagEngine @@ -67,18 +101,19 @@ mkTagEngine = case initialTagDistributor of Just 0 -> do initialTagDistributor := Nothing - (select tagUsageTracker 0) := True + updateUsageRequestTag.wset 0 return 0 Just tag -> do initialTagDistributor := Just |> tag - 1 - (select tagUsageTracker tag) := True + updateUsageRequestTag.wset tag return tag Nothing -> do let tag = tagFIFO.first tagFIFO.deq + updateUsageRequestTag.wset tag return tag - -- `retireTag` isn't guarded on tag validity(this would break Bluespec's safety model) + -- `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. @@ -90,6 +125,6 @@ mkTagEngine = tagInUse = readReg (select tagUsageTracker tag) if (tagValid && tagInUse) then do - retireTag := tag + validatedTagToRetire.enq tag else do action {} diff --git a/bs/Tests/TagEngineTester.bs b/bs/Tests/TagEngineTester.bs index 6c140c3..4fc700e 100644 --- a/bs/Tests/TagEngineTester.bs +++ b/bs/Tests/TagEngineTester.bs @@ -6,23 +6,22 @@ import ActionSeq mkTagEngineTester :: Module Empty mkTagEngineTester = do tagEngine :: TagEngine 5 <- mkTagEngine - count :: Reg (UInt 32) <- mkReg 0; runOnce :: Reg Bool <- mkReg False s :: ActionSeq - s <- + s <- let requestTagAction :: Action requestTagAction = do tag <- tagEngine.requestTag - $display "got tag : " (fshow tag) + $display $time " got tag : " (fshow tag) retireTagAction :: UInt 3 -> Action retireTagAction tag = do res <- tagEngine.retireTag tag - $display "retiring tag : " (fshow tag) " " (fshow res) + $display $time " retiring tag : " (fshow tag) " " (fshow res) action {} in @@ -34,12 +33,12 @@ mkTagEngineTester = do |> do requestTagAction |> do retireTagAction 2 -- |> do $display "BEGIN TRY SIMULTANEOUS RETIRE and REQUEST" - |> do + |> do retireTagAction 4 requestTagAction -- |> do $display "END TRY SIMULTANEOUS RETIRE and REQUEST" -- |> do $display "BEGIN TRY SIMULTANEOUS RETIRE and REQUEST" - |> do + |> do retireTagAction 4 requestTagAction -- |> do $display "END TRY SIMULTANEOUS RETIRE and REQUEST" @@ -55,11 +54,11 @@ mkTagEngineTester = do addRules $ rules - "counter": when True ==> - do - count := count + 1 - $display "count : " (fshow count) + -- "counter": when True ==> + -- do + -- count := count + 1 + -- $display "count : " (fshow count) "testIncrement": when (runOnce == False) ==> do s.start - runOnce := True \ No newline at end of file + runOnce := True