diff --git a/bs/Bus.bs b/bs/Bus.bs index 7df4955..0faaa54 100644 --- a/bs/Bus.bs +++ b/bs/Bus.bs @@ -1,65 +1,7 @@ -package Bus(mkBus) where +package Bus(a) where import Types import BusTypes -import TagEngine -import Vector -import Util -import Arbiter -clientRequest :: Arbiter.ArbiterClient_IFC -> Action -clientRequest ifc = ifc.request - -busRequestToAddr :: BusRequest -> Addr -busRequestToAddr req = case req of - BusReadRequest (ReadRequest addr _) -> addr - WriteReadRequest (WriteRequest addr _) -> addr - -mkBus :: (Addr -> Integer) - -> Vector numClients (BusClient inFlightTransactions) - -> Vector numServers (BusServer inFlightTransactions numClients) - -> Module Empty -mkBus addrToServerTranslation clientVec serverVec = do - tagEngineByClientVec :: Vector numClients (TagEngine inFlightTransactions) - tagEngineByClientVec <- replicateM mkTagEngine - - arbiterByServerVec :: Vector numServers (Arbiter_IFC numClients) - arbiterByServerVec <- replicateM (mkArbiter False) - - -- statically determinate criteria - let - clientIdx :: Integer = 0 - selectedClient ::(BusClient inFlightTransactions) - selectedClient = (select clientVec clientIdx) - selectedTagEngine = (select tagEngineByClientVec clientIdx) - - addRules |> - rules - "placeholder rule": when True ==> do - let selectedServerArbiter = (select arbiterByServerVec 0) - mapM_ clientRequest selectedServerArbiter.clients - - "connect request client 0": - when True - ==> do - tag <- selectedTagEngine.requestTag - - busRequest :: BusRequest - busRequest <- selectedClient.dequeueRequest tag - - -- let - -- addr = busRequestToAddr busRequest - -- targetServerIdx = addrToServerTranslation addr - -- targetServer = (select serverVec targetServerIdx) - -- targetServerArbiter = (select arbiterByServerVec targetServerIdx) - - -- targetServerArbiter.request - - -- if targetServerArbiter.grant - -- then targetServer.enqueueRequest (tag, busRequest) - -- else action {} - - -- targetServer - action {} - - return $ interface Empty { } +a :: UInt 5 +a = 3 diff --git a/bs/BusTypes.bs b/bs/BusTypes.bs index 818fd3d..99d0fb4 100644 --- a/bs/BusTypes.bs +++ b/bs/BusTypes.bs @@ -1,16 +1,12 @@ package BusTypes( - MkClientTagType, - BusClient(..), BusServer(..), - BusRequest(..), BusResponse(..), - ReadRequest(..), ReadResponse(..), WriteRequest(..), WriteResponse(..), - BusVal(..), BusError(..), TransactionSize(..) + BusVal(..), + BusError(..), + TransactionSize(..), + ReadRequest(..), + WriteRequest(..) ) where import Types -import Vector -import TagEngine - -type MkClientTagType a = (UInt (TLog a)) data BusError = UnMapped @@ -52,47 +48,21 @@ data BusResponse | BusWriteResponse WriteResponse deriving (Bits, Eq, FShow) --- # BusClient.dequeueRequest --- * The Bus arbiter will call the Bus Client's request method if it is --- the Bus Client's turn to make a request, or if another client forfits --- its turn. --- * The BusClient must guard its request method such that calling its --- request method is only valid when the BusClient has a request to make. --- * This has implications about for the implementor of BusClient, --- namely, that it should hold its request until it's request method --- gets called. The arbiter tags the request so that the client can --- later correctly correlate the response. --- * Although the tag is technically passed in as an argument from the --- 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 = - dequeueRequest :: MkTagType inFlightTransactions - -> ActionValue BusRequest - enqueueResponse :: (BusResponse, MkTagType inFlightTransactions) - -> Action +interface BusMaster = + -- The Bus arbiter will call the Bus Master's request method + -- if and only if it's the Bus Master's turn to make a request, and the Bus Master + -- has a request to make. + -- It is up to the BusMaster to guard it's request method such that calling + -- it's request method is only valid when the BusMaster has a request to make. + -- This has implications about for the implementor of BusMaster, namely, that it + -- should hold its request until it's request method gets called. + request :: BusRequest + -- From the masters's perspective, the response should not be called by the + -- arbiter until the master is ready to accept the response. In other words, + -- response should be guarded by the client. + response :: BusResponse -> Action --- # BusServer.dequeueResponse --- * If the arbiter is able to successfully call `dequeueResponse`, then --- the BusServer's internal logic must update such that it understands --- 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 +type Token = UInt 5 + +a :: UInt 5 +a = 3 diff --git a/bs/TagEngine.bs b/bs/TagEngine.bs index 2ddb304..921e58e 100644 --- a/bs/TagEngine.bs +++ b/bs/TagEngine.bs @@ -1,5 +1,4 @@ package TagEngine( - MkTagType, TagEngine(..), Util.BasicResult(..), mkTagEngine) where @@ -10,11 +9,11 @@ import FIFO import FIFOF import SpecialFIFOs -type MkTagType numTags = (UInt (TLog numTags)) +#define UIntLog2N(n) (UInt (TLog n)) interface (TagEngine :: # -> *) numTags = - requestTag :: ActionValue (MkTagType numTags) - retireTag :: (MkTagType numTags) -> Action + requestTag :: ActionValue UIntLog2N(numTags) + retireTag :: UIntLog2N(numTags) -> Action -- The tag engine returns a tag that is unique for the duration of -- the lifetime of the tag. Useful when you need to tag transactions @@ -45,7 +44,7 @@ mkTagEngine = do debugOnce <- mkReg True -- Rules - addRules |> + addRules $ rules "debug_initial_state": when debugOnce ==> do $display "tagUsage: " (fshow (readVReg tagUsage)) @@ -78,9 +77,9 @@ mkTagEngine = do (Nothing, Nothing) -> action {} -- Interface - return |> + return $ interface TagEngine - requestTag :: ActionValue (MkTagType numTags) + requestTag :: ActionValue UIntLog2N(numTags) requestTag = do case initialTagDistributor of Just 0 -> do @@ -101,7 +100,7 @@ mkTagEngine = do -- so it is advisable that the caller of `retireTag` only attempt to retire valid tags. -- Internally, the tagEngine will keep a correct and consistent state since TagEngine -- validates tags before attempting to retire them. - retireTag :: (MkTagType numTags) -> Action + retireTag :: UIntLog2N(numTags) -> Action retireTag tag = do let