forked from libre-chip/fayalite
Add .to_trace_as_string() and clean up code
This commit is contained in:
parent
ea183eac87
commit
cf3e6cfc6b
18 changed files with 894 additions and 255 deletions
|
|
@ -218,7 +218,7 @@ expr_enum! {
|
||||||
SliceSInt(ops::SliceSInt),
|
SliceSInt(ops::SliceSInt),
|
||||||
CastToBits(ops::CastToBits),
|
CastToBits(ops::CastToBits),
|
||||||
CastBitsTo(ops::CastBitsTo),
|
CastBitsTo(ops::CastBitsTo),
|
||||||
AsTraceAsString(ops::AsTraceAsString),
|
ToTraceAsString(ops::ToTraceAsString),
|
||||||
TraceAsStringAsInner(ops::TraceAsStringAsInner),
|
TraceAsStringAsInner(ops::TraceAsStringAsInner),
|
||||||
ModuleIO(ModuleIO<CanonicalType>),
|
ModuleIO(ModuleIO<CanonicalType>),
|
||||||
Instance(Instance<Bundle>),
|
Instance(Instance<Bundle>),
|
||||||
|
|
@ -394,7 +394,7 @@ impl<T: Type> Expr<T> {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn as_trace_as_string(this: Self, ty: TraceAsString<T>) -> Expr<TraceAsString<T>> {
|
pub fn as_trace_as_string(this: Self, ty: TraceAsString<T>) -> Expr<TraceAsString<T>> {
|
||||||
assert_eq!(this.ty(), ty.inner_ty());
|
assert_eq!(this.ty(), ty.inner_ty());
|
||||||
ops::AsTraceAsString::new(Expr::canonical(this), ty).to_expr()
|
ops::ToTraceAsString::new(Expr::canonical(this), ty).to_expr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1723,3 +1723,188 @@ impl<'a, T: Type> ToSimValueInner<'a> for &'a SimValue<T> {
|
||||||
Cow::Borrowed(&**this)
|
Cow::Borrowed(&**this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ToTraceAsString: ValueType {
|
||||||
|
type Output: ValueType<Type = TraceAsString<Self::Type>, ValueCategory = Self::ValueCategory>;
|
||||||
|
fn to_trace_as_string_with_ty(&self, ty: TraceAsString<Self::Type>) -> Self::Output;
|
||||||
|
fn into_trace_as_string_with_ty(self, ty: TraceAsString<Self::Type>) -> Self::Output
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
fn to_trace_as_string(&self) -> Self::Output;
|
||||||
|
fn into_trace_as_string(self) -> Self::Output
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
T: ?Sized
|
||||||
|
+ ValueType
|
||||||
|
+ ToTraceAsStringImpl<<Self as ValueType>::Type, <Self as ValueType>::ValueCategory>,
|
||||||
|
> ToTraceAsString for T
|
||||||
|
{
|
||||||
|
type Output = T::ImplOutput;
|
||||||
|
fn to_trace_as_string_with_ty(&self, ty: TraceAsString<Self::Type>) -> Self::Output {
|
||||||
|
Self::to_trace_as_string_with_ty_impl(self, ty)
|
||||||
|
}
|
||||||
|
fn into_trace_as_string_with_ty(self, ty: TraceAsString<Self::Type>) -> Self::Output
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Self::into_trace_as_string_with_ty_impl(self, ty)
|
||||||
|
}
|
||||||
|
fn to_trace_as_string(&self) -> Self::Output {
|
||||||
|
Self::to_trace_as_string_impl(self)
|
||||||
|
}
|
||||||
|
fn into_trace_as_string(self) -> Self::Output
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Self::into_trace_as_string_impl(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ToTraceAsStringImpl<Ty: Type, C: value_category::ValueCategory> {
|
||||||
|
type ImplOutput: ValueType<Type = TraceAsString<Ty>, ValueCategory = C>;
|
||||||
|
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput;
|
||||||
|
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
fn to_trace_as_string_with_ty_impl(this: &Self, ty: TraceAsString<Ty>) -> Self::ImplOutput;
|
||||||
|
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<Ty>) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + crate::sim::value::ToSimValue>
|
||||||
|
ToTraceAsStringImpl<T::Type, value_category::ValueCategoryValue> for T
|
||||||
|
{
|
||||||
|
type ImplOutput = crate::ty::TraceAsStringSimValue<T::Type>;
|
||||||
|
|
||||||
|
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
||||||
|
crate::ty::TraceAsStringSimValue::new(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
crate::ty::TraceAsStringSimValue::new(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_trace_as_string_with_ty_impl(
|
||||||
|
this: &Self,
|
||||||
|
ty: TraceAsString<T::Type>,
|
||||||
|
) -> Self::ImplOutput {
|
||||||
|
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + crate::sim::value::ToSimValue>
|
||||||
|
ToTraceAsStringImpl<T::Type, value_category::ValueCategorySimValue> for T
|
||||||
|
{
|
||||||
|
type ImplOutput = SimValue<TraceAsString<T::Type>>;
|
||||||
|
|
||||||
|
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
||||||
|
crate::ty::TraceAsStringSimValue::new(this).into_sim_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
crate::ty::TraceAsStringSimValue::new(this).into_sim_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_trace_as_string_with_ty_impl(
|
||||||
|
this: &Self,
|
||||||
|
ty: TraceAsString<T::Type>,
|
||||||
|
) -> Self::ImplOutput {
|
||||||
|
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + ToExpr> ToTraceAsStringImpl<T::Type, value_category::ValueCategoryExpr> for T {
|
||||||
|
type ImplOutput = Expr<TraceAsString<T::Type>>;
|
||||||
|
|
||||||
|
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
||||||
|
let this = this.to_expr();
|
||||||
|
ops::ToTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let this = this.to_expr();
|
||||||
|
ops::ToTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_trace_as_string_with_ty_impl(
|
||||||
|
this: &Self,
|
||||||
|
ty: TraceAsString<T::Type>,
|
||||||
|
) -> Self::ImplOutput {
|
||||||
|
let this = this.to_expr();
|
||||||
|
ops::ToTraceAsString::new(
|
||||||
|
Expr::canonical(this),
|
||||||
|
ty.with_new_inner_ty(this.ty().intern_sized()),
|
||||||
|
)
|
||||||
|
.to_expr()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
let this = this.to_expr();
|
||||||
|
ops::ToTraceAsString::new(
|
||||||
|
Expr::canonical(this),
|
||||||
|
ty.with_new_inner_ty(this.ty().intern_sized()),
|
||||||
|
)
|
||||||
|
.to_expr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized + ValueType> ToTraceAsStringImpl<T::Type, value_category::ValueCategoryValueless>
|
||||||
|
for T
|
||||||
|
{
|
||||||
|
type ImplOutput = Valueless<TraceAsString<T::Type>>;
|
||||||
|
|
||||||
|
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
|
||||||
|
Valueless::new(TraceAsString::new(this.ty()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Valueless::new(TraceAsString::new(this.ty()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_trace_as_string_with_ty_impl(
|
||||||
|
this: &Self,
|
||||||
|
ty: TraceAsString<T::Type>,
|
||||||
|
) -> Self::ImplOutput {
|
||||||
|
Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ use crate::{
|
||||||
HdlPartialEqImpl, HdlPartialOrd, HdlPartialOrdImpl, NotALiteralExpr, ReduceBitsImpl,
|
HdlPartialEqImpl, HdlPartialOrd, HdlPartialOrdImpl, NotALiteralExpr, ReduceBitsImpl,
|
||||||
ToExpr, ToLiteralBits, ToSimValueInner, ToValueless, ValueType, Valueless,
|
ToExpr, ToLiteralBits, ToSimValueInner, ToValueless, ValueType, Valueless,
|
||||||
target::{
|
target::{
|
||||||
GetTarget, Target, TargetPathArrayElement, TargetPathAsTraceAsString,
|
GetTarget, Target, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathBundleField, TargetPathDynArrayElement, TargetPathElement,
|
TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString,
|
||||||
TargetPathTraceAsStringInner,
|
TargetPathTraceAsStringInner,
|
||||||
},
|
},
|
||||||
value_category::ValueCategoryExpr,
|
value_category::ValueCategoryExpr,
|
||||||
|
|
@ -45,6 +45,9 @@ use std::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test_ops_impls;
|
||||||
|
|
||||||
macro_rules! make_impls {
|
macro_rules! make_impls {
|
||||||
(
|
(
|
||||||
$([$($args:tt)*])?
|
$([$($args:tt)*])?
|
||||||
|
|
@ -584,9 +587,6 @@ macro_rules! make_impls {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) use make_impls;
|
pub(crate) use make_impls;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test_ops_impls;
|
|
||||||
|
|
||||||
macro_rules! impl_simple_binary_op_trait {
|
macro_rules! impl_simple_binary_op_trait {
|
||||||
(
|
(
|
||||||
[$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*),
|
[$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*),
|
||||||
|
|
@ -4697,14 +4697,14 @@ impl<This: ExprFromIterator<A>, A> FromIterator<A> for Expr<This> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct AsTraceAsString<T: Type = CanonicalType> {
|
pub struct ToTraceAsString<T: Type = CanonicalType> {
|
||||||
inner: Expr<CanonicalType>,
|
inner: Expr<CanonicalType>,
|
||||||
ty: TraceAsString<T>,
|
ty: TraceAsString<T>,
|
||||||
literal_bits: Result<Interned<BitSlice>, NotALiteralExpr>,
|
literal_bits: Result<Interned<BitSlice>, NotALiteralExpr>,
|
||||||
target: Option<Interned<Target>>,
|
target: Option<Interned<Target>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> fmt::Debug for AsTraceAsString<T> {
|
impl<T: Type> fmt::Debug for ToTraceAsString<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let Self {
|
let Self {
|
||||||
inner,
|
inner,
|
||||||
|
|
@ -4712,24 +4712,25 @@ impl<T: Type> fmt::Debug for AsTraceAsString<T> {
|
||||||
literal_bits: _,
|
literal_bits: _,
|
||||||
target: _,
|
target: _,
|
||||||
} = self;
|
} = self;
|
||||||
f.debug_struct("AsTraceAsString")
|
f.debug_struct("ToTraceAsString")
|
||||||
.field("inner", inner)
|
.field("inner", inner)
|
||||||
.finish_non_exhaustive()
|
.finish_non_exhaustive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> AsTraceAsString<T> {
|
impl<T: Type> ToTraceAsString<T> {
|
||||||
pub fn new(inner: Expr<CanonicalType>, ty: TraceAsString<T>) -> Self {
|
pub fn new(inner: Expr<CanonicalType>, ty: TraceAsString<T>) -> Self {
|
||||||
assert_eq!(inner.ty(), ty.inner_ty().canonical());
|
assert_eq!(inner.ty(), ty.inner_ty().canonical());
|
||||||
let literal_bits = inner.to_literal_bits();
|
let literal_bits = inner.to_literal_bits();
|
||||||
let target = inner.target().map(|base| {
|
let target = inner.target().map(|base| {
|
||||||
Intern::intern_sized(
|
Intern::intern_sized(
|
||||||
base.join(TargetPathElement::intern_sized(
|
base.join(TargetPathElement::intern_sized(
|
||||||
TargetPathAsTraceAsString {
|
TargetPathToTraceAsString {
|
||||||
ty: ty.canonical_trace_as_string(),
|
ty: ty.canonical_trace_as_string(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
)),
|
))
|
||||||
|
.canonicalized(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -4744,19 +4745,19 @@ impl<T: Type> AsTraceAsString<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> GetTarget for AsTraceAsString<T> {
|
impl<T: Type> GetTarget for ToTraceAsString<T> {
|
||||||
fn target(&self) -> Option<Interned<Target>> {
|
fn target(&self) -> Option<Interned<Target>> {
|
||||||
self.target
|
self.target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> ToLiteralBits for AsTraceAsString<T> {
|
impl<T: Type> ToLiteralBits for ToTraceAsString<T> {
|
||||||
fn to_literal_bits(&self) -> Result<Interned<BitSlice>, NotALiteralExpr> {
|
fn to_literal_bits(&self) -> Result<Interned<BitSlice>, NotALiteralExpr> {
|
||||||
self.literal_bits
|
self.literal_bits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> ValueType for AsTraceAsString<T> {
|
impl<T: Type> ValueType for ToTraceAsString<T> {
|
||||||
type Type = TraceAsString<T>;
|
type Type = TraceAsString<T>;
|
||||||
type ValueCategory = ValueCategoryExpr;
|
type ValueCategory = ValueCategoryExpr;
|
||||||
|
|
||||||
|
|
@ -4765,10 +4766,10 @@ impl<T: Type> ValueType for AsTraceAsString<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> ToExpr for AsTraceAsString<T> {
|
impl<T: Type> ToExpr for ToTraceAsString<T> {
|
||||||
fn to_expr(&self) -> Expr<Self::Type> {
|
fn to_expr(&self) -> Expr<Self::Type> {
|
||||||
Expr {
|
Expr {
|
||||||
__enum: ExprEnum::AsTraceAsString(AsTraceAsString {
|
__enum: ExprEnum::ToTraceAsString(ToTraceAsString {
|
||||||
inner: self.inner,
|
inner: self.inner,
|
||||||
ty: self.ty.canonical_trace_as_string(),
|
ty: self.ty.canonical_trace_as_string(),
|
||||||
literal_bits: self.literal_bits,
|
literal_bits: self.literal_bits,
|
||||||
|
|
@ -4808,9 +4809,12 @@ impl<T: Type> TraceAsStringAsInner<T> {
|
||||||
assert_eq!(arg.ty().inner_ty(), ty.canonical());
|
assert_eq!(arg.ty().inner_ty(), ty.canonical());
|
||||||
let literal_bits = arg.to_literal_bits();
|
let literal_bits = arg.to_literal_bits();
|
||||||
let target = arg.target().map(|base| {
|
let target = arg.target().map(|base| {
|
||||||
Intern::intern_sized(base.join(TargetPathElement::intern_sized(
|
Intern::intern_sized(
|
||||||
TargetPathTraceAsStringInner {}.into(),
|
base.join(TargetPathElement::intern_sized(
|
||||||
)))
|
TargetPathTraceAsStringInner {}.into(),
|
||||||
|
))
|
||||||
|
.canonicalized(),
|
||||||
|
)
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
arg,
|
arg,
|
||||||
|
|
|
||||||
|
|
@ -56,13 +56,13 @@ impl fmt::Display for TargetPathTraceAsStringInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct TargetPathAsTraceAsString {
|
pub struct TargetPathToTraceAsString {
|
||||||
pub ty: TraceAsString<CanonicalType>,
|
pub ty: TraceAsString<CanonicalType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for TargetPathAsTraceAsString {
|
impl fmt::Display for TargetPathToTraceAsString {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, ".as_trace_as_string(...)")
|
write!(f, ".to_trace_as_string(...)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ pub enum TargetPathElement {
|
||||||
ArrayElement(TargetPathArrayElement),
|
ArrayElement(TargetPathArrayElement),
|
||||||
DynArrayElement(TargetPathDynArrayElement),
|
DynArrayElement(TargetPathDynArrayElement),
|
||||||
TraceAsStringInner(TargetPathTraceAsStringInner),
|
TraceAsStringInner(TargetPathTraceAsStringInner),
|
||||||
AsTraceAsString(TargetPathAsTraceAsString),
|
ToTraceAsString(TargetPathToTraceAsString),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TargetPathBundleField> for TargetPathElement {
|
impl From<TargetPathBundleField> for TargetPathElement {
|
||||||
|
|
@ -99,9 +99,9 @@ impl From<TargetPathTraceAsStringInner> for TargetPathElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TargetPathAsTraceAsString> for TargetPathElement {
|
impl From<TargetPathToTraceAsString> for TargetPathElement {
|
||||||
fn from(value: TargetPathAsTraceAsString) -> Self {
|
fn from(value: TargetPathToTraceAsString) -> Self {
|
||||||
Self::AsTraceAsString(value)
|
Self::ToTraceAsString(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ impl fmt::Display for TargetPathElement {
|
||||||
Self::ArrayElement(v) => v.fmt(f),
|
Self::ArrayElement(v) => v.fmt(f),
|
||||||
Self::DynArrayElement(v) => v.fmt(f),
|
Self::DynArrayElement(v) => v.fmt(f),
|
||||||
Self::TraceAsStringInner(v) => v.fmt(f),
|
Self::TraceAsStringInner(v) => v.fmt(f),
|
||||||
Self::AsTraceAsString(v) => v.fmt(f),
|
Self::ToTraceAsString(v) => v.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +141,7 @@ impl TargetPathElement {
|
||||||
TraceAsString::<CanonicalType>::from_canonical(parent.canonical_ty());
|
TraceAsString::<CanonicalType>::from_canonical(parent.canonical_ty());
|
||||||
parent_ty.inner_ty()
|
parent_ty.inner_ty()
|
||||||
}
|
}
|
||||||
&Self::AsTraceAsString(TargetPathAsTraceAsString { ty }) => {
|
&Self::ToTraceAsString(TargetPathToTraceAsString { ty }) => {
|
||||||
assert_eq!(parent.canonical_ty(), ty.inner_ty());
|
assert_eq!(parent.canonical_ty(), ty.inner_ty());
|
||||||
ty.canonical()
|
ty.canonical()
|
||||||
}
|
}
|
||||||
|
|
@ -159,7 +159,7 @@ impl TargetPathElement {
|
||||||
Self::ArrayElement(_)
|
Self::ArrayElement(_)
|
||||||
| Self::DynArrayElement(_)
|
| Self::DynArrayElement(_)
|
||||||
| Self::TraceAsStringInner(_)
|
| Self::TraceAsStringInner(_)
|
||||||
| Self::AsTraceAsString(_) => parent.flow(),
|
| Self::ToTraceAsString(_) => parent.flow(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_static(&self) -> bool {
|
pub fn is_static(&self) -> bool {
|
||||||
|
|
@ -167,7 +167,7 @@ impl TargetPathElement {
|
||||||
Self::BundleField(_)
|
Self::BundleField(_)
|
||||||
| Self::ArrayElement(_)
|
| Self::ArrayElement(_)
|
||||||
| Self::TraceAsStringInner(_)
|
| Self::TraceAsStringInner(_)
|
||||||
| Self::AsTraceAsString(_) => true,
|
| Self::ToTraceAsString(_) => true,
|
||||||
Self::DynArrayElement(_) => false,
|
Self::DynArrayElement(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -364,6 +364,7 @@ pub struct TargetChild {
|
||||||
path_element: Interned<TargetPathElement>,
|
path_element: Interned<TargetPathElement>,
|
||||||
canonical_ty: CanonicalType,
|
canonical_ty: CanonicalType,
|
||||||
flow: Flow,
|
flow: Flow,
|
||||||
|
canonicalized_if_different: Option<Interned<Target>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for TargetChild {
|
impl fmt::Debug for TargetChild {
|
||||||
|
|
@ -373,6 +374,7 @@ impl fmt::Debug for TargetChild {
|
||||||
path_element,
|
path_element,
|
||||||
canonical_ty: _,
|
canonical_ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
|
canonicalized_if_different: _,
|
||||||
} = self;
|
} = self;
|
||||||
parent.fmt(f)?;
|
parent.fmt(f)?;
|
||||||
fmt::Display::fmt(path_element, f)
|
fmt::Display::fmt(path_element, f)
|
||||||
|
|
@ -386,6 +388,7 @@ impl fmt::Display for TargetChild {
|
||||||
path_element,
|
path_element,
|
||||||
canonical_ty: _,
|
canonical_ty: _,
|
||||||
flow: _,
|
flow: _,
|
||||||
|
canonicalized_if_different: _,
|
||||||
} = self;
|
} = self;
|
||||||
parent.fmt(f)?;
|
parent.fmt(f)?;
|
||||||
path_element.fmt(f)
|
path_element.fmt(f)
|
||||||
|
|
@ -393,14 +396,69 @@ impl fmt::Display for TargetChild {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetChild {
|
impl TargetChild {
|
||||||
pub fn new(parent: Interned<Target>, path_element: Interned<TargetPathElement>) -> Self {
|
fn new_helper(
|
||||||
|
parent: Interned<Target>,
|
||||||
|
path_element: Interned<TargetPathElement>,
|
||||||
|
canonicalized_if_different: Option<Interned<Target>>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
parent,
|
parent,
|
||||||
path_element,
|
path_element,
|
||||||
canonical_ty: path_element.canonical_ty(parent),
|
canonical_ty: path_element.canonical_ty(parent),
|
||||||
flow: path_element.flow(parent),
|
flow: path_element.flow(parent),
|
||||||
|
canonicalized_if_different,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn make_canonicalized_if_different(
|
||||||
|
parent: Interned<Target>,
|
||||||
|
path_element: Interned<TargetPathElement>,
|
||||||
|
) -> Option<Interned<Target>> {
|
||||||
|
use TargetPathElement::*;
|
||||||
|
match *path_element {
|
||||||
|
BundleField(_) => {}
|
||||||
|
ArrayElement(_) => {}
|
||||||
|
DynArrayElement(_) => {}
|
||||||
|
TraceAsStringInner(_) => {
|
||||||
|
if let Some(child) = parent.canonicalized().child() {
|
||||||
|
match *child.path_element() {
|
||||||
|
BundleField(_)
|
||||||
|
| ArrayElement(_)
|
||||||
|
| DynArrayElement(_)
|
||||||
|
| TraceAsStringInner(_) => {}
|
||||||
|
ToTraceAsString(_) => return Some(child.parent()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ToTraceAsString(TargetPathToTraceAsString { ty }) => {
|
||||||
|
if let Some(child) = parent.canonicalized().child() {
|
||||||
|
match *child.path_element() {
|
||||||
|
BundleField(_) | ArrayElement(_) | DynArrayElement(_)
|
||||||
|
| ToTraceAsString(_) => {}
|
||||||
|
TraceAsStringInner(_) => {
|
||||||
|
if ty.canonical() == child.parent().canonical_ty() {
|
||||||
|
return Some(child.parent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(
|
||||||
|
Target::Child(Self::new_helper(
|
||||||
|
parent.canonicalized_if_different()?,
|
||||||
|
path_element,
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
.intern_sized(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn new(parent: Interned<Target>, path_element: Interned<TargetPathElement>) -> Self {
|
||||||
|
Self::new_helper(
|
||||||
|
parent,
|
||||||
|
path_element,
|
||||||
|
Self::make_canonicalized_if_different(parent, path_element),
|
||||||
|
)
|
||||||
|
}
|
||||||
pub fn parent(self) -> Interned<Target> {
|
pub fn parent(self) -> Interned<Target> {
|
||||||
self.parent
|
self.parent
|
||||||
}
|
}
|
||||||
|
|
@ -413,6 +471,19 @@ impl TargetChild {
|
||||||
pub fn flow(self) -> Flow {
|
pub fn flow(self) -> Flow {
|
||||||
self.flow
|
self.flow
|
||||||
}
|
}
|
||||||
|
pub fn is_canonicalized(self) -> bool {
|
||||||
|
self.canonicalized_if_different.is_none()
|
||||||
|
}
|
||||||
|
pub fn canonicalized_if_different(self) -> Option<Interned<Target>> {
|
||||||
|
self.canonicalized_if_different
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn canonicalized(self) -> Target {
|
||||||
|
match self.canonicalized_if_different {
|
||||||
|
Some(v) => *v,
|
||||||
|
None => Target::Child(self),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn bundle_field(self) -> Option<BundleField> {
|
pub fn bundle_field(self) -> Option<BundleField> {
|
||||||
if let TargetPathElement::BundleField(TargetPathBundleField { name }) = *self.path_element {
|
if let TargetPathElement::BundleField(TargetPathBundleField { name }) = *self.path_element {
|
||||||
let parent_ty = Bundle::from_canonical(self.parent.canonical_ty());
|
let parent_ty = Bundle::from_canonical(self.parent.canonical_ty());
|
||||||
|
|
@ -493,6 +564,82 @@ impl Target {
|
||||||
Target::Child(v) => v.canonical_ty(),
|
Target::Child(v) => v.canonical_ty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn is_canonicalized(self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Base(_) => true,
|
||||||
|
Self::Child(child) => child.is_canonicalized(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn canonicalized_if_different(self) -> Option<Interned<Self>> {
|
||||||
|
match self {
|
||||||
|
Self::Base(_) => None,
|
||||||
|
Self::Child(child) => child.canonicalized_if_different(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn canonicalized(self) -> Target {
|
||||||
|
match self.canonicalized_if_different() {
|
||||||
|
Some(v) => *v,
|
||||||
|
None => self,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn canonicalized_interned(this: Interned<Target>) -> Interned<Target> {
|
||||||
|
this.canonicalized_if_different().unwrap_or(this)
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn unwrap_transparent_types(mut self) -> Target {
|
||||||
|
loop {
|
||||||
|
self = self.canonicalized();
|
||||||
|
match self.canonical_ty() {
|
||||||
|
CanonicalType::UInt(_)
|
||||||
|
| CanonicalType::SInt(_)
|
||||||
|
| CanonicalType::Bool(_)
|
||||||
|
| CanonicalType::Array(_)
|
||||||
|
| CanonicalType::Enum(_)
|
||||||
|
| CanonicalType::Bundle(_)
|
||||||
|
| CanonicalType::AsyncReset(_)
|
||||||
|
| CanonicalType::SyncReset(_)
|
||||||
|
| CanonicalType::Reset(_)
|
||||||
|
| CanonicalType::Clock(_)
|
||||||
|
| CanonicalType::PhantomConst(_)
|
||||||
|
| CanonicalType::DynSimOnly(_) => return self,
|
||||||
|
CanonicalType::TraceAsString(_) => {
|
||||||
|
if let Self::Child(child) = self
|
||||||
|
&& let TargetPathElement::ToTraceAsString(_) = *child.path_element()
|
||||||
|
{
|
||||||
|
self = *child.parent();
|
||||||
|
} else {
|
||||||
|
self = self.join(TargetPathElement::intern_sized(
|
||||||
|
TargetPathTraceAsStringInner {}.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn unwrap_transparent_types_interned(this: Interned<Target>) -> Interned<Target> {
|
||||||
|
let retval = this.unwrap_transparent_types();
|
||||||
|
if retval != *this {
|
||||||
|
retval.intern_sized()
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn without_trailing_transparent_path_elements(mut self) -> Target {
|
||||||
|
use TargetPathElement::*;
|
||||||
|
loop {
|
||||||
|
match self {
|
||||||
|
Self::Base(_) => return self,
|
||||||
|
Self::Child(child) => match *child.path_element() {
|
||||||
|
BundleField(_) | ArrayElement(_) | DynArrayElement(_) => return self,
|
||||||
|
TraceAsStringInner(_) | ToTraceAsString(_) => self = *child.parent(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Target {
|
impl fmt::Display for Target {
|
||||||
|
|
|
||||||
|
|
@ -1802,7 +1802,7 @@ impl<'a> Exporter<'a> {
|
||||||
write!(out, "[{index}]").unwrap();
|
write!(out, "[{index}]").unwrap();
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
ExprEnum::AsTraceAsString(expr) => self.expr(expr.inner(), definitions, const_ty),
|
ExprEnum::ToTraceAsString(expr) => self.expr(expr.inner(), definitions, const_ty),
|
||||||
ExprEnum::TraceAsStringAsInner(expr) => {
|
ExprEnum::TraceAsStringAsInner(expr) => {
|
||||||
self.expr(Expr::canonical(expr.arg()), definitions, const_ty)
|
self.expr(Expr::canonical(expr.arg()), definitions, const_ty)
|
||||||
}
|
}
|
||||||
|
|
@ -1965,7 +1965,7 @@ impl<'a> Exporter<'a> {
|
||||||
.segments
|
.segments
|
||||||
.push(AnnotationTargetRefSegment::Index { index }),
|
.push(AnnotationTargetRefSegment::Index { index }),
|
||||||
TargetPathElement::DynArrayElement(_) => unreachable!(),
|
TargetPathElement::DynArrayElement(_) => unreachable!(),
|
||||||
TargetPathElement::AsTraceAsString(_)
|
TargetPathElement::ToTraceAsString(_)
|
||||||
| TargetPathElement::TraceAsStringInner(_) => {
|
| TargetPathElement::TraceAsStringInner(_) => {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
@ -3223,7 +3223,7 @@ impl ScalarizeTreeNode {
|
||||||
TargetPathElement::DynArrayElement(_) => {
|
TargetPathElement::DynArrayElement(_) => {
|
||||||
unreachable!("annotations are only on static targets");
|
unreachable!("annotations are only on static targets");
|
||||||
}
|
}
|
||||||
TargetPathElement::AsTraceAsString(_)
|
TargetPathElement::ToTraceAsString(_)
|
||||||
| TargetPathElement::TraceAsStringInner(_) => parent,
|
| TargetPathElement::TraceAsStringInner(_) => parent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
ops::VariantAccess,
|
ops::VariantAccess,
|
||||||
target::{
|
target::{
|
||||||
GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField,
|
GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathElement, TargetPathTraceAsStringInner,
|
TargetPathElement,
|
||||||
},
|
},
|
||||||
value_category::ValueCategoryExpr,
|
value_category::ValueCategoryExpr,
|
||||||
},
|
},
|
||||||
|
|
@ -1113,7 +1113,7 @@ fn validate_clock_for_past<S: ModuleBuildingStatus>(
|
||||||
match *child.path_element() {
|
match *child.path_element() {
|
||||||
TargetPathElement::BundleField(_)
|
TargetPathElement::BundleField(_)
|
||||||
| TargetPathElement::ArrayElement(_)
|
| TargetPathElement::ArrayElement(_)
|
||||||
| TargetPathElement::AsTraceAsString(_)
|
| TargetPathElement::ToTraceAsString(_)
|
||||||
| TargetPathElement::TraceAsStringInner(_) => {}
|
| TargetPathElement::TraceAsStringInner(_) => {}
|
||||||
TargetPathElement::DynArrayElement(_) => {
|
TargetPathElement::DynArrayElement(_) => {
|
||||||
panic!(
|
panic!(
|
||||||
|
|
@ -1538,6 +1538,7 @@ impl TargetState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn new(target: Interned<Target>, declared_in_block: usize) -> Self {
|
fn new(target: Interned<Target>, declared_in_block: usize) -> Self {
|
||||||
|
let target = Target::unwrap_transparent_types_interned(target);
|
||||||
Self {
|
Self {
|
||||||
target,
|
target,
|
||||||
inner: match target.canonical_ty() {
|
inner: match target.canonical_ty() {
|
||||||
|
|
@ -1590,12 +1591,7 @@ impl TargetState {
|
||||||
written_in_blocks: RefCell::default(),
|
written_in_blocks: RefCell::default(),
|
||||||
},
|
},
|
||||||
CanonicalType::TraceAsString(_) => {
|
CanonicalType::TraceAsString(_) => {
|
||||||
return Self::new(
|
unreachable!("handled by Target::unwrap_transparent_types_interned")
|
||||||
target
|
|
||||||
.join(Intern::intern_sized(TargetPathTraceAsStringInner {}.into()))
|
|
||||||
.intern_sized(),
|
|
||||||
declared_in_block,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -1616,13 +1612,14 @@ impl AssertValidityState {
|
||||||
}
|
}
|
||||||
fn get_target_states<'a>(
|
fn get_target_states<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
mut target: &Target,
|
target: Target,
|
||||||
process_target_state: &dyn Fn(&'a TargetState, bool),
|
process_target_state: &dyn Fn(&'a TargetState, bool),
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
|
let mut target = target.unwrap_transparent_types();
|
||||||
loop {
|
loop {
|
||||||
break match target {
|
break match target {
|
||||||
Target::Base(target_base) => {
|
Target::Base(target_base) => {
|
||||||
let target_state = self.get_base_state(*target_base)?;
|
let target_state = self.get_base_state(target_base)?;
|
||||||
process_target_state(target_state, false);
|
process_target_state(target_state, false);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -1630,7 +1627,7 @@ impl AssertValidityState {
|
||||||
TargetPathElement::BundleField(_)
|
TargetPathElement::BundleField(_)
|
||||||
| TargetPathElement::ArrayElement(_)
|
| TargetPathElement::ArrayElement(_)
|
||||||
| TargetPathElement::DynArrayElement(_) => self.get_target_states(
|
| TargetPathElement::DynArrayElement(_) => self.get_target_states(
|
||||||
&target_child.parent(),
|
*target_child.parent(),
|
||||||
&|target_state, exact_target_unknown| {
|
&|target_state, exact_target_unknown| {
|
||||||
let TargetStateInner::Decomposed { subtargets } = &target_state.inner
|
let TargetStateInner::Decomposed { subtargets } = &target_state.inner
|
||||||
else {
|
else {
|
||||||
|
|
@ -1657,13 +1654,13 @@ impl AssertValidityState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetPathElement::TraceAsStringInner(_)
|
TargetPathElement::TraceAsStringInner(_)
|
||||||
| TargetPathElement::AsTraceAsString(_) => unreachable!(),
|
| TargetPathElement::ToTraceAsString(_) => unreachable!(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
TargetPathElement::TraceAsStringInner(_)
|
TargetPathElement::TraceAsStringInner(_)
|
||||||
| TargetPathElement::AsTraceAsString(_) => {
|
| TargetPathElement::ToTraceAsString(_) => {
|
||||||
target = Interned::into_inner(target_child.parent());
|
target = *target_child.parent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1718,6 +1715,7 @@ impl AssertValidityState {
|
||||||
&TargetPathElement::BundleField(_) => {
|
&TargetPathElement::BundleField(_) => {
|
||||||
let field = sub_target_state
|
let field = sub_target_state
|
||||||
.target
|
.target
|
||||||
|
.without_trailing_transparent_path_elements()
|
||||||
.child()
|
.child()
|
||||||
.expect("known to be a child")
|
.expect("known to be a child")
|
||||||
.bundle_field()
|
.bundle_field()
|
||||||
|
|
@ -1742,7 +1740,7 @@ impl AssertValidityState {
|
||||||
Self::set_connect_target_written(sub_target_state, is_lhs, block, true);
|
Self::set_connect_target_written(sub_target_state, is_lhs, block, true);
|
||||||
}
|
}
|
||||||
TargetPathElement::TraceAsStringInner(_)
|
TargetPathElement::TraceAsStringInner(_)
|
||||||
| TargetPathElement::AsTraceAsString(_) => unreachable!("never added"),
|
| TargetPathElement::ToTraceAsString(_) => unreachable!("never added"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1760,7 +1758,7 @@ impl AssertValidityState {
|
||||||
debug_assert!(!is_lhs, "the ModuleBuilder asserts lhs.target().is_some()");
|
debug_assert!(!is_lhs, "the ModuleBuilder asserts lhs.target().is_some()");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let result = self.get_target_states(&target, &|target_state, exact_target_unknown| {
|
let result = self.get_target_states(*target, &|target_state, exact_target_unknown| {
|
||||||
Self::set_connect_target_written(target_state, is_lhs, block, exact_target_unknown);
|
Self::set_connect_target_written(target_state, is_lhs, block, exact_target_unknown);
|
||||||
});
|
});
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ use crate::{
|
||||||
ExprEnum, ValueType,
|
ExprEnum, ValueType,
|
||||||
ops::{self, ArrayLiteral},
|
ops::{self, ArrayLiteral},
|
||||||
target::{
|
target::{
|
||||||
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathAsTraceAsString,
|
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathBundleField, TargetPathDynArrayElement, TargetPathElement,
|
TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString,
|
||||||
TargetPathTraceAsStringInner,
|
TargetPathTraceAsStringInner,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -1207,7 +1207,7 @@ impl<P: Pass> RunPass<P> for ExprEnum {
|
||||||
ExprEnum::TraceAsStringAsInner(expr) => {
|
ExprEnum::TraceAsStringAsInner(expr) => {
|
||||||
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
Ok(expr.run_pass(pass_args)?.map(ExprEnum::from))
|
||||||
}
|
}
|
||||||
ExprEnum::AsTraceAsString(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::ToTraceAsString(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::ModuleIO(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::ModuleIO(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::Instance(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::Instance(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
ExprEnum::Wire(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
ExprEnum::Wire(expr) => Ok(expr.run_pass(pass_args)?.map(ExprEnum::from)),
|
||||||
|
|
@ -1617,7 +1617,7 @@ impl RunPassExpr for ops::TraceAsStringAsInner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunPassExpr for ops::AsTraceAsString {
|
impl RunPassExpr for ops::ToTraceAsString {
|
||||||
type Args<'a> = [Expr<CanonicalType>; 1];
|
type Args<'a> = [Expr<CanonicalType>; 1];
|
||||||
|
|
||||||
fn args<'a>(&'a self) -> Self::Args<'a> {
|
fn args<'a>(&'a self) -> Self::Args<'a> {
|
||||||
|
|
@ -2307,8 +2307,8 @@ impl<P: Pass> RunPass<P> for TargetChild {
|
||||||
| TargetPathElement::TraceAsStringInner(TargetPathTraceAsStringInner {}) => {
|
| TargetPathElement::TraceAsStringInner(TargetPathTraceAsStringInner {}) => {
|
||||||
self.path_element()
|
self.path_element()
|
||||||
}
|
}
|
||||||
TargetPathElement::AsTraceAsString(TargetPathAsTraceAsString { ty }) => {
|
TargetPathElement::ToTraceAsString(TargetPathToTraceAsString { ty }) => {
|
||||||
TargetPathElement::from(TargetPathAsTraceAsString {
|
TargetPathElement::from(TargetPathToTraceAsString {
|
||||||
ty: ty.with_new_inner_ty(parent.canonical_ty().intern_sized()),
|
ty: ty.with_new_inner_ty(parent.canonical_ty().intern_sized()),
|
||||||
})
|
})
|
||||||
.intern_sized()
|
.intern_sized()
|
||||||
|
|
|
||||||
|
|
@ -807,7 +807,7 @@ impl Folder for State {
|
||||||
| ExprEnum::CastToBits(_)
|
| ExprEnum::CastToBits(_)
|
||||||
| ExprEnum::CastBitsTo(_)
|
| ExprEnum::CastBitsTo(_)
|
||||||
| ExprEnum::TraceAsStringAsInner(_)
|
| ExprEnum::TraceAsStringAsInner(_)
|
||||||
| ExprEnum::AsTraceAsString(_)
|
| ExprEnum::ToTraceAsString(_)
|
||||||
| ExprEnum::ModuleIO(_)
|
| ExprEnum::ModuleIO(_)
|
||||||
| ExprEnum::Instance(_)
|
| ExprEnum::Instance(_)
|
||||||
| ExprEnum::Wire(_)
|
| ExprEnum::Wire(_)
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ use crate::{
|
||||||
expr::{
|
expr::{
|
||||||
Expr, ExprEnum, ValueType, ops,
|
Expr, ExprEnum, ValueType, ops,
|
||||||
target::{
|
target::{
|
||||||
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathAsTraceAsString,
|
Target, TargetBase, TargetChild, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathBundleField, TargetPathDynArrayElement, TargetPathElement,
|
TargetPathDynArrayElement, TargetPathElement, TargetPathToTraceAsString,
|
||||||
TargetPathTraceAsStringInner,
|
TargetPathTraceAsStringInner,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ pub use crate::{
|
||||||
enum_::{Enum, HdlNone, HdlOption, HdlSome},
|
enum_::{Enum, HdlNone, HdlOption, HdlSome},
|
||||||
expr::{
|
expr::{
|
||||||
CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr,
|
CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr,
|
||||||
ReduceBits, ToExpr, ValueType, repeat,
|
ReduceBits, ToExpr, ToTraceAsString, ValueType, repeat,
|
||||||
},
|
},
|
||||||
formal::{
|
formal::{
|
||||||
MakeFormalExpr, all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset,
|
MakeFormalExpr, all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset,
|
||||||
|
|
@ -38,7 +38,7 @@ pub use crate::{
|
||||||
},
|
},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
testing::{FormalMode, assert_formal},
|
testing::{FormalMode, assert_formal},
|
||||||
ty::{AsMask, CanonicalType, Type},
|
ty::{AsMask, CanonicalType, TraceAsString, Type},
|
||||||
util::{ConstUsize, GenericConstUsize},
|
util::{ConstUsize, GenericConstUsize},
|
||||||
wire::Wire,
|
wire::Wire,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1307,7 +1307,7 @@ impl SimulationModuleState {
|
||||||
TargetPathElement::BundleField(_)
|
TargetPathElement::BundleField(_)
|
||||||
| TargetPathElement::ArrayElement(_)
|
| TargetPathElement::ArrayElement(_)
|
||||||
| TargetPathElement::TraceAsStringInner(_)
|
| TargetPathElement::TraceAsStringInner(_)
|
||||||
| TargetPathElement::AsTraceAsString(_) => {}
|
| TargetPathElement::ToTraceAsString(_) => {}
|
||||||
TargetPathElement::DynArrayElement(_) => panic!(
|
TargetPathElement::DynArrayElement(_) => panic!(
|
||||||
"simulator read/write expression must not have dynamic array indexes"
|
"simulator read/write expression must not have dynamic array indexes"
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ use crate::{
|
||||||
expr::{
|
expr::{
|
||||||
ExprEnum, Flow, ValueType, ops,
|
ExprEnum, Flow, ValueType, ops,
|
||||||
target::{
|
target::{
|
||||||
GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathAsTraceAsString,
|
GetTarget, Target, TargetBase, TargetPathArrayElement, TargetPathBundleField,
|
||||||
TargetPathBundleField, TargetPathElement, TargetPathTraceAsStringInner,
|
TargetPathElement, TargetPathToTraceAsString, TargetPathTraceAsStringInner,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
int::BoolOrIntType,
|
int::BoolOrIntType,
|
||||||
|
|
@ -2686,7 +2686,7 @@ impl Compiler {
|
||||||
TargetPathElement::TraceAsStringInner(TargetPathTraceAsStringInner {}) => {
|
TargetPathElement::TraceAsStringInner(TargetPathTraceAsStringInner {}) => {
|
||||||
parent.map_ty(TraceAsString::from_canonical).inner()
|
parent.map_ty(TraceAsString::from_canonical).inner()
|
||||||
}
|
}
|
||||||
TargetPathElement::AsTraceAsString(TargetPathAsTraceAsString { ty }) => parent
|
TargetPathElement::ToTraceAsString(TargetPathToTraceAsString { ty }) => parent
|
||||||
.wrap_in_trace_as_string(ty)
|
.wrap_in_trace_as_string(ty)
|
||||||
.map_ty(|ty| ty.canonical()),
|
.map_ty(|ty| ty.canonical()),
|
||||||
}
|
}
|
||||||
|
|
@ -3017,7 +3017,7 @@ impl Compiler {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
CanonicalType::TraceAsString(ty) => Expr::canonical(
|
CanonicalType::TraceAsString(ty) => Expr::canonical(
|
||||||
ops::AsTraceAsString::new(
|
ops::ToTraceAsString::new(
|
||||||
match arg {
|
match arg {
|
||||||
Some(arg) => arg.cast_bits_to(ty.inner_ty()),
|
Some(arg) => arg.cast_bits_to(ty.inner_ty()),
|
||||||
None => ty.inner_ty().uninit(),
|
None => ty.inner_ty().uninit(),
|
||||||
|
|
@ -3838,7 +3838,7 @@ impl Compiler {
|
||||||
ExprEnum::CastBitsTo(expr) => self
|
ExprEnum::CastBitsTo(expr) => self
|
||||||
.compile_cast_bits_to_or_uninit(instantiated_module, Some(expr.arg()), expr.ty())
|
.compile_cast_bits_to_or_uninit(instantiated_module, Some(expr.arg()), expr.ty())
|
||||||
.into(),
|
.into(),
|
||||||
ExprEnum::AsTraceAsString(expr) => self
|
ExprEnum::ToTraceAsString(expr) => self
|
||||||
.compile_expr(instantiated_module, expr.inner())
|
.compile_expr(instantiated_module, expr.inner())
|
||||||
.wrap_in_trace_as_string(expr.ty())
|
.wrap_in_trace_as_string(expr.ty())
|
||||||
.map_ty(|ty| ty.canonical()),
|
.map_ty(|ty| ty.canonical()),
|
||||||
|
|
|
||||||
|
|
@ -19,20 +19,19 @@ use crate::{
|
||||||
impl_match_variant_as_self,
|
impl_match_variant_as_self,
|
||||||
},
|
},
|
||||||
util::{
|
util::{
|
||||||
ConstUsize, HashMap,
|
ConstUsize,
|
||||||
alternating_cell::{AlternatingCell, AlternatingCellMethods},
|
alternating_cell::{AlternatingCell, AlternatingCellMethods},
|
||||||
|
serde_by_id::{SerdeById, SerdeByIdProperties, SerdeByIdTable, SerdeByIdTrait},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bitvec::{slice::BitSlice, vec::BitVec};
|
use bitvec::{slice::BitSlice, vec::BitVec};
|
||||||
use hashbrown::hash_map::Entry;
|
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::{Borrow, BorrowMut, Cow},
|
borrow::{Borrow, BorrowMut, Cow},
|
||||||
fmt::{self, Write},
|
fmt,
|
||||||
hash::{BuildHasher, Hash, Hasher, RandomState},
|
|
||||||
num::NonZero,
|
num::NonZero,
|
||||||
ops::{Deref, DerefMut, Index, IndexMut},
|
ops::{Deref, DerefMut, Index, IndexMut},
|
||||||
sync::{Arc, Mutex},
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) mod sim_only_value_unsafe;
|
pub(crate) mod sim_only_value_unsafe;
|
||||||
|
|
@ -1228,80 +1227,17 @@ macro_rules! impl_to_sim_value_for_int_value {
|
||||||
impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType);
|
impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType);
|
||||||
impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType);
|
impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType);
|
||||||
|
|
||||||
#[derive(Default)]
|
impl SerdeByIdTrait for DynSimOnly {
|
||||||
struct DynSimOnlySerdeTableRest {
|
fn serde_by_id_properties(&self) -> SerdeByIdProperties<Self> {
|
||||||
from_serde: HashMap<DynSimOnlySerdeId, DynSimOnly>,
|
self.serde_by_id_properties_inner()
|
||||||
serde_id_random_state: RandomState,
|
|
||||||
buffer: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DynSimOnlySerdeTableRest {
|
|
||||||
#[cold]
|
|
||||||
fn add_new(&mut self, ty: DynSimOnly) -> DynSimOnlySerdeId {
|
|
||||||
let mut try_number = 0u64;
|
|
||||||
let mut hasher = self.serde_id_random_state.build_hasher();
|
|
||||||
// extract more bits of randomness from TypeId -- its Hash impl only hashes 64-bits
|
|
||||||
write!(self.buffer, "{:?}", ty.type_id()).expect("shouldn't ever fail");
|
|
||||||
self.buffer.hash(&mut hasher);
|
|
||||||
loop {
|
|
||||||
let mut hasher = hasher.clone();
|
|
||||||
try_number.hash(&mut hasher);
|
|
||||||
try_number += 1;
|
|
||||||
let retval = DynSimOnlySerdeId(std::array::from_fn(|i| {
|
|
||||||
let mut hasher = hasher.clone();
|
|
||||||
i.hash(&mut hasher);
|
|
||||||
hasher.finish() as u32
|
|
||||||
}));
|
|
||||||
match self.from_serde.entry(retval) {
|
|
||||||
Entry::Occupied(_) => continue,
|
|
||||||
Entry::Vacant(e) => {
|
|
||||||
e.insert(ty);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
fn static_table() -> &'static SerdeByIdTable<Self> {
|
||||||
struct DynSimOnlySerdeTable {
|
static TABLE: SerdeByIdTable<DynSimOnly> = SerdeByIdTable::new();
|
||||||
to_serde: HashMap<DynSimOnly, DynSimOnlySerdeId>,
|
&TABLE
|
||||||
rest: DynSimOnlySerdeTableRest,
|
|
||||||
}
|
|
||||||
|
|
||||||
static DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE: Mutex<Option<DynSimOnlySerdeTable>> = Mutex::new(None);
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(transparent)]
|
|
||||||
struct DynSimOnlySerdeId([u32; 4]);
|
|
||||||
|
|
||||||
impl From<DynSimOnly> for DynSimOnlySerdeId {
|
|
||||||
fn from(ty: DynSimOnly) -> Self {
|
|
||||||
let mut locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE
|
|
||||||
.lock()
|
|
||||||
.expect("shouldn't be poison");
|
|
||||||
let DynSimOnlySerdeTable { to_serde, rest } = locked.get_or_insert_default();
|
|
||||||
match to_serde.entry(ty) {
|
|
||||||
Entry::Occupied(occupied_entry) => *occupied_entry.get(),
|
|
||||||
Entry::Vacant(vacant_entry) => *vacant_entry.insert(rest.add_new(ty)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl DynSimOnlySerdeId {
|
const NAME: &'static str = "DynSimOnly";
|
||||||
fn ty(self) -> Option<DynSimOnly> {
|
|
||||||
let locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE
|
|
||||||
.lock()
|
|
||||||
.expect("shouldn't be poison");
|
|
||||||
Some(*locked.as_ref()?.rest.from_serde.get(&self)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
|
|
||||||
struct DynSimOnlySerde<'a> {
|
|
||||||
random_id: DynSimOnlySerdeId,
|
|
||||||
#[serde(borrow)]
|
|
||||||
type_name: Cow<'a, str>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for DynSimOnly {
|
impl Serialize for DynSimOnly {
|
||||||
|
|
@ -1309,11 +1245,7 @@ impl Serialize for DynSimOnly {
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
DynSimOnlySerde {
|
SerdeById { inner: *self }.serialize(serializer)
|
||||||
random_id: (*self).into(),
|
|
||||||
type_name: Cow::Borrowed(self.type_name()),
|
|
||||||
}
|
|
||||||
.serialize(serializer)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1322,16 +1254,7 @@ impl<'de> Deserialize<'de> for DynSimOnly {
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let deserialized = DynSimOnlySerde::deserialize(deserializer)?;
|
Ok(SerdeById::deserialize(deserializer)?.inner)
|
||||||
let retval = deserialized
|
|
||||||
.random_id
|
|
||||||
.ty()
|
|
||||||
.filter(|ty| ty.type_name() == deserialized.type_name);
|
|
||||||
retval.ok_or_else(|| {
|
|
||||||
D::Error::custom(
|
|
||||||
"doesn't match any DynSimOnly that was serialized this time this program was run",
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@
|
||||||
|
|
||||||
//! `unsafe` parts of [`DynSimOnlyValue`]
|
//! `unsafe` parts of [`DynSimOnlyValue`]
|
||||||
|
|
||||||
use crate::expr::{ValueType, value_category::ValueCategoryValue};
|
use crate::{
|
||||||
|
expr::{ValueType, value_category::ValueCategoryValue},
|
||||||
|
util::serde_by_id::SerdeByIdProperties,
|
||||||
|
};
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
use serde::{Serialize, de::DeserializeOwned};
|
||||||
use std::{
|
use std::{
|
||||||
any::{self, TypeId},
|
any::{self, TypeId},
|
||||||
|
|
@ -33,6 +36,7 @@ unsafe trait DynSimOnlyTrait: 'static + Send + Sync {
|
||||||
&self,
|
&self,
|
||||||
json_str: &str,
|
json_str: &str,
|
||||||
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>>;
|
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>>;
|
||||||
|
fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties<DynSimOnly>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safety: `type_id_dyn` is implemented correctly
|
/// Safety: `type_id_dyn` is implemented correctly
|
||||||
|
|
@ -55,6 +59,9 @@ unsafe impl<T: SimOnlyValueTrait> DynSimOnlyTrait for SimOnly<T> {
|
||||||
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>> {
|
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>> {
|
||||||
Ok(Rc::<T>::new(serde_json::from_str(json_str)?))
|
Ok(Rc::<T>::new(serde_json::from_str(json_str)?))
|
||||||
}
|
}
|
||||||
|
fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties<DynSimOnly> {
|
||||||
|
SerdeByIdProperties::of::<T>()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Safety:
|
/// Safety:
|
||||||
|
|
@ -151,6 +158,9 @@ impl DynSimOnly {
|
||||||
pub fn default_value(self) -> DynSimOnlyValue {
|
pub fn default_value(self) -> DynSimOnlyValue {
|
||||||
DynSimOnlyValue(self.ty.default_value())
|
DynSimOnlyValue(self.ty.default_value())
|
||||||
}
|
}
|
||||||
|
pub(super) fn serde_by_id_properties_inner(self) -> SerdeByIdProperties<Self> {
|
||||||
|
self.ty.serde_by_id_properties_inner()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for DynSimOnly {
|
impl PartialEq for DynSimOnly {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
bundle::{Bundle, BundleField, BundleType},
|
bundle::{Bundle, BundleField, BundleType},
|
||||||
clock::Clock,
|
clock::Clock,
|
||||||
enum_::{Enum, EnumType, EnumVariant},
|
enum_::{Enum, EnumType, EnumVariant},
|
||||||
expr::{Expr, ToExpr, ValueType, ops},
|
expr::{Expr, HdlPartialEqImpl, HdlPartialOrdImpl, ToExpr, ValueType, Valueless, ops},
|
||||||
int::{Bool, SInt, UInt, UIntValue},
|
int::{Bool, SInt, UInt, UIntValue},
|
||||||
intern::{Intern, Interned, LazyInterned, Memoize, SupportsPtrEqWithTypeId},
|
intern::{Intern, Interned, LazyInterned, Memoize, SupportsPtrEqWithTypeId},
|
||||||
module::transform::visit::{Fold, Folder, Visit, Visitor},
|
module::transform::visit::{Fold, Folder, Visit, Visitor},
|
||||||
|
|
@ -23,6 +23,7 @@ use crate::{
|
||||||
use bitvec::{slice::BitSlice, vec::BitVec};
|
use bitvec::{slice::BitSlice, vec::BitVec};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::DeserializeOwned};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::DeserializeOwned};
|
||||||
use std::{
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
fmt::{self, Write},
|
fmt::{self, Write},
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
iter::{FusedIterator, Sum},
|
iter::{FusedIterator, Sum},
|
||||||
|
|
@ -997,9 +998,6 @@ impl OpaqueSimValue {
|
||||||
pub fn sim_only_values(&self) -> &[DynSimOnlyValue] {
|
pub fn sim_only_values(&self) -> &[DynSimOnlyValue] {
|
||||||
&self.sim_only_values
|
&self.sim_only_values
|
||||||
}
|
}
|
||||||
pub(crate) fn sim_only_values_vec(&self) -> &Vec<DynSimOnlyValue> {
|
|
||||||
&self.sim_only_values
|
|
||||||
}
|
|
||||||
pub fn sim_only_values_mut(&mut self) -> &mut Vec<DynSimOnlyValue> {
|
pub fn sim_only_values_mut(&mut self) -> &mut Vec<DynSimOnlyValue> {
|
||||||
&mut self.sim_only_values
|
&mut self.sim_only_values
|
||||||
}
|
}
|
||||||
|
|
@ -1463,14 +1461,14 @@ impl<T: Type> SimValueDebug for TraceAsString<T> {
|
||||||
value: &<Self as Type>::SimValue,
|
value: &<Self as Type>::SimValue,
|
||||||
f: &mut fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
T::sim_value_debug(value, f)
|
T::sim_value_debug(value.inner(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Type> Type for TraceAsString<T> {
|
impl<T: Type> Type for TraceAsString<T> {
|
||||||
type BaseType = TraceAsString<CanonicalType>;
|
type BaseType = TraceAsString<CanonicalType>;
|
||||||
type MaskType = T::MaskType;
|
type MaskType = T::MaskType;
|
||||||
type SimValue = TraceAsStringSimValue<T::SimValue>;
|
type SimValue = TraceAsStringSimValue<T>;
|
||||||
type MatchVariant = Expr<T>;
|
type MatchVariant = Expr<T>;
|
||||||
type MatchActiveScope = ();
|
type MatchActiveScope = ();
|
||||||
type MatchVariantAndInactiveScope = MatchVariantWithoutScope<Self::MatchVariant>;
|
type MatchVariantAndInactiveScope = MatchVariantWithoutScope<Self::MatchVariant>;
|
||||||
|
|
@ -1507,7 +1505,8 @@ impl<T: Type> Type for TraceAsString<T> {
|
||||||
|
|
||||||
fn sim_value_from_opaque(&self, opaque: OpaqueSimValueSlice<'_>) -> Self::SimValue {
|
fn sim_value_from_opaque(&self, opaque: OpaqueSimValueSlice<'_>) -> Self::SimValue {
|
||||||
TraceAsStringSimValue {
|
TraceAsStringSimValue {
|
||||||
inner: self.inner_ty.sim_value_from_opaque(opaque),
|
inner: SimValue::from_opaque(self.inner_ty(), opaque.to_owned()),
|
||||||
|
trace_as_string: self.trace_as_string.interned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1594,101 +1593,217 @@ impl<T: Type> Index<T> for TraceAsStringWithoutGenerics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, Ord, Hash, Default, Serialize, Deserialize)]
|
#[derive(Clone)]
|
||||||
pub struct TraceAsStringSimValue<T> {
|
pub struct TraceAsStringSimValue<T: Type> {
|
||||||
|
inner: SimValue<T>,
|
||||||
|
trace_as_string: Interned<dyn TraceAsStringTrait>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename = "TraceAsStringSimValue")]
|
||||||
|
struct TraceAsStringSimValueSerde<T> {
|
||||||
inner: T,
|
inner: T,
|
||||||
|
trace_as_string: crate::util::serde_by_id::SerdeById<Interned<dyn TraceAsStringTrait>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> TraceAsStringSimValue<T> {
|
impl<T: Type<SimValue: Serialize> + Serialize> Serialize for TraceAsStringSimValue<T> {
|
||||||
pub const fn new(inner: T) -> Self {
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
Self { inner }
|
where
|
||||||
}
|
S: Serializer,
|
||||||
pub fn into_inner(this: Self) -> T {
|
{
|
||||||
let Self { inner } = this;
|
let Self {
|
||||||
inner
|
inner,
|
||||||
|
trace_as_string,
|
||||||
|
} = self;
|
||||||
|
TraceAsStringSimValueSerde {
|
||||||
|
inner,
|
||||||
|
trace_as_string: crate::util::serde_by_id::SerdeById {
|
||||||
|
inner: *trace_as_string,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ValueType> ValueType for TraceAsStringSimValue<T> {
|
impl<'de, T: Type<SimValue: Deserialize<'de>> + Deserialize<'de>> Deserialize<'de>
|
||||||
type Type = TraceAsString<T::Type>;
|
|
||||||
type ValueCategory = T::ValueCategory;
|
|
||||||
|
|
||||||
fn ty(&self) -> Self::Type {
|
|
||||||
TraceAsString::new(self.inner.ty())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ToExpr> ToExpr for TraceAsStringSimValue<T> {
|
|
||||||
fn to_expr(&self) -> Expr<Self::Type> {
|
|
||||||
let inner = self.inner.to_expr();
|
|
||||||
ops::AsTraceAsString::new(Expr::canonical(inner), TraceAsString::new(inner.ty())).to_expr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: ToSimValueWithType<Ty>, Ty: Type> ToSimValueWithType<TraceAsString<Ty>>
|
|
||||||
for TraceAsStringSimValue<T>
|
for TraceAsStringSimValue<T>
|
||||||
{
|
{
|
||||||
fn to_sim_value_with_type(&self, ty: TraceAsString<Ty>) -> SimValue<TraceAsString<Ty>> {
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
let inner = self.inner.to_sim_value_with_type(ty.inner_ty());
|
where
|
||||||
let inner = SimValue::into_value(inner);
|
D: Deserializer<'de>,
|
||||||
SimValue::from_value(ty, TraceAsStringSimValue { inner })
|
{
|
||||||
}
|
let TraceAsStringSimValueSerde {
|
||||||
fn into_sim_value_with_type(self, ty: TraceAsString<Ty>) -> SimValue<TraceAsString<Ty>> {
|
inner,
|
||||||
let inner = self.inner.into_sim_value_with_type(ty.inner_ty());
|
trace_as_string:
|
||||||
let inner = SimValue::into_value(inner);
|
crate::util::serde_by_id::SerdeById {
|
||||||
SimValue::from_value(ty, TraceAsStringSimValue { inner })
|
inner: trace_as_string,
|
||||||
|
},
|
||||||
|
} = Deserialize::deserialize(deserializer)?;
|
||||||
|
Ok(Self {
|
||||||
|
inner,
|
||||||
|
trace_as_string,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ToSimValue> ToSimValue for TraceAsStringSimValue<T> {
|
impl<T: Type> TraceAsStringSimValue<T> {
|
||||||
fn to_sim_value(&self) -> SimValue<Self::Type> {
|
pub fn new_with_ty(inner: impl ToSimValueWithType<T>, ty: TraceAsString<T>) -> Self {
|
||||||
self.to_sim_value_with_type(self.ty())
|
Self {
|
||||||
|
inner: inner.into_sim_value_with_type(ty.inner_ty()),
|
||||||
|
trace_as_string: ty.trace_as_string.interned(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn into_sim_value(self) -> SimValue<Self::Type> {
|
pub fn new(inner: impl ToSimValue<Type = T>) -> Self {
|
||||||
let ty = self.ty();
|
let inner = inner.into_sim_value();
|
||||||
self.into_sim_value_with_type(ty)
|
Self {
|
||||||
|
trace_as_string: TraceAsString::new(inner.ty()).trace_as_string.interned(),
|
||||||
|
inner,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
pub fn into_inner(self) -> SimValue<T> {
|
||||||
|
self.inner
|
||||||
impl<T> std::ops::Deref for TraceAsStringSimValue<T> {
|
}
|
||||||
type Target = T;
|
pub fn inner(&self) -> &SimValue<T> {
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
}
|
pub fn inner_mut(&mut self) -> &mut SimValue<T> {
|
||||||
|
|
||||||
impl<T> std::ops::DerefMut for TraceAsStringSimValue<T> {
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
&mut self.inner
|
&mut self.inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: fmt::Debug> fmt::Debug for TraceAsStringSimValue<T> {
|
impl<T: Type> ValueType for TraceAsStringSimValue<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
type Type = TraceAsString<T>;
|
||||||
let Self { inner } = self;
|
type ValueCategory = crate::expr::value_category::ValueCategoryValue;
|
||||||
fmt::Debug::fmt(inner, f)
|
|
||||||
|
fn ty(&self) -> Self::Type {
|
||||||
|
let inner_ty = self.inner.ty().intern_sized();
|
||||||
|
if self
|
||||||
|
.trace_as_string
|
||||||
|
.can_substitute_type(inner_ty.canonical())
|
||||||
|
{
|
||||||
|
TraceAsString {
|
||||||
|
inner_ty: LazyInterned::Interned(inner_ty),
|
||||||
|
trace_as_string: LazyInterned::Interned(self.trace_as_string),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TraceAsString::new_interned(inner_ty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: fmt::Display> fmt::Display for TraceAsStringSimValue<T> {
|
impl<T: Type> ToExpr for TraceAsStringSimValue<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
#[track_caller]
|
||||||
let Self { inner } = self;
|
fn to_expr(&self) -> Expr<Self::Type> {
|
||||||
fmt::Display::fmt(inner, f)
|
let inner = self.inner.to_expr();
|
||||||
|
let inner_canonical = Expr::canonical(inner);
|
||||||
|
let inner_ty = inner.ty().intern_sized();
|
||||||
|
let ty = if self
|
||||||
|
.trace_as_string
|
||||||
|
.can_substitute_type(inner_canonical.ty())
|
||||||
|
{
|
||||||
|
TraceAsString {
|
||||||
|
inner_ty: LazyInterned::Interned(inner_ty),
|
||||||
|
trace_as_string: LazyInterned::Interned(self.trace_as_string),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TraceAsString::new_interned(inner_ty)
|
||||||
|
};
|
||||||
|
ops::ToTraceAsString::new(inner_canonical, ty).to_expr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialOrd<U>, U> PartialOrd<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T> {
|
impl<T: Type> ToSimValueWithType<TraceAsString<T>> for TraceAsStringSimValue<T> {
|
||||||
|
fn to_sim_value_with_type(&self, ty: TraceAsString<T>) -> SimValue<TraceAsString<T>> {
|
||||||
|
let inner = self.inner.to_sim_value_with_type(ty.inner_ty());
|
||||||
|
SimValue::from_value(
|
||||||
|
ty,
|
||||||
|
TraceAsStringSimValue {
|
||||||
|
inner,
|
||||||
|
trace_as_string: ty.trace_as_string.interned(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fn into_sim_value_with_type(self, ty: TraceAsString<T>) -> SimValue<TraceAsString<T>> {
|
||||||
|
let inner = self.inner.into_sim_value_with_type(ty.inner_ty());
|
||||||
|
SimValue::from_value(
|
||||||
|
ty,
|
||||||
|
TraceAsStringSimValue {
|
||||||
|
inner,
|
||||||
|
trace_as_string: ty.trace_as_string.interned(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type> ToSimValue for TraceAsStringSimValue<T> {
|
||||||
|
fn to_sim_value(&self) -> SimValue<Self::Type> {
|
||||||
|
SimValue::from_value(self.ty(), self.clone())
|
||||||
|
}
|
||||||
|
fn into_sim_value(self) -> SimValue<Self::Type> {
|
||||||
|
SimValue::from_value(self.ty(), self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type> fmt::Debug for TraceAsStringSimValue<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::Debug::fmt(&self.inner, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type<SimValue: fmt::Display>> fmt::Display for TraceAsStringSimValue<T> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt::Display::fmt(&self.inner, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type> Ord for TraceAsStringSimValue<T>
|
||||||
|
where
|
||||||
|
SimValue<T>: Ord,
|
||||||
|
{
|
||||||
|
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||||
|
self.inner.cmp(&other.inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type, U: Type> PartialOrd<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T>
|
||||||
|
where
|
||||||
|
SimValue<T>: PartialOrd<SimValue<U>>,
|
||||||
|
{
|
||||||
fn partial_cmp(&self, other: &TraceAsStringSimValue<U>) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &TraceAsStringSimValue<U>) -> Option<std::cmp::Ordering> {
|
||||||
let Self { inner } = self;
|
self.inner.partial_cmp(&other.inner)
|
||||||
inner.partial_cmp(&other.inner)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq<U>, U> PartialEq<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T> {
|
impl<T: Type> Eq for TraceAsStringSimValue<T> where SimValue<T>: Eq {}
|
||||||
|
|
||||||
|
impl<T: Type> Hash for TraceAsStringSimValue<T>
|
||||||
|
where
|
||||||
|
SimValue<T>: Hash,
|
||||||
|
{
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.inner.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type> Default for TraceAsStringSimValue<T>
|
||||||
|
where
|
||||||
|
SimValue<T>: Default,
|
||||||
|
{
|
||||||
|
fn default() -> Self {
|
||||||
|
let inner = SimValue::default();
|
||||||
|
Self {
|
||||||
|
trace_as_string: TraceAsString::new(inner.ty()).trace_as_string.interned(),
|
||||||
|
inner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Type, U: Type> PartialEq<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T>
|
||||||
|
where
|
||||||
|
SimValue<T>: PartialEq<SimValue<U>>,
|
||||||
|
{
|
||||||
fn eq(&self, other: &TraceAsStringSimValue<U>) -> bool {
|
fn eq(&self, other: &TraceAsStringSimValue<U>) -> bool {
|
||||||
let Self { inner } = self;
|
self.inner == other.inner
|
||||||
*inner == other.inner
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1711,3 +1826,259 @@ impl<T: Type + Visit<State>, State: ?Sized + Visitor> Visit<State> for TraceAsSt
|
||||||
self.interned_inner_ty().visit(state)
|
self.interned_inner_ty().visit(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trace_as_string_cow_into_inner<T: Type>(
|
||||||
|
this: Cow<'_, SimValue<TraceAsString<T>>>,
|
||||||
|
) -> Cow<'_, SimValue<T>> {
|
||||||
|
match this {
|
||||||
|
Cow::Borrowed(v) => Cow::Borrowed(&v.inner),
|
||||||
|
Cow::Owned(v) => Cow::Owned(SimValue::into_value(v).inner),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trace_as_string_cow_into_inner_value<T: Type>(
|
||||||
|
this: Cow<'_, TraceAsStringSimValue<T>>,
|
||||||
|
) -> Cow<'_, T::SimValue> {
|
||||||
|
match this {
|
||||||
|
Cow::Borrowed(v) => Cow::Borrowed(&v.inner),
|
||||||
|
Cow::Owned(v) => Cow::Owned(SimValue::into_value(v.inner)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: HdlPartialEqImpl<U>, U: Type> HdlPartialEqImpl<TraceAsString<U>> for TraceAsString<T> {
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_value_eq(
|
||||||
|
lhs: Self,
|
||||||
|
lhs_value: Cow<'_, Self::SimValue>,
|
||||||
|
rhs: TraceAsString<U>,
|
||||||
|
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
|
||||||
|
) -> bool {
|
||||||
|
HdlPartialEqImpl::cmp_value_eq(
|
||||||
|
lhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(lhs_value),
|
||||||
|
rhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(rhs_value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_value_ne(
|
||||||
|
lhs: Self,
|
||||||
|
lhs_value: Cow<'_, Self::SimValue>,
|
||||||
|
rhs: TraceAsString<U>,
|
||||||
|
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
|
||||||
|
) -> bool {
|
||||||
|
HdlPartialEqImpl::cmp_value_ne(
|
||||||
|
lhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(lhs_value),
|
||||||
|
rhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(rhs_value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_sim_value_eq(
|
||||||
|
lhs: Cow<'_, SimValue<Self>>,
|
||||||
|
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
|
||||||
|
) -> SimValue<Bool> {
|
||||||
|
HdlPartialEqImpl::cmp_sim_value_eq(
|
||||||
|
trace_as_string_cow_into_inner(lhs),
|
||||||
|
trace_as_string_cow_into_inner(rhs),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_sim_value_ne(
|
||||||
|
lhs: Cow<'_, SimValue<Self>>,
|
||||||
|
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
|
||||||
|
) -> SimValue<Bool> {
|
||||||
|
HdlPartialEqImpl::cmp_sim_value_ne(
|
||||||
|
trace_as_string_cow_into_inner(lhs),
|
||||||
|
trace_as_string_cow_into_inner(rhs),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
|
||||||
|
HdlPartialEqImpl::cmp_expr_eq(*lhs, *rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_expr_ne(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
|
||||||
|
HdlPartialEqImpl::cmp_expr_ne(*lhs, *rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_valueless_eq(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
|
||||||
|
HdlPartialEqImpl::cmp_valueless_eq(
|
||||||
|
Valueless::new(lhs.ty().inner_ty()),
|
||||||
|
Valueless::new(rhs.ty().inner_ty()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_valueless_ne(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
|
||||||
|
HdlPartialEqImpl::cmp_valueless_ne(
|
||||||
|
Valueless::new(lhs.ty().inner_ty()),
|
||||||
|
Valueless::new(rhs.ty().inner_ty()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: HdlPartialOrdImpl<U>, U: Type> HdlPartialOrdImpl<TraceAsString<U>> for TraceAsString<T> {
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_value_lt(
|
||||||
|
lhs: Self,
|
||||||
|
lhs_value: Cow<'_, Self::SimValue>,
|
||||||
|
rhs: TraceAsString<U>,
|
||||||
|
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
|
||||||
|
) -> bool {
|
||||||
|
HdlPartialOrdImpl::cmp_value_lt(
|
||||||
|
lhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(lhs_value),
|
||||||
|
rhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(rhs_value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_value_le(
|
||||||
|
lhs: Self,
|
||||||
|
lhs_value: Cow<'_, Self::SimValue>,
|
||||||
|
rhs: TraceAsString<U>,
|
||||||
|
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
|
||||||
|
) -> bool {
|
||||||
|
HdlPartialOrdImpl::cmp_value_le(
|
||||||
|
lhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(lhs_value),
|
||||||
|
rhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(rhs_value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_value_gt(
|
||||||
|
lhs: Self,
|
||||||
|
lhs_value: Cow<'_, Self::SimValue>,
|
||||||
|
rhs: TraceAsString<U>,
|
||||||
|
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
|
||||||
|
) -> bool {
|
||||||
|
HdlPartialOrdImpl::cmp_value_gt(
|
||||||
|
lhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(lhs_value),
|
||||||
|
rhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(rhs_value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_value_ge(
|
||||||
|
lhs: Self,
|
||||||
|
lhs_value: Cow<'_, Self::SimValue>,
|
||||||
|
rhs: TraceAsString<U>,
|
||||||
|
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
|
||||||
|
) -> bool {
|
||||||
|
HdlPartialOrdImpl::cmp_value_ge(
|
||||||
|
lhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(lhs_value),
|
||||||
|
rhs.inner_ty(),
|
||||||
|
trace_as_string_cow_into_inner_value(rhs_value),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_sim_value_lt(
|
||||||
|
lhs: Cow<'_, SimValue<Self>>,
|
||||||
|
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
|
||||||
|
) -> SimValue<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_sim_value_lt(
|
||||||
|
trace_as_string_cow_into_inner(lhs),
|
||||||
|
trace_as_string_cow_into_inner(rhs),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_sim_value_le(
|
||||||
|
lhs: Cow<'_, SimValue<Self>>,
|
||||||
|
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
|
||||||
|
) -> SimValue<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_sim_value_le(
|
||||||
|
trace_as_string_cow_into_inner(lhs),
|
||||||
|
trace_as_string_cow_into_inner(rhs),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_sim_value_gt(
|
||||||
|
lhs: Cow<'_, SimValue<Self>>,
|
||||||
|
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
|
||||||
|
) -> SimValue<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_sim_value_gt(
|
||||||
|
trace_as_string_cow_into_inner(lhs),
|
||||||
|
trace_as_string_cow_into_inner(rhs),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_sim_value_ge(
|
||||||
|
lhs: Cow<'_, SimValue<Self>>,
|
||||||
|
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
|
||||||
|
) -> SimValue<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_sim_value_ge(
|
||||||
|
trace_as_string_cow_into_inner(lhs),
|
||||||
|
trace_as_string_cow_into_inner(rhs),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_expr_lt(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_expr_lt(*lhs, *rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_expr_le(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_expr_le(*lhs, *rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_expr_gt(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_expr_gt(*lhs, *rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_expr_ge(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_expr_ge(*lhs, *rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_valueless_lt(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_valueless_lt(
|
||||||
|
Valueless::new(lhs.ty().inner_ty()),
|
||||||
|
Valueless::new(rhs.ty().inner_ty()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_valueless_le(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_valueless_le(
|
||||||
|
Valueless::new(lhs.ty().inner_ty()),
|
||||||
|
Valueless::new(rhs.ty().inner_ty()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_valueless_gt(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_valueless_gt(
|
||||||
|
Valueless::new(lhs.ty().inner_ty()),
|
||||||
|
Valueless::new(rhs.ty().inner_ty()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn cmp_valueless_ge(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
|
||||||
|
HdlPartialOrdImpl::cmp_valueless_ge(
|
||||||
|
Valueless::new(lhs.ty().inner_ty()),
|
||||||
|
Valueless::new(rhs.ty().inner_ty()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for SerdePhantomConst<
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(rename = "CanonicalType")]
|
#[serde(rename = "CanonicalType")]
|
||||||
|
#[expect(private_interfaces)]
|
||||||
pub(crate) enum SerdeCanonicalType<
|
pub(crate) enum SerdeCanonicalType<
|
||||||
ArrayElement = CanonicalType,
|
ArrayElement = CanonicalType,
|
||||||
ThePhantomConst = SerdePhantomConst<Interned<PhantomConstCanonicalValue>>,
|
ThePhantomConst = SerdePhantomConst<Interned<PhantomConstCanonicalValue>>,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use fayalite::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
reset::ResetType,
|
reset::ResetType,
|
||||||
sim::vcd::VcdWriterDecls,
|
sim::vcd::VcdWriterDecls,
|
||||||
ty::{SimValueDebug, StaticType, TraceAsString, TraceAsStringSimValue},
|
ty::SimValueDebug,
|
||||||
util::{RcWriter, ready_valid::queue},
|
util::{RcWriter, ready_valid::queue},
|
||||||
};
|
};
|
||||||
use std::{collections::BTreeMap, num::NonZeroUsize, rc::Rc};
|
use std::{collections::BTreeMap, num::NonZeroUsize, rc::Rc};
|
||||||
|
|
@ -3019,6 +3019,9 @@ impl HasCustomDebug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn new(text: Result<&str, std::fmt::Error>) -> Expr<Self> {
|
||||||
|
Self::new_sim(text).to_expr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimValueDebug for HasCustomDebug {
|
impl SimValueDebug for HasCustomDebug {
|
||||||
|
|
@ -3061,10 +3064,7 @@ pub fn sim_trace_as_string() {
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let write: WriteStruct<Array<TraceAsString<HasCustomDebug>, 2>, ConstUsize<8>> = m.input();
|
let write: WriteStruct<Array<TraceAsString<HasCustomDebug>, 2>, ConstUsize<8>> = m.input();
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let mut mem = memory_with_init(
|
let mut mem = memory_with_init([[HasCustomDebug::new(Ok("")).to_trace_as_string(); 2]; 4]);
|
||||||
[[Expr::as_trace_as_string(HasCustomDebug::new_sim(Ok("")).to_expr(), StaticType::TYPE); 2];
|
|
||||||
4],
|
|
||||||
);
|
|
||||||
let read_port = mem.new_read_port();
|
let read_port = mem.new_read_port();
|
||||||
connect(read_port.clk, clk);
|
connect(read_port.clk, clk);
|
||||||
connect_any(read_port.addr, read.addr);
|
connect_any(read_port.addr, read.addr);
|
||||||
|
|
@ -3156,7 +3156,7 @@ fn test_sim_trace_as_string() {
|
||||||
sim.write(sim.io().write.en, write_addr.is_some());
|
sim.write(sim.io().write.en, write_addr.is_some());
|
||||||
sim.write(
|
sim.write(
|
||||||
sim.io().write.data,
|
sim.io().write.data,
|
||||||
write_data.map(|v| TraceAsStringSimValue::new(HasCustomDebug::new_sim(v))),
|
write_data.map(|v| HasCustomDebug::new_sim(v).to_trace_as_string()),
|
||||||
);
|
);
|
||||||
sim.write(
|
sim.write(
|
||||||
sim.io().write.mask,
|
sim.io().write.mask,
|
||||||
|
|
@ -3172,7 +3172,7 @@ fn test_sim_trace_as_string() {
|
||||||
.map(HasCustomDebug::new_sim)
|
.map(HasCustomDebug::new_sim)
|
||||||
.into_sim_value();
|
.into_sim_value();
|
||||||
assert!(
|
assert!(
|
||||||
**read_data == *expected_read_data,
|
*read_data.inner() == expected_read_data,
|
||||||
"{read_data:#?}\n!= {expected_read_data:#?}",
|
"{read_data:#?}\n!= {expected_read_data:#?}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta
|
||||||
note: required because it appears within the type `DynSimOnlyValue`
|
note: required because it appears within the type `DynSimOnlyValue`
|
||||||
--> src/sim/value/sim_only_value_unsafe.rs
|
--> src/sim/value/sim_only_value_unsafe.rs
|
||||||
|
|
|
|
||||||
271 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
|
281 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
|
note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
|
||||||
--> $RUST/core/src/marker.rs
|
--> $RUST/core/src/marker.rs
|
||||||
|
|
@ -75,12 +75,12 @@ note: required because it appears within the type `Vec<DynSimOnlyValue>`
|
||||||
note: required because it appears within the type `OpaqueSimValue`
|
note: required because it appears within the type `OpaqueSimValue`
|
||||||
--> src/ty.rs
|
--> src/ty.rs
|
||||||
|
|
|
|
||||||
895 | pub struct OpaqueSimValue {
|
896 | pub struct OpaqueSimValue {
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `value::SimValueInner<()>`
|
note: required because it appears within the type `value::SimValueInner<()>`
|
||||||
--> src/sim/value.rs
|
--> src/sim/value.rs
|
||||||
|
|
|
|
||||||
52 | struct SimValueInner<T: Type> {
|
51 | struct SimValueInner<T: Type> {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
|
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
|
||||||
--> $RUST/core/src/cell.rs
|
--> $RUST/core/src/cell.rs
|
||||||
|
|
@ -95,7 +95,7 @@ note: required because it appears within the type `util::alternating_cell::Alter
|
||||||
note: required because it appears within the type `fayalite::prelude::SimValue<()>`
|
note: required because it appears within the type `fayalite::prelude::SimValue<()>`
|
||||||
--> src/sim/value.rs
|
--> src/sim/value.rs
|
||||||
|
|
|
|
||||||
161 | pub struct SimValue<T: Type> {
|
160 | pub struct SimValue<T: Type> {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
note: required by a bound in `fayalite::intern::Interned`
|
note: required by a bound in `fayalite::intern::Interned`
|
||||||
--> src/intern.rs
|
--> src/intern.rs
|
||||||
|
|
@ -194,7 +194,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta
|
||||||
note: required because it appears within the type `DynSimOnlyValue`
|
note: required because it appears within the type `DynSimOnlyValue`
|
||||||
--> src/sim/value/sim_only_value_unsafe.rs
|
--> src/sim/value/sim_only_value_unsafe.rs
|
||||||
|
|
|
|
||||||
271 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
|
281 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
|
note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
|
||||||
--> $RUST/core/src/marker.rs
|
--> $RUST/core/src/marker.rs
|
||||||
|
|
@ -214,12 +214,12 @@ note: required because it appears within the type `Vec<DynSimOnlyValue>`
|
||||||
note: required because it appears within the type `OpaqueSimValue`
|
note: required because it appears within the type `OpaqueSimValue`
|
||||||
--> src/ty.rs
|
--> src/ty.rs
|
||||||
|
|
|
|
||||||
895 | pub struct OpaqueSimValue {
|
896 | pub struct OpaqueSimValue {
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `value::SimValueInner<()>`
|
note: required because it appears within the type `value::SimValueInner<()>`
|
||||||
--> src/sim/value.rs
|
--> src/sim/value.rs
|
||||||
|
|
|
|
||||||
52 | struct SimValueInner<T: Type> {
|
51 | struct SimValueInner<T: Type> {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
|
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
|
||||||
--> $RUST/core/src/cell.rs
|
--> $RUST/core/src/cell.rs
|
||||||
|
|
@ -234,7 +234,7 @@ note: required because it appears within the type `util::alternating_cell::Alter
|
||||||
note: required because it appears within the type `fayalite::prelude::SimValue<()>`
|
note: required because it appears within the type `fayalite::prelude::SimValue<()>`
|
||||||
--> src/sim/value.rs
|
--> src/sim/value.rs
|
||||||
|
|
|
|
||||||
161 | pub struct SimValue<T: Type> {
|
160 | pub struct SimValue<T: Type> {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
note: required by a bound in `intern_sized`
|
note: required by a bound in `intern_sized`
|
||||||
--> src/intern.rs
|
--> src/intern.rs
|
||||||
|
|
@ -306,7 +306,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta
|
||||||
note: required because it appears within the type `DynSimOnlyValue`
|
note: required because it appears within the type `DynSimOnlyValue`
|
||||||
--> src/sim/value/sim_only_value_unsafe.rs
|
--> src/sim/value/sim_only_value_unsafe.rs
|
||||||
|
|
|
|
||||||
271 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
|
281 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
|
note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
|
||||||
--> $RUST/core/src/marker.rs
|
--> $RUST/core/src/marker.rs
|
||||||
|
|
@ -326,12 +326,12 @@ note: required because it appears within the type `Vec<DynSimOnlyValue>`
|
||||||
note: required because it appears within the type `OpaqueSimValue`
|
note: required because it appears within the type `OpaqueSimValue`
|
||||||
--> src/ty.rs
|
--> src/ty.rs
|
||||||
|
|
|
|
||||||
895 | pub struct OpaqueSimValue {
|
896 | pub struct OpaqueSimValue {
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `value::SimValueInner<()>`
|
note: required because it appears within the type `value::SimValueInner<()>`
|
||||||
--> src/sim/value.rs
|
--> src/sim/value.rs
|
||||||
|
|
|
|
||||||
52 | struct SimValueInner<T: Type> {
|
51 | struct SimValueInner<T: Type> {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
|
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
|
||||||
--> $RUST/core/src/cell.rs
|
--> $RUST/core/src/cell.rs
|
||||||
|
|
@ -346,7 +346,7 @@ note: required because it appears within the type `util::alternating_cell::Alter
|
||||||
note: required because it appears within the type `fayalite::prelude::SimValue<()>`
|
note: required because it appears within the type `fayalite::prelude::SimValue<()>`
|
||||||
--> src/sim/value.rs
|
--> src/sim/value.rs
|
||||||
|
|
|
|
||||||
161 | pub struct SimValue<T: Type> {
|
160 | pub struct SimValue<T: Type> {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
note: required by a bound in `fayalite::intern::Interned`
|
note: required by a bound in `fayalite::intern::Interned`
|
||||||
--> src/intern.rs
|
--> src/intern.rs
|
||||||
|
|
|
||||||
|
|
@ -1022,10 +1022,10 @@
|
||||||
"fold_where": "T: Fold<State>",
|
"fold_where": "T: Fold<State>",
|
||||||
"visit_where": "T: Visit<State>"
|
"visit_where": "T: Visit<State>"
|
||||||
},
|
},
|
||||||
"ops::AsTraceAsString": {
|
"ops::ToTraceAsString": {
|
||||||
"data": {
|
"data": {
|
||||||
"$kind": "Struct",
|
"$kind": "Struct",
|
||||||
"$constructor": "ops::AsTraceAsString::new",
|
"$constructor": "ops::ToTraceAsString::new",
|
||||||
"inner()": "Visible",
|
"inner()": "Visible",
|
||||||
"ty()": "Visible"
|
"ty()": "Visible"
|
||||||
},
|
},
|
||||||
|
|
@ -1310,7 +1310,7 @@
|
||||||
"$kind": "Struct"
|
"$kind": "Struct"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TargetPathAsTraceAsString": {
|
"TargetPathToTraceAsString": {
|
||||||
"data": {
|
"data": {
|
||||||
"$kind": "Struct",
|
"$kind": "Struct",
|
||||||
"ty": "Visible"
|
"ty": "Visible"
|
||||||
|
|
@ -1323,7 +1323,7 @@
|
||||||
"ArrayElement": "Visible",
|
"ArrayElement": "Visible",
|
||||||
"DynArrayElement": "Visible",
|
"DynArrayElement": "Visible",
|
||||||
"TraceAsStringInner": "Visible",
|
"TraceAsStringInner": "Visible",
|
||||||
"AsTraceAsString": "Visible"
|
"ToTraceAsString": "Visible"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"PhantomConst": {
|
"PhantomConst": {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue