reduced latency

This commit is contained in:
Yehowshua Immanuel 2025-04-02 02:59:49 -04:00
parent d436209f54
commit e055b1bbdf
2 changed files with 38 additions and 24 deletions

View file

@ -23,8 +23,10 @@ mkTagEngine =
do do
let reifiedNumTags = fromInteger |> valueOf numTags let reifiedNumTags = fromInteger |> valueOf numTags
-- we really only use inUseVec after emptying out our `resetTagCounter` buffer
-- perhaps rename this variable to better communicate that
inUseVec :: Vector numTags (Reg Bool) inUseVec :: Vector numTags (Reg Bool)
inUseVec <- replicateM |> mkReg False inUseVec <- replicateM |> mkReg True
-- Since Bluespec doesn't allow us to initialize FIFOs with values at -- 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 -- reset, we can pretend as if the buffer within our tagFIFO is populated
@ -32,11 +34,12 @@ mkTagEngine =
-- by having our tag engine effectively return the value of a decrementing -- 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`. -- to TagEngine where `n := numTags`.
-- Maybe resetTagCounter isn't the greatest name?
resetTagCounter :: (Reg (Maybe UIntLog2N(numTags))) resetTagCounter :: (Reg (Maybe UIntLog2N(numTags)))
resetTagCounter <- mkReg |> Just |> reifiedNumTags - 1 resetTagCounter <- mkReg |> Just |> reifiedNumTags - 1
retireQueue :: FIFOF UIntLog2N(numTags) retireTag :: Wire UIntLog2N(numTags)
retireQueue <- mkSizedFIFOF reifiedNumTags retireTag <- mkWire
freeQueue :: FIFOF UIntLog2N(numTags) freeQueue :: FIFOF UIntLog2N(numTags)
freeQueue <- mkSizedFIFOF reifiedNumTags freeQueue <- mkSizedFIFOF reifiedNumTags
@ -56,11 +59,9 @@ mkTagEngine =
-- 2. the `requestTag` method handles the case where there are some tags to retire. -- 2. the `requestTag` method handles the case where there are some tags to retire.
"retire_tags": when True ==> "retire_tags": when True ==>
do do
let tag = retireQueue.first $display "firing retire_tags" (fshow retireTag)
$display "firing retire_tags" (fshow tag) freeQueue.enq retireTag
retireQueue.deq (select inUseVec retireTag) := False
freeQueue.enq tag
(select inUseVec tag) := False
return $ return $
interface TagEngine interface TagEngine
@ -71,11 +72,9 @@ mkTagEngine =
case resetTagCounter of case resetTagCounter of
Just 0 -> do Just 0 -> do
resetTagCounter := Nothing resetTagCounter := Nothing
(select inUseVec 0) := True
return 0 return 0
Just tag -> do Just tag -> do
resetTagCounter := Just |> tag - 1 resetTagCounter := Just |> tag - 1
(select inUseVec tag) := True
return tag return tag
Nothing -> do Nothing -> do
let tag = freeQueue.first let tag = freeQueue.first
@ -86,14 +85,18 @@ mkTagEngine =
-- so it is advisable that the caller of `retireTag` only attempt to retire valid tags. -- 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 -- Internally, the tagEngine will keep a correct and consistent state since TagEngine
-- validates tags before attempting to retire them. -- validates tags before attempting to retire them.
-- Also worth noting the TagEngin will ignore attempts to retire a tag you just
-- requested in the same cycle. This is enforce with `tag > tagCounter` below.
retireTag :: UIntLog2N(numTags) -> Action retireTag :: UIntLog2N(numTags) -> Action
retireTag tag = retireTag tag =
do do
let let
tagValid = tag < reifiedNumTags tagValid = tag < reifiedNumTags
tagInUse = readReg (select inUseVec tag) tagInUse = case resetTagCounter of
Just tagCounter -> tag > tagCounter
Nothing -> readReg (select inUseVec tag)
if (tagValid && tagInUse) if (tagValid && tagInUse)
then do then do
retireQueue.enq tag retireTag := tag
else do else do
action {} action {}

View file

@ -6,7 +6,7 @@ import ActionSeq
mkTagEngineTester :: Module Empty mkTagEngineTester :: Module Empty
mkTagEngineTester = do mkTagEngineTester = do
tagEngine :: TagEngine 5 <- mkTagEngine tagEngine :: TagEngine 5 <- mkTagEngine
count :: Reg (UInt 4) <- mkReg 0; count :: Reg (UInt 32) <- mkReg 0;
runOnce :: Reg Bool <- mkReg False runOnce :: Reg Bool <- mkReg False
s :: ActionSeq s :: ActionSeq
@ -30,24 +30,35 @@ mkTagEngineTester = do
do requestTagAction do requestTagAction
|> do requestTagAction |> do requestTagAction
|> do requestTagAction |> do requestTagAction
|> do retireTagAction 3 |> do requestTagAction
|> do $display "BEGIN TRY SIMULTANEOUS RETIRE and REQUEST" |> do requestTagAction
|> do retireTagAction 2
-- |> do $display "BEGIN TRY SIMULTANEOUS RETIRE and REQUEST"
|> do |> do
retireTagAction 4 retireTagAction 4
requestTagAction requestTagAction
|> do $display "END TRY SIMULTANEOUS RETIRE and REQUEST" -- |> do $display "END TRY SIMULTANEOUS RETIRE and REQUEST"
|> do requestTagAction -- |> do $display "BEGIN TRY SIMULTANEOUS RETIRE and REQUEST"
|> do retireTagAction 4 |> do
|> do retireTagAction 4 retireTagAction 4
|> do retireTagAction 0 requestTagAction
|> do requestTagAction -- |> do $display "END TRY SIMULTANEOUS RETIRE and REQUEST"
|> do requestTagAction
|> do retireTagAction 1
|> do requestTagAction
|> do $finish |> do $finish
-- |> do retireTagAction 4
-- |> do retireTagAction 4
-- |> do retireTagAction 0
-- |> do requestTagAction
-- |> do requestTagAction
-- |> do retireTagAction 1
-- |> do requestTagAction
-- |> do $finish
addRules $ addRules $
rules rules
"counter": when True ==>
do
count := count + 1
$display "count : " (fshow count)
"testIncrement": when (runOnce == False) ==> "testIncrement": when (runOnce == False) ==>
do do
s.start s.start