-
Notifications
You must be signed in to change notification settings - Fork 10
Arbiter
This page is dedicated for the implementation of a fixed priority arbiter. The host connected with the lowest index port of the Arbiter is given the priority.
class Arbiter(M: Int)(implicit val conf: TLConfiguration) extends Module {
val io = IO(new Bundle {
val req_i = Input(Vec(M, Bool())) // a_valid signals coming from all the hosts
val data_i = Vec(M, Flipped(new TL_H2D)) // Channel A data coming from all the hosts
val gnt_o = Output(Vec(M, Bool())) // The grant output used for indicating the host that the device is ready to accept the request
val valid_o = Output(Bool()) // The valid signal from the host to the device
val data_o = new TL_H2D // The Channel A data of selected host forwarded to the device
val ready_i = Input(Bool()) // The ready signal coming from the device
})
As discussed in the M:1 Socket description where this module is actually used, the Arbiter takes:
-
req_i
input which is a bundle of wires that containa_valid
signals coming from M hosts. -
data_i
input which is bundle of Channel A bundles (TL_H2D) coming from M hosts. -
gnt_o
output which is a bundle of wires connected to M hosts indicating them whether the device is ready to accept their request or not. -
valid_o
output connected with the device which indicates a valid request is being sent from the host. -
data_o
output which is a Channel A bundle of the selected host. -
ready_i
input which is a signal coming in from the device indicating it is ready to accept a request.
// by default setting the arbiter to pass the request of last host
io.data_o <> io.data_i(M-1)
io.valid_o := io.req_i(M-1)
io.gnt_o(M-1) := Mux(io.ready_i, Mux(io.req_i(M-1), true.B, false.B), false.B)
Here we are by default setting up the last host with the output of the Arbiter to be connected with the device. The data_o
is wired with the last host's TL_H2D bundle with data_i(M-1)
. Similarly, the valid_o
of the Arbiter is connected with the valid request of the last host req_i(M-1)
by default and the gnt_o
of the last host gnt_o(M-1)
is connected with the following logic:
Mux(io.ready_i, Mux(io.req_i(M-1), true.B, false.B), false.B)
This first checks if the ready_i
is high indicating that device is ready to accept the request:
If true:
Checks if the valid of last host `req_i(M-1)` is high:
If true:
Sets the `gnt_o` to true
else:
Sets the `gnt_o` to false
else:
It means the device is not ready to accept the request so wire the `gnt_o` with false.
This concludes the default setup of the Arbiter which sets the connections of the last host with the device.
for(i <- M-2 to 0 by -1) {
when(io.req_i(i)) {
io.gnt_o(i) := Mux(io.ready_i, true.B, false.B)
io.data_o := io.data_i(i)
io.valid_o := io.req_i(i)
} .otherwise {
io.gnt_o(i) := false.B
}
}
Then we loop over the remaining hosts M-2
and see if their valid signals coming in to req_i
are high or not:
If true:
Connect the `data_o` of the Arbiter with the `data_i` of that specific host.
Connect the `valid_o` of the Arbiter with the `req_i` of that specific host.
Check whether device is ready to accept the request with `ready_i`:
If true:
Set the `gnt_o` of that specific host to true.
else:
Set the `gnt_o` of that specific host to false.
else:
Set the `gnt_o` of that specific host to false.
So what happens is that let's assume we have 4 hosts: host(0)
, host(1)
, host(2)
and host(3)
. By default the Arbiter connects host(3)
with the device. Then we loop over from host(2)
till host(0)
and see if their valid signals req_i
are high. So if host(2)
has it's valid signal set which means it wants to access the device then the when
block gets executed and we connect the host(2)
with the Arbiter's output and eventually with the device. Next we again loop and assume if host(1)
also wants to send a request to the device and it's req_i
is also high. Again the when
block gets executed and we connect the Arbiter's output with the host(1)
signals. The same process goes on if the host(0)
's valid signal is also high which means in the end when the for loop ends the host with the lowest index is given the highest priority.