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
All checks were successful
/ test (pull_request) Successful in 5m44s
This commit is contained in:
parent
8bee576a2a
commit
0d3c41fa14
4 changed files with 35839 additions and 1340471 deletions
|
|
@ -56,7 +56,7 @@ pub struct MOpInstance<MOp> {
|
|||
/// it needs to be canceled along with all other µ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(®_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()) {
|
||||
|
|
|
|||
607708
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
607708
crates/cpu/tests/expected/rename_execute_retire_fibonacci.vcd
generated
File diff suppressed because it is too large
Load diff
768392
crates/cpu/tests/expected/rename_execute_retire_slow_loop.vcd
generated
768392
crates/cpu/tests/expected/rename_execute_retire_slow_loop.vcd
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue