fayalite 0.2.0

Hardware Description Language embedded in Rust, using FIRRTL's semantics
Documentation
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use crate::{
    expr::{Expr, ToExpr},
    hdl,
    int::Bool,
    reset::Reset,
    source_location::SourceLocation,
    ty::{impl_match_variant_as_self, CanonicalType, StaticType, Type, TypeProperties},
};

#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default)]
pub struct Clock;

impl Type for Clock {
    type BaseType = Clock;
    type MaskType = Bool;

    impl_match_variant_as_self!();

    fn mask_type(&self) -> Self::MaskType {
        Bool
    }

    fn canonical(&self) -> CanonicalType {
        CanonicalType::Clock(*self)
    }

    fn source_location() -> SourceLocation {
        SourceLocation::builtin()
    }

    fn from_canonical(canonical_type: CanonicalType) -> Self {
        let CanonicalType::Clock(retval) = canonical_type else {
            panic!("expected Clock");
        };
        retval
    }
}

impl Clock {
    pub fn type_properties(self) -> TypeProperties {
        Self::TYPE_PROPERTIES
    }
    pub fn can_connect(self, _rhs: Self) -> bool {
        true
    }
}

impl StaticType for Clock {
    const TYPE: Self = Self;
    const MASK_TYPE: Self::MaskType = Bool;
    const TYPE_PROPERTIES: TypeProperties = TypeProperties {
        is_passive: true,
        is_storable: false,
        is_castable_from_bits: true,
        bit_width: 1,
    };
    const MASK_TYPE_PROPERTIES: TypeProperties = Bool::TYPE_PROPERTIES;
}

pub trait ToClock {
    fn to_clock(&self) -> Expr<Clock>;
}

impl<T: ?Sized + ToClock> ToClock for &'_ T {
    fn to_clock(&self) -> Expr<Clock> {
        (**self).to_clock()
    }
}

impl<T: ?Sized + ToClock> ToClock for &'_ mut T {
    fn to_clock(&self) -> Expr<Clock> {
        (**self).to_clock()
    }
}

impl<T: ?Sized + ToClock> ToClock for Box<T> {
    fn to_clock(&self) -> Expr<Clock> {
        (**self).to_clock()
    }
}

impl ToClock for Expr<Clock> {
    fn to_clock(&self) -> Expr<Clock> {
        *self
    }
}

#[hdl]
pub struct ClockDomain {
    pub clk: Clock,
    pub rst: Reset,
}

impl ToClock for bool {
    fn to_clock(&self) -> Expr<Clock> {
        self.to_expr().to_clock()
    }
}