diff --git a/difftest/dpi_t1rocketemu/src/dpi.rs b/difftest/dpi_t1rocketemu/src/dpi.rs index 1d8a9c7a7..9c6f40956 100644 --- a/difftest/dpi_t1rocketemu/src/dpi.rs +++ b/difftest/dpi_t1rocketemu/src/dpi.rs @@ -127,7 +127,7 @@ unsafe extern "C" fn axi_read_highBandwidthAXI( assert_eq!(data_width as u32, dlen); assert_eq!(arlen, 0); - let response = driver.axi_read(araddr as u32, arsize as u32, dlen); + let response = driver.axi_read(araddr as u32, arsize as u32, 0, dlen); fill_axi_read_payload(payload, dlen, &response); driver.update_commit_cycle(); @@ -195,7 +195,7 @@ unsafe extern "C" fn axi_read_highOutstandingAXI( assert_eq!(data_width, 32); assert_eq!(arlen, 0); - let response = driver.axi_read(araddr as u32, arsize as u32, 32); + let response = driver.axi_read(araddr as u32, arsize as u32, 0, 32); fill_axi_read_payload(payload, 32, &response); driver.update_commit_cycle(); @@ -269,7 +269,7 @@ unsafe extern "C" fn axi_read_loadStoreAXI( assert_eq!(data_width, 32); assert_eq!(arlen, 0); - let response = driver.axi_read(araddr as u32, arsize as u32, 32); + let response = driver.axi_read(araddr as u32, arsize as u32, 0, 32); fill_axi_read_payload(payload, 8 * 32, &response); driver.update_commit_cycle(); @@ -306,12 +306,12 @@ unsafe extern "C" fn axi_read_instructionFetchAXI( arprot={arprot}, arqos={arqos}, arregion={arregion})" ); TARGET.with(|driver| { - assert_eq!(data_width, 256); - assert_eq!(arlen, 0); + assert_eq!(data_width, 32); + assert_eq!(arlen, 7); assert_eq!(8 * (1 << arsize), data_width); - let response = driver.axi_read(araddr as u32, arsize as u32, 256); + let response = driver.axi_read(araddr as u32, arsize as u32, arlen as u32, 32); fill_axi_read_payload(payload, 256, &response); }); } diff --git a/difftest/dpi_t1rocketemu/src/drive.rs b/difftest/dpi_t1rocketemu/src/drive.rs index 2ed461b86..c42e2e1cc 100644 --- a/difftest/dpi_t1rocketemu/src/drive.rs +++ b/difftest/dpi_t1rocketemu/src/drive.rs @@ -135,9 +135,16 @@ impl Driver { } // data_width: AXI width (count in bits) - // return: Vec with len=bus_size + // return: Vec with len=bus_size*(arlen+1) // if size < bus_size, the result is padded due to AXI narrow transfer rules - pub(crate) fn axi_read(&mut self, addr: u32, arsize: u32, data_width: u32) -> Vec { + // if size < bus_size, arlen must be 0 (narrow burst is NOT supported) + pub(crate) fn axi_read( + &mut self, + addr: u32, + arsize: u32, + arlen: u32, + data_width: u32, + ) -> Vec { let bus_size = data_width / 8; let size = 1 << arsize; @@ -146,13 +153,20 @@ impl Driver { "unaligned read addr={addr:#x} size={size}B dlen={bus_size}B" ); - let mut data = vec![0; bus_size as usize]; + assert!( + !(size < bus_size && arlen > 0), + "narrow burst not supported, axsize={arsize}, axlen={arlen}, data_width={data_width}" + ); + let transaction_size = bus_size * (arlen + 1); + + let mut data = vec![0; transaction_size as usize]; if size < bus_size { + assert_eq!(arlen, 0); let start = (addr % bus_size) as usize; let end = start + (size as usize); self.addr_space.read_mem(addr, size, &mut data[start..end]); } else { - self.addr_space.read_mem(addr, size, &mut data); + self.addr_space.read_mem(addr, transaction_size, &mut data); } data }