-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement kernel ROM in processor
- Loading branch information
Showing
10 changed files
with
256 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
use super::{BTreeMap, Digest, ExecutionError, Felt, Kernel, TraceFragment, Word, ONE, ZERO}; | ||
|
||
// KERNEL ROM | ||
// ================================================================================================ | ||
|
||
/// | ||
pub struct KernelRom { | ||
access_map: BTreeMap<[u8; 32], ProcAccessInfo>, | ||
trace_len: usize, | ||
} | ||
|
||
impl KernelRom { | ||
// CONSTRUCTOR | ||
// -------------------------------------------------------------------------------------------- | ||
/// TODO: add comments | ||
pub fn new(kernel: &Kernel) -> Self { | ||
let mut access_map = BTreeMap::new(); | ||
for &proc_hash in kernel.proc_hashes() { | ||
access_map.insert(proc_hash.into(), ProcAccessInfo::new(proc_hash)); | ||
} | ||
|
||
Self { | ||
access_map, | ||
trace_len: kernel.proc_hashes().len(), | ||
} | ||
} | ||
|
||
// PUBLIC ACCESSORS | ||
// -------------------------------------------------------------------------------------------- | ||
|
||
/// Returns length of execution trace required to describe kernel ROM. | ||
pub fn trace_len(&self) -> usize { | ||
self.trace_len | ||
} | ||
|
||
// STATE MUTATORS | ||
// -------------------------------------------------------------------------------------------- | ||
|
||
/// | ||
pub fn access_proc(&mut self, proc_hash: Digest) -> Result<(), ExecutionError> { | ||
let proc_hash_bytes: [u8; 32] = proc_hash.into(); | ||
let access_info = self | ||
.access_map | ||
.get_mut(&proc_hash_bytes) | ||
.ok_or(ExecutionError::SyscallTargetNotInKernel(proc_hash))?; | ||
// when access count is going from 0 to 1 we don't increment trace length as both 0 and 1 | ||
// accesses require a single row in the trace | ||
if access_info.num_accesses > 0 { | ||
self.trace_len += 1; | ||
} | ||
access_info.num_accesses += 1; | ||
Ok(()) | ||
} | ||
|
||
// EXECUTION TRACE GENERATION | ||
// -------------------------------------------------------------------------------------------- | ||
/// | ||
pub fn fill_trace(self, trace: &mut TraceFragment) { | ||
let mut row = 0; | ||
for (addr, access_info) in self.access_map.values().enumerate() { | ||
let addr = Felt::from(addr as u16); | ||
|
||
// write at least one row into the trace for each kernel procedure | ||
access_info.write_into_trace(trace, row, addr); | ||
row += 1; | ||
|
||
// if the procedure was accessed more than once, we need write a row per additional | ||
// access | ||
for _ in 1..access_info.num_accesses { | ||
access_info.write_into_trace(trace, row, addr); | ||
row += 1; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// PROCEDURE ACCESS INFO | ||
// ================================================================================================ | ||
|
||
struct ProcAccessInfo { | ||
proc_hash: Word, | ||
num_accesses: usize, | ||
} | ||
|
||
impl ProcAccessInfo { | ||
pub fn new(proc_hash: Digest) -> Self { | ||
Self { | ||
proc_hash: proc_hash.into(), | ||
num_accesses: 0, | ||
} | ||
} | ||
|
||
pub fn write_into_trace(&self, trace: &mut TraceFragment, row: usize, addr: Felt) { | ||
let selector = if self.num_accesses == 0 { ZERO } else { ONE }; | ||
trace.set(row, 0, selector); | ||
trace.set(row, 1, addr); | ||
trace.set(row, 2, self.proc_hash[0]); | ||
trace.set(row, 3, self.proc_hash[1]); | ||
trace.set(row, 4, self.proc_hash[2]); | ||
trace.set(row, 5, self.proc_hash[3]); | ||
} | ||
} |
Oops, something went wrong.