package BusTypes( Bus(..), MkServerIdx, MkClientTagType, BusClient(..), BusServer(..), BusRequest(..), BusResponse(..), ReadRequest(..), ReadResponse(..), WriteRequest(..), WriteResponse(..), BusVal(..), BusError(..), TransactionSize(..), TaggedBusRequest(..), TaggedBusResponse(..) ) where import Types import Vector import TagEngine type MkClientTagType numClients = (UInt (TLog numClients)) type MkServerIdx numServers = (UInt (TLog numServers)) data BusError = UnMapped | UnAligned deriving (Bits, Eq, FShow) data TransactionSize = SizeByte | SizeHalfWord | SizeFullWord | SizeDoubleWord | SizeQuadWord deriving (Bits, Eq, FShow) data BusVal = BusByte Byte | BusHalfWord HalfWord | BusFullWord FullWord | BusDoubleWord DoubleWord | BusQuadWord QuadWord deriving (Bits, Eq, FShow) data ReadRequest = ReadRequest Addr TransactionSize deriving (Bits, Eq, FShow) data WriteRequest = WriteRequest Addr BusVal deriving (Bits, Eq, FShow) type ReadResponse = Either BusError BusVal type WriteResponse = Either BusError () data BusRequest = BusReadRequest ReadRequest | BusWriteRequest WriteRequest deriving (Bits, Eq, FShow) data BusResponse = BusReadResponse ReadResponse | BusWriteResponse WriteResponse deriving (Bits, Eq, FShow) struct TaggedBusRequest inFlightTransactions = { tag :: (MkTagType inFlightTransactions); busRequest :: BusRequest } deriving (Bits, Eq, FShow) struct TaggedBusResponse inFlightTransactions = { tag :: (MkTagType inFlightTransactions); busResponse :: BusResponse } deriving (Bits, Eq, FShow) -- # BusClient.submitRequest -- * The bus client calls the `submitRequest` method of the `BusClient` interface -- with the `BusRequest` it wishes to submit and immediately recieves back -- a transaction-duration-unqiue tag that it can later correlate with the -- returned response should responses arrive out of order(OOO). OOO can -- happen if a bus server is is able to process bus requests faster than -- other bus servers for example. -- # BusClient.consumeResponse -- * The bus client is able to consume a response when a response is available. -- Responses are tagged with the tag given to bus client when it called -- `submitRequest` interface (BusClient :: # -> *) inFlightTransactions = submitRequest :: BusRequest -> ActionValue (MkTagType inFlightTransactions) consumeResponse :: ActionValue (TaggedBusResponse 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 ( MkClientTagType numClients, TaggedBusRequest inFlightTransactions ) submitResponse :: ( MkClientTagType numClients, TaggedBusResponse inFlightTransactions ) -> Action interface (Bus :: # -> # -> # -> *) inFlightTransactions numClients numServers = clients :: Vector numClients (BusClient inFlightTransactions) servers :: Vector numServers (BusServer inFlightTransactions numClients)