PLBExample
OK, here is a PLB example
Marks comments are like this...
SingleThreadRouter(2f)PLBExample/attachments/plb_example.png)
In this example, we have 3 masters talking to one slave via the PLB. This bus fabric provides an address bus, a read data bus and a write data bus which all can be used concurrently. Each PLB transaction splits up into a request phase, a transfer phase, and an acknowledge phase:
SingleThreadRouter(2f)PLBExample/attachments/plb_phases.png)
So, for implementing the PLB with Marks single-threaded router (MASTR) at BA/CC, I guess a transaction object with 2 atoms (address stage, data stage) might be sufficient.
Let's play
- Master 1 creates a read request.
- Address atom
- Quarks are filled with address data
- Address atom
* Atom is also marked BY THE MASTER as requested
- Data atom
- Data quarks are asserted invalid
- Request_1 is stored into the request queue and a requestEvent is fired
the BUS CLASS is used to determine \"when\" the event should wake the router (i.e. when the request can have the bus). First job is to note that it's requested, and that the router wants to \"grant\" access to the bus, so it adds one to \"granters\" IF the bus is free now, then there is no \"event\" generated, it simply sends the transaction to the slave - JOB DONE :-) IF there has to be a delay, then it puts the transaction on the queue, and sets up an event... In both cases, at this point the router would also pass the transaction to the slave, but if it is not marked as granted, the slave would ignore it, as it's a CC slave... so, who cares :-)
- The sleeping router wakes up and pops request_1 from the queue
- Request_1 is parsed and target slave is determined
- Address atom state of request_1 is changed to requested by the router
This would have been done by the master - otherwise the router does nothing. The router changes the state of granted (actually previously the router must set up \"granters\" and then it can say \"granted++\", so that granted == granters i.e. it's granted)
- Router calls the slave's non-blocking IMC, passing the request_1 object, checks whether there are more requests in the queue (answer=no), and puts itself asleep
we like being asleep :-)
- Slave parses the request_1 object, changes address atom state to granted, notices that itself now is in primary address state, and fires requestEvent
I assume the slave is threaded, and requestEvent is in this case an INTERNAL slave event? We should probably call it something like \"slaveWakeUp\" The ROUTER changes granted, the slave just receives the transaction in the non-blocking IMC call. (I think the confusion here is that the slave could ALSO be a \"granter\" for some busses. I dont think it is for PLB, but I could be wrong. If it is, then BOTH router and slave probably need to play with the granters and granted values....
- Router wakes up again in the same clock cycle, checks all requests in the request queue (there actually is only one), and processes our request_1 again
- Data atom state of request_1 is changed to requested by the router
- Router calls the slave's non-blocking IMC, passing the request_1 object, checks whether there are more requests in the queue (answer=no again), and puts itself asleep
dont think these last three steps happen...
- Slave parses request_1, checks its own state, and figures out that it has to wait 2 cycles until it may assert Sl_readAck the first time. However, the slave cannot foresee how long the data transfer will take, thus it can just fire a timed requestEvent for the router to occur in 2 clock cycles and puts itself to sleep.
Furthermore, the slave must either be implemented as a thread, or it must somehow store the current clock cycle so that it will be able to determine the correct clock cycle to continue with processing the data transfer (since it might be called with the same request object from the router again before). Confused here --- the slave has to fire readAck in two cycles, so, for a cycle callable slave, it presumably has a counter (or \"does stuff\" in those 2 cycles. For a threaded slave, (and this example seems to be threaded, -- see assumptions above) it simply calls wait(2)... not sure what the issue is...
- Clock cycle 2: Master 2 places its request_2 onto the bus (non-blocking IMC).
- Request_2 is stored into the request queue and a requestEvent is fired
after arbitration....
- The sleeping router wakes up and pops request_2 from the queue
- Request_2 is parsed and target slave is determined
ish :-)
- Address atom state is changed to requested by the router
see above...
- Router calls the slave's non-blocking IMC, passing the request_2 object, checks whether there are more requests in the queue (yes, there is one more!)
I dont think so. Request one was issued last cycle.... so there is nothing in the queue. Indeed, if the bus is empty, this transaction wont go into the queue. But in this case, the bus is busy (gratedTransaction=request_1)....
- Router checks the request_1 object from the queue and notices that this request object's data atom is in the requested state. How does the router know that it must not take any action for this request? We need a semaphore here.
The next thing to \"happen\" for this transaction will be the slave sending it back to the router when the slave \"does something\" to it (like fills some data in). Anyway, the transaction is currently \"granted\" and, because I've assumed the bus can only grant one thing at a time, we know that WE have granted it, so we dont need to do anything more to this transaction. The ONLY thing we need to do is, once it is finished, (i.e. valid and accepted), we can remove it from the bus (i.e. grantedTransaction=NULL - at which point we pop the transaction queue, and potentially back-to-back grant the next transaction)
- Slave parses the request_2 object, notices that itself is in primary address, changes address atom state to granted, changes own state to secondary address, and fires requestEvent to wake up the router
- Router wakes up again in the same clock cycle, checks all requests in the request queue (there are two), and processes our request again. How does the router know which request is addressed by this event? A gs_event which carries a payload would make things much easier here..
- Data atom state of request_2 is changed to requested by the router
Again, not sure the last 3 things happen for PLB?
- Router calls the slave's non-blocking IMC, passing the request_2 object, checks whether there are more requests in the queue (answer=yes again), finds out again that there is nothing to do for the second request in the queue (request_1), and puts itself asleep
Hmm, have to complete this tomorrow (after receiving the getBackToWorkEvent), and put myself to sleep now...
I'm taking the \"must deliver child to school\" trap, but will return to this high priority thread soon :-)
Posted January 8th, 2008 by MarkBurton