sv-parser/src/parser/source_text/module_parameters_and_ports.rs
2019-07-24 12:23:14 +09:00

530 lines
14 KiB
Rust

use crate::ast::*;
use crate::parser::*;
use nom::branch::*;
use nom::combinator::*;
use nom::multi::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Clone, Debug, Node)]
pub enum ParameterPortList {
Assignment(ParameterPortListAssignment),
Declaration(ParameterPortListDeclaration),
Empty((Symbol, Symbol, Symbol)),
}
#[derive(Clone, Debug, Node)]
pub struct ParameterPortListAssignment {
pub nodes: (
Symbol,
Paren<
(
ListOfParamAssignments,
Vec<(Symbol, ParameterPortDeclaration)>,
),
>,
),
}
#[derive(Clone, Debug, Node)]
pub struct ParameterPortListDeclaration {
pub nodes: (
Symbol,
Paren< List<Symbol, ParameterPortDeclaration>>,
),
}
#[derive(Clone, Debug, Node)]
pub enum ParameterPortDeclaration {
ParameterDeclaration(ParameterDeclaration),
LocalParameterDeclaration(LocalParameterDeclaration),
ParamList(ParameterPortDeclarationParamList),
TypeList(ParameterPortDeclarationTypeList),
}
#[derive(Clone, Debug, Node)]
pub struct ParameterPortDeclarationParamList {
pub nodes: (DataType, ListOfParamAssignments),
}
#[derive(Clone, Debug, Node)]
pub struct ParameterPortDeclarationTypeList {
pub nodes: (Keyword, ListOfTypeAssignments),
}
#[derive(Clone, Debug, Node)]
pub struct ListOfPorts {
pub nodes: (Paren< List<Symbol, Port>>,),
}
#[derive(Clone, Debug, Node)]
pub struct ListOfPortDeclarations {
pub nodes: (
Paren< Option<List<Symbol, (Vec<AttributeInstance>, AnsiPortDeclaration)>>>,
),
}
#[derive(Clone, Debug, Node)]
pub enum PortDeclaration {
Inout(PortDeclarationInout),
Input(PortDeclarationInput),
Output(PortDeclarationOutput),
Ref(PortDeclarationRef),
Interface(PortDeclarationInterface),
}
#[derive(Clone, Debug, Node)]
pub struct PortDeclarationInout {
pub nodes: (Vec<AttributeInstance>, InoutDeclaration),
}
#[derive(Clone, Debug, Node)]
pub struct PortDeclarationInput {
pub nodes: (Vec<AttributeInstance>, InputDeclaration),
}
#[derive(Clone, Debug, Node)]
pub struct PortDeclarationOutput {
pub nodes: (Vec<AttributeInstance>, OutputDeclaration),
}
#[derive(Clone, Debug, Node)]
pub struct PortDeclarationRef {
pub nodes: (Vec<AttributeInstance>, RefDeclaration),
}
#[derive(Clone, Debug, Node)]
pub struct PortDeclarationInterface {
pub nodes: (Vec<AttributeInstance>, InterfacePortDeclaration),
}
#[derive(Clone, Debug, Node)]
pub enum Port {
NonNamed(PortNonNamed),
Named(PortNamed),
}
#[derive(Clone, Debug, Node)]
pub struct PortNonNamed {
pub nodes: (Option<PortExpression>,),
}
#[derive(Clone, Debug, Node)]
pub struct PortNamed {
pub nodes: (
Symbol,
PortIdentifier,
Paren< Option<PortExpression>>,
),
}
#[derive(Clone, Debug, Node)]
pub enum PortExpression {
PortReference(PortReference),
Brace(PortExpressionBrace),
}
#[derive(Clone, Debug, Node)]
pub struct PortExpressionBrace {
pub nodes: (Brace< List<Symbol, PortReference>>,),
}
#[derive(Clone, Debug, Node)]
pub struct PortReference {
pub nodes: (PortIdentifier, ConstantSelect),
}
#[derive(Clone, Debug, Node)]
pub enum PortDirection {
Input(Keyword),
Output(Keyword),
Inout(Keyword),
Ref(Keyword),
}
#[derive(Clone, Debug, Node)]
pub struct NetPortHeader {
pub nodes: (Option<PortDirection>, NetPortType),
}
#[derive(Clone, Debug, Node)]
pub struct VariablePortHeader {
pub nodes: (Option<PortDirection>, VariablePortType),
}
#[derive(Clone, Debug, Node)]
pub enum InterfacePortHeader {
Identifier(InterfacePortHeaderIdentifier),
Interface(InterfacePortHeaderInterface),
}
#[derive(Clone, Debug, Node)]
pub struct InterfacePortHeaderIdentifier {
pub nodes: (
InterfaceIdentifier,
Option<(Symbol, ModportIdentifier)>,
),
}
#[derive(Clone, Debug, Node)]
pub struct InterfacePortHeaderInterface {
pub nodes: (Keyword, Option<(Symbol, ModportIdentifier)>),
}
#[derive(Clone, Debug, Node)]
pub enum NetPortHeaderOrInterfacePortHeader {
NetPortHeader(NetPortHeader),
InterfacePortHeader(InterfacePortHeader),
}
#[derive(Clone, Debug, Node)]
pub enum AnsiPortDeclaration {
Net(AnsiPortDeclarationNet),
Variable(AnsiPortDeclarationVariable),
Paren(AnsiPortDeclarationParen),
}
#[derive(Clone, Debug, Node)]
pub struct AnsiPortDeclarationNet {
pub nodes: (
Option<NetPortHeaderOrInterfacePortHeader>,
PortIdentifier,
Vec<UnpackedDimension>,
Option<(Symbol, ConstantExpression)>,
),
}
#[derive(Clone, Debug, Node)]
pub struct AnsiPortDeclarationVariable {
pub nodes: (
Option<VariablePortHeader>,
PortIdentifier,
Vec<VariableDimension>,
Option<(Symbol, ConstantExpression)>,
),
}
#[derive(Clone, Debug, Node)]
pub struct AnsiPortDeclarationParen {
pub nodes: (
Option<PortDirection>,
Symbol,
PortIdentifier,
Paren< Option<Expression>>,
),
}
// -----------------------------------------------------------------------------
#[parser]
pub fn parameter_port_list(s: Span) -> IResult<Span, ParameterPortList> {
alt((
parameter_port_list_assignment,
parameter_port_list_declaration,
parameter_port_list_empty,
))(s)
}
#[parser]
pub fn parameter_port_list_assignment(s: Span) -> IResult<Span, ParameterPortList> {
let (s, a) = symbol("#")(s)?;
let (s, b) = paren(pair(
list_of_param_assignments,
many0(pair(symbol(","), parameter_port_declaration)),
))(s)?;
Ok((
s,
ParameterPortList::Assignment(ParameterPortListAssignment { nodes: (a, b) }),
))
}
#[parser]
pub fn parameter_port_list_declaration(s: Span) -> IResult<Span, ParameterPortList> {
let (s, a) = symbol("#")(s)?;
let (s, b) = paren(list(symbol(","), parameter_port_declaration))(s)?;
Ok((
s,
ParameterPortList::Declaration(ParameterPortListDeclaration { nodes: (a, b) }),
))
}
#[parser]
pub fn parameter_port_list_empty(s: Span) -> IResult<Span, ParameterPortList> {
let (s, a) = symbol("#")(s)?;
let (s, b) = symbol("(")(s)?;
let (s, c) = symbol(")")(s)?;
Ok((s, ParameterPortList::Empty((a, b, c))))
}
#[parser]
pub fn parameter_port_declaration(s: Span) -> IResult<Span, ParameterPortDeclaration> {
alt((
map(parameter_declaration, |x| {
ParameterPortDeclaration::ParameterDeclaration(x)
}),
map(local_parameter_declaration, |x| {
ParameterPortDeclaration::LocalParameterDeclaration(x)
}),
parameter_port_declaration_param_list,
parameter_port_declaration_type_list,
))(s)
}
#[parser]
pub fn parameter_port_declaration_param_list(s: Span) -> IResult<Span, ParameterPortDeclaration> {
let (s, a) = data_type(s)?;
let (s, b) = list_of_param_assignments(s)?;
Ok((
s,
ParameterPortDeclaration::ParamList(ParameterPortDeclarationParamList { nodes: (a, b) }),
))
}
#[parser]
pub fn parameter_port_declaration_type_list(s: Span) -> IResult<Span, ParameterPortDeclaration> {
let (s, a) = keyword("type")(s)?;
let (s, b) = list_of_type_assignments(s)?;
Ok((
s,
ParameterPortDeclaration::TypeList(ParameterPortDeclarationTypeList { nodes: (a, b) }),
))
}
#[parser]
pub fn list_of_ports(s: Span) -> IResult<Span, ListOfPorts> {
let (s, a) = paren(list(symbol(","), port))(s)?;
Ok((s, ListOfPorts { nodes: (a,) }))
}
#[parser]
pub fn list_of_port_declarations(s: Span) -> IResult<Span, ListOfPortDeclarations> {
let (s, a) = paren(opt(list(
symbol(","),
pair(many0(attribute_instance), ansi_port_declaration),
)))(s)?;
Ok((s, ListOfPortDeclarations { nodes: (a,) }))
}
#[parser]
pub fn port_declaration(s: Span) -> IResult<Span, PortDeclaration> {
alt((
port_declaration_inout,
port_declaration_input,
port_declaration_output,
port_declaration_ref,
port_declaration_interface,
))(s)
}
#[parser]
pub fn port_declaration_inout(s: Span) -> IResult<Span, PortDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = inout_declaration(s)?;
Ok((
s,
PortDeclaration::Inout(PortDeclarationInout { nodes: (a, b) }),
))
}
#[parser]
pub fn port_declaration_input(s: Span) -> IResult<Span, PortDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = input_declaration(s)?;
Ok((
s,
PortDeclaration::Input(PortDeclarationInput { nodes: (a, b) }),
))
}
#[parser]
pub fn port_declaration_output(s: Span) -> IResult<Span, PortDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = output_declaration(s)?;
Ok((
s,
PortDeclaration::Output(PortDeclarationOutput { nodes: (a, b) }),
))
}
#[parser]
pub fn port_declaration_ref(s: Span) -> IResult<Span, PortDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = ref_declaration(s)?;
Ok((
s,
PortDeclaration::Ref(PortDeclarationRef { nodes: (a, b) }),
))
}
#[parser]
pub fn port_declaration_interface(s: Span) -> IResult<Span, PortDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = interface_port_declaration(s)?;
Ok((
s,
PortDeclaration::Interface(PortDeclarationInterface { nodes: (a, b) }),
))
}
#[parser]
pub fn port(s: Span) -> IResult<Span, Port> {
alt((port_non_named, port_named))(s)
}
#[parser(MaybeRecursive)]
pub fn port_non_named(s: Span) -> IResult<Span, Port> {
let (s, a) = opt(port_expression)(s)?;
Ok((s, Port::NonNamed(PortNonNamed { nodes: (a,) })))
}
#[parser]
pub fn port_named(s: Span) -> IResult<Span, Port> {
let (s, a) = symbol(".")(s)?;
let (s, b) = port_identifier(s)?;
let (s, c) = paren(opt(port_expression))(s)?;
Ok((s, Port::Named(PortNamed { nodes: (a, b, c) })))
}
#[parser]
pub fn port_expression(s: Span) -> IResult<Span, PortExpression> {
alt((
map(port_reference, |x| PortExpression::PortReference(x)),
port_expressio_named,
))(s)
}
#[parser]
pub fn port_expressio_named(s: Span) -> IResult<Span, PortExpression> {
let (s, a) = brace(list(symbol(","), port_reference))(s)?;
Ok((
s,
PortExpression::Brace(PortExpressionBrace { nodes: (a,) }),
))
}
#[parser]
pub fn port_reference(s: Span) -> IResult<Span, PortReference> {
let (s, a) = port_identifier(s)?;
let (s, b) = constant_select(s)?;
Ok((s, PortReference { nodes: (a, b) }))
}
#[parser]
pub fn port_direction(s: Span) -> IResult<Span, PortDirection> {
alt((
map(keyword("input"), |x| PortDirection::Input(x)),
map(keyword("output"), |x| PortDirection::Output(x)),
map(keyword("inout"), |x| PortDirection::Inout(x)),
map(keyword("ref"), |x| PortDirection::Ref(x)),
))(s)
}
#[parser]
pub fn net_port_header(s: Span) -> IResult<Span, NetPortHeader> {
let (s, a) = opt(port_direction)(s)?;
let (s, b) = net_port_type(s)?;
Ok((s, NetPortHeader { nodes: (a, b) }))
}
#[parser]
pub fn variable_port_header(s: Span) -> IResult<Span, VariablePortHeader> {
let (s, a) = opt(port_direction)(s)?;
let (s, b) = variable_port_type(s)?;
Ok((s, VariablePortHeader { nodes: (a, b) }))
}
#[parser]
pub fn interface_port_header(s: Span) -> IResult<Span, InterfacePortHeader> {
alt((
interface_port_header_identifier,
interface_port_header_interface,
))(s)
}
#[parser]
pub fn interface_port_header_identifier(s: Span) -> IResult<Span, InterfacePortHeader> {
let (s, a) = interface_identifier(s)?;
let (s, b) = opt(pair(symbol("."), modport_identifier))(s)?;
Ok((
s,
InterfacePortHeader::Identifier(InterfacePortHeaderIdentifier { nodes: (a, b) }),
))
}
#[parser]
pub fn interface_port_header_interface(s: Span) -> IResult<Span, InterfacePortHeader> {
let (s, a) = keyword("interface")(s)?;
let (s, b) = opt(pair(symbol("."), modport_identifier))(s)?;
Ok((
s,
InterfacePortHeader::Interface(InterfacePortHeaderInterface { nodes: (a, b) }),
))
}
#[parser]
pub fn ansi_port_declaration(s: Span) -> IResult<Span, AnsiPortDeclaration> {
alt((
ansi_port_declaration_net,
ansi_port_declaration_port,
ansi_port_declaration_paren,
))(s)
}
#[parser]
pub fn ansi_port_declaration_net(s: Span) -> IResult<Span, AnsiPortDeclaration> {
let (s, a) = opt(net_port_header_or_interface_port_header)(s)?;
let (s, b) = port_identifier(s)?;
let (s, c) = many0(unpacked_dimension)(s)?;
let (s, d) = opt(pair(symbol("="), constant_expression))(s)?;
Ok((
s,
AnsiPortDeclaration::Net(AnsiPortDeclarationNet {
nodes: (a, b, c, d),
}),
))
}
#[parser]
pub fn net_port_header_or_interface_port_header(
s: Span,
) -> IResult<Span, NetPortHeaderOrInterfacePortHeader> {
alt((
map(net_port_header, |x| {
NetPortHeaderOrInterfacePortHeader::NetPortHeader(x)
}),
map(interface_port_header, |x| {
NetPortHeaderOrInterfacePortHeader::InterfacePortHeader(x)
}),
))(s)
}
#[parser]
pub fn ansi_port_declaration_port(s: Span) -> IResult<Span, AnsiPortDeclaration> {
let (s, a) = opt(variable_port_header)(s)?;
let (s, b) = port_identifier(s)?;
let (s, c) = many0(variable_dimension)(s)?;
let (s, d) = opt(pair(symbol("="), constant_expression))(s)?;
Ok((
s,
AnsiPortDeclaration::Variable(AnsiPortDeclarationVariable {
nodes: (a, b, c, d),
}),
))
}
#[parser]
pub fn ansi_port_declaration_paren(s: Span) -> IResult<Span, AnsiPortDeclaration> {
let (s, a) = opt(port_direction)(s)?;
let (s, b) = symbol(".")(s)?;
let (s, c) = port_identifier(s)?;
let (s, d) = paren(opt(expression))(s)?;
Ok((
s,
AnsiPortDeclaration::Paren(AnsiPortDeclarationParen {
nodes: (a, b, c, d),
}),
))
}