-
Notifications
You must be signed in to change notification settings - Fork 10
Get: (a_size = 2)
This page deals with the configuration when the operation is a Get
and a_size = 2
which indicates the Host wants to read 4 bytes or a word and expects that data from the device in AccessAckData
response.
For this overview we will consider the following memory organisation which makes it clear what is happening in this operation.
In this configuration the host will read 4 bytes of data and only word aligned addressing is possible i.e a_address
can only be in the following configuration (0, 4, 8, 12, 16, 20, 24 ...). This can also be seen in the diagram above.
In this case a_mask
acts as a don't care. Since a_size = 2
the slave must respond with all 4 bytes d_size = 2
. So the Host will never select any active byte lanes out of the total byte lanes since all will be active (all will be read). So in this scenario we will set mask_chk = 1
by default and only check that the a_address
is valid i.e it is word aligned only.
This is as simple as it gets. We just set a_address
to be 'h8
and a_mask
acts as a don't care.
Following are the points needed to be considered when dealing with reading whole word (Get: a_size = 2
)
-
a_address
should only be word aligned(0, 4, 8, 12, 16, 20, 24 ...)
// Our own mask created using the a_address
// If data bus width (DBW) is 32-bits then 32/8 = 4 bytes so a_mask uses 4 bits to represent the active byte lane.
val mask = Wire(UInt((DBW/8).W))
mask := (1 << a_address(1,0))
// Creating two wires of Chisel.Bool type in order to set them `true.B` if the check is passed or `false.B` if the check is failed.
val addr_chk = Wire(Bool())
val mask_chk = Wire(Bool())
when(a_size === 0.U) { // 1 Byte covered in Get: (a_size = 0)
addr_chk := true.B
mask_chk := ~((a_mask & ~mask).orR)
} .elsewhen(a_size === 1.U) { // 2 Bytes
addr_chk := ~a_address(0)
mask_chk := Mux(a_address(1), ~((a_mask & "b0011".U).orR), ~((a_mask & "b1100".U).orR))
} .elsewhen(a_size === 2.U) { // 4 Bytes
addr_chk := ~(a_address(2,0).orR)
mask_chk := true.B
}
Note: The code above is taken from the previous case where a_size = 1
and was modified to deal with a_size = 2
as well.
Here we simply check for word alignment by checking the first two bits of the a_address
. If both the bits of a_address
are not set it means that the address is word aligned. If any of them is set then the address would not be word aligned.
The logic ~(a_address(2,0).orR)
wired with addr_chk
just validates what is described above. It extracts the first two bits and uses the .orR
reduction to check if any bit is set or not. If any bit is set then .orR
returns true.B
and then the inverter inverts the result as ~true.B
to false.B
which fails the addr_chk
.