-
Notifications
You must be signed in to change notification settings - Fork 10
Get: (a_size = 0)
This configuration means that the master wants to read a single byte of data. It expects the response AccessAckData
to have d_size = 0
which means d_data
carries an 8-bit data payload.
For this overview we will assume the following memory organisation
Since we are reading a single byte (a_size = 0
) the a_address
can not only have word aligned but subword aligned addressing as well. The a_mask
selects the byte lane to read from. Which means if we want to read from the zeroth byte lane then a_mask = 'b0001
. One HIGH bit of
a_mask
indicates the active byte lane.
Note: When a_size = 0
which means 2a_size = 20 = 1 byte then a_mask
must have only one bit HIGH since we need to read only one byte of data.
a_address[31:0] | a_mask[3:0] |
---|---|
'd0 | 'b0001 |
'd1 | 'b0010 |
'd2 | 'b0100 |
'd3 | 'b1000 |
'd4 | 'b0001 |
'd5 | 'b0010 |
'd6 | 'b0100 |
'd7 | 'b1000 |
. | . |
. | . |
Note: The 'd in above table indicates decimal representation and the 'b indicates binary representation.
So if we want to read the zeroth byte E F
from the above memory we will set a_address = 'd0
and a_mask = 'b0001
.
So if we want to read the second byte F F
from the above memory we will set a_address = 'd6
and a_mask = 'b0100
.
Following are the points needed to be considered when dealing with reading one byte (Get: a_size = 0
)
-
a_address
can be word aligned as well as subword aligned (0, 1, 2, 3, 4, 5, 6, 7, 8 ...) -
a_mask
must have only one bit active at any given time. -
a_mask
must be aligned witha_address
at any given time according to the table given above.
// 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) {
addr_chk := true.B
mask_chk := ~((a_mask & ~mask).orR)
}
Here we created our own mask to check against the a_mask we receive from the Host. In the when
block we are checking for the one byte
condition and we hardwired addr_chk := true.B
as discussed above that address can be word as well as subword aligned so by default we pass the check.
For mask_chk
we have set up a logic which ensures that at a given time only one bit of a_mask is set and is aligned with the address as shown in the table above.
We will go through some test cases to ensure the logic works well and is lucid.
a_address[31:0] | a_size[1:0] | a_mask[3:0] |
---|---|---|
'h0 | 'h0 | 'b0001 |
With these inputs incoming let's analyse what is happening in the wires we declared mask
, addr_chk
, mask_chk
.
mask = (1 << a_address(1,0))
a_address bits are as follows:
a_address[31] | a_address[30] | ... | a_address[1] | a_address[0] |
---|---|---|---|---|
0 | 0 | ... | 0 | 0 |
Since we extract the first two bits of a_address
we get 'b00
So 'b0001 << 'b00
results in the same 'b0001
or 'd1
Which means,
mask := 1.U
Since we have a_size = 0
so our when
block executes and addr_chk
is set to true. So,
addr_chk := true.B
We are using the mask
and a_mask
to set this wire. Currently we have mask := 'b0001
and a_mask := 'b0001
.
In the first step we do a bitwise AND operation between a_mask
and inverted mask
as:
a_mask & ~mask
This results in
'b0001 & 'b1110 = 'b0000
The .orR
is a Chisel function for OR Reduction. Which returns true if any bit is set. Here it checks if any bit is set or not. As seen above there are no bits set so
'b0000.orR
returns false.
Then we invert the result returned from .orR
, ~false.B
which makes mask_chk := true.B
and passes the check.
Which means Input 1 was correct and passes the verification check ✅
Now let's test another input under the same example where we want to read the byte E F
from Memory.
a_address[31:0] | a_size[1:0] | a_mask[3:0] |
---|---|---|
'h0 | 'h0 | 'b0010 |
With these inputs incoming let's analyse what is happening in the wires we declared mask
, addr_chk
, mask_chk
.
mask = (1 << a_address(1,0))
a_address bits are as follows:
a_address[31] | a_address[30] | ... | a_address[1] | a_address[0] |
---|---|---|---|---|
0 | 0 | ... | 0 | 0 |
Since we extract the first two bits of a_address
we get 'b00
So 'b0001 << 'b00
results in the same 'b0001
or 'd1
Which means,
mask := 1.U
Since we have a_size = 0
so our when
block executes and addr_chk
is set to true. So,
addr_chk := true.B
We are using the mask
and a_mask
to set this wire. Currently we have mask := 'b0001
and a_mask := 'b0010
.
In the first step we do a bitwise AND operation between a_mask
and inverted mask
as:
a_mask & ~mask
This results in
'b0010 & 'b1110 = 'b0010
This time the .orR returns true since a bit is set.
'b0010.orR
returns true.
Then we invert the result returned from .orR
, ~true.B
which makes mask_chk := false.B
and fails the check.
This is rightly so, since we are providing the a_address = 0
we need to read the zeroth byte lane not the first byte lane which means the a_mask
must have been 'b0001
instead of b0010
which is incorrect and our logic implementation catches this error and fails the test pass resulting in error being generated.
Which means Input 2 was incorrect and fails in the verification check ❌
a_address[31:0] | a_size[1:0] | a_mask[3:0] |
---|---|---|
'h6 | 'h0 | 'b0100 |
With these inputs incoming let's analyse what is happening in the wires we declared mask
, addr_chk
, mask_chk
.
mask = (1 << a_address(1,0))
a_address bits are as follows:
a_address[31] | a_address[30] | ... | a_address[1] | a_address[0] |
---|---|---|---|---|
0 | 0 | ... | 1 | 0 |
Since we extract the first two bits of a_address
we get 'b10
So 'b0001 << 'b10
results in 'b0100
or 'd4
Which means,
mask := 4.U
Since we have a_size = 0
so our when
block executes and addr_chk
is set to true. So,
addr_chk := true.B
We are using the mask
and a_mask
to set this wire. Currently we have mask := 'b0100
and a_mask := 'b0100
.
In the first step we do a bitwise AND operation between a_mask
and inverted mask
as:
a_mask & ~mask
This results in
'b0100 & 'b1011 = 'b0000
The .orR returns false since no bit is set.
'b0000.orR
returns false.B
Then we invert the result returned from .orR
, ~false.B
which makes mask_chk := true.B
and passes the check.
This test passes correctly as if you see the memory diagram above the byte F F
is at subword address location 'h6
and the a_mask = 'b0100
correctly activates the second byte lane where F F
is present which means there are no errors in the inputs passed.
Which means Input 1 was correct and passes in the verification check ✅
Let's try with another input.
a_address[31:0] | a_size[1:0] | a_mask[3:0] |
---|---|---|
'h6 | 'h0 | 'b1100 |
With these inputs incoming let's analyse what is happening in the wires we declared mask
, addr_chk
, mask_chk
.
mask = (1 << a_address(1,0))
a_address bits are as follows:
a_address[31] | a_address[30] | ... | a_address[1] | a_address[0] |
---|---|---|---|---|
0 | 0 | ... | 1 | 0 |
Since we extract the first two bits of a_address
we get 'b10
So 'b0001 << 'b10
results in 'b0100
or 'd4
Which means,
mask := 4.U
Since we have a_size = 0
so our when
block executes and addr_chk
is set to true. So,
addr_chk := true.B
We are using the mask
and a_mask
to set this wire. Currently we have mask := 'b0100
and a_mask := 'b1100
.
In the first step we do a bitwise AND operation between a_mask
and inverted mask
as:
a_mask & ~mask
This results in
'b1100 & 'b1011 = 'b1000
The .orR returns true since a bit is set.
'b1000.orR
returns true.B
Then we invert the result returned from .orR
, ~true.B
which makes mask_chk := false.B
and fails the check.
The check rightly fails since we have a_size = 0
which means we need to read only one byte of data at any given time and while giving the inputs we set a_mask = 'b1100
which tells to read two bytes lanes and this is not allowed under the provided circumstances, so our logic correctly fails the test.
Which means Input 2 was incorrect and fails in the verification check ❌