From d552934b95c3b4f42f0d4944da4309ecdb97ecac Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Thu, 17 Apr 2025 22:47:24 -0400 Subject: [PATCH] Fixed grant bug Just becasue we have a grant id doesn't mean that anything has actually been granted... --- bs/Bus/Bus.bs | 42 +++++------ bs/Bus/Client.bs | 16 +++-- bs/Bus/Server.bs | 43 +++++------ diagrams/bus.drawio | 169 ++++++++++++++++++++++---------------------- 4 files changed, 140 insertions(+), 130 deletions(-) diff --git a/bs/Bus/Bus.bs b/bs/Bus/Bus.bs index cf1cafd..2386995 100644 --- a/bs/Bus/Bus.bs +++ b/bs/Bus/Bus.bs @@ -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, diff --git a/bs/Bus/Client.bs b/bs/Bus/Client.bs index 4d3d10a..e3cedb3 100644 --- a/bs/Bus/Client.bs +++ b/bs/Bus/Client.bs @@ -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 diff --git a/bs/Bus/Server.bs b/bs/Bus/Server.bs index 794a161..eaeb541 100644 --- a/bs/Bus/Server.bs +++ b/bs/Bus/Server.bs @@ -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 \ No newline at end of file + 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 \ No newline at end of file diff --git a/diagrams/bus.drawio b/diagrams/bus.drawio index 7f93ffd..a199715 100644 --- a/diagrams/bus.drawio +++ b/diagrams/bus.drawio @@ -1,75 +1,75 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -78,7 +78,7 @@ - + @@ -91,20 +91,20 @@ - + - + - + @@ -117,25 +117,25 @@ - + - + - + - + @@ -145,63 +145,63 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -210,7 +210,7 @@ - + @@ -223,19 +223,20 @@ - - - - + + + + + - + - + @@ -248,32 +249,32 @@ - + - + - + - + - + @@ -284,7 +285,7 @@ - + @@ -295,7 +296,7 @@ - + @@ -306,7 +307,7 @@ - + @@ -317,18 +318,7 @@ - - - - - - - - - - - - + @@ -339,7 +329,7 @@ - + @@ -350,18 +340,18 @@ - + - - + + - + @@ -371,7 +361,7 @@ - + @@ -382,20 +372,7 @@ - - - - - - - - - - - - - - + @@ -406,7 +383,7 @@ - + @@ -417,6 +394,30 @@ + + + + + + + + + + + + + + + + + + + + + + + +