Zero-cycle JUMP
This commit is contained in:
@@ -53,9 +53,9 @@ pub extern "C" fn entry() -> ! {
|
|||||||
barrier::dsb(barrier::SY);
|
barrier::dsb(barrier::SY);
|
||||||
|
|
||||||
pim_state.set_bank_mode(BankMode::PimAllBank);
|
pim_state.set_bank_mode(BankMode::PimAllBank);
|
||||||
compute_array.0[0].execute_instruction_read();
|
|
||||||
compute_array.0[2].execute_instruction_read();
|
|
||||||
compute_array.0[1].execute_instruction_read();
|
compute_array.0[1].execute_instruction_read();
|
||||||
|
compute_array.0[2].execute_instruction_read();
|
||||||
|
compute_array.0[0].execute_instruction_read();
|
||||||
compute_array.0[2].execute_instruction_write();
|
compute_array.0[2].execute_instruction_write();
|
||||||
dummy_array.execute_instruction_read();
|
dummy_array.execute_instruction_read();
|
||||||
pim_state.set_bank_mode(BankMode::SingleBank);
|
pim_state.set_bank_mode(BankMode::SingleBank);
|
||||||
@@ -70,6 +70,8 @@ pub extern "C" fn entry() -> ! {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
writeln!(&mut uart, "ComputeArray:\n{:?}", compute_array).unwrap();
|
||||||
|
|
||||||
m5ops::exit();
|
m5ops::exit();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
|||||||
@@ -7,17 +7,17 @@ pub const TEST_KERNEL: Kernel = Kernel([
|
|||||||
},
|
},
|
||||||
Instruction::MOV {
|
Instruction::MOV {
|
||||||
src: File::Bank,
|
src: File::Bank,
|
||||||
dst: File::GrfA { index: 1 },
|
dst: File::GrfB { index: 0 },
|
||||||
},
|
},
|
||||||
Instruction::MAC {
|
Instruction::MAC {
|
||||||
src0: File::Bank,
|
src0: File::Bank,
|
||||||
src1: File::GrfA { index: 0 },
|
src1: File::GrfA { index: 0 },
|
||||||
src2: File::GrfA { index: 1 },
|
src2: File::GrfB { index: 0 },
|
||||||
dst: File::GrfA { index: 1 },
|
dst: File::GrfB { index: 0 },
|
||||||
aam: false
|
aam: true
|
||||||
},
|
},
|
||||||
Instruction::FILL {
|
Instruction::FILL {
|
||||||
src: File::GrfA { index: 1 },
|
src: File::GrfB { index: 0 },
|
||||||
dst: File::Bank,
|
dst: File::Bank,
|
||||||
},
|
},
|
||||||
Instruction::EXIT,
|
Instruction::EXIT,
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ fn init_logger() {
|
|||||||
env_logger::init();
|
env_logger::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
const COLUMN_BIT_OFFSET: usize = 10;
|
const GRF_A_BIT_OFFSET: usize = 10;
|
||||||
|
const GRF_B_BIT_OFFSET: usize = 13;
|
||||||
const BURST_LENGTH: usize = 32;
|
const BURST_LENGTH: usize = 32;
|
||||||
|
|
||||||
const GRF_NUM_REGISTERS: usize = 8;
|
const GRF_NUM_REGISTERS: usize = 8;
|
||||||
@@ -111,15 +112,35 @@ impl PimVM {
|
|||||||
|
|
||||||
let pim_unit = &mut self.pim_units[bank_index as usize];
|
let pim_unit = &mut self.pim_units[bank_index as usize];
|
||||||
|
|
||||||
let current_pc = pim_unit.pc;
|
let mut inst = self.pim_config.kernel.0[pim_unit.pc as usize];
|
||||||
pim_unit.pc += 1;
|
pim_unit.pc += 1;
|
||||||
|
|
||||||
let inst = self.pim_config.kernel.0[current_pc as usize];
|
let aam_grf_a_index = (address >> GRF_A_BIT_OFFSET) & 0b111;
|
||||||
|
let aam_grf_b_index = (address >> GRF_B_BIT_OFFSET) & 0b111;
|
||||||
|
|
||||||
let aam_grf_a_index = (address >> COLUMN_BIT_OFFSET) & 0b111;
|
log::debug!("PimUnit {bank_index} Execute PC {}: {inst:?}", pim_unit.pc);
|
||||||
let aam_grf_b_index = (address >> COLUMN_BIT_OFFSET + 3) & 0b111;
|
|
||||||
|
|
||||||
log::debug!("PimUnit {bank_index} Execute PC {current_pc}: {inst:?}");
|
// The JUMP instruction is zero-cycle and not actually executed
|
||||||
|
while let Instruction::JUMP { offset, count } = inst {
|
||||||
|
pim_unit.jump_counter = match pim_unit.jump_counter {
|
||||||
|
Some(jump_counter) => jump_counter.checked_sub(1),
|
||||||
|
None => count.checked_sub(1),
|
||||||
|
};
|
||||||
|
|
||||||
|
if pim_unit.jump_counter != None {
|
||||||
|
let new_pc = pim_unit.pc as i32 + offset as i32;
|
||||||
|
|
||||||
|
if new_pc < 0 || new_pc >= 32 {
|
||||||
|
panic!("Invalid PC {new_pc} after JUMP: {inst:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
pim_unit.pc = new_pc as _;
|
||||||
|
log::debug!("PimUnit {bank_index} New PC {new_pc}: {inst:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
inst = self.pim_config.kernel.0[pim_unit.pc as usize];
|
||||||
|
pim_unit.pc += 1;
|
||||||
|
}
|
||||||
|
|
||||||
match inst {
|
match inst {
|
||||||
Instruction::NOP => (),
|
Instruction::NOP => (),
|
||||||
@@ -127,23 +148,7 @@ impl PimVM {
|
|||||||
pim_unit.jump_counter = None;
|
pim_unit.jump_counter = None;
|
||||||
pim_unit.pc = 0;
|
pim_unit.pc = 0;
|
||||||
}
|
}
|
||||||
Instruction::JUMP { offset, count } => {
|
Instruction::JUMP { .. } => unreachable!(),
|
||||||
pim_unit.jump_counter = match pim_unit.jump_counter {
|
|
||||||
Some(jump_counter) => jump_counter.checked_sub(1),
|
|
||||||
None => count.checked_sub(1),
|
|
||||||
};
|
|
||||||
|
|
||||||
if pim_unit.jump_counter != None {
|
|
||||||
let new_pc = current_pc as i32 + offset as i32;
|
|
||||||
|
|
||||||
if new_pc < 0 || new_pc >= 32 {
|
|
||||||
panic!("Invalid PC {new_pc} after JUMP: {inst:?}");
|
|
||||||
}
|
|
||||||
|
|
||||||
pim_unit.pc = new_pc as _;
|
|
||||||
log::debug!("PimUnit {bank_index} New PC {new_pc}: {inst:?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Instruction::MOV { src, dst } | Instruction::FILL { src, dst } => {
|
Instruction::MOV { src, dst } | Instruction::FILL { src, dst } => {
|
||||||
let data = PimVM::load(src, pim_unit, &bank_data);
|
let data = PimVM::load(src, pim_unit, &bank_data);
|
||||||
PimVM::store(dst, pim_unit, &data);
|
PimVM::store(dst, pim_unit, &data);
|
||||||
@@ -284,7 +289,7 @@ impl PimVM {
|
|||||||
.try_into()
|
.try_into()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
log::debug!("{data0:#?}\n{data1:#?}\n{data2:#?}\n{product:#?}\n{sum:#?}");
|
log::debug!("{data0:?}\n{data1:?}\n{data2:?}\n{product:?}\n{sum:?}");
|
||||||
PimVM::store(dst, pim_unit, &sum);
|
PimVM::store(dst, pim_unit, &sum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user