#[cfg(feature = "tracing")]
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
pub struct MemoryRecord {
pub shard: u32,
pub timestamp: u32,
pub value: u32,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum MemoryAccessPosition {
Memory = 0,
C = 1,
B = 2,
A = 3,
}
#[allow(clippy::manual_non_exhaustive)]
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Default)]
pub struct MemoryReadRecord {
pub value: u32,
pub shard: u32,
pub timestamp: u32,
pub prev_shard: u32,
pub prev_timestamp: u32,
}
#[allow(clippy::manual_non_exhaustive)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct MemoryWriteRecord {
pub value: u32,
pub shard: u32,
pub timestamp: u32,
pub prev_value: u32,
pub prev_shard: u32,
pub prev_timestamp: u32,
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum MemoryRecordEnum {
Read(MemoryReadRecord),
Write(MemoryWriteRecord),
}
impl MemoryRecordEnum {
#[must_use]
pub fn current_record(&self) -> MemoryRecord {
match self {
MemoryRecordEnum::Read(record) => MemoryRecord {
shard: record.shard,
timestamp: record.timestamp,
value: record.value,
},
MemoryRecordEnum::Write(record) => MemoryRecord {
shard: record.shard,
timestamp: record.timestamp,
value: record.value,
},
}
}
#[must_use]
pub fn previous_record(&self) -> MemoryRecord {
match self {
MemoryRecordEnum::Read(record) => MemoryRecord {
shard: record.prev_shard,
timestamp: record.prev_timestamp,
value: record.value,
},
MemoryRecordEnum::Write(record) => MemoryRecord {
shard: record.prev_shard,
timestamp: record.prev_timestamp,
value: record.prev_value,
},
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryInitializeFinalizeEvent {
pub addr: u32,
pub value: u32,
pub shard: u32,
pub timestamp: u32,
pub used: u32,
}
impl MemoryReadRecord {
#[must_use]
pub const fn new(
value: u32,
shard: u32,
timestamp: u32,
prev_shard: u32,
prev_timestamp: u32,
) -> Self {
assert!(shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)));
Self {
value,
shard,
timestamp,
prev_shard,
prev_timestamp,
}
}
}
impl MemoryWriteRecord {
#[must_use]
pub fn new(
value: u32,
shard: u32,
timestamp: u32,
prev_value: u32,
prev_shard: u32,
prev_timestamp: u32,
) -> Self {
assert!(
shard > prev_shard || ((shard == prev_shard) && (timestamp > prev_timestamp)),
"shard not in prev shard: shard={} prev_shared={} timestamp={} prev_timestamp={}",
shard,
prev_shard,
timestamp,
prev_timestamp
);
Self {
value,
shard,
timestamp,
prev_value,
prev_shard,
prev_timestamp,
}
}
}
impl MemoryRecordEnum {
#[must_use]
pub const fn value(&self) -> u32 {
match self {
MemoryRecordEnum::Read(record) => record.value,
MemoryRecordEnum::Write(record) => record.value,
}
}
}
impl MemoryInitializeFinalizeEvent {
#[must_use]
pub const fn initialize(addr: u32, value: u32, used: bool) -> Self {
Self {
addr,
value,
shard: 1,
timestamp: 1,
used: if used { 1 } else { 0 },
}
}
#[must_use]
pub const fn finalize_from_record(addr: u32, record: &MemoryRecord) -> Self {
Self {
addr,
value: record.value,
shard: record.shard,
timestamp: record.timestamp,
used: 1,
}
}
}
impl From<MemoryReadRecord> for MemoryRecordEnum {
fn from(read_record: MemoryReadRecord) -> Self {
MemoryRecordEnum::Read(read_record)
}
}
impl From<MemoryWriteRecord> for MemoryRecordEnum {
fn from(write_record: MemoryWriteRecord) -> Self {
MemoryRecordEnum::Write(write_record)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryLocalEvent {
pub addr: u32,
pub initial_mem_access: MemoryRecord,
pub final_mem_access: MemoryRecord,
}
#[derive(Debug, Copy, Clone, Default)]
pub struct MemoryAccessRecord {
pub a: Option<MemoryRecordEnum>,
pub b: Option<MemoryRecordEnum>,
pub c: Option<MemoryRecordEnum>,
pub memory: Option<MemoryRecordEnum>,
}