Implement ADD and JUMP instructions
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
use half::f16;
|
||||
use pim_isa::{BankMode, File, Instruction, Kernel, PimConfig};
|
||||
use std::io::Cursor;
|
||||
|
||||
#[cxx::bridge(namespace = "pim_vm")]
|
||||
mod ffi {
|
||||
@@ -28,28 +27,32 @@ fn init_logger() {
|
||||
env_logger::init();
|
||||
}
|
||||
|
||||
const BURST_LENGTH: usize = 32;
|
||||
|
||||
const GRF_NUM_REGISTERS: usize = 16;
|
||||
const SRF_A_NUM_REGISTERS: usize = 8;
|
||||
const SRF_M_NUM_REGISTERS: usize = 8;
|
||||
|
||||
const REG_NUM_ENTRIES: usize = 16;
|
||||
type Register = [f16; REG_NUM_ENTRIES];
|
||||
const FP_UNITS: usize = 16;
|
||||
type GrfRegister = [f16; FP_UNITS];
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct PimUnit {
|
||||
grf: [Register; GRF_NUM_REGISTERS],
|
||||
srf_a: [Register; SRF_A_NUM_REGISTERS],
|
||||
srf_m: [Register; SRF_A_NUM_REGISTERS],
|
||||
grf: [GrfRegister; GRF_NUM_REGISTERS],
|
||||
srf_a: [f16; SRF_A_NUM_REGISTERS],
|
||||
srf_m: [f16; SRF_A_NUM_REGISTERS],
|
||||
pc: u8,
|
||||
jump_counter: Option<u16>,
|
||||
}
|
||||
|
||||
impl Default for PimUnit {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
grf: [[f16::PI; REG_NUM_ENTRIES]; GRF_NUM_REGISTERS],
|
||||
srf_a: [[f16::ZERO; REG_NUM_ENTRIES]; SRF_A_NUM_REGISTERS],
|
||||
srf_m: [[f16::ZERO; REG_NUM_ENTRIES]; SRF_M_NUM_REGISTERS],
|
||||
grf: [[f16::ZERO; FP_UNITS]; GRF_NUM_REGISTERS],
|
||||
srf_a: [f16::ZERO; SRF_A_NUM_REGISTERS],
|
||||
srf_m: [f16::ZERO; SRF_M_NUM_REGISTERS],
|
||||
pc: 0,
|
||||
jump_counter: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +67,7 @@ impl PimVM {
|
||||
fn reset(&mut self) {
|
||||
for unit in self.pim_units.iter_mut() {
|
||||
unit.pc = 0;
|
||||
unit.jump_counter = None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,11 +100,11 @@ fn new_pim_vm(num_pim_units: u32) -> Box<PimVM> {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct BankData([f16; REG_NUM_ENTRIES]);
|
||||
struct BankData([f16; FP_UNITS]);
|
||||
|
||||
impl PimVM {
|
||||
pub fn execute_read(&mut self, bank_index: u32, bank_data: &[u8]) {
|
||||
assert_eq!(bank_data.len(), 32);
|
||||
assert_eq!(bank_data.len(), BURST_LENGTH);
|
||||
|
||||
let pim_unit = &mut self.pim_units[bank_index as usize];
|
||||
|
||||
@@ -113,42 +117,48 @@ impl PimVM {
|
||||
|
||||
match inst {
|
||||
Instruction::NOP => (),
|
||||
Instruction::EXIT => (),
|
||||
Instruction::JUMP { offset, count } => todo!(),
|
||||
Instruction::MOV { src, dst } => {
|
||||
let data: [f16; REG_NUM_ENTRIES] = match src {
|
||||
File::Grf { index } => pim_unit.grf[*index as usize],
|
||||
File::Bank => unsafe {
|
||||
std::ptr::read(bank_data.as_ptr() as *const BankData).0
|
||||
},
|
||||
_ => panic!("Unsupported src operand: {src:?}"),
|
||||
Instruction::EXIT => {
|
||||
pim_unit.jump_counter = None;
|
||||
pim_unit.pc = 0;
|
||||
}
|
||||
Instruction::JUMP { offset, count } => {
|
||||
pim_unit.jump_counter = match pim_unit.jump_counter {
|
||||
Some(jump_counter) => jump_counter.checked_sub(1),
|
||||
None => Some(*count),
|
||||
};
|
||||
|
||||
match dst {
|
||||
File::Grf { index } => pim_unit.grf[*index as usize] = data,
|
||||
File::SrfM { index } => pim_unit.srf_m[*index as usize] = data,
|
||||
File::SrfA { index } => pim_unit.srf_a[*index as usize] = data,
|
||||
_ => panic!("Unsupported dst operand: {dst:?}"),
|
||||
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 _;
|
||||
}
|
||||
}
|
||||
Instruction::FILL { src, dst } => {
|
||||
let data: [f16; REG_NUM_ENTRIES] = match src {
|
||||
File::Grf { index } => pim_unit.grf[*index as usize],
|
||||
File::Bank => unsafe {
|
||||
std::ptr::read(bank_data.as_ptr() as *const BankData).0
|
||||
},
|
||||
_ => panic!("Unsupported src operand: {src:?}"),
|
||||
};
|
||||
Instruction::MOV { src, dst } | Instruction::FILL { src, dst } => {
|
||||
let data = PimVM::load(*src, pim_unit, &bank_data);
|
||||
PimVM::store(*dst, pim_unit, &data);
|
||||
}
|
||||
Instruction::ADD { src0, src1, dst } => {
|
||||
let data0 = PimVM::load(*src0, pim_unit, &bank_data);
|
||||
let data1 = PimVM::load(*src1, pim_unit, &bank_data);
|
||||
|
||||
match dst {
|
||||
File::Grf { index } => pim_unit.grf[*index as usize] = data,
|
||||
_ => panic!("Unsupported dst operand: {dst:?}"),
|
||||
}
|
||||
let sum: [f16; FP_UNITS] = data0
|
||||
.into_iter()
|
||||
.zip(data1)
|
||||
.map(|(src0, src1)| src0 + src1)
|
||||
.collect::<Vec<_>>()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
|
||||
PimVM::store(*dst, pim_unit, &sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_write(&mut self, bank_index: u32) -> [u8; 32] {
|
||||
pub fn execute_write(&mut self, bank_index: u32) -> [u8; BURST_LENGTH] {
|
||||
let pim_unit = &mut self.pim_units[bank_index as usize];
|
||||
|
||||
let current_pc = pim_unit.pc;
|
||||
@@ -160,7 +170,7 @@ impl PimVM {
|
||||
|
||||
let data = match inst {
|
||||
Instruction::FILL { src, dst } => {
|
||||
let data: [f16; REG_NUM_ENTRIES] = match src {
|
||||
let data: [f16; FP_UNITS] = match src {
|
||||
File::Grf { index } => pim_unit.grf[*index as usize],
|
||||
_ => panic!("Unsupported src operand: {src:?}"),
|
||||
};
|
||||
@@ -176,4 +186,22 @@ impl PimVM {
|
||||
|
||||
unsafe { std::mem::transmute(data) }
|
||||
}
|
||||
|
||||
fn load(src: File, pim_unit: &PimUnit, bank_data: &[u8]) -> [f16; FP_UNITS] {
|
||||
match src {
|
||||
File::Grf { index } => pim_unit.grf[index as usize],
|
||||
File::SrfM { index } => [pim_unit.srf_m[index as usize]; FP_UNITS],
|
||||
File::SrfA { index } => [pim_unit.srf_a[index as usize]; FP_UNITS],
|
||||
File::Bank => unsafe { std::ptr::read(bank_data.as_ptr() as *const BankData).0 },
|
||||
}
|
||||
}
|
||||
|
||||
fn store(dst: File, pim_unit: &mut PimUnit, data: &[f16; FP_UNITS]) {
|
||||
match dst {
|
||||
File::Grf { index } => pim_unit.grf[index as usize] = data.clone(),
|
||||
File::SrfM { index } => pim_unit.srf_m[index as usize] = data[0],
|
||||
File::SrfA { index } => pim_unit.srf_a[index as usize] = data[0],
|
||||
File::Bank => panic!("Unsupported dst operand: {dst:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user