Skip to content

Commit

Permalink
Add TCDM alias feature
Browse files Browse the repository at this point in the history
  • Loading branch information
paulsc96 committed Nov 23, 2023
1 parent 2be5628 commit f17947f
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ pub struct Memories {
pub tcdm: Memory,
pub dram: Memory,
pub periphs: MemoryCallback,
pub tcdm_alias: bool,
pub tcdm_alias_start: u32,
}

impl Default for Memories {
Expand All @@ -140,6 +142,8 @@ impl Default for Memories {
latency: 2,
callbacks: vec![],
},
tcdm_alias: false,
tcdm_alias_start: 0,
}
}
}
Expand Down
39 changes: 39 additions & 0 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,23 @@ impl<'a, 'b> Cpu<'a, 'b> {
} // cluster_base_hartid
x if x == self.engine.config.address.cluster_num => self.engine.num_clusters as u32, // cluster_num
x if x == self.engine.config.address.cluster_id => self.cluster_id as u32, // cluster_id
// TCDM alias
x if (self.engine.config.memory.tcdm_alias
&& x >= self.engine.config.memory.tcdm_alias_start
&& x < (self.engine.config.memory.tcdm_alias_start
+ self.engine.config.memory.tcdm.size)) =>
{
debug!("TCDM Alias Binary Load");
debug!("Binary load address: 0x{:x}", x);
let tcdm_addr = addr
- (self.engine.config.memory.tcdm.start
+ self.engine.config.memory.tcdm.offset * self.cluster_id as u32);
let word_addr = tcdm_addr / 4;
let word_offs = tcdm_addr - 4 * word_addr;
let ptr: *const u32 = self.tcdm_ptr[self.cluster_id];
let word = unsafe { *ptr.offset(word_addr as isize) };
(word >> (8 * word_offs)) & ((((1 as u64) << (8 << size)) - 1) as u32)
}
// TCDM
x if (0..self.engine.num_clusters).any(|i| {
x >= (self.engine.config.memory.tcdm.start
Expand Down Expand Up @@ -887,6 +904,28 @@ impl<'a, 'b> Cpu<'a, 'b> {
buffer.push(value as u8);
}
}
// TCDM alias
x if (self.engine.config.memory.tcdm_alias
&& x >= self.engine.config.memory.tcdm_alias_start
&& x < (self.engine.config.memory.tcdm_alias_start
+ self.engine.config.memory.tcdm.size)) =>
{
debug!("TCDM Alias Binary Store");
debug!("Binary store address: 0x{:x}", x);
let tcdm_addr = addr
- (self.engine.config.memory.tcdm.start
+ self.engine.config.memory.tcdm.offset * self.cluster_id as u32);
let word_addr = tcdm_addr / 4;
let word_offs = tcdm_addr - 4 * word_addr;
let ptr = self.tcdm_ptr[self.cluster_id] as *const u32;
let ptr_mut = ptr as *mut u32;
let wmask = ((((1 as u64) << (8 << size)) - 1) as u32) << (8 * word_offs);
unsafe {
let word_ptr = ptr_mut.offset(word_addr as isize);
let word = *word_ptr;
*word_ptr = (word & !wmask) | ((value << (8 * word_offs)) & wmask);
}
}
// TCDM
// TODO: this is *not* thread-safe and *will* lead to undefined behavior on simultaneous access
// by 2 harts. However, changing `tcdm_ptr` to a locked structure would require pervasive redesign.
Expand Down
49 changes: 32 additions & 17 deletions src/tran.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ pub struct ElfTranslator<'a> {
pub tcdm_start: u32,
/// End address of the fast local scratchpad.
pub tcdm_end: u32,
/// Whether a fast local scratchpad alias exists.
pub tcdm_alias: bool,
/// Start address of the fast local scratchpad alias.
pub tcdm_alias_start: u32,
/// End address of the fast local scratchpad alias.
pub tcdm_alias_end: u32,
/// External TCDM range (Cluster id, start, end)
pub tcdm_range: Vec<(u32, u32, u32)>,
/// Cluster ID
Expand Down Expand Up @@ -229,6 +235,10 @@ impl<'a> ElfTranslator<'a> {
tcdm_end: engine.config.memory.tcdm.start
+ engine.config.memory.tcdm.offset * cluster_id as u32
+ engine.config.memory.tcdm.size,

Check warning on line 237 in src/tran.rs

View workflow job for this annotation

GitHub Actions / Format

Diff in /home/runner/work/banshee/banshee/src/tran.rs
tcdm_alias: engine.config.memory.tcdm_alias,
tcdm_alias_start: engine.config.memory.tcdm_alias_start,
tcdm_alias_end: engine.config.memory.tcdm_alias_start
+ engine.config.memory.tcdm.size,
tcdm_range,
cluster_id,
}
Expand Down Expand Up @@ -1107,9 +1117,9 @@ impl<'a> InstructionTranslator<'a> {
let mut values: Vec<LLVMValueRef> = Vec::with_capacity(phi_size);
let mut bbs: Vec<LLVMBasicBlockRef> = Vec::with_capacity(phi_size);

// Check if the address is in the TCDM, and emit a fast access.
// Check if the address is in the TCDM alias range, and emit a fast access.
LLVMPositionBuilderAtEnd(self.builder, bb_valid);
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_check(addr);
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_alias_check(addr);
let mut bb_yes = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
let mut bb_no = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
LLVMInsertExistingBasicBlockAfterInsertBlock(self.builder, bb_yes);
Expand Down Expand Up @@ -1249,7 +1259,7 @@ impl<'a> InstructionTranslator<'a> {

// Check if the address is in the TCDM, and emit a fast access.
LLVMPositionBuilderAtEnd(self.builder, bb_valid);
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_check(addr);
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_alias_check(addr);
let mut bb_yes = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
let mut bb_no = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
LLVMInsertExistingBasicBlockAfterInsertBlock(self.builder, bb_yes);
Expand Down Expand Up @@ -6222,7 +6232,7 @@ impl<'a> InstructionTranslator<'a> {

let latency = if let Some(access) = mem_access {
// Check config
let (is_tcdm, _tcdm_ptr) = self.emit_tcdm_check(access.1);
let (is_tcdm, _tcdm_ptr) = self.emit_tcdm_alias_check(access.1);
LLVMBuildSelect(
self.builder,
is_tcdm,
Expand Down Expand Up @@ -6401,7 +6411,7 @@ impl<'a> InstructionTranslator<'a> {
let mut bbs: Vec<LLVMBasicBlockRef> = Vec::with_capacity(phi_size);

// Check if the address is in the TCDM, and emit a fast access.
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_check(aligned_addr);
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_alias_check(aligned_addr);
let mut bb_yes = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
let mut bb_no = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
LLVMInsertExistingBasicBlockAfterInsertBlock(self.builder, bb_yes);
Expand Down Expand Up @@ -6514,7 +6524,7 @@ impl<'a> InstructionTranslator<'a> {
LLVMInsertExistingBasicBlockAfterInsertBlock(self.builder, bb_end);

// Check if the address is in the TCDM, and emit a fast access.
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_check(addr);
let (is_tcdm, tcdm_ptr) = self.emit_tcdm_alias_check(addr);
let mut bb_yes = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
let mut bb_no = LLVMCreateBasicBlockInContext(self.section.engine.context, NONAME);
LLVMInsertExistingBasicBlockAfterInsertBlock(self.builder, bb_yes);
Expand Down Expand Up @@ -6618,19 +6628,25 @@ impl<'a> InstructionTranslator<'a> {
LLVMPositionBuilderAtEnd(self.builder, bb_end);
}

/// Emit the code to check if an address is within the TCDM.
/// Emit the code to check if an address is within the TCDM alias if it exists.
///
/// Returns an `i1` indicating whether it is as first result, and a pointer
/// to that location in the TCDM.
unsafe fn emit_tcdm_check(&self, addr: LLVMValueRef) -> (LLVMValueRef, LLVMValueRef) {
let tcdm_start = LLVMConstInt(LLVMInt32Type(), self.section.elf.tcdm_start as u64, 0);
// let tcdm_end = LLVMConstInt(LLVMInt32Type(), self.section.elf.tcdm_end as u64, 0);
// let mut in_range = LLVMBuildAnd(
// self.builder,
// LLVMBuildICmp(self.builder, LLVMIntUGE, addr, tcdm_start, NONAME),
// LLVMBuildICmp(self.builder, LLVMIntULT, addr, tcdm_end, NONAME),
// NONAME,
// );
unsafe fn emit_tcdm_alias_check(&self, addr: LLVMValueRef) -> (LLVMValueRef, LLVMValueRef) {
if !self.section.elf.tcdm_alias {
// No TCDM alias defined: return static false
let in_range = LLVMConstInt(LLVMInt1Type(), 0, 0);
let ptr = LLVMConstInt(LLVMInt32Type(), 0, 0);
(in_range, ptr)

Check failure on line 6640 in src/tran.rs

View workflow job for this annotation

GitHub Actions / Banshee (1.63.0)

mismatched types
}
let tcdm_start = LLVMConstInt(LLVMInt32Type(), self.section.elf.tcdm_alias_start as u64, 0);
let tcdm_end = LLVMConstInt(LLVMInt32Type(), self.section.elf.tcdm_alias_end as u64, 0);
let in_range = LLVMBuildAnd(
self.builder,
LLVMBuildICmp(self.builder, LLVMIntUGE, addr, tcdm_start, NONAME),
LLVMBuildICmp(self.builder, LLVMIntULT, addr, tcdm_end, NONAME),
NONAME,
);
let index = LLVMBuildSub(self.builder, addr, tcdm_start, NONAME);
let pty32 = LLVMPointerType(LLVMInt32Type(), 0);
let pty8 = LLVMPointerType(LLVMInt8Type(), 0);
Expand All @@ -6642,7 +6658,6 @@ impl<'a> InstructionTranslator<'a> {
b"ptr_tcdm\0".as_ptr() as *const _,
);
let ptr = LLVMBuildBitCast(self.builder, ptr, pty32, NONAME);
let in_range = LLVMConstInt(LLVMInt1Type(), 0, 0);
(in_range, ptr)
}

Expand Down

0 comments on commit f17947f

Please sign in to comment.