stubbed out mkBus for now - awaits full implementation

This commit is contained in:
Yehowshua Immanuel 2025-04-09 22:31:26 -04:00
parent 076d3aed43
commit ca02c88be3
2 changed files with 86 additions and 82 deletions

View file

@ -6,60 +6,66 @@ import TagEngine
import Vector import Vector
import Util import Util
import Arbiter import Arbiter
import FIFO
import FIFOF
import SpecialFIFOs
clientRequest :: Arbiter.ArbiterClient_IFC -> Action clientRequest :: Arbiter.ArbiterClient_IFC -> Action
clientRequest ifc = ifc.request clientRequest ifc = ifc.request
busRequestToAddr :: BusRequest -> Addr busRequestToAddr :: BusRequest -> Maybe Addr
busRequestToAddr req = case req of busRequestToAddr req = case req of
BusReadRequest (ReadRequest addr _) -> addr BusReadRequest (ReadRequest addr _) -> addr
WriteReadRequest (WriteRequest addr _) -> addr BusWriteRequest (WriteRequest addr _) -> addr
mkBus :: (Addr -> Integer) mkBus :: (Addr -> Maybe Integer)
-> Vector numClients (BusClient inFlightTransactions) -> Module (Bus inFlightTransactions numClients numServers)
-> Vector numServers (BusServer inFlightTransactions numClients) mkBus addrToServerTranslation = do
-> Module Empty -- Tag engines for each client to manage transaction tags
mkBus addrToServerTranslation clientVec serverVec = do
tagEngineByClientVec :: Vector numClients (TagEngine inFlightTransactions) tagEngineByClientVec :: Vector numClients (TagEngine inFlightTransactions)
tagEngineByClientVec <- replicateM mkTagEngine tagEngineByClientVec <- replicateM mkTagEngine
arbiterByServerVec :: Vector numServers (Arbiter_IFC numClients) -- Arbitration for clients to send requests to servers
arbiterByServerVec <- replicateM (mkArbiter False) clientArbiter :: Arbiter.Arbiter_IFC numClients
clientArbiter <- mkArbiter False
-- statically determinate criteria dummyVar :: Reg(Bool)
let dummyVar <- mkReg False
clientIdx :: Integer = 0
selectedClient ::(BusClient inFlightTransactions)
selectedClient = (select clientVec clientIdx)
selectedTagEngine = (select tagEngineByClientVec clientIdx)
addRules |> -- Queues to hold requests from clients to servers
rules requestQueues :: Vector numServers (FIFOF BusRequest)
"placeholder rule": when True ==> do requestQueues <- replicateM (mkSizedBypassFIFOF (valueOf inFlightTransactions))
let selectedServerArbiter = (select arbiterByServerVec 0)
mapM_ clientRequest selectedServerArbiter.clients
"connect request client 0": -- Queues to hold responses from servers to clients
when True responseQueues :: Vector numClients (FIFOF (BusResponse, MkTagType inFlightTransactions))
==> do responseQueues <- replicateM (mkSizedBypassFIFOF (valueOf inFlightTransactions))
tag <- selectedTagEngine.requestTag
busRequest :: BusRequest -- Client interface vector
busRequest <- selectedClient.dequeueRequest tag let clients :: Vector numClients (BusClient inFlightTransactions)
clients = genWith $ \clientIdx ->
interface BusClient
submitRequest req = do
dummyVar := (not dummyVar)
return 0
-- let consumeResponse = do
-- addr = busRequestToAddr busRequest dummyVar := (not dummyVar)
-- targetServerIdx = addrToServerTranslation addr let dummyResponse = BusReadResponse (Left UnMapped)
-- targetServer = (select serverVec targetServerIdx) return (dummyResponse, 0)
-- targetServerArbiter = (select arbiterByServerVec targetServerIdx)
-- targetServerArbiter.request -- Server interface vector
let servers :: Vector numServers (BusServer inFlightTransactions numClients)
servers = genWith $ \serverIdx ->
interface BusServer
consumeRequest = do
dummyVar := (not dummyVar)
let dummyBusRequest = BusReadRequest (ReadRequest 0 SizeByte)
return (0, dummyBusRequest)
-- if targetServerArbiter.grant submitResponse (clientTag, busResponse, transactionTag) = do
-- then targetServer.enqueueRequest (tag, busRequest) dummyVar := (not dummyVar)
-- else action {}
-- targetServer return $
action {} interface Bus
clients = clients
return $ interface Empty { } servers = servers

View file

@ -1,4 +1,5 @@
package BusTypes( package BusTypes(
Bus(..),
MkClientTagType, MkClientTagType,
BusClient(..), BusServer(..), BusClient(..), BusServer(..),
BusRequest(..), BusResponse(..), BusRequest(..), BusResponse(..),
@ -44,7 +45,7 @@ type WriteResponse = Either BusError ()
data BusRequest data BusRequest
= BusReadRequest ReadRequest = BusReadRequest ReadRequest
| WriteReadRequest WriteRequest | BusWriteRequest WriteRequest
deriving (Bits, Eq, FShow) deriving (Bits, Eq, FShow)
data BusResponse data BusResponse
@ -52,47 +53,44 @@ data BusResponse
| BusWriteResponse WriteResponse | BusWriteResponse WriteResponse
deriving (Bits, Eq, FShow) deriving (Bits, Eq, FShow)
-- # BusClient.dequeueRequest -- # BusClient.submitRequest
-- * The Bus arbiter will call the Bus Client's request method if it is -- * The bus client calls the `submitRequest` method of the `BusClient` interface
-- the Bus Client's turn to make a request, or if another client forfits -- with the `BusRequest` it wishes to submit and immediately recieves back
-- its turn. -- a transaction-duration-unqiue tag that it can later correlate with the
-- * The BusClient must guard its request method such that calling its -- returned response should responses arrive out of order(OOO). OOO can
-- request method is only valid when the BusClient has a request to make. -- happen if a bus server is is able to process bus requests faster than
-- * This has implications about for the implementor of BusClient, -- other bus servers for example.
-- namely, that it should hold its request until it's request method -- # BusClient.consumeResponse
-- gets called. The arbiter tags the request so that the client can -- * The bus client is able to consume a response when a response is available.
-- later correctly correlate the response. -- Responses are tagged with the tag given to bus client when it called
-- * Although the tag is technically passed in as an argument from the -- `submitRequest`
-- arbiter to the client's request method, given that methods are
-- atomic in Bluespec, this is effectively equivalent to tagging the
-- transaction from the client's perspective. Thus, the client must
-- take care to appropiately store the tag.
-- # BusClient.enqueueResponse
-- * From the client's perspective, the response should not be called
-- by the arbiter until the client is ready to accept the response.
-- In other words, the response method should be guarded by the client.
interface (BusClient :: # -> *) inFlightTransactions = interface (BusClient :: # -> *) inFlightTransactions =
dequeueRequest :: MkTagType inFlightTransactions submitRequest :: BusRequest
-> ActionValue BusRequest -> ActionValue (MkTagType inFlightTransactions)
enqueueResponse :: (BusResponse, MkTagType inFlightTransactions) consumeResponse :: ActionValue (BusResponse, MkTagType inFlightTransactions)
-- # BusServer.consumeRequest
-- * The bus server calls the `consumeRequest` method of the `BusServer` interface
-- to retrieve a pending bus request initiated by a client. It immediately
-- receives a tuple containing a transaction-duration-unique tag
-- (associated with the original request) and the `BusRequest` itself. This
-- tag is used to track the transaction and correlate it with the eventual
-- response.
-- # BusServer.submitResponse
-- * The bus server calls the `submitResponse` method to send a `BusResponse`
-- back to the originating client. The method takes a tuple containing:
-- - A client tag (of type `MkClientTagType numClients`) identifying the
-- client that submitted the request.
-- - The `BusResponse` containing the result of the request (either a read
-- or write response).
-- - The transaction tag (of type `transactionTagType`) that matches the tag
-- received from `consumeRequest`, ensuring the response is correctly
-- associated with the original request.
interface (BusServer :: # -> # -> *) inFlightTransactions numClients =
consumeRequest :: ActionValue (MkTagType inFlightTransactions, BusRequest)
submitResponse :: (MkClientTagType numClients, BusResponse, transactionTagType)
-> Action -> Action
-- # BusServer.dequeueResponse interface (Bus :: # -> # -> # -> *) inFlightTransactions numClients numServers =
-- * If the arbiter is able to successfully call `dequeueResponse`, then clients :: Vector numClients (BusClient inFlightTransactions)
-- the BusServer's internal logic must update such that it understands servers :: Vector numServers (BusServer inFlightTransactions numClients)
-- the response has been handed off.
-- # BusServer.peekClientTagDestination
-- * The arbiter looks at (peekClientTagDestination :: MkClientTagType) to
-- determine whether or not it is currently safe whether to dequeue the
-- response as well as where to route the response should it dequeue the
-- response.
-- * `peekClientTagDestination` should be guarded on whether or not there is
-- a valid response available.
interface (BusServer :: # -> # -> *) inFlightTransactions numClients =
enqueueRequest :: (MkTagType inFlightTransactions, BusRequest)
-> Action
dequeueResponse :: ActionValue (
MkClientTagType numClients,
BusResponse, transactionTagType
)
peekClientTagDestination :: MkClientTagType numClients