Fixed grant bug
Just becasue we have a grant id doesn't mean that anything has actually been granted...
This commit is contained in:
parent
a58c908763
commit
d552934b95
4 changed files with 140 additions and 130 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Reference in a new issue