Add support for EVEN/ODD PIM configuration

This commit is contained in:
2023-12-16 22:34:11 +01:00
parent aecb19b4f4
commit 2e44890c53
6 changed files with 133 additions and 58 deletions

View File

@@ -5,6 +5,8 @@ use half::f16;
const NUMBER_OF_BANKS: usize = 32;
const ELEMENTS_PER_CACHE_LINE: usize = 16;
const ELEMENTS_PER_BANK_ARRAY: usize = NUMBER_OF_BANKS * ELEMENTS_PER_CACHE_LINE;
const EVEN_BANK_INDEX: usize = 0;
const ODD_BANK_INDEX: usize = 8;
#[derive(Clone, Debug)]
#[repr(C, align(1024))]
@@ -17,88 +19,119 @@ impl Default for BankArray {
}
impl BankArray {
pub fn execute_instruction_read(&self) {
if !cfg!(cacheless) {
self.invalidate_single_bank(0);
pub fn execute_instruction_read_single_bank(&self) {
if !cfg!(feature = "cacheless") {
self.invalidate_bank(EVEN_BANK_INDEX);
barrier::dsb(barrier::SY);
}
self.read_data();
// Read from first bank
self.read_data_bank(EVEN_BANK_INDEX);
barrier::dsb(barrier::SY);
}
pub fn read_data(&self) {
pub fn execute_instruction_read_dual_bank(&self) {
if !cfg!(feature = "cacheless") {
self.invalidate_bank(EVEN_BANK_INDEX);
self.invalidate_bank(ODD_BANK_INDEX);
barrier::dsb(barrier::SY);
}
// Read from first and second bank
self.read_data_bank(EVEN_BANK_INDEX);
self.read_data_bank(ODD_BANK_INDEX);
barrier::dsb(barrier::SY);
}
fn read_data_bank(&self, bank_index: usize) {
let bank = &self.0[bank_index * ELEMENTS_PER_CACHE_LINE];
unsafe {
// Read from first bank
let first_bank = &self.0[0];
core::ptr::read_volatile(first_bank);
core::ptr::read_volatile(bank);
}
}
pub fn execute_instruction_write(&mut self) {
if !cfg!(cacheless) {
pub fn execute_instruction_write_single_bank(&mut self) {
if !cfg!(feature = "cacheless") {
self.preload_zero();
barrier::dsb(barrier::SY);
}
self.write_data();
// Write to first bank
self.write_data_bank(EVEN_BANK_INDEX);
if !cfg!(cacheless) {
self.invalidate_flush_single_bank(0);
if !cfg!(feature = "cacheless") {
self.invalidate_flush_bank(EVEN_BANK_INDEX);
}
barrier::dsb(barrier::SY);
}
pub fn write_data(&mut self) {
pub fn execute_instruction_write_dual_bank(&mut self) {
if !cfg!(feature = "cacheless") {
self.preload_zero();
barrier::dsb(barrier::SY);
}
// Write to first and second bank
self.write_data_bank(EVEN_BANK_INDEX);
self.write_data_bank(ODD_BANK_INDEX);
if !cfg!(feature = "cacheless") {
self.invalidate_flush_bank(EVEN_BANK_INDEX);
self.invalidate_flush_bank(ODD_BANK_INDEX);
}
barrier::dsb(barrier::SY);
}
fn write_data_bank(&mut self, bank_index: usize) {
let bank = &mut self.0[bank_index * ELEMENTS_PER_CACHE_LINE];
unsafe {
// Write to first bank
let first_bank = &mut self.0[0];
core::ptr::write_volatile(first_bank, f16::ZERO);
core::ptr::write_volatile(bank, f16::ZERO);
}
}
pub fn invalidate(&self) {
(0..ELEMENTS_PER_BANK_ARRAY)
.step_by(ELEMENTS_PER_CACHE_LINE)
.for_each(|idx| self.invalidate_single_bank(idx));
(0..NUMBER_OF_BANKS).for_each(|idx| self.invalidate_bank(idx));
}
pub fn invalidate_single_bank(&self, idx: usize) {
fn invalidate_bank(&self, bank_index: usize) {
let bank = &self.0[bank_index * ELEMENTS_PER_CACHE_LINE];
unsafe {
// Invalidate first bank
asm!("dc ivac, {val}", val = in(reg) &self.0[idx]);
asm!("dc ivac, {val}", val = in(reg) bank);
}
}
pub fn invalidate_flush(&self) {
(0..ELEMENTS_PER_BANK_ARRAY)
.step_by(ELEMENTS_PER_CACHE_LINE)
.for_each(|idx| self.invalidate_flush_single_bank(idx));
(0..NUMBER_OF_BANKS).for_each(|idx| self.invalidate_flush_bank(idx));
}
pub fn invalidate_flush_single_bank(&self, idx: usize) {
fn invalidate_flush_bank(&self, bank_index: usize) {
let bank = &self.0[bank_index * ELEMENTS_PER_CACHE_LINE];
unsafe {
// Invalidate and flush first bank
asm!("dc civac, {val}", val = in(reg) &self.0[idx]);
asm!("dc civac, {val}", val = in(reg) bank);
}
}
pub fn preload_zero(&self) {
(0..ELEMENTS_PER_BANK_ARRAY)
.step_by(ELEMENTS_PER_CACHE_LINE)
.for_each(|idx| self.preload_zero_single_bank(idx));
(0..NUMBER_OF_BANKS).for_each(|idx| self.preload_zero_bank(idx));
}
pub fn preload_zero_single_bank(&self, idx: usize) {
fn preload_zero_bank(&self, bank_index: usize) {
let bank = &self.0[bank_index * ELEMENTS_PER_CACHE_LINE];
unsafe {
// Preload first bank
asm!("dc zva, {val}", val = in(reg) &self.0[idx]);
asm!("dc zva, {val}", val = in(reg) bank);
}
}
}
#[derive(Clone, Debug)]
#[repr(C, align(65536))]
pub struct ComputeArray<const N: usize>(pub [BankArray; N]);
impl<const N: usize> ComputeArray<N> {