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::{
    clock::ClockDomain,
    expr::{Expr, Flow},
    intern::Interned,
    module::{NameId, ScopedNameId},
    source_location::SourceLocation,
    ty::{CanonicalType, Type},
};
use std::fmt;

#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Reg<T: Type> {
    name: ScopedNameId,
    source_location: SourceLocation,
    ty: T,
    clock_domain: Expr<ClockDomain>,
    init: Option<Expr<T>>,
}

impl<T: Type + fmt::Debug> fmt::Debug for Reg<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let Self {
            name,
            source_location: _,
            ty,
            clock_domain,
            init,
        } = self;
        f.debug_struct("Reg")
            .field("name", name)
            .field("ty", ty)
            .field("clock_domain", clock_domain)
            .field("init", init)
            .finish_non_exhaustive()
    }
}

impl<T: Type> Reg<T> {
    pub fn canonical(&self) -> Reg<CanonicalType> {
        let Self {
            name,
            source_location,
            ref ty,
            clock_domain,
            init,
        } = *self;
        Reg {
            name,
            source_location,
            ty: ty.canonical(),
            clock_domain,
            init: init.map(Expr::canonical),
        }
    }
    #[track_caller]
    pub fn new_unchecked(
        scoped_name: ScopedNameId,
        source_location: SourceLocation,
        ty: T,
        clock_domain: Expr<ClockDomain>,
        init: Option<Expr<T>>,
    ) -> Self {
        assert!(
            ty.canonical().is_storable(),
            "register type must be a storable type"
        );
        if let Some(init) = init {
            assert_eq!(ty, Expr::ty(init), "register's type must match init type");
        }
        Self {
            name: scoped_name,
            source_location,
            ty,
            clock_domain,
            init,
        }
    }
    pub fn ty(&self) -> T {
        self.ty
    }
    pub fn source_location(&self) -> SourceLocation {
        self.source_location
    }
    pub fn containing_module_name(&self) -> Interned<str> {
        self.containing_module_name_id().0
    }
    pub fn containing_module_name_id(&self) -> NameId {
        self.name.0
    }
    pub fn name(&self) -> Interned<str> {
        self.name_id().0
    }
    pub fn name_id(&self) -> NameId {
        self.name.1
    }
    pub fn scoped_name(&self) -> ScopedNameId {
        self.name
    }
    pub fn clock_domain(&self) -> Expr<ClockDomain> {
        self.clock_domain
    }
    pub fn init(&self) -> Option<Expr<T>> {
        self.init
    }
    pub fn flow(&self) -> Flow {
        Flow::Duplex
    }
    pub fn must_connect_to(&self) -> bool {
        false
    }
}