// Copyright (c) 2017 Fabian Schuiki //! This module contains the nodes of the tree structure that is the HIR. use std::collections::HashMap; pub use moore_common::name::Name; pub use moore_common::source::Span; pub use moore_svlog_syntax::ast::NodeId; use moore_svlog_syntax::ast; // TODO: Take the AST expressions and split them into lvalue and rvalue // expressions. This should make a few things easier. /// The root of the HIR tree. This represents one elaborated design. pub struct Root { pub top: NodeId, pub mods: HashMap, pub intfs: HashMap, pub pkgs: HashMap, } /// An search index of all nodes in a HIR tree. pub struct NodeIndex<'hir> { pub hir: &'hir Root, pub nodes: HashMap>, } #[derive(Copy, Clone)] pub enum Node<'hir> { Module(&'hir Module), Interface(&'hir Interface), Package(&'hir Package), Port(&'hir Port), PortSlice(&'hir PortSlice), TypeParam(&'hir ast::ParamTypeDecl), ValueParam(&'hir ast::ParamValueDecl), VarDecl(&'hir ast::VarDecl, &'hir ast::VarDeclName), } /// A module. pub struct Module { pub id: NodeId, pub name: Name, pub span: Span, pub lifetime: ast::Lifetime, pub ports: Vec, pub params: Vec, pub body: HierarchyBody, } /// An interface. pub struct Interface { pub id: NodeId, pub name: Name, pub span: Span, pub lifetime: ast::Lifetime, pub ports: Vec, pub params: Vec, pub body: HierarchyBody, } /// A package. pub struct Package { pub name: Name, pub span: Span, pub lifetime: ast::Lifetime, pub body: HierarchyBody, } /// A hierarchy body represents the contents of a module, interface, or package. /// Generate regions and nested modules introduce additional bodies. The point /// of hierarchy bodies is to take a level of the design hierarchy and group all /// declarations by type, rather than having them in a single array in /// declaration order. pub struct HierarchyBody { pub procs: Vec, pub nets: Vec, pub vars: Vec, pub assigns: Vec, pub params: Vec, pub insts: Vec, pub genreg: Vec, pub genvars: Vec, pub genfors: Vec, pub genifs: Vec, pub gencases: Vec, pub classes: Vec, // TODO: Make this an HIR node, since it contains hierarchy items pub subroutines: Vec, // TODO: Make this an HIR node pub asserts: Vec, pub typedefs: Vec, } #[derive(Debug)] pub struct Port { pub name: Option, pub span: Span, pub slices: Vec, } /// A port slice refers to a port declaration within the module. It consists of /// the name of the declaration and a list of optional member and index accesses /// that select individual parts of the declaration. #[derive(Debug)] pub struct PortSlice { pub id: NodeId, pub name: Name, pub span: Span, pub selects: Vec, pub dir: ast::PortDir, pub kind: ast::PortKind, pub ty: Option, pub dims: Vec, } #[derive(Debug)] pub enum PortSelect { Member(Span, Name), Index(Span, Expr), } pub struct PortDecl { pub dir: ast::PortDir, } // pub enum PortDir { // } #[derive(Debug)] pub struct Expr; pub struct GenerateBlock { pub span: Span, pub label: Option, pub body: HierarchyBody, } pub struct GenerateFor { pub span: Span, pub init: ast::Stmt, pub cond: ast::Expr, pub step: ast::Expr, pub block: GenerateBlock, } pub struct GenerateIf { pub span: Span, pub cond: ast::Expr, pub main_block: GenerateBlock, pub else_block: Option, }