notable refactor with grok
This commit is contained in:
parent
ca59e6eaec
commit
020bc5b646
131
bs/TagEngine.bs
131
bs/TagEngine.bs
|
@ -20,111 +20,84 @@ interface (TagEngine :: # -> *) numTags =
|
||||||
-- on a bus for example.
|
-- on a bus for example.
|
||||||
-- This implementation is FIFO based.
|
-- This implementation is FIFO based.
|
||||||
mkTagEngine :: Module (TagEngine numTags)
|
mkTagEngine :: Module (TagEngine numTags)
|
||||||
mkTagEngine =
|
mkTagEngine = do
|
||||||
do
|
-- Constants
|
||||||
let reifiedNumTags = fromInteger |> valueOf numTags
|
let maxTagCount = fromInteger (valueOf numTags)
|
||||||
|
|
||||||
-- we really only use tagUsageTracker after emptying out our
|
-- State
|
||||||
-- `initialTagDistributor` buffer
|
tagUsage :: Vector numTags (Reg Bool) <- replicateM (mkReg False) -- Tracks which tags are in use
|
||||||
tagUsageTracker :: Vector numTags (Reg Bool)
|
initialTagCounter <- mkReg (Just (maxTagCount - 1)) -- Distributes initial tags
|
||||||
tagUsageTracker <- replicateM |> mkReg False
|
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
|
-- Signals
|
||||||
-- reset, we can pretend as if the buffer within our tagFIFO is populated
|
retireSignal <- mkRWire -- Signals a tag retirement
|
||||||
-- with sequentially incrementing values(starting from 0) on reset
|
requestSignal <- mkRWire -- Signals a tag request
|
||||||
-- 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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
-- Debug
|
||||||
debugOnce <- mkReg True
|
debugOnce <- mkReg True
|
||||||
|
|
||||||
|
-- Rules
|
||||||
addRules $
|
addRules $
|
||||||
rules
|
rules
|
||||||
"display": when (debugOnce == True) ==>
|
"debug_initial_state": when debugOnce ==> do
|
||||||
do
|
$display "tagUsage: " (fshow (readVReg tagUsage))
|
||||||
$display "tagUsageTracker : " (fshow |> readVReg tagUsageTracker)
|
|
||||||
debugOnce := False
|
debugOnce := False
|
||||||
|
|
||||||
"update_usage_just_retire": when
|
"retire_tag": when True ==> do
|
||||||
Just tag <- updateUsageRetireTag.wget,
|
let tag = retireQueue.first
|
||||||
Nothing <- updateUsageRequestTag.wget ==>
|
$display "Retiring tag: " (fshow tag)
|
||||||
do
|
retireQueue.deq
|
||||||
$display $time " tagUsageTracker after update retire: " (fshow |> readVReg tagUsageTracker)
|
freeTagQueue.enq tag
|
||||||
(select tagUsageTracker tag) := False
|
retireSignal.wset tag
|
||||||
|
|
||||||
"update_usage_just_request": when
|
-- Combined update rules (simplified below)
|
||||||
Nothing <- updateUsageRetireTag.wget,
|
"update_usage": when True ==> do
|
||||||
Just tag <- updateUsageRequestTag.wget ==>
|
let mRetireTag = retireSignal.wget
|
||||||
do
|
mRequestTag = requestSignal.wget
|
||||||
$display $time " tagUsageTracker after update request: " (fshow |> readVReg tagUsageTracker)
|
case (mRetireTag, mRequestTag) of
|
||||||
(select tagUsageTracker tag) := True
|
(Just retireTag, Just requestTag) -> do
|
||||||
|
let usage = readVReg tagUsage
|
||||||
"update_usage_request_and_retire": when
|
usage' = update usage requestTag True
|
||||||
Just retireTag <- updateUsageRetireTag.wget,
|
usage'' = update usage' retireTag False
|
||||||
Just requestTag <- updateUsageRequestTag.wget ==>
|
writeVReg tagUsage usage''
|
||||||
do
|
$display $time " Updated usage (request + retire): " (fshow |> readVReg tagUsage)
|
||||||
$display $time " tagUsageTracker after update request and retire: " (fshow |> readVReg tagUsageTracker)
|
(Just retireTag, Nothing) -> do
|
||||||
let
|
(select tagUsage retireTag) := False
|
||||||
tagUsageTrackerInner = readVReg tagUsageTracker
|
$display $time " Updated usage (retire): " (fshow (readVReg tagUsage))
|
||||||
tagUsageTracker' = update tagUsageTrackerInner requestTag True
|
(Nothing, Just requestTag) -> do
|
||||||
tagUsageTracker'' = update tagUsageTracker' retireTag False
|
(select tagUsage requestTag) := True
|
||||||
writeVReg tagUsageTracker tagUsageTracker''
|
$display $time " Updated usage (request): " (fshow (readVReg tagUsage))
|
||||||
|
(Nothing, Nothing) -> action {}
|
||||||
"retire_tags": when True ==>
|
|
||||||
do
|
|
||||||
let tagToRetire = validatedTagToRetire.first
|
|
||||||
$display "firing retire_tags" (fshow tagToRetire)
|
|
||||||
validatedTagToRetire.deq
|
|
||||||
tagFIFO.enq tagToRetire
|
|
||||||
updateUsageRetireTag.wset tagToRetire
|
|
||||||
|
|
||||||
|
-- Interface
|
||||||
return $
|
return $
|
||||||
interface TagEngine
|
interface TagEngine
|
||||||
|
|
||||||
requestTag :: ActionValue UIntLog2N(numTags)
|
requestTag :: ActionValue UIntLog2N(numTags)
|
||||||
requestTag =
|
requestTag = do
|
||||||
do
|
case initialTagCounter of
|
||||||
case initialTagDistributor of
|
|
||||||
Just 0 -> do
|
Just 0 -> do
|
||||||
initialTagDistributor := Nothing
|
initialTagCounter := Nothing
|
||||||
updateUsageRequestTag.wset 0
|
requestSignal.wset 0
|
||||||
return 0
|
return 0
|
||||||
Just tag -> do
|
Just tag -> do
|
||||||
initialTagDistributor := Just |> tag - 1
|
initialTagCounter := Just (tag - 1)
|
||||||
updateUsageRequestTag.wset tag
|
requestSignal.wset tag
|
||||||
return tag
|
return tag
|
||||||
Nothing -> do
|
Nothing -> do
|
||||||
let tag = tagFIFO.first
|
let tag = freeTagQueue.first
|
||||||
tagFIFO.deq
|
freeTagQueue.deq
|
||||||
updateUsageRequestTag.wset tag
|
requestSignal.wset tag
|
||||||
return 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 :: UIntLog2N(numTags) -> Action
|
||||||
retireTag tag =
|
retireTag tag =
|
||||||
do
|
do
|
||||||
let
|
let
|
||||||
tagValid = tag < reifiedNumTags
|
tagValid = tag < maxTagCount
|
||||||
tagInUse = readReg (select tagUsageTracker tag)
|
tagInUse = readReg (select tagUsage tag)
|
||||||
if (tagValid && tagInUse)
|
if (tagValid && tagInUse)
|
||||||
then do
|
then do
|
||||||
validatedTagToRetire.enq tag
|
retireQueue.enq tag
|
||||||
else do
|
else do
|
||||||
action {}
|
action {}
|
||||||
|
|
Loading…
Reference in a new issue