stubbed out mkBus for now - awaits full implementation
This commit is contained in:
parent
076d3aed43
commit
ca02c88be3
84
bs/Bus.bs
84
bs/Bus.bs
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
Loading…
Reference in a new issue