adapt code for new fayalite features

This commit is contained in:
Jacob Lifshay 2026-05-03 18:22:21 -07:00
parent 1229d9c758
commit ba9ec3bd29
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
9 changed files with 56 additions and 544 deletions

View file

@ -523,7 +523,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
kind, kind,
read_data, read_data,
config: _, config: _,
} = memory_operation_finish; } = memory_operation_finish.into_sim_value();
#[hdl(sim)] #[hdl(sim)]
match kind { match kind {
MemoryOperationFinishKind::Success(success) => MemoryOperationFinishKind::Success(success) =>
@ -746,7 +746,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
let NextPcToFetchInterfaceInner { let NextPcToFetchInterfaceInner {
start_pc, start_pc,
fetch_block_id, fetch_block_id,
} = fetch; } = fetch.into_sim_value();
let entry_ty = FetchQueueEntry[config]; let entry_ty = FetchQueueEntry[config];
self.queue.push_back( self.queue.push_back(
#[hdl(sim)] #[hdl(sim)]
@ -895,7 +895,7 @@ impl<C: PhantomConstCpuConfig> L1ICacheStateSim<C> {
let CacheReadData::<_> { let CacheReadData::<_> {
cache_line_index: read_cache_line_index, cache_line_index: read_cache_line_index,
cache_line, cache_line,
} = cache_read_data; } = cache_read_data.into_sim_value();
let config = self.config(); let config = self.config();
for entry in &mut self.queue { for entry in &mut self.queue {
#[hdl(sim)] #[hdl(sim)]
@ -1151,8 +1151,6 @@ fn l1_i_cache_impl(config: PhantomConst<CpuConfig>) {
sim.wait_for_clock_edge(cd.clk).await; sim.wait_for_clock_edge(cd.clk).await;
} }
sim.write(from_next_pc.cancel.ready, true).await; sim.write(from_next_pc.cancel.ready, true).await;
let memory_interface_start_data_ty = memory_interface.start.data.ty();
let to_decode_fetched_data_ty = to_decode_fetched.data.ty();
let cache_read_data_ty = CacheReadData[config]; let cache_read_data_ty = CacheReadData[config];
let mut state = L1ICacheStateSim::new(state_expr); let mut state = L1ICacheStateSim::new(state_expr);
loop { loop {
@ -1168,26 +1166,11 @@ fn l1_i_cache_impl(config: PhantomConst<CpuConfig>) {
.await; .await;
sim.write( sim.write(
memory_interface.start.data, memory_interface.start.data,
if let Some(v) = state.clone().try_start_memory_operation() { state.clone().try_start_memory_operation(),
#[hdl(sim)]
memory_interface_start_data_ty.HdlSome(v)
} else {
#[hdl(sim)]
memory_interface_start_data_ty.HdlNone()
},
)
.await;
sim.write(
to_decode_fetched.data,
if let Some(v) = state.clone().to_decode_fetched() {
#[hdl(sim)]
to_decode_fetched_data_ty.HdlSome(v)
} else {
#[hdl(sim)]
to_decode_fetched_data_ty.HdlNone()
},
) )
.await; .await;
sim.write(to_decode_fetched.data, state.clone().to_decode_fetched())
.await;
state.write_debug_state(&mut sim).await; state.write_debug_state(&mut sim).await;
sim.write(max_cancel_in_fetch, state.queue.len()).await; sim.write(max_cancel_in_fetch, state.queue.len()).await;
state state

View file

@ -12,7 +12,7 @@ use fayalite::{
intern::Interned, intern::Interned,
module::wire_with_loc, module::wire_with_loc,
prelude::*, prelude::*,
ty::{StaticType, TypeProperties}, ty::{SimValueDebug, StaticType, TypeProperties},
util::ConstBool, util::ConstBool,
}; };
use std::{ use std::{
@ -381,7 +381,7 @@ impl<T: CommonMOpTrait> MOpVisitVariants for T {
} }
} }
#[hdl] #[hdl(cmp_eq)]
pub enum OutputIntegerMode { pub enum OutputIntegerMode {
Full64, Full64,
DupLow32, DupLow32,
@ -410,40 +410,6 @@ impl OutputIntegerMode {
} }
} }
impl HdlPartialEqImpl<Self> for OutputIntegerMode {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
pub const MOP_IMM_WIDTH: usize = 34; pub const MOP_IMM_WIDTH: usize = 34;
pub const MOP_MIN_REG_WIDTH: usize = 8; pub const MOP_MIN_REG_WIDTH: usize = 8;
pub const COMMON_MOP_SRC_LEN: usize = 3; pub const COMMON_MOP_SRC_LEN: usize = 3;
@ -494,6 +460,15 @@ impl<SrcCount: KnownSize> fmt::Debug for CommonMOpDefaultImm<SrcCount> {
} }
} }
impl<SrcCount: KnownSize> SimValueDebug for CommonMOpDefaultImm<SrcCount> {
fn sim_value_debug(
value: &<Self as Type>::SimValue,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
fmt::Debug::fmt(value, f)
}
}
impl<SrcCount: KnownSize> MOpImmDebug for CommonMOpDefaultImm<SrcCount> { impl<SrcCount: KnownSize> MOpImmDebug for CommonMOpDefaultImm<SrcCount> {
fn mop_imm_debug(this: &SimValue<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn mop_imm_debug(this: &SimValue<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<SIntValue as fmt::Display>::fmt(this, f) <SIntValue as fmt::Display>::fmt(this, f)
@ -2254,7 +2229,7 @@ impl<DestReg: Type, SrcRegWidth: Size> LogicalMOp<DestReg, SrcRegWidth, ConstUsi
} }
} }
#[hdl] #[hdl(cmp_eq)]
pub enum ShiftRotateMode { pub enum ShiftRotateMode {
/// like `llvm.fsh[lr].i8(src0, src1, shift_rotate_amount.unwrap_or(src2))` /// like `llvm.fsh[lr].i8(src0, src1, shift_rotate_amount.unwrap_or(src2))`
FunnelShift2x8Bit, FunnelShift2x8Bit,
@ -2274,40 +2249,6 @@ pub enum ShiftRotateMode {
ShiftSigned64, ShiftSigned64,
} }
impl HdlPartialEqImpl<Self> for ShiftRotateMode {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl ShiftRotateMode { impl ShiftRotateMode {
#[hdl] #[hdl]
fn debug_str(this: &SimValue<Self>) -> &'static str { fn debug_str(this: &SimValue<Self>) -> &'static str {
@ -2505,7 +2446,7 @@ impl<DestReg: Type, SrcRegWidth: Size> ShiftRotateMOp<DestReg, SrcRegWidth> {
} }
} }
#[hdl] #[hdl(cmp_eq)]
pub enum CompareMode { pub enum CompareMode {
U64, U64,
S64, S64,
@ -2523,40 +2464,6 @@ pub enum CompareMode {
CmpEqB, CmpEqB,
} }
impl HdlPartialEqImpl<Self> for CompareMode {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl CompareMode { impl CompareMode {
#[hdl] #[hdl]
fn debug_str(this: &SimValue<Self>) -> &'static str { fn debug_str(this: &SimValue<Self>) -> &'static str {
@ -2652,7 +2559,7 @@ impl<DestReg: Type, SrcRegWidth: Size> CompareMOp<DestReg, SrcRegWidth, ConstUsi
} }
} }
#[hdl] #[hdl(cmp_eq)]
pub enum ConditionMode { pub enum ConditionMode {
Eq, Eq,
ULt, ULt,
@ -2664,40 +2571,6 @@ pub enum ConditionMode {
Parity, Parity,
} }
impl HdlPartialEqImpl<Self> for ConditionMode {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl ConditionMode { impl ConditionMode {
#[hdl] #[hdl]
fn debug_str(this: &SimValue<Self>, inverted: bool) -> &'static str { fn debug_str(this: &SimValue<Self>, inverted: bool) -> &'static str {
@ -2892,46 +2765,12 @@ impl<DestReg: Type, SrcRegWidth: Size> BranchMOp<DestReg, SrcRegWidth, ConstUsiz
} }
} }
#[hdl] #[hdl(cmp_eq)]
pub enum ReadSpecialMOpImm { pub enum ReadSpecialMOpImm {
PowerIsaTimeBase, PowerIsaTimeBase,
PowerIsaTimeBaseU, PowerIsaTimeBaseU,
} }
impl HdlPartialEqImpl<Self> for ReadSpecialMOpImm {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl MOpImmDebug for ReadSpecialMOpImm { impl MOpImmDebug for ReadSpecialMOpImm {
fn mop_imm_debug(this: &SimValue<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn mop_imm_debug(this: &SimValue<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(Self::debug_str(this)) f.write_str(Self::debug_str(this))
@ -3151,7 +2990,7 @@ where
} }
} }
#[hdl] #[hdl(cmp_eq)]
pub enum LoadStoreWidth { pub enum LoadStoreWidth {
Width8Bit, Width8Bit,
Width16Bit, Width16Bit,
@ -3159,81 +2998,13 @@ pub enum LoadStoreWidth {
Width64Bit, Width64Bit,
} }
impl HdlPartialEqImpl<Self> for LoadStoreWidth { #[hdl(cmp_eq)]
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
#[hdl]
pub enum LoadStoreConversion { pub enum LoadStoreConversion {
ZeroExt, ZeroExt,
SignExt, SignExt,
// TODO(FP): add Power ISA's f32 in f64 format and RISC-V's ones-extension of floating-point // TODO(FP): add Power ISA's f32 in f64 format and RISC-V's ones-extension of floating-point
} }
impl HdlPartialEqImpl<Self> for LoadStoreConversion {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
SimValue::opaque(&SimValue::from_value(lhs, lhs_value.into_owned()))
== SimValue::opaque(&SimValue::from_value(rhs, rhs_value.into_owned()))
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) == SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::opaque(&lhs) != SimValue::opaque(&rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
common_mop_struct! { common_mop_struct! {
#[mapped(<NewDestReg, NewSrcRegWidth> LoadStoreCommonMOp<NewDestReg, NewSrcRegWidth, SrcCount>)] #[mapped(<NewDestReg, NewSrcRegWidth> LoadStoreCommonMOp<NewDestReg, NewSrcRegWidth, SrcCount>)]
#[hdl(cmp_eq)] #[hdl(cmp_eq)]

View file

@ -23,14 +23,13 @@ use crate::{
util::array_vec::ArrayVec, util::array_vec::ArrayVec,
}; };
use fayalite::{ use fayalite::{
expr::HdlPartialEqImpl,
int::{UIntInRange, UIntInRangeInclusive, UIntInRangeInclusiveType, UIntInRangeType}, int::{UIntInRange, UIntInRangeInclusive, UIntInRangeInclusiveType, UIntInRangeType},
prelude::*, prelude::*,
sim::value::SimOnlyValueTrait, sim::value::SimOnlyValueTrait,
ty::StaticType, ty::StaticType,
util::{DebugAsDisplay, ready_valid::ReadyValid}, util::{DebugAsDisplay, ready_valid::ReadyValid},
}; };
use std::{borrow::Cow, fmt}; use std::fmt;
pub const FETCH_BLOCK_ID_WIDTH: usize = FetchBlockIdInt::BITS as usize; pub const FETCH_BLOCK_ID_WIDTH: usize = FetchBlockIdInt::BITS as usize;
type FetchBlockIdInt = u8; type FetchBlockIdInt = u8;
@ -53,7 +52,7 @@ pub struct NextPcToFetchInterface<C: PhantomConstGet<CpuConfig>> {
pub config: C, pub config: C,
} }
#[hdl] #[hdl(cmp_eq)]
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`] /// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
/// since the actual instruction definition isn't finalized yet. /// since the actual instruction definition isn't finalized yet.
/// This will be replaced at a later point. /// This will be replaced at a later point.
@ -93,101 +92,6 @@ impl WipDecodedInsnKind {
} }
} }
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
impl HdlPartialEqImpl<Self> for WipDecodedInsnKind {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
*Self::cmp_sim_value_eq(
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
Cow::Owned(SimValue::from_value(rhs, rhs_value.into_owned())),
)
}
#[hdl]
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
let clear_unused_bits = |v: Cow<'_, SimValue<Self>>| {
#[hdl(sim)]
match &*v {
Self::NonBranch =>
{
#[hdl(sim)]
Self::NonBranch()
}
Self::Branch(target) =>
{
#[hdl(sim)]
Self::Branch(target)
}
Self::BranchCond(target) =>
{
#[hdl(sim)]
Self::BranchCond(target)
}
Self::IndirectBranch =>
{
#[hdl(sim)]
Self::IndirectBranch()
}
Self::Call(target) =>
{
#[hdl(sim)]
Self::Call(target)
}
Self::CallCond(target) =>
{
#[hdl(sim)]
Self::CallCond(target)
}
Self::IndirectCall =>
{
#[hdl(sim)]
Self::IndirectCall()
}
Self::Ret =>
{
#[hdl(sim)]
Self::Ret()
}
Self::RetCond =>
{
#[hdl(sim)]
Self::RetCond()
}
Self::Interrupt(target) =>
{
#[hdl(sim)]
Self::Interrupt(target)
}
Self::Unknown => v.into_owned(),
}
};
(SimValue::bits(&clear_unused_bits(lhs)) == SimValue::bits(&clear_unused_bits(rhs)))
.to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
!Self::cmp_sim_value_eq(lhs, rhs)
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
todo!()
}
}
#[hdl(cmp_eq)] #[hdl(cmp_eq)]
/// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`] /// WIP version of decoded instruction just good enough to represent stuff needed for [`next_pc()`]
/// since the actual instruction definition isn't finalized yet. /// since the actual instruction definition isn't finalized yet.
@ -2781,8 +2685,10 @@ impl<T: SimValueDefault, N: Size> SimValueDefault for ArrayType<T, N> {
} }
impl<T: Type> SimValueDefault for HdlOption<T> { impl<T: Type> SimValueDefault for HdlOption<T> {
#[hdl]
fn sim_value_default(self) -> SimValue<Self> { fn sim_value_default(self) -> SimValue<Self> {
self.HdlNone().to_sim_value_with_type(self) #[hdl(sim)]
self.HdlNone()
} }
} }
@ -2911,50 +2817,13 @@ impl ResetSteps for CallStack {
} }
} }
#[hdl] #[hdl(cmp_eq)]
enum BTBEntryInsnKind { enum BTBEntryInsnKind {
Branch, Branch,
Call, Call,
Ret, Ret,
} }
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
impl HdlPartialEqImpl<Self> for BTBEntryInsnKind {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
*Self::cmp_sim_value_eq(
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
Cow::Owned(SimValue::from_value(rhs, rhs_value.into_owned())),
)
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) == SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) != SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl BTBEntryInsnKind { impl BTBEntryInsnKind {
#[hdl] #[hdl]
fn try_from_decoded_insn_kind(kind: &SimValue<WipDecodedInsnKind>) -> Option<SimValue<Self>> { fn try_from_decoded_insn_kind(kind: &SimValue<WipDecodedInsnKind>) -> Option<SimValue<Self>> {
@ -2983,7 +2852,7 @@ impl BTBEntryInsnKind {
} }
} }
#[hdl] #[hdl(cmp_eq)]
enum BTBEntryAddrKind { enum BTBEntryAddrKind {
Unconditional, Unconditional,
Indirect, Indirect,
@ -2991,43 +2860,6 @@ enum BTBEntryAddrKind {
CondNotTaken, CondNotTaken,
} }
// TODO: replace with #[hdl(cmp_eq)] when that's implemented for enums
impl HdlPartialEqImpl<Self> for BTBEntryAddrKind {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: Self,
rhs_value: Cow<'_, Self::SimValue>,
) -> bool {
*Self::cmp_sim_value_eq(
Cow::Owned(SimValue::from_value(lhs, lhs_value.into_owned())),
Cow::Owned(SimValue::from_value(rhs, rhs_value.into_owned())),
)
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) == SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<Self>>,
) -> SimValue<Bool> {
(SimValue::bits(&*lhs) != SimValue::bits(&*rhs)).to_sim_value()
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<Self>) -> Expr<Bool> {
lhs.cast_to_bits().cmp_eq(rhs.cast_to_bits())
}
}
impl BTBEntryAddrKind { impl BTBEntryAddrKind {
#[hdl] #[hdl]
fn taken(this: &SimValue<Self>) -> bool { fn taken(this: &SimValue<Self>) -> bool {

View file

@ -635,20 +635,8 @@ impl<C: PhantomConstCpuConfig> RobEntry<C> {
mop, mop,
mop_in_unit_state: SimOnlyValue::new(*mop_in_unit_state), mop_in_unit_state: SimOnlyValue::new(*mop_in_unit_state),
is_speculative, is_speculative,
finished: if let Some(finished) = finished { finished: finished.into_sim_value_with_type(ret_ty.finished),
#[hdl(sim)] caused_cancel: caused_cancel.into_sim_value_with_type(ret_ty.caused_cancel),
(ret_ty.finished).HdlSome(finished)
} else {
#[hdl(sim)]
(ret_ty.finished).HdlNone()
},
caused_cancel: if let Some(caused_cancel) = caused_cancel {
#[hdl(sim)]
(ret_ty.caused_cancel).HdlSome(caused_cancel)
} else {
#[hdl(sim)]
(ret_ty.caused_cancel).HdlNone()
},
} }
} }
} }
@ -813,13 +801,7 @@ impl<C: PhantomConstCpuConfig> ReorderBuffer<C> {
entries.iter().map(RobEntries::debug_state), entries.iter().map(RobEntries::debug_state),
) )
.expect("known to fit"), .expect("known to fit"),
incomplete_back_entry: if let Some(incomplete_back_entry) = incomplete_back_entry { incomplete_back_entry: incomplete_back_entry.as_ref().map(|v| v.debug_state()),
#[hdl(sim)]
HdlSome(incomplete_back_entry.debug_state())
} else {
#[hdl(sim)]
HdlNone()
},
renamed: ty renamed: ty
.renamed .renamed
.from_iter_sim( .from_iter_sim(
@ -1085,18 +1067,7 @@ impl<C: PhantomConstCpuConfig> RenameExecuteRetireState<C> {
l1_reg_file: SimValue::from_array_elements( l1_reg_file: SimValue::from_array_elements(
state_for_debug.ty().l1_reg_file, state_for_debug.ty().l1_reg_file,
l1_reg_file.iter().map(|v| { l1_reg_file.iter().map(|v| {
SimValue::from_array_elements( SimValue::from_array_elements(state_for_debug.ty().l1_reg_file.element(), v)
state_for_debug.ty().l1_reg_file.element(),
v.iter().map(|v| {
if let Some(v) = v {
#[hdl(sim)]
HdlSome(v)
} else {
#[hdl(sim)]
HdlNone()
}
}),
)
}), }),
), ),
per_insn_timeline: self.per_insn_timeline(), per_insn_timeline: self.per_insn_timeline(),

View file

@ -7,7 +7,10 @@ use fayalite::{
expr::ops::FieldAccess, expr::ops::FieldAccess,
intern::{Intern, Interned, Memoize}, intern::{Intern, Interned, Memoize},
prelude::*, prelude::*,
ty::{OpaqueSimValue, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten}, ty::{
OpaqueSimValue, OpaqueSimValueSlice, OpaqueSimValueWriter, OpaqueSimValueWritten,
SimValueDebug,
},
}; };
use std::{fmt, marker::PhantomData, ops::Index}; use std::{fmt, marker::PhantomData, ops::Index};
@ -116,6 +119,15 @@ impl<C: Type + PhantomConstGet<CpuConfig>> Index<C> for ExecuteToUnitInterfacesW
} }
} }
impl<C: Type + PhantomConstGet<CpuConfig>> SimValueDebug for ExecuteToUnitInterfaces<C> {
fn sim_value_debug(
value: &<Self as Type>::SimValue,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
fmt::Debug::fmt(value, f)
}
}
impl<C: Type + PhantomConstGet<CpuConfig>> Type for ExecuteToUnitInterfaces<C> { impl<C: Type + PhantomConstGet<CpuConfig>> Type for ExecuteToUnitInterfaces<C> {
type BaseType = Bundle; type BaseType = Bundle;
type MaskType = Bundle; type MaskType = Bundle;

View file

@ -1163,13 +1163,7 @@ impl MockExecuteState {
id: &insn.id, id: &insn.id,
next_pc, next_pc,
call_stack_op: mock_insn.call_stack_op(pc), call_stack_op: mock_insn.call_stack_op(pc),
cond_br_taken: if let Some(cond_br_taken) = cond_br_taken { cond_br_taken,
#[hdl(sim)]
HdlSome(cond_br_taken)
} else {
#[hdl(sim)]
HdlNone()
},
config: self.config, config: self.config,
}, },
) )

View file

@ -1817,20 +1817,8 @@ impl<C: PhantomConstCpuConfig> MockUnitOp<C> {
mop, mop,
src_values, src_values,
sent_cant_cause_cancel, sent_cant_cause_cancel,
output_ready: if let Some(output_ready) = output_ready { output_ready: output_ready.into_sim_value_with_type(output_ready_ty),
#[hdl(sim)] caused_cancel: caused_cancel.into_sim_value_with_type(caused_cancel_ty),
output_ready_ty.HdlSome(output_ready)
} else {
#[hdl(sim)]
output_ready_ty.HdlNone()
},
caused_cancel: if let Some(caused_cancel) = caused_cancel {
#[hdl(sim)]
caused_cancel_ty.HdlSome(caused_cancel)
} else {
#[hdl(sim)]
caused_cancel_ty.HdlNone()
},
config, config,
} }
} }
@ -1985,20 +1973,8 @@ impl<C: PhantomConstCpuConfig, E: MockExecutionStateTrait> MockUnitState<C, E> {
if op.output_ready.is_none() && op.caused_cancel.is_none() { if op.output_ready.is_none() && op.caused_cancel.is_none() {
continue; continue;
} }
let output_ready = if let Some(output_ready) = &op.output_ready { let output_ready = op.output_ready.to_sim_value_with_type(output_ready_ty);
#[hdl(sim)] let caused_cancel = op.caused_cancel.to_sim_value_with_type(caused_cancel_ty);
output_ready_ty.HdlSome(output_ready)
} else {
#[hdl(sim)]
output_ready_ty.HdlNone()
};
let caused_cancel = if let Some(caused_cancel) = &op.caused_cancel {
#[hdl(sim)]
caused_cancel_ty.HdlSome(caused_cancel)
} else {
#[hdl(sim)]
caused_cancel_ty.HdlNone()
};
// TODO: add delay // TODO: add delay
return ( return (
output_ready, output_ready,
@ -2301,20 +2277,8 @@ impl<C: PhantomConstCpuConfig> MockLoadStoreOp<C> {
MockLoadStoreOpDebugState::<_> { MockLoadStoreOpDebugState::<_> {
mop, mop,
is_speculative, is_speculative,
src_values: if let Some(v) = src_values { src_values,
#[hdl(sim)] dest_value,
HdlSome(v)
} else {
#[hdl(sim)]
HdlNone()
},
dest_value: if let Some(v) = dest_value {
#[hdl(sim)]
HdlSome(v)
} else {
#[hdl(sim)]
HdlNone()
},
ran_nonspeculatively, ran_nonspeculatively,
sent_cant_cause_cancel, sent_cant_cause_cancel,
sent_output_ready, sent_output_ready,

View file

@ -152,16 +152,7 @@ fn test_decode_insn() {
} in test_cases::test_cases() } in test_cases::test_cases()
{ {
sim.write(sim.io().first_input, first_input); sim.write(sim.io().first_input, first_input);
sim.write( sim.write(sim.io().second_input, second_input);
sim.io().second_input,
if let Some(v) = second_input {
#[hdl(sim)]
HdlSome(v)
} else {
#[hdl(sim)]
HdlNone()
},
);
sim.advance_time(SimDuration::from_micros(1)); sim.advance_time(SimDuration::from_micros(1));
let second_input_used = sim.read_bool(sim.io().second_input_used); let second_input_used = sim.read_bool(sim.io().second_input_used);
let is_illegal = sim.read_bool(sim.io().is_illegal); let is_illegal = sim.read_bool(sim.io().is_illegal);

View file

@ -30,13 +30,7 @@ fn rotate_imm(
) -> SimValue<ShiftRotateMOpImm> { ) -> SimValue<ShiftRotateMOpImm> {
#[hdl(sim)] #[hdl(sim)]
ShiftRotateMOpImm { ShiftRotateMOpImm {
shift_rotate_amount: if let Some(amount) = amount { shift_rotate_amount: amount.map(|amount| amount.cast_to_static::<UInt<_>>()),
#[hdl(sim)]
HdlSome(amount.cast_to_static::<UInt<_>>())
} else {
#[hdl(sim)]
HdlNone()
},
shift_rotate_right: false, shift_rotate_right: false,
dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) = dest_logic_op: if let Some((rotated_output_start, rotated_output_len)) =
rotated_output_start_and_len rotated_output_start_and_len