Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory Align #148

Draft
wants to merge 24 commits into
base: mem-integration
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 18 additions & 1 deletion core/src/zisk_required_operation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::fmt;

#[derive(Clone)]
pub struct ZiskRequiredOperation {
Expand All @@ -8,7 +9,7 @@ pub struct ZiskRequiredOperation {
pub b: u64,
}

#[derive(Clone, Debug)]
#[derive(Clone)]
pub struct ZiskRequiredMemory {
pub step: u64,
pub is_write: bool,
Expand All @@ -17,6 +18,22 @@ pub struct ZiskRequiredMemory {
pub value: u64,
}

impl fmt::Debug for ZiskRequiredMemory {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let label = if self.is_write { "WR" } else { "RD" };
write!(
f,
"{0} addr:{1:#08X}({1}) with:{2} value:{3:#016X}({3}) step:{4} offset:{5}",
label,
self.address,
self.width,
self.value,
self.step,
self.address & 0x07
)
}
}

#[derive(Clone, Default)]
pub struct ZiskRequired {
pub arith: Vec<ZiskRequiredOperation>,
Expand Down
141 changes: 60 additions & 81 deletions emulator/src/emu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ impl<'a> Emu<'a> {
&mut self,
instruction: &ZiskInst,
emu_mem: &mut Vec<ZiskRequiredMemory>,
is_aligned: bool,
) {
match instruction.a_src {
SRC_C => self.ctx.inst_ctx.a = self.ctx.inst_ctx.c,
Expand All @@ -109,16 +108,14 @@ impl<'a> Emu<'a> {
}
self.ctx.inst_ctx.a = self.ctx.inst_ctx.mem.read(addr, 8);

if is_aligned == Self::is_8_aligned(addr, 8) {
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: false,
address: addr,
width: 8,
value: self.ctx.inst_ctx.a,
};
emu_mem.push(required_memory);
}
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: false,
address: addr,
width: 8,
value: self.ctx.inst_ctx.a,
};
emu_mem.push(required_memory);
}
SRC_IMM => {
self.ctx.inst_ctx.a = instruction.a_offset_imm0 | (instruction.a_use_sp_imm1 << 32)
Expand Down Expand Up @@ -175,7 +172,6 @@ impl<'a> Emu<'a> {
&mut self,
instruction: &ZiskInst,
emu_mem: &mut Vec<ZiskRequiredMemory>,
is_aligned: bool,
) {
match instruction.b_src {
SRC_C => self.ctx.inst_ctx.b = self.ctx.inst_ctx.c,
Expand All @@ -186,16 +182,14 @@ impl<'a> Emu<'a> {
}
self.ctx.inst_ctx.b = self.ctx.inst_ctx.mem.read(addr, 8);

if is_aligned == Self::is_8_aligned(addr, 8) {
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: false,
address: addr,
width: 8,
value: self.ctx.inst_ctx.b,
};
emu_mem.push(required_memory);
}
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: false,
address: addr,
width: 8,
value: self.ctx.inst_ctx.b,
};
emu_mem.push(required_memory);
}
SRC_IMM => {
self.ctx.inst_ctx.b = instruction.b_offset_imm0 | (instruction.b_use_sp_imm1 << 32)
Expand All @@ -207,16 +201,14 @@ impl<'a> Emu<'a> {
addr += self.ctx.inst_ctx.sp;
}
self.ctx.inst_ctx.b = self.ctx.inst_ctx.mem.read(addr, instruction.ind_width);
if is_aligned == Self::is_8_aligned(addr, instruction.ind_width) {
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: false,
address: addr,
width: instruction.ind_width,
value: self.ctx.inst_ctx.b,
};
emu_mem.push(required_memory);
}
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: false,
address: addr,
width: instruction.ind_width,
value: self.ctx.inst_ctx.b,
};
emu_mem.push(required_memory);
}
_ => panic!(
"Emu::source_b() Invalid b_src={} pc={}",
Expand Down Expand Up @@ -274,7 +266,6 @@ impl<'a> Emu<'a> {
&mut self,
instruction: &ZiskInst,
emu_mem: &mut Vec<ZiskRequiredMemory>,
is_aligned: bool,
) {
match instruction.store {
STORE_NONE => {}
Expand All @@ -290,16 +281,14 @@ impl<'a> Emu<'a> {
}
self.ctx.inst_ctx.mem.write_silent(addr as u64, val as u64, 8);

if is_aligned == Self::is_8_aligned(addr as u64, 8) {
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: true,
address: addr as u64,
width: 8,
value: val as u64,
};
emu_mem.push(required_memory);
}
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: true,
address: addr as u64,
width: 8,
value: val as u64,
};
emu_mem.push(required_memory);
}
STORE_IND => {
let val: i64 = if instruction.store_ra {
Expand All @@ -314,16 +303,14 @@ impl<'a> Emu<'a> {
addr += self.ctx.inst_ctx.a as i64;
self.ctx.inst_ctx.mem.write_silent(addr as u64, val as u64, instruction.ind_width);

if is_aligned == Self::is_8_aligned(addr as u64, instruction.ind_width) {
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: true,
address: addr as u64,
width: instruction.ind_width,
value: val as u64,
};
emu_mem.push(required_memory);
}
let required_memory = ZiskRequiredMemory {
step: self.ctx.inst_ctx.step,
is_write: true,
address: addr as u64,
width: instruction.ind_width,
value: val as u64,
};
emu_mem.push(required_memory);
}
_ => panic!(
"Emu::store_c() Invalid store={} pc={}",
Expand Down Expand Up @@ -501,9 +488,9 @@ impl<'a> Emu<'a> {
}

// Log emulation step, if requested
if options.print_step.is_some() &&
(options.print_step.unwrap() != 0) &&
((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0)
if options.print_step.is_some()
&& (options.print_step.unwrap() != 0)
&& ((self.ctx.inst_ctx.step % options.print_step.unwrap()) == 0)
{
println!("step={}", self.ctx.inst_ctx.step);
}
Expand Down Expand Up @@ -615,11 +602,7 @@ impl<'a> Emu<'a> {
(emu_traces, emu_segments)
}

pub fn par_run_memory<F: PrimeField>(
&mut self,
inputs: Vec<u8>,
is_aligned: bool,
) -> Vec<ZiskRequiredMemory> {
pub fn par_run_memory<F: PrimeField>(&mut self, inputs: Vec<u8>) -> Vec<ZiskRequiredMemory> {
// Context, where the state of the execution is stored and modified at every execution step
self.ctx = self.create_emu_context(inputs);

Expand All @@ -629,7 +612,7 @@ impl<'a> Emu<'a> {
let mut emu_mem = Vec::new();

while !self.ctx.inst_ctx.end {
self.par_step_memory::<F>(&mut emu_mem, is_aligned);
self.par_step_memory::<F>(&mut emu_mem);
}

emu_mem
Expand Down Expand Up @@ -706,9 +689,9 @@ impl<'a> Emu<'a> {
// Increment step counter
self.ctx.inst_ctx.step += 1;

if self.ctx.inst_ctx.end ||
((self.ctx.inst_ctx.step - self.ctx.last_callback_step) ==
self.ctx.callback_steps)
if self.ctx.inst_ctx.end
|| ((self.ctx.inst_ctx.step - self.ctx.last_callback_step)
== self.ctx.callback_steps)
{
// In run() we have checked the callback consistency with ctx.do_callback
let callback = callback.as_ref().unwrap();
Expand Down Expand Up @@ -811,27 +794,23 @@ impl<'a> Emu<'a> {
/// Performs one single step of the emulation
#[inline(always)]
#[allow(unused_variables)]
pub fn par_step_memory<F: PrimeField>(
&mut self,
emu_mem: &mut Vec<ZiskRequiredMemory>,
is_aligned: bool,
) {
pub fn par_step_memory<F: PrimeField>(&mut self, emu_mem: &mut Vec<ZiskRequiredMemory>) {
let last_pc = self.ctx.inst_ctx.pc;
let last_c = self.ctx.inst_ctx.c;

let instruction = self.rom.get_instruction(self.ctx.inst_ctx.pc);

// Build the 'a' register value based on the source specified by the current instruction
self.source_a_memory(instruction, emu_mem, is_aligned);
self.source_a_memory(instruction, emu_mem);

// Build the 'b' register value based on the source specified by the current instruction
self.source_b_memory(instruction, emu_mem, is_aligned);
self.source_b_memory(instruction, emu_mem);

// Call the operation
(instruction.func)(&mut self.ctx.inst_ctx);

// Store the 'c' register value based on the storage specified by the current instruction
self.store_c_memory(instruction, emu_mem, is_aligned);
self.store_c_memory(instruction, emu_mem);

// Set SP, if specified by the current instruction
// #[cfg(feature = "sp")]
Expand Down Expand Up @@ -924,11 +903,11 @@ impl<'a> Emu<'a> {

let mut current_box_id = 0;
let mut current_step_idx = loop {
if current_box_id == vec_traces.len() - 1 ||
vec_traces[current_box_id + 1].start_state.step >= emu_trace_start.step
if current_box_id == vec_traces.len() - 1
|| vec_traces[current_box_id + 1].start_state.step >= emu_trace_start.step
{
break emu_trace_start.step as usize -
vec_traces[current_box_id].start_state.step as usize;
break emu_trace_start.step as usize
- vec_traces[current_box_id].start_state.step as usize;
}
current_box_id += 1;
};
Expand Down Expand Up @@ -1039,8 +1018,8 @@ impl<'a> Emu<'a> {
let b = [inst_ctx.b & 0xFFFFFFFF, (inst_ctx.b >> 32) & 0xFFFFFFFF];
let c = [inst_ctx.c & 0xFFFFFFFF, (inst_ctx.c >> 32) & 0xFFFFFFFF];

let addr1 = (inst.b_offset_imm0 as i64 +
if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64;
let addr1 = (inst.b_offset_imm0 as i64
+ if inst.b_src == SRC_IND { inst_ctx.a as i64 } else { 0 }) as u64;

let jmp_offset1 = if inst.jmp_offset1 >= 0 {
F::from_canonical_u64(inst.jmp_offset1 as u64)
Expand Down Expand Up @@ -1118,8 +1097,8 @@ impl<'a> Emu<'a> {
m32: F::from_bool(inst.m32),
addr1: F::from_canonical_u64(addr1),
__debug_operation_bus_enabled: F::from_bool(
inst.op_type == ZiskOperationType::Binary ||
inst.op_type == ZiskOperationType::BinaryE,
inst.op_type == ZiskOperationType::Binary
|| inst.op_type == ZiskOperationType::BinaryE,
),
}
}
Expand Down
23 changes: 8 additions & 15 deletions emulator/src/emulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,22 +246,15 @@ impl ZiskEmulator {
pub fn par_process_rom_memory<F: PrimeField>(
rom: &ZiskRom,
inputs: &[u8],
) -> Result<[Vec<ZiskRequiredMemory>; 2], ZiskEmulatorErr> {
let mut result: [Vec<ZiskRequiredMemory>; 2] = [Vec::new(), Vec::new()];

result.par_iter_mut().enumerate().for_each(|(is_aligned, result)| {
let is_aligned = is_aligned == 0;
let mut emu = Emu::new(rom);
let required = emu.par_run_memory::<F>(inputs.to_owned(), is_aligned);

if !emu.terminated() {
panic!("Emulation did not complete");
// TODO!
// return Err(ZiskEmulatorErr::EmulationNoCompleted);
}
) -> Result<Vec<ZiskRequiredMemory>, ZiskEmulatorErr> {
let mut emu = Emu::new(rom);
let result = emu.par_run_memory::<F>(inputs.to_owned());

*result = required;
});
if !emu.terminated() {
panic!("Emulation did not complete");
// TODO!
// return Err(ZiskEmulatorErr::EmulationNoCompleted);
}

Ok(result)
}
Expand Down
6 changes: 3 additions & 3 deletions pil/src/pil_helpers/pilout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Manual modifications are not recommended and may be overwritten.
use proofman_common::WitnessPilout;

pub const PILOUT_HASH: &[u8] = b"ZiskMem-hash";
pub const PILOUT_HASH: &[u8] = b"Zisk-hash";

//AIRGROUP CONSTANTS

Expand Down Expand Up @@ -36,7 +36,7 @@ pub struct Pilout;

impl Pilout {
pub fn pilout() -> WitnessPilout {
let mut pilout = WitnessPilout::new("ZiskMem", 2, PILOUT_HASH.to_vec());
let mut pilout = WitnessPilout::new("Zisk", 2, PILOUT_HASH.to_vec());

let air_group = pilout.add_air_group(Some("Zisk"));

Expand All @@ -54,4 +54,4 @@ impl Pilout {

pilout
}
}
}
4 changes: 3 additions & 1 deletion pil/src/pil_helpers/traces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ trace!(SpecifiedRangesRow, SpecifiedRangesTrace<F> {

trace!(U8AirRow, U8AirTrace<F> {
mul: F,
});
});


2 changes: 1 addition & 1 deletion state-machines/main/pil/main.pil
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ airtemplate Main(int N = 2**21, int RC = 2, int stack_enabled = 0, const int ope
col witness air.b_imm1;
}
col witness b_src_ind;
col witness ind_width; // 8 , 4, 2, 1
col witness ind_width; // 8, 4, 2, 1

// Operations related

Expand Down
Loading