Ensure the MMIO platform issues aligned requests by changing the AXI4_Size field based on the byte enables
This commit is contained in:
@@ -852,7 +852,10 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
// Send a load-request to the fabric adapter.
|
||||
// Align addr to 8-byte boundary (FabricData-aligned)
|
||||
Addr addr1 = { addr [63:3], 3'b_000 };
|
||||
let req = MMIOCRq {addr:addr, func:tagged Ld, byteEn:?, data:?};
|
||||
// Byte enables are used in the AXI adapter to determine the size of the req. Set 8 bits (it
|
||||
// doesn't matter which) to preserve the behaviour of requesting 8 bytes).
|
||||
// TODO: instead specify access size in interface
|
||||
let req = MMIOCRq {addr:addr, func:tagged Ld, byteEn:unpack(16'b0000_0000_1111_1111), data:?};
|
||||
mmio_fabric_adapter_core_side.request.put (req);
|
||||
state <= WaitResp;
|
||||
amoWaitWriteResp <= False;
|
||||
@@ -927,7 +930,10 @@ module mkMMIOPlatform #(Vector#(CoreNum, MMIOCoreToPlatform) cores,
|
||||
// Note: addr may not be FabricData-aligned; result will be Data that contains addr
|
||||
// TODO: currently assumes superscalarity fits in fabric width
|
||||
Addr addr1 = { addr [63:3], 3'b_000 };
|
||||
let req = MMIOCRq {addr:addr1, func: tagged Ld, byteEn: ?, data: ? };
|
||||
// Byte enables are used in the AXI adapter to determine the size of the req. Set 8 bits (it
|
||||
// doesn't matter which) to preserve the behaviour of requesting 8 bytes).
|
||||
// TODO: instead specify access size in interface
|
||||
let req = MMIOCRq {addr:addr1, func: tagged Ld, byteEn: unpack(16'b0000_0000_1111_1111), data: ? };
|
||||
mmio_fabric_adapter_core_side.request.put (req);
|
||||
state <= WaitResp;
|
||||
|
||||
|
||||
@@ -103,6 +103,13 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
Reg #(Bit #(1)) rg_rd_rsp_beat <- mkReg (0);
|
||||
Reg #(MemTaggedData) rspData <- mkReg (unpack(0));
|
||||
|
||||
// ================================================================
|
||||
// Convert a request's byte enables to an AXI 4 size, to ensure that
|
||||
// peripherals don't get confused about how large our access is.
|
||||
function AXI4_Size byteEnToAxiSize (MemDataByteEn byteEn);
|
||||
return toAXI4_Size(zeroExtend(pack(countIf(id, byteEn)))).Valid;
|
||||
endfunction
|
||||
|
||||
rule rl_handle_read_req (f_reqs_from_core.first.func matches Ld
|
||||
&&& (ctr_wr_rsps_pending.value == 0));
|
||||
let req <- pop (f_reqs_from_core);
|
||||
@@ -119,7 +126,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// necessary; the AXI4 fabric should return a DECERR for illegal
|
||||
// addrs; but not all AXI4 fabrics do the right thing.
|
||||
if (soc_map.m_is_IO_addr (req.addr, False)) begin
|
||||
AXI4_Size size = 8;
|
||||
AXI4_Size size = byteEnToAxiSize(req.byteEn);
|
||||
let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_2x3_default_mid,
|
||||
araddr: req.addr,
|
||||
arlen: (burst) ? 1:0, // burst len = arlen+1
|
||||
@@ -211,7 +218,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// on first flit...
|
||||
// ================
|
||||
if (first) begin
|
||||
AXI4_Size size = 8;
|
||||
AXI4_Size size = byteEnToAxiSize(req.byteEn);
|
||||
AXI4_AWFlit #(Wd_MId_2x3, Wd_Addr, Wd_AW_User)
|
||||
mem_req_wr_addr = AXI4_AWFlit {awid: fabric_2x3_default_mid,
|
||||
awaddr: req.addr,
|
||||
|
||||
Reference in New Issue
Block a user