add TraceAsString around instructions and stuff to make the .vcd files much smaller and easier to read
All checks were successful
/ test (pull_request) Successful in 5m44s

This commit is contained in:
Jacob Lifshay 2026-05-13 23:34:24 -07:00
parent 8bee576a2a
commit 0d3c41fa14
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
4 changed files with 35839 additions and 1340471 deletions

View file

@ -56,7 +56,7 @@ pub struct MOpInstance<MOp> {
/// it needs to be canceled along with all other &micro;Ops that
/// come from the same ISA-level instruction.
pub is_last_mop_in_insn: Bool,
pub mop: MOp,
pub mop: TraceAsString<MOp>,
}
impl<MOp: Type> SimValueDebug for MOpInstance<MOp> {
@ -139,14 +139,14 @@ pub struct UnitEnqueue<C: PhantomConstGet<CpuConfig>> {
pub struct UnitInputsReady<C: PhantomConstGet<CpuConfig>> {
/// the whole `MOpInstance` is sent again so Units can just ignore all [`UnitEnqueue`] messages if desired.
pub mop: MOpInstance<RenamedMOp<C>>,
pub src_values: Array<PRegValue, { COMMON_MOP_SRC_LEN }>,
pub src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>,
pub config: C,
}
#[hdl(no_static)]
pub struct UnitOutputReady<C: PhantomConstGet<CpuConfig>> {
pub id: MOpId,
pub dest_value: PRegValue,
pub dest_value: TraceAsString<PRegValue>,
pub predictor_op: NextPcPredictorOp<C>,
}
@ -273,13 +273,13 @@ type MOpRegCount<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(no_static)]
struct RenameTableDebugState<C: PhantomConstGet<CpuConfig>> {
entries: ArrayType<RenameTableEntry<C>, MOpRegCount<C>>,
entries: ArrayType<TraceAsString<RenameTableEntry<C>>, MOpRegCount<C>>,
config: C,
}
#[derive(Debug)]
struct RenameTable<C: PhantomConstCpuConfig> {
entries: Box<[SimValue<RenameTableEntry<C>>; 1 << MOpRegNum::WIDTH]>,
entries: Box<[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH]>,
config: C,
}
@ -301,7 +301,7 @@ impl<C: PhantomConstCpuConfig> Clone for RenameTable<C> {
enum RenameTableUpdate<C: PhantomConstCpuConfig> {
Write {
unrenamed_reg_num: u32,
new: SimValue<RenameTableEntry<C>>,
new: SimValue<TraceAsString<RenameTableEntry<C>>>,
},
UpdateForReadL2Reg {
dest: SimValue<PRegNum<C>>,
@ -315,10 +315,13 @@ enum RenameTableUpdate<C: PhantomConstCpuConfig> {
impl<C: PhantomConstCpuConfig> RenameTable<C> {
fn new(config: C) -> Self {
let entries: Box<[SimValue<RenameTableEntry<C>>; 1 << MOpRegNum::WIDTH]> =
vec![RenameTableEntry[config].const_zero(); 1 << MOpRegNum::WIDTH]
.try_into()
.expect("size is known to match");
let entries: Box<[SimValue<TraceAsString<RenameTableEntry<C>>>; 1 << MOpRegNum::WIDTH]> =
vec![
RenameTableEntry[config].const_zero().into_trace_as_string();
1 << MOpRegNum::WIDTH
]
.try_into()
.expect("size is known to match");
Self { entries, config }
}
#[hdl]
@ -350,7 +353,7 @@ impl<C: PhantomConstCpuConfig> RenameTable<C> {
(RenameTableEntry[self.config]).L1(dest);
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
#[hdl(sim)]
match &entry {
match entry.inner() {
RenameTableEntry::<_>::L1(_) => {}
RenameTableEntry::<_>::L2(l2) => {
if L2RegNum::value_sim(l2) == L2RegNum::value_sim(src) {
@ -358,7 +361,7 @@ impl<C: PhantomConstCpuConfig> RenameTable<C> {
"{rename_table_name}: UpdateForReadL2Reg: {unrenamed_reg_num:#x} \
updating from {entry:?} to {new:?}",
);
*entry = new.clone();
*entry = new.to_trace_as_string();
}
}
}
@ -369,14 +372,14 @@ impl<C: PhantomConstCpuConfig> RenameTable<C> {
(RenameTableEntry[self.config]).L2(dest);
for (unrenamed_reg_num, entry) in self.entries.iter_mut().enumerate() {
#[hdl(sim)]
match &entry {
match entry.inner() {
RenameTableEntry::<_>::L1(l1) => {
if l1 == src {
println!(
"{rename_table_name}: UpdateForWriteL2Reg: {unrenamed_reg_num:#x} \
updating from {entry:?} to {new:?}",
);
*entry = new.clone();
*entry = new.to_trace_as_string();
}
}
RenameTableEntry::<_>::L2(_) => {}
@ -390,7 +393,7 @@ impl<C: PhantomConstCpuConfig> RenameTable<C> {
let mut seen = BTreeSet::new();
for entry in self.entries.iter() {
#[hdl(sim)]
match entry {
match entry.inner() {
RenameTableEntry::<_>::L1(v) => {
if UnitNum::index_sim(&v.unit_num) == Some(unit_index) {
seen.insert(UnitOutRegNum::value_sim(&v.unit_out_reg));
@ -649,7 +652,7 @@ impl<C: PhantomConstCpuConfig> RobEntry<C> {
}
}
fn dest_reg(&self) -> Option<&SimValue<PRegNum<C>>> {
let dest_reg = MOpTrait::dest_reg_sim_ref(&self.mop.mop);
let dest_reg = MOpTrait::dest_reg_sim_ref(self.mop.mop.inner());
let unit_index = UnitNum::index_sim(&dest_reg.unit_num)?;
assert_eq!(unit_index, self.unit_index);
Some(dest_reg)
@ -1035,7 +1038,7 @@ pub struct RenameExecuteRetireDebugState<C: PhantomConstGet<CpuConfig>> {
next_pc_canceling: HdlOption<NextPcCancelingDebugState>,
unit_canceling: ArrayType<Bool, CpuConfigUnitCount<C>>,
l1_reg_file: ArrayType<
ArrayType<HdlOption<PRegValue>, CpuConfig2PowOutRegNumWidth<C>>,
ArrayType<HdlOption<TraceAsString<PRegValue>>, CpuConfig2PowOutRegNumWidth<C>>,
CpuConfigUnitCount<C>,
>,
lfsr: LFSR31,
@ -1050,7 +1053,7 @@ struct RenameExecuteRetireState<C: PhantomConstCpuConfig> {
rob: ReorderBuffer<C>,
next_pc_canceling: Option<NextPcCancelingState>,
unit_canceling: Box<[bool]>,
l1_reg_file: Box<[Box<[Option<SimValue<PRegValue>>]>]>,
l1_reg_file: Box<[Box<[Option<SimValue<TraceAsString<PRegValue>>>]>]>,
lfsr: SimValue<LFSR31>,
l2_reg_file_unit_index: usize,
config: C,
@ -1227,7 +1230,7 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
{
allocated_regs[unit_out_reg_index] = true;
}
MOpTrait::for_each_src_reg_sim_ref(&renamed.mop.mop, &mut |src_reg, _index| {
MOpTrait::for_each_src_reg_sim_ref(renamed.mop.mop.inner(), &mut |src_reg, _index| {
#[hdl(sim)]
let PRegNum::<_> {
unit_num,
@ -1245,7 +1248,7 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
.chain(self.retire_rename_table.entries.iter())
{
#[hdl(sim)]
match entry {
match entry.inner() {
RenameTableEntry::<_>::L1(entry) => {
if Some(unit_index) == UnitNum::index_sim(&entry.unit_num) {
allocated_regs[UnitOutRegNum::value_sim(&entry.unit_out_reg)] = true;
@ -1262,7 +1265,7 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
let mut allocated_regs = vec![false; L2RegNum.l2_reg_count()];
for renamed in self.rob.renamed() {
#[hdl(sim)]
if let RenamedMOp::<_>::TransformedMove(l2_register_file_op) = &renamed.mop.mop {
if let RenamedMOp::<_>::TransformedMove(l2_register_file_op) = renamed.mop.mop.inner() {
let l2_reg = #[hdl(sim)]
match l2_register_file_op {
L2RegisterFileMOp::<_, _>::ReadL2Reg(v) => &v.common.imm,
@ -1278,7 +1281,7 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
.chain(self.retire_rename_table.entries.iter())
{
#[hdl(sim)]
match entry {
match entry.inner() {
RenameTableEntry::<_>::L1(_) => {}
RenameTableEntry::<_>::L2(entry) => {
allocated_regs[L2RegNum::value_sim(entry)] = true;
@ -1337,9 +1340,9 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
},
);
}
let unit_kind = UnitMOp::kind_sim(&insn.mop);
let unit_kind = UnitMOp::kind_sim(insn.mop.inner());
#[hdl(sim)]
if let MOp::TransformedMove(move_reg_mop) = &insn.mop {
if let MOp::TransformedMove(move_reg_mop) = insn.mop.inner() {
let mut src_regs = [MOpRegNum::const_zero_sim()];
MOpTrait::for_each_src_reg_sim_ref(move_reg_mop, &mut |src_reg, index| {
src_regs[index] = src_reg.clone();
@ -1468,14 +1471,14 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
};
println!("try_rename: picked {reg_to_free:?}");
let mut any_collisions = false;
MOpTrait::for_each_src_reg_sim_ref(&insn.mop, &mut |src_reg, _| {
MOpTrait::for_each_src_reg_sim_ref(insn.mop.inner(), &mut |src_reg, _| {
let renamed =
&self.rename_table.entries[MOpRegNum::reg_num_sim(&src_reg) as usize];
println!(
"try_rename: checking that mop src reg ({renamed:?}) doesn't conflict with picked reg"
);
#[hdl(sim)]
match renamed {
match renamed.inner() {
RenameTableEntry::<_>::L1(v) => {
if reg_to_free == *v {
any_collisions = true;
@ -1520,7 +1523,8 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
PRegNum[self.config].const_zero(),
repeat(&reg_to_free, ConstUsize::<1>),
dest,
),
)
.into_trace_as_string(),
},
self.l2_reg_file_unit_index,
),
@ -1561,21 +1565,21 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
mop,
} = &insn;
let mut needed_load = None;
let unrenamed_dest_regs = MOpDestReg::regs_sim(MOpTrait::dest_reg_sim_ref(mop));
let unrenamed_dest_regs = MOpDestReg::regs_sim(MOpTrait::dest_reg_sim_ref(mop.inner()));
let renamed_dest_reg = #[hdl(sim)]
PRegNum::<_> {
unit_num: UnitNum[self.config].from_index_sim(unit_index),
unit_out_reg: out_reg_num_sim,
};
let mop = MOpTrait::map_regs_sim(
mop,
mop.inner(),
&renamed_dest_reg,
PRegNum[self.config],
&mut |src_reg, index| {
let renamed = &self.rename_table.entries[MOpRegNum::reg_num_sim(&src_reg) as usize];
println!("renaming src[{index}] from {src_reg:?} to {renamed:?}");
#[hdl(sim)]
match renamed {
match renamed.inner() {
RenameTableEntry::<_>::L1(v) => v.clone(),
RenameTableEntry::<_>::L2(v) => {
needed_load.get_or_insert_with(|| v.clone());
@ -1616,7 +1620,8 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
dest,
repeat(PRegNum[self.config].const_zero_sim(), ConstUsize),
needed_load,
),
)
.into_trace_as_string(),
},
self.l2_reg_file_unit_index,
),
@ -1644,7 +1649,8 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
mop,
RenamedMOp[self.config].TransformedMove,
|_move_reg| unreachable!(),
);
)
.into_trace_as_string();
let renamed_dest_reg = #[hdl(sim)]
(RenameTableEntry[self.config]).L1(renamed_dest_reg);
for unrenamed_reg_num in unrenamed_dest_regs {
@ -1652,7 +1658,7 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
&insn,
RenameTableUpdate::Write {
unrenamed_reg_num,
new: renamed_dest_reg.clone(),
new: renamed_dest_reg.to_trace_as_string(),
},
);
}
@ -1711,14 +1717,14 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
return retval; // separate variable to work around rust-analyzer parse error
}
let zero_reg = PRegNum[self.config].const_zero().into_sim_value();
let zero_value = zeroed(PRegValue);
let zero_value = zeroed(TraceAsString[PRegValue]);
for rob in self.rob.renamed() {
if rob.unit_index == unit_index
&& let Some(_) = rob.mop_in_unit_state.with_inputs_ready()
{
let mut src_values: [_; COMMON_MOP_SRC_LEN] =
std::array::from_fn(|_| Some(zero_value.clone()));
MOpTrait::for_each_src_reg_sim_ref(&rob.mop.mop, &mut |src_reg, index| {
MOpTrait::for_each_src_reg_sim_ref(rob.mop.mop.inner(), &mut |src_reg, index| {
#[hdl(sim)]
let PRegNum::<_> {
unit_num,
@ -1730,7 +1736,6 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
.clone();
} else {
assert_eq!(*src_reg, zero_reg);
src_values[index] = Some(zeroed(PRegValue));
}
});
if src_values.iter().all(|v| v.is_some()) {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -87,15 +87,15 @@ impl RandomState {
const START_PC: u64 = 0x0; // match microwatt's reset pc
#[derive(Clone, Debug)]
struct Insn<MOps = Vec<SimValue<self::MOp>>> {
struct Insn<MOps = Vec<SimValue<TraceAsString<self::MOp>>>> {
size_in_bytes: u8,
power_isa: String,
mops: MOps,
}
enum LazyMOps {
MOps(Vec<SimValue<self::MOp>>),
Lazy(Box<dyn FnOnce(&[InsnsBuilderLabelState]) -> Vec<SimValue<self::MOp>>>),
MOps(Vec<SimValue<TraceAsString<self::MOp>>>),
Lazy(Box<dyn FnOnce(&[InsnsBuilderLabelState]) -> Vec<SimValue<TraceAsString<self::MOp>>>>),
}
impl Insn<LazyMOps> {
@ -107,7 +107,11 @@ impl Insn<LazyMOps> {
Self {
size_in_bytes,
power_isa,
mops: LazyMOps::MOps(mops.into_iter().map(|mop| mop.into_sim_value()).collect()),
mops: LazyMOps::MOps(
mops.into_iter()
.map(|mop| mop.into_sim_value().into_trace_as_string())
.collect(),
),
}
}
fn new_lazy<I: IntoIterator<Item: ToSimValue<Type = MOp>>>(
@ -121,7 +125,7 @@ impl Insn<LazyMOps> {
mops: LazyMOps::Lazy(Box::new(|labels| {
lazy_mops(labels)
.into_iter()
.map(|mop| mop.into_sim_value())
.map(|mop| mop.into_sim_value().into_trace_as_string())
.collect()
})),
}
@ -772,7 +776,7 @@ impl<'a, C: PhantomConstCpuConfig> MockNextPcState<'a, C> {
};
let mop = &insn.mops[self.next_mop_index];
#[hdl(sim)]
if let MOp::AluBranch(mop) = mop {
if let MOp::AluBranch(mop) = mop.inner() {
#[hdl(sim)]
match mop {
AluBranchMOp::<_, _>::Branch(mop) => {
@ -1043,7 +1047,8 @@ type SimOnlyMemoryChunk = SimOnly<MemoryChunk>;
struct MockMemoryDebugState<C: PhantomConstGet<()> = PhantomConst<()>> {
wrote_output: Bool,
memory: ArrayType<SimOnlyMemoryChunk, MockMemoryDebugStateMemorySize<C>>,
l1_cache: Array<HdlOption<MockCacheLineDebugState>, { MockMemory::CACHE_LINE_COUNT }>,
l1_cache:
Array<TraceAsString<HdlOption<MockCacheLineDebugState>>, { MockMemory::CACHE_LINE_COUNT }>,
}
#[derive(Debug, Clone)]
@ -1291,6 +1296,7 @@ impl MockMemory {
#[hdl(sim)]
HdlNone()
}
.into_trace_as_string()
}),
}
}
@ -1298,16 +1304,16 @@ impl MockMemory {
fn run_mop<C: PhantomConstCpuConfig>(
&mut self,
mop: &SimValue<MOpInstance<LoadStoreMOp<PRegNum<C>, PRegNum<C>>>>,
src_values: &[SimValue<PRegValue>; COMMON_MOP_SRC_LEN],
src_values: &[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN],
is_speculative: bool,
) -> Result<SimValue<PRegValue>, AddressCantBeSpeculativelyAccessed> {
) -> Result<SimValue<TraceAsString<PRegValue>>, AddressCantBeSpeculativelyAccessed> {
println!("MockMemory::run_mop: {:#x}: {:?}", mop.pc.as_int(), mop.mop);
println!(
"<- {}{src_values:?}",
if is_speculative { "(speculative) " } else { "" },
);
let retval = #[hdl(sim)]
match &mop.mop {
match mop.mop.inner() {
LoadStoreMOp::<_, _>::Load(mop) => {
#[hdl(sim)]
let LoadMOp::<_, _> { load_store_common } = mop;
@ -1317,7 +1323,7 @@ impl MockMemory {
width,
conversion,
} = load_store_common;
let addr = src_values[0].int_fp.as_int();
let addr = src_values[0].inner().int_fp.as_int();
let loaded = #[hdl(sim)]
match conversion {
LoadStoreConversion::ZeroExt =>
@ -1372,8 +1378,8 @@ impl MockMemory {
width,
conversion,
} = load_store_common;
let addr = src_values[0].int_fp.as_int();
let value = src_values[1].int_fp.as_int();
let addr = src_values[0].inner().int_fp.as_int();
let value = src_values[1].inner().int_fp.as_int();
#[hdl(sim)]
match conversion {
LoadStoreConversion::ZeroExt | LoadStoreConversion::SignExt =>
@ -1399,7 +1405,7 @@ impl MockMemory {
}
};
println!("-> {retval:?}");
Ok(retval)
Ok(retval.into_trace_as_string())
}
}
@ -1413,8 +1419,8 @@ trait MockExecutionStateTrait: Default {
&mut self,
pc: u64,
mop: &SimValue<AddSubMOp<PRegNum<C>, PRegNum<C>, SrcCount>>,
src_values: &[SimValue<PRegValue>; COMMON_MOP_SRC_LEN],
) -> SimValue<PRegValue> {
src_values: &[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN],
) -> SimValue<TraceAsString<PRegValue>> {
#[hdl(sim)]
let AddSubMOp::<_, _, _> {
alu_common,
@ -1447,10 +1453,11 @@ trait MockExecutionStateTrait: Default {
let pc_or_zero = if **add_pc { pc } else { 0 };
let [src0, src1, src2] = src_values;
let int_fp = src0
.inner()
.int_fp
.as_int()
.wrapping_add(src1.int_fp.as_int())
.wrapping_add(src2.int_fp.as_int())
.wrapping_add(src1.inner().int_fp.as_int())
.wrapping_add(src2.inner().int_fp.as_int())
.wrapping_add(SimValue::value(imm).cast_to_static::<UInt<64>>().as_int())
.wrapping_add(pc_or_zero);
let int_fp = #[hdl(sim)]
@ -1467,18 +1474,19 @@ trait MockExecutionStateTrait: Default {
OutputIntegerMode::ZeroExt8 => int_fp as u8 as u64,
OutputIntegerMode::SignExt8 => int_fp as i8 as u64,
};
#[hdl(sim)]
let retval = #[hdl(sim)]
PRegValue {
int_fp,
flags: PRegFlags::zeroed_sim(), // TODO: compute flags
}
};
retval.into_trace_as_string()
}
#[hdl]
fn run_compare<C: PhantomConstCpuConfig, SrcCount: KnownSize>(
&mut self,
mop: &SimValue<CompareMOp<PRegNum<C>, PRegNum<C>, SrcCount>>,
src_values: &[SimValue<PRegValue>; COMMON_MOP_SRC_LEN],
) -> SimValue<PRegValue> {
src_values: &[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN],
) -> SimValue<TraceAsString<PRegValue>> {
#[hdl(sim)]
let CompareMOp::<_, _, _> {
common,
@ -1493,13 +1501,16 @@ trait MockExecutionStateTrait: Default {
} = common;
let (lhs, rhs) = match SrcCount::VALUE {
1 => (
src_values[0].int_fp.as_int(),
src_values[0].inner().int_fp.as_int(),
SimValue::value(imm).cast_to_static::<UInt<64>>().as_int(),
),
2 => (src_values[0].int_fp.as_int(), src_values[1].int_fp.as_int()),
2 => (
src_values[0].inner().int_fp.as_int(),
src_values[1].inner().int_fp.as_int(),
),
_ => todo!(),
};
let ordering_to_result = |v: Ordering| -> SimValue<PRegValue> {
let ordering_to_result = |v: Ordering| -> SimValue<TraceAsString<PRegValue>> {
let mut retval = #[hdl(sim)]
PRegValue {
int_fp: 0u64,
@ -1511,7 +1522,7 @@ trait MockExecutionStateTrait: Default {
Ordering::Equal => **flags.cr_eq = true,
Ordering::Greater => **flags.cr_gt = true,
}
retval
retval.into_trace_as_string()
};
#[hdl(sim)]
match compare_mode {
@ -1537,10 +1548,10 @@ trait MockExecutionStateTrait: Default {
fallthrough_pc: u64,
predicted_next_pc: u64,
mop: &SimValue<BranchMOp<PRegNum<C>, PRegNum<C>, SrcCount>>,
src_values: &[SimValue<PRegValue>; COMMON_MOP_SRC_LEN],
src_values: &[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN],
config: C,
) -> (
SimValue<PRegValue>,
SimValue<TraceAsString<PRegValue>>,
SimValue<NextPcPredictorOp<C>>,
Option<SimValue<UnitCausedCancel<C>>>,
) {
@ -1577,7 +1588,7 @@ trait MockExecutionStateTrait: Default {
} else {
true
};
let src0_flags = PRegFlags::view_sim_ref::<PRegFlagsPowerISA>(&src0.flags);
let src0_flags = PRegFlags::view_sim_ref::<PRegFlagsPowerISA>(&src0.inner().flags);
let src0_cond = #[hdl(sim)]
match src0_cond_mode {
ConditionMode::Eq => **src0_flags.cr_eq,
@ -1592,6 +1603,7 @@ trait MockExecutionStateTrait: Default {
let src0_cond = src0_cond ^ **invert_src0_cond;
let pc_or_zero = if **pc_relative { pc } else { 0 };
let target_pc = src1
.inner()
.int_fp
.as_int()
.wrapping_add(SimValue::value(imm).cast_to_static::<UInt<64>>().as_int())
@ -1615,12 +1627,13 @@ trait MockExecutionStateTrait: Default {
} else {
None
};
let fallthrough_pc_value = #[hdl(sim)]
PRegValue {
int_fp: fallthrough_pc,
flags: PRegFlags::zeroed_sim(),
};
(
#[hdl(sim)]
PRegValue {
int_fp: fallthrough_pc,
flags: PRegFlags::zeroed_sim(),
},
fallthrough_pc_value.into_trace_as_string(),
#[hdl(sim)]
NextPcPredictorOp::<_> {
call_stack_op: if **is_ret {
@ -1649,10 +1662,13 @@ trait MockExecutionStateTrait: Default {
fn run_mop<C: PhantomConstCpuConfig>(
&mut self,
mop: &SimValue<MOpInstance<RenamedMOp<C>>>,
src_values: &[SimValue<PRegValue>; COMMON_MOP_SRC_LEN],
src_values: &[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN],
config: C,
) -> (
Option<(SimValue<PRegValue>, SimValue<NextPcPredictorOp<C>>)>,
Option<(
SimValue<TraceAsString<PRegValue>>,
SimValue<NextPcPredictorOp<C>>,
)>,
Option<SimValue<UnitCausedCancel<C>>>,
) {
#[hdl(sim)]
@ -1680,7 +1696,7 @@ trait MockExecutionStateTrait: Default {
}
};
#[hdl(sim)]
match mop {
match mop.inner() {
UnitMOp::<_, _, _>::AluBranch(mop) =>
{
#[hdl(sim)]
@ -1780,7 +1796,7 @@ impl MockExecutionStateTrait for () {
#[hdl(no_static)]
struct MockUnitOpDebugState<C: PhantomConstGet<CpuConfig>> {
mop: MOpInstance<RenamedMOp<C>>,
src_values: Array<PRegValue, { COMMON_MOP_SRC_LEN }>,
src_values: Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>,
sent_cant_cause_cancel: Bool,
output_ready: HdlOption<UnitOutputReady<C>>,
caused_cancel: HdlOption<UnitCausedCancel<C>>,
@ -1790,7 +1806,7 @@ struct MockUnitOpDebugState<C: PhantomConstGet<CpuConfig>> {
#[derive(Debug)]
struct MockUnitOp<C: PhantomConstCpuConfig> {
mop: SimValue<MOpInstance<RenamedMOp<C>>>,
src_values: [SimValue<PRegValue>; COMMON_MOP_SRC_LEN],
src_values: [SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN],
sent_cant_cause_cancel: bool,
output_ready: Option<SimValue<UnitOutputReady<C>>>,
caused_cancel: Option<SimValue<UnitCausedCancel<C>>>,
@ -1999,7 +2015,7 @@ impl<C: PhantomConstCpuConfig, E: MockExecutionStateTrait> MockUnitState<C, E> {
config: _,
} = inputs_ready;
assert_eq!(
UnitNum::index_sim(&MOpTrait::dest_reg_sim_ref(&mop.mop).unit_num),
UnitNum::index_sim(&MOpTrait::dest_reg_sim_ref(mop.mop.inner()).unit_num),
Some(self.unit_index),
);
let mut op = MockUnitOp {
@ -2225,8 +2241,8 @@ fn mock_unit<#[hdl(skip)] E: MockExecutionStateTrait>(
#[hdl(no_static)]
struct MockL2RegFileOpDebugState<C: PhantomConstGet<CpuConfig>> {
mop: MOpInstance<L2RegisterFileMOp<PRegNum<C>, PRegNum<C>>>,
src_values: HdlOption<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
dest_value: HdlOption<PRegValue>,
src_values: HdlOption<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
dest_value: HdlOption<TraceAsString<PRegValue>>,
sent_cant_cause_cancel: Bool,
sent_output_ready: Bool,
config: C,
@ -2235,8 +2251,8 @@ struct MockL2RegFileOpDebugState<C: PhantomConstGet<CpuConfig>> {
#[derive(Debug)]
struct MockL2RegFileOp<C: PhantomConstCpuConfig> {
mop: SimValue<MOpInstance<L2RegisterFileMOp<PRegNum<C>, PRegNum<C>>>>,
src_values: Option<[SimValue<PRegValue>; COMMON_MOP_SRC_LEN]>,
dest_value: Option<SimValue<PRegValue>>,
src_values: Option<[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN]>,
dest_value: Option<SimValue<TraceAsString<PRegValue>>>,
sent_cant_cause_cancel: bool,
sent_output_ready: bool,
config: C,
@ -2274,13 +2290,13 @@ type L2RegFileSize<C: PhantomConstGet<CpuConfig>> = DynSize;
#[hdl(no_static)]
struct MockL2RegFileUnitDebugState<C: PhantomConstGet<CpuConfig>> {
ops: ArrayVec<MockL2RegFileOpDebugState<C>, CpuConfigMaxUnitMaxInFlight<C>>,
l2_regs: ArrayType<PRegValue, L2RegFileSize<C>>,
l2_regs: ArrayType<TraceAsString<PRegValue>, L2RegFileSize<C>>,
config: C,
}
struct MockL2RegFileUnitState<C: PhantomConstCpuConfig> {
ops: VecDeque<MockL2RegFileOp<C>>,
l2_regs: Box<[SimValue<PRegValue>]>,
l2_regs: Box<[SimValue<TraceAsString<PRegValue>>]>,
config: C,
}
@ -2288,7 +2304,8 @@ impl<C: PhantomConstCpuConfig> MockL2RegFileUnitState<C> {
fn new(config: C) -> Self {
Self {
ops: VecDeque::new(),
l2_regs: vec![PRegValue::zeroed_sim(); L2RegFileSize[config]].into_boxed_slice(),
l2_regs: vec![PRegValue::zeroed_sim().into_trace_as_string(); L2RegFileSize[config]]
.into_boxed_slice(),
config,
}
}
@ -2346,7 +2363,7 @@ impl<C: PhantomConstCpuConfig> MockL2RegFileUnitState<C> {
config: _,
} = op;
#[hdl(sim)]
match &mop.mop {
match mop.mop.inner() {
L2RegisterFileMOp::<_, _>::ReadL2Reg(mop) => {
#[hdl(sim)]
let ReadL2RegMOp::<_, _> { common } = mop;
@ -2361,7 +2378,7 @@ impl<C: PhantomConstCpuConfig> MockL2RegFileUnitState<C> {
&& dest_value.is_none()
{
self.l2_regs[L2RegNum::value_sim(&common.imm)] = src_values[0].clone();
*dest_value = Some(PRegValue::zeroed_sim());
*dest_value = Some(PRegValue::zeroed_sim().into_trace_as_string());
}
if dest_value.is_none() {
// we can't run following reads yet.
@ -2387,7 +2404,7 @@ impl<C: PhantomConstCpuConfig> MockL2RegFileUnitState<C> {
mop,
} = mop;
let mop = #[hdl(sim)]
match &mop {
match mop.inner() {
RenamedMOp::<_>::TransformedMove(mop) => mop,
_ => {
panic!("MockL2RegFileUnitState can only handle L2RegisterFile MOps, got: {mop:#?}");
@ -2402,7 +2419,7 @@ impl<C: PhantomConstCpuConfig> MockL2RegFileUnitState<C> {
size_in_bytes,
is_first_mop_in_insn,
is_last_mop_in_insn,
mop,
mop: mop.into_trace_as_string(),
};
self.ops.push_back(MockL2RegFileOp {
mop,
@ -2767,8 +2784,8 @@ fn mock_l2_reg_file_unit(config: PhantomConst<CpuConfig>, unit_index: usize) {
struct MockLoadStoreOpDebugState<C: PhantomConstGet<CpuConfig>> {
mop: MOpInstance<LoadStoreMOp<PRegNum<C>, PRegNum<C>>>,
is_speculative: Bool,
src_values: HdlOption<Array<PRegValue, { COMMON_MOP_SRC_LEN }>>,
dest_value: HdlOption<PRegValue>,
src_values: HdlOption<Array<TraceAsString<PRegValue>, { COMMON_MOP_SRC_LEN }>>,
dest_value: HdlOption<TraceAsString<PRegValue>>,
ran_nonspeculatively: Bool,
sent_cant_cause_cancel: Bool,
sent_output_ready: Bool,
@ -2779,8 +2796,8 @@ struct MockLoadStoreOpDebugState<C: PhantomConstGet<CpuConfig>> {
struct MockLoadStoreOp<C: PhantomConstCpuConfig> {
mop: SimValue<MOpInstance<LoadStoreMOp<PRegNum<C>, PRegNum<C>>>>,
is_speculative: bool,
src_values: Option<[SimValue<PRegValue>; COMMON_MOP_SRC_LEN]>,
dest_value: Option<SimValue<PRegValue>>,
src_values: Option<[SimValue<TraceAsString<PRegValue>>; COMMON_MOP_SRC_LEN]>,
dest_value: Option<SimValue<TraceAsString<PRegValue>>>,
ran_nonspeculatively: bool,
sent_cant_cause_cancel: bool,
sent_output_ready: bool,
@ -2913,7 +2930,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
}
}
#[hdl(sim)]
match &mop.mop {
match mop.mop.inner() {
LoadStoreMOp::<_, _>::Load(load_mop) => {
#[hdl(sim)]
let LoadMOp::<_, _> { load_store_common } = load_mop;
@ -2988,7 +3005,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
mop,
} = mop;
let mop = #[hdl(sim)]
match &mop {
match mop.inner() {
RenamedMOp::<_>::LoadStore(mop) => mop,
_ => panic!("MockLoadStoreUnitState can only handle LoadStore MOps, got: {mop:#?}"),
};
@ -3001,7 +3018,7 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreUnitState<C> {
size_in_bytes,
is_first_mop_in_insn,
is_last_mop_in_insn,
mop,
mop: mop.into_trace_as_string(),
};
self.ops.push_back(MockLoadStoreOp {
mop,