Fixed grant bug

Just becasue we have a grant id doesn't mean that anything has actually
been granted...
This commit is contained in:
Yehowshua Immanuel 2025-04-17 22:47:24 -04:00
parent a58c908763
commit d552934b95
4 changed files with 140 additions and 130 deletions

View file

@ -14,16 +14,14 @@ import FIFOF
import SpecialFIFOs
import Printf
busRequestToAddr :: BusRequest -> Addr
busRequestToAddr req = case req of
BusReadRequest (ReadRequest addr _) -> addr
BusWriteRequest (WriteRequest addr _) -> addr
-- Create a Bus Module that supports multiple clients and servers
-- Creates a Bus Module that supports multiple clients and servers
-- submitting requests and simultaneously returning responses.
-- Responses can be consumed by clients out of order as all client
-- submitted requests are tagged - and servers keep that tag
-- when responding.
-- Responses can be consumed by clients out of order(useful when some
-- servers respond before others) as all client submitted requests are
-- tagged with tags that are unique for the duration of the transaction
-- - and well-behaved servers should keep that tag when responding.
-- Explicitly inform the compiler that log2 n <= log2(n + 1)
mkBus :: (Add n (TLog numServers) (TLog (TAdd numServers 1)))
=> (Addr -> Maybe (MkServerIdx numServers))
-> Module (Bus inFlightTransactions numClients numServers)
@ -32,13 +30,15 @@ mkBus serverMap = do
tagEngineByClientVec :: Vector numClients (TagEngine inFlightTransactions)
tagEngineByClientVec <- replicateM mkTagEngine
-- There are `numClients` clients, each of which needs its own arbiter as
-- there are up to `numServer` servers that may wish to submit a response
-- to a given client. Furthermore the rule that routes client requests to
-- servers makes for another potential requestor as it may determine that
-- a request is unmappable and instead opt to form and submit a
-- `BusError UnMapped` response directly to a client response arbiter. Thus
-- we must arbit between a total of `numServers + 1` requestors.
-- There are `numClients` clients, each of which needs its own client
-- response arbiter as there are `numServer` servers that may wish to
-- submit a response to a given client. Furthermore the rule that routes
-- client requests to servers makes for another potential submitter to
-- the client response arbiter as it may determine that a request is
-- unmappable and simply bypass submitting the request to a server,
-- instead opting to form a `BusError UnMapped` response to be submitted
-- directly to a client response arbiter. Thus the client response arbiter
-- must arbit between a total of `numServers + 1` requestors.
responseArbiterByClient :: Vector numClients (Arbiter.Arbiter_IFC (TAdd numServers 1))
responseArbiterByClient <- replicateM (mkArbiter False)
@ -48,9 +48,6 @@ mkBus serverMap = do
requestArbiterByServer :: Vector numServers (Arbiter.Arbiter_IFC numClients)
requestArbiterByServer <- replicateM (mkArbiter False)
dummyVar :: Reg(Bool)
dummyVar <- mkReg False
-- Queues to hold requests from clients
clientRequestQueues :: Vector numClients (FIFOF (TaggedBusRequest inFlightTransactions))
clientRequestQueues <- replicateM (mkSizedBypassFIFOF (valueOf inFlightTransactions))
@ -59,8 +56,11 @@ mkBus serverMap = do
clientResponseQueues :: Vector numClients (FIFOF (TaggedBusResponse inFlightTransactions))
clientResponseQueues <- replicateM (mkSizedBypassFIFOF (valueOf inFlightTransactions))
-- The following two vectors of FIFOs make it easier to push/pull data to/from internal
-- server methods:
-- The following two vectors of single depth FIFOs make it easier to push/pull data
-- to/from internal server methods as they provide back-pressure in both directions,
-- and behave as a wire when queue is empty.
-- If looking at the example bus.drawio diagram, the following two vectors effectively
-- correspond to the two arrows going from the blue box to the servers.
consumeRequestQueues :: Vector numServers (
FIFOF (
MkClientTagType numClients,

View file

@ -45,6 +45,9 @@ clientRouteRequest clientIdx clientReqQueue requestArbiterByServer responseArbit
arbiterClientSlot :: Arbiter.ArbiterClient_IFC
arbiterClientSlot = select targetServerArbiter.clients clientIdx
arbiterClientSlot.request
-- We bypass sensing the request to the server instead option to form
-- a `BusError Unmapped` response which we request to send directly to
-- the appropiate client response queue.
Nothing -> do
let targetClientResponseArbiter :: Arbiter.Arbiter_IFC (TAdd numServers 1)
targetClientResponseArbiter = select responseArbiterByClient clientIdx
@ -74,12 +77,15 @@ clientArbitSubmission :: (Add n (TLog numServers) (TLog (TAdd numServers 1)))
-> Vector numServers (FIFOF (MkClientTagType numClients, TaggedBusResponse inFlightTransactions))
-> Rules
clientArbitSubmission clientIdx clientReqQueue clientRespQueue clientRespArbiter submitRespQueues =
rules
(sprintf "client[%d] arbit submission" clientIdx): when True ==> do
let grantedIdx :: UInt (TLog (TAdd numServers 1))
grantedIdx = unpack clientRespArbiter.grant_id
let grantedIdx :: UInt (TLog (TAdd numServers 1))
grantedIdx = unpack clientRespArbiter.grant_id
isClientRequest :: Bool
selectedServerInterface :: ArbiterClient_IFC
selectedServerInterface = select clientRespArbiter.clients grantedIdx
in
rules
(sprintf "client[%d] arbit submission" clientIdx): when selectedServerInterface.grant ==> do
let isClientRequest :: Bool
isClientRequest = grantedIdx == fromInteger (valueOf numServers)
if isClientRequest then do
let clientRequest :: TaggedBusRequest inFlightTransactions

View file

@ -14,25 +14,6 @@ import FIFOF
import SpecialFIFOs
import Printf
serverArbitRequests :: Integer
-> Arbiter.Arbiter_IFC numClients
-> FIFOF (MkClientTagType numClients, TaggedBusRequest inFlightTransactions)
-> Vector numClients (FIFOF (TaggedBusRequest inFlightTransactions))
-> Rules
serverArbitRequests serverIdx serverArbiter consumeReqQueue clientReqQueues =
rules
(sprintf "server[%d] arbit requests" serverIdx): when True ==> do
let grantedClientIdx :: MkClientTagType numClients
grantedClientIdx = unpack serverArbiter.grant_id
selectedClientReqQueue :: FIFOF (TaggedBusRequest inFlightTransactions)
selectedClientReqQueue = select clientReqQueues grantedClientIdx
clientRequest :: TaggedBusRequest inFlightTransactions
clientRequest = selectedClientReqQueue.first
consumeReqQueue.enq (grantedClientIdx, clientRequest)
selectedClientReqQueue.deq
serverRouteResponse :: Integer
-> FIFOF (MkClientTagType numClients, TaggedBusResponse inFlightTransactions)
-> Vector numClients (Arbiter.Arbiter_IFC (TAdd numServers 1))
@ -51,4 +32,26 @@ serverRouteResponse serverIdx submitRespQueue responseArbiterByClient =
arbiterClientSlot :: Arbiter.ArbiterClient_IFC
arbiterClientSlot = select targetClientRespArbiter.clients serverIdx
arbiterClientSlot.request
arbiterClientSlot.request
serverArbitRequests :: Integer
-> Arbiter.Arbiter_IFC numClients
-> FIFOF (MkClientTagType numClients, TaggedBusRequest inFlightTransactions)
-> Vector numClients (FIFOF (TaggedBusRequest inFlightTransactions))
-> Rules
serverArbitRequests serverIdx serverArbiter consumeReqQueue clientReqQueues =
let grantedClientIdx :: MkClientTagType numClients
grantedClientIdx = unpack serverArbiter.grant_id
selectedClientInterface :: ArbiterClient_IFC
selectedClientInterface = select serverArbiter.clients grantedClientIdx
in
rules
(sprintf "server[%d] arbit requests" serverIdx): when selectedClientInterface.grant ==> do
let selectedClientReqQueue :: FIFOF (TaggedBusRequest inFlightTransactions)
selectedClientReqQueue = select clientReqQueues grantedClientIdx
clientRequest :: TaggedBusRequest inFlightTransactions
clientRequest = selectedClientReqQueue.first
consumeReqQueue.enq (grantedClientIdx, clientRequest)
selectedClientReqQueue.deq