diff --git a/src_Core/CPU/MMIOPlatform.bsv b/src_Core/CPU/MMIOPlatform.bsv index 7802054..a3450fb 100644 --- a/src_Core/CPU/MMIOPlatform.bsv +++ b/src_Core/CPU/MMIOPlatform.bsv @@ -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; diff --git a/src_Core/CPU/MMIO_AXI4_Adapter.bsv b/src_Core/CPU/MMIO_AXI4_Adapter.bsv index e33dc51..113d86f 100644 --- a/src_Core/CPU/MMIO_AXI4_Adapter.bsv +++ b/src_Core/CPU/MMIO_AXI4_Adapter.bsv @@ -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,