Add parser

This commit is contained in:
dalance 2019-07-19 13:03:07 +09:00
parent ecb89f691f
commit 4a2cc5416c
13 changed files with 2295 additions and 44 deletions

View File

@ -41,9 +41,9 @@ A parser library for System Verilog.
| instantiations | program_instantiation | x | x | | | instantiations | program_instantiation | x | x | |
| instantiations | checker_instantiation | x | x | | | instantiations | checker_instantiation | x | x | |
| instantiations | generated_instantiation | x | x | | | instantiations | generated_instantiation | x | x | |
| udp_declaration_and_instantiation | udp_declaration | | | | | udp_declaration_and_instantiation | udp_declaration | x | x | |
| udp_declaration_and_instantiation | udp_ports | | | | | udp_declaration_and_instantiation | udp_ports | x | x | |
| udp_declaration_and_instantiation | udp_body | | | | | udp_declaration_and_instantiation | udp_body | x | x | |
| udp_declaration_and_instantiation | udp_instantiation | x | x | | | udp_declaration_and_instantiation | udp_instantiation | x | x | |
| behavioral_statements | continuous_assignment_and_net_alias | x | x | | | behavioral_statements | continuous_assignment_and_net_alias | x | x | |
| behavioral_statements | procedural_blocks_and_assignments | x | x | | | behavioral_statements | procedural_blocks_and_assignments | x | x | |
@ -58,13 +58,13 @@ A parser library for System Verilog.
| behavioral_statements | assertion_statements | x | x | | | behavioral_statements | assertion_statements | x | x | |
| behavioral_statements | clocking_block | x | x | | | behavioral_statements | clocking_block | x | x | |
| behavioral_statements | randsequence | x | x | | | behavioral_statements | randsequence | x | x | |
| specify_section | specify_block_declaration | | | | | specify_section | specify_block_declaration | x | x | |
| specify_section | specify_path_declarations | | | | | specify_section | specify_path_declarations | x | x | |
| specify_section | specify_block_terminals | | | | | specify_section | specify_block_terminals | x | x | |
| specify_section | specify_path_delays | | | | | specify_section | specify_path_delays | x | x | |
| specify_section | system_timing_check_commands | | | | | specify_section | system_timing_check_commands | x | x | |
| specify_section | system_timing_check_command_arguments | | | | | specify_section | system_timing_check_command_arguments | x | x | |
| specify_section | system_timing_check_event_definitions | | | | | specify_section | system_timing_check_event_definitions | x | x | |
| expressions | concatenations | x | x | | | expressions | concatenations | x | x | |
| expressions | subroutine_calls | x | x | | | expressions | subroutine_calls | x | x | |
| expressions | expressions | x | x | | | expressions | expressions | x | x | |
@ -76,3 +76,8 @@ A parser library for System Verilog.
| general | attributes | x | x | x | | general | attributes | x | x | x |
| general | comments | x | x | x | | general | comments | x | x | x |
| general | identifiers | x | x | x | | general | identifiers | x | x | x |
## TODO
* Exclude reserved keyword from identifiers.
* Implement ambiguous_alt for varirble_port_type.

View File

@ -1,6 +1,14 @@
pub mod specify_block_declaration; pub mod specify_block_declaration;
pub mod specify_block_terminals; pub mod specify_block_terminals;
pub mod specify_path_declarations;
pub mod specify_path_delays; pub mod specify_path_delays;
pub mod system_timing_check_command_arguments;
pub mod system_timing_check_commands;
pub mod system_timing_check_event_definitions;
pub use specify_block_declaration::*; pub use specify_block_declaration::*;
pub use specify_block_terminals::*; pub use specify_block_terminals::*;
pub use specify_path_declarations::*;
pub use specify_path_delays::*; pub use specify_path_delays::*;
pub use system_timing_check_command_arguments::*;
pub use system_timing_check_commands::*;
pub use system_timing_check_event_definitions::*;

View File

@ -1,20 +1,75 @@
use crate::ast::*; use crate::ast::*;
use crate::parser::*; use crate::parser::*;
//use nom::branch::*; use nom::branch::*;
//use nom::combinator::*; use nom::combinator::*;
use nom::error::*; use nom::multi::*;
use nom::{Err, IResult}; use nom::IResult;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Debug, Node)] #[derive(Debug, Node)]
pub struct SpecifyBlock<'a> { pub struct SpecifyBlock<'a> {
pub nodes: (Identifier<'a>,), pub nodes: (Symbol<'a>, Vec<SpecifyItem<'a>>, Symbol<'a>),
}
#[derive(Debug, Node)]
pub enum SpecifyItem<'a> {
SpecparamDeclaration(SpecparamDeclaration<'a>),
PulsestyleDeclaration(PulsestyleDeclaration<'a>),
ShowcancelledDeclaration(ShowcancelledDeclaration<'a>),
PathDeclaration(PathDeclaration<'a>),
SystemTimingCheck(SystemTimingCheck<'a>),
}
#[derive(Debug, Node)]
pub struct PulsestyleDeclaration<'a> {
pub nodes: (Symbol<'a>, ListOfPathOutputs<'a>, Symbol<'a>),
}
#[derive(Debug, Node)]
pub struct ShowcancelledDeclaration<'a> {
pub nodes: (Symbol<'a>, ListOfPathOutputs<'a>, Symbol<'a>),
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[parser] #[parser]
pub fn specify_block(s: Span) -> IResult<Span, SpecifyBlock> { pub fn specify_block(s: Span) -> IResult<Span, SpecifyBlock> {
Err(Err::Error(make_error(s, ErrorKind::Fix))) let (s, a) = symbol("specify")(s)?;
let (s, b) = many0(specify_item)(s)?;
let (s, c) = symbol("endspecify")(s)?;
Ok((s, SpecifyBlock { nodes: (a, b, c) }))
}
#[parser]
pub fn specify_item(s: Span) -> IResult<Span, SpecifyItem> {
alt((
map(specparam_declaration, |x| {
SpecifyItem::SpecparamDeclaration(x)
}),
map(pulsestyle_declaration, |x| {
SpecifyItem::PulsestyleDeclaration(x)
}),
map(showcancelled_declaration, |x| {
SpecifyItem::ShowcancelledDeclaration(x)
}),
map(path_declaration, |x| SpecifyItem::PathDeclaration(x)),
map(system_timing_check, |x| SpecifyItem::SystemTimingCheck(x)),
))(s)
}
#[parser]
pub fn pulsestyle_declaration(s: Span) -> IResult<Span, PulsestyleDeclaration> {
let (s, a) = alt((symbol("pulsestyle_onevent"), symbol("pulsestyle_ondetect")))(s)?;
let (s, b) = list_of_path_outputs(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, PulsestyleDeclaration { nodes: (a, b, c) }))
}
#[parser]
pub fn showcancelled_declaration(s: Span) -> IResult<Span, ShowcancelledDeclaration> {
let (s, a) = alt((symbol("showcalcelled"), symbol("noshowcancelled")))(s)?;
let (s, b) = list_of_path_outputs(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, ShowcancelledDeclaration { nodes: (a, b, c) }))
} }

View File

@ -1,20 +1,25 @@
use crate::ast::*; use crate::ast::*;
use crate::parser::*; use crate::parser::*;
//use nom::branch::*; use nom::branch::*;
//use nom::combinator::*; use nom::combinator::*;
use nom::error::*; use nom::IResult;
use nom::{Err, IResult};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Debug, Node)] #[derive(Debug, Node)]
pub struct SpecifyInputTerminalDescriptor<'a> { pub struct SpecifyInputTerminalDescriptor<'a> {
pub nodes: (InputIdentifier<'a>, Option<ConstantRangeExpression<'a>>), pub nodes: (
InputIdentifier<'a>,
Option<Bracket<'a, ConstantRangeExpression<'a>>>,
),
} }
#[derive(Debug, Node)] #[derive(Debug, Node)]
pub struct SpecifyOutputTerminalDescriptor<'a> { pub struct SpecifyOutputTerminalDescriptor<'a> {
pub nodes: (OutputIdentifier<'a>, Option<ConstantRangeExpression<'a>>), pub nodes: (
OutputIdentifier<'a>,
Option<Bracket<'a, ConstantRangeExpression<'a>>>,
),
} }
#[derive(Debug, Node)] #[derive(Debug, Node)]
@ -26,7 +31,7 @@ pub enum InputIdentifier<'a> {
#[derive(Debug, Node)] #[derive(Debug, Node)]
pub struct InputIdentifierInterface<'a> { pub struct InputIdentifierInterface<'a> {
pub nodes: (InterfaceIdentifier<'a>, PortIdentifier<'a>), pub nodes: (InterfaceIdentifier<'a>, Symbol<'a>, PortIdentifier<'a>),
} }
#[derive(Debug, Node)] #[derive(Debug, Node)]
@ -38,29 +43,71 @@ pub enum OutputIdentifier<'a> {
#[derive(Debug, Node)] #[derive(Debug, Node)]
pub struct OutputIdentifierInterface<'a> { pub struct OutputIdentifierInterface<'a> {
pub nodes: (InterfaceIdentifier<'a>, PortIdentifier<'a>), pub nodes: (InterfaceIdentifier<'a>, Symbol<'a>, PortIdentifier<'a>),
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[parser] #[parser]
pub fn specify_input_terminal_descriptor(s: Span) -> IResult<Span, SpecifyInputTerminalDescriptor> { pub fn specify_input_terminal_descriptor(s: Span) -> IResult<Span, SpecifyInputTerminalDescriptor> {
Err(Err::Error(make_error(s, ErrorKind::Fix))) let (s, a) = input_identifier(s)?;
let (s, b) = opt(bracket(constant_range_expression))(s)?;
Ok((s, SpecifyInputTerminalDescriptor { nodes: (a, b) }))
} }
#[parser] #[parser]
pub fn specify_output_terminal_descriptor( pub fn specify_output_terminal_descriptor(
s: Span, s: Span,
) -> IResult<Span, SpecifyOutputTerminalDescriptor> { ) -> IResult<Span, SpecifyOutputTerminalDescriptor> {
Err(Err::Error(make_error(s, ErrorKind::Fix))) let (s, a) = output_identifier(s)?;
let (s, b) = opt(bracket(constant_range_expression))(s)?;
Ok((s, SpecifyOutputTerminalDescriptor { nodes: (a, b) }))
} }
#[parser] #[parser]
pub fn input_identifier(s: Span) -> IResult<Span, InputIdentifier> { pub fn input_identifier(s: Span) -> IResult<Span, InputIdentifier> {
Err(Err::Error(make_error(s, ErrorKind::Fix))) alt((
map(input_port_identifier, |x| {
InputIdentifier::InputPortIdentifier(x)
}),
map(inout_port_identifier, |x| {
InputIdentifier::InoutPortIdentifier(x)
}),
input_identifier_interface,
))(s)
}
#[parser]
pub fn input_identifier_interface(s: Span) -> IResult<Span, InputIdentifier> {
let (s, a) = interface_identifier(s)?;
let (s, b) = symbol(".")(s)?;
let (s, c) = port_identifier(s)?;
Ok((
s,
InputIdentifier::Interface(InputIdentifierInterface { nodes: (a, b, c) }),
))
} }
#[parser] #[parser]
pub fn output_identifier(s: Span) -> IResult<Span, OutputIdentifier> { pub fn output_identifier(s: Span) -> IResult<Span, OutputIdentifier> {
Err(Err::Error(make_error(s, ErrorKind::Fix))) alt((
map(output_port_identifier, |x| {
OutputIdentifier::OutputPortIdentifier(x)
}),
map(inout_port_identifier, |x| {
OutputIdentifier::InoutPortIdentifier(x)
}),
output_identifier_interface,
))(s)
}
#[parser]
pub fn output_identifier_interface(s: Span) -> IResult<Span, OutputIdentifier> {
let (s, a) = interface_identifier(s)?;
let (s, b) = symbol(".")(s)?;
let (s, c) = port_identifier(s)?;
Ok((
s,
OutputIdentifier::Interface(OutputIdentifierInterface { nodes: (a, b, c) }),
))
} }

View File

@ -0,0 +1,152 @@
use crate::ast::*;
use crate::parser::*;
use nom::branch::*;
use nom::combinator::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug, Node)]
pub enum PathDeclaration<'a> {
SimplePathDeclaration((SimplePathDeclaration<'a>, Symbol<'a>)),
EdgeSensitivePathDeclaration((EdgeSensitivePathDeclaration<'a>, Symbol<'a>)),
StateDependentPathDeclaration((StateDependentPathDeclaration<'a>, Symbol<'a>)),
}
#[derive(Debug, Node)]
pub enum SimplePathDeclaration<'a> {
Parallel(SimplePathDeclarationParallel<'a>),
Full(SimplePathDeclarationFull<'a>),
}
#[derive(Debug, Node)]
pub struct SimplePathDeclarationParallel<'a> {
pub nodes: (ParallelPathDescription<'a>, Symbol<'a>, PathDelayValue<'a>),
}
#[derive(Debug, Node)]
pub struct SimplePathDeclarationFull<'a> {
pub nodes: (FullPathDescription<'a>, Symbol<'a>, PathDelayValue<'a>),
}
#[derive(Debug, Node)]
pub struct ParallelPathDescription<'a> {
pub nodes: (
Paren<
'a,
(
SpecifyInputTerminalDescriptor<'a>,
Option<PolarityOperator<'a>>,
Symbol<'a>,
SpecifyOutputTerminalDescriptor<'a>,
),
>,
),
}
#[derive(Debug, Node)]
pub struct FullPathDescription<'a> {
pub nodes: (
Paren<
'a,
(
ListOfPathInputs<'a>,
Option<PolarityOperator<'a>>,
Symbol<'a>,
ListOfPathOutputs<'a>,
),
>,
),
}
#[derive(Debug, Node)]
pub struct ListOfPathInputs<'a> {
pub nodes: (List<Symbol<'a>, SpecifyInputTerminalDescriptor<'a>>,),
}
#[derive(Debug, Node)]
pub struct ListOfPathOutputs<'a> {
pub nodes: (List<Symbol<'a>, SpecifyOutputTerminalDescriptor<'a>>,),
}
// -----------------------------------------------------------------------------
#[parser]
pub fn path_declaration(s: Span) -> IResult<Span, PathDeclaration> {
alt((
map(pair(simple_path_declaration, symbol(";")), |x| {
PathDeclaration::SimplePathDeclaration(x)
}),
map(pair(edge_sensitive_path_declaration, symbol(";")), |x| {
PathDeclaration::EdgeSensitivePathDeclaration(x)
}),
map(pair(state_dependent_path_declaration, symbol(";")), |x| {
PathDeclaration::StateDependentPathDeclaration(x)
}),
))(s)
}
#[parser]
pub fn simple_path_declaration(s: Span) -> IResult<Span, SimplePathDeclaration> {
alt((
simple_path_declaration_parallel,
simple_path_declaration_full,
))(s)
}
#[parser]
pub fn simple_path_declaration_parallel(s: Span) -> IResult<Span, SimplePathDeclaration> {
let (s, a) = parallel_path_description(s)?;
let (s, b) = symbol("=")(s)?;
let (s, c) = path_delay_value(s)?;
Ok((
s,
SimplePathDeclaration::Parallel(SimplePathDeclarationParallel { nodes: (a, b, c) }),
))
}
#[parser]
pub fn simple_path_declaration_full(s: Span) -> IResult<Span, SimplePathDeclaration> {
let (s, a) = full_path_description(s)?;
let (s, b) = symbol("=")(s)?;
let (s, c) = path_delay_value(s)?;
Ok((
s,
SimplePathDeclaration::Full(SimplePathDeclarationFull { nodes: (a, b, c) }),
))
}
#[parser]
pub fn parallel_path_description(s: Span) -> IResult<Span, ParallelPathDescription> {
let (s, a) = paren(tuple((
specify_input_terminal_descriptor,
opt(polarity_operator),
symbol("=>"),
specify_output_terminal_descriptor,
)))(s)?;
Ok((s, ParallelPathDescription { nodes: (a,) }))
}
#[parser]
pub fn full_path_description(s: Span) -> IResult<Span, FullPathDescription> {
let (s, a) = paren(tuple((
list_of_path_inputs,
opt(polarity_operator),
symbol("*>"),
list_of_path_outputs,
)))(s)?;
Ok((s, FullPathDescription { nodes: (a,) }))
}
#[parser]
pub fn list_of_path_inputs(s: Span) -> IResult<Span, ListOfPathInputs> {
let (s, a) = list(symbol(","), specify_input_terminal_descriptor)(s)?;
Ok((s, ListOfPathInputs { nodes: (a,) }))
}
#[parser]
pub fn list_of_path_outputs(s: Span) -> IResult<Span, ListOfPathOutputs> {
let (s, a) = list(symbol(","), specify_output_terminal_descriptor)(s)?;
Ok((s, ListOfPathOutputs { nodes: (a,) }))
}

View File

@ -1,20 +1,341 @@
use crate::ast::*; use crate::ast::*;
use crate::parser::*; use crate::parser::*;
//use nom::branch::*; use nom::branch::*;
//use nom::combinator::*; use nom::combinator::*;
use nom::error::*; use nom::sequence::*;
use nom::{Err, IResult}; use nom::IResult;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Debug, Node)] #[derive(Debug, Node)]
pub struct EdgeIdentifier<'a> { pub enum PathDelayValue<'a> {
pub nodes: (Identifier<'a>,), ListOfPathDelayExpressions(ListOfPathDelayExpressions<'a>),
Paren(PathDelayValueParen<'a>),
}
#[derive(Debug, Node)]
pub struct PathDelayValueParen<'a> {
pub nodes: (Paren<'a, ListOfPathDelayExpressions<'a>>,),
}
#[derive(Debug, Node)]
pub struct ListOfPathDelayExpressions<'a> {
pub nodes: (List<Symbol<'a>, TPathDelayExpression<'a>>,),
}
#[derive(Debug, Node)]
pub struct TPathDelayExpression<'a> {
pub nodes: (PathDelayExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct PathDelayExpression<'a> {
pub nodes: (ConstantMintypmaxExpression<'a>,),
}
#[derive(Debug, Node)]
pub enum EdgeSensitivePathDeclaration<'a> {
Parallel(EdgeSensitivePathDeclarationParallel<'a>),
Full(EdgeSensitivePathDeclarationFull<'a>),
}
#[derive(Debug, Node)]
pub struct EdgeSensitivePathDeclarationParallel<'a> {
pub nodes: (
ParallelEdgeSensitivePathDescription<'a>,
Symbol<'a>,
PathDelayValue<'a>,
),
}
#[derive(Debug, Node)]
pub struct EdgeSensitivePathDeclarationFull<'a> {
pub nodes: (
FullEdgeSensitivePathDescription<'a>,
Symbol<'a>,
PathDelayValue<'a>,
),
}
#[derive(Debug, Node)]
pub struct ParallelEdgeSensitivePathDescription<'a> {
pub nodes: (
Paren<
'a,
(
Option<EdgeIdentifier<'a>>,
SpecifyInputTerminalDescriptor<'a>,
Option<PolarityOperator<'a>>,
Symbol<'a>,
Paren<
'a,
(
SpecifyOutputTerminalDescriptor<'a>,
Option<PolarityOperator<'a>>,
Symbol<'a>,
DataSourceExpression<'a>,
),
>,
),
>,
),
}
#[derive(Debug, Node)]
pub struct FullEdgeSensitivePathDescription<'a> {
pub nodes: (
Paren<
'a,
(
Option<EdgeIdentifier<'a>>,
ListOfPathInputs<'a>,
Option<PolarityOperator<'a>>,
Symbol<'a>,
Paren<
'a,
(
ListOfPathOutputs<'a>,
Option<PolarityOperator<'a>>,
Symbol<'a>,
DataSourceExpression<'a>,
),
>,
),
>,
),
}
#[derive(Debug, Node)]
pub struct DataSourceExpression<'a> {
pub nodes: (Expression<'a>,),
}
#[derive(Debug, Node)]
pub enum EdgeIdentifier<'a> {
Posedge(Symbol<'a>),
Negedge(Symbol<'a>),
Edge(Symbol<'a>),
}
#[derive(Debug, Node)]
pub enum StateDependentPathDeclaration<'a> {
IfSimple(StateDependentPathDeclarationIfSimple<'a>),
IfEdgeSensitive(StateDependentPathDeclarationIfEdgeSensitive<'a>),
IfNone(StateDependentPathDeclarationIfNone<'a>),
}
#[derive(Debug, Node)]
pub struct StateDependentPathDeclarationIfSimple<'a> {
pub nodes: (
Symbol<'a>,
Paren<'a, ModulePathExpression<'a>>,
SimplePathDeclaration<'a>,
),
}
#[derive(Debug, Node)]
pub struct StateDependentPathDeclarationIfEdgeSensitive<'a> {
pub nodes: (
Symbol<'a>,
Paren<'a, ModulePathExpression<'a>>,
EdgeSensitivePathDeclaration<'a>,
),
}
#[derive(Debug, Node)]
pub struct StateDependentPathDeclarationIfNone<'a> {
pub nodes: (Symbol<'a>, SimplePathDeclaration<'a>),
}
#[derive(Debug, Node)]
pub struct PolarityOperator<'a> {
pub nodes: (Symbol<'a>,),
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[parser] #[parser]
pub fn edge_identifier(s: Span) -> IResult<Span, EdgeIdentifier> { pub fn path_delay_value(s: Span) -> IResult<Span, PathDelayValue> {
Err(Err::Error(make_error(s, ErrorKind::Fix))) alt((
map(list_of_path_delay_expressions, |x| {
PathDelayValue::ListOfPathDelayExpressions(x)
}),
path_delay_value_paren,
))(s)
}
#[parser]
pub fn path_delay_value_paren(s: Span) -> IResult<Span, PathDelayValue> {
let (s, a) = paren(list_of_path_delay_expressions)(s)?;
Ok((
s,
PathDelayValue::Paren(PathDelayValueParen { nodes: (a,) }),
))
}
#[parser]
pub fn list_of_path_delay_expressions(s: Span) -> IResult<Span, ListOfPathDelayExpressions> {
let (s, a) = list(symbol(","), t_path_delay_expression)(s)?;
Ok((s, ListOfPathDelayExpressions { nodes: (a,) }))
}
#[parser]
pub fn t_path_delay_expression(s: Span) -> IResult<Span, TPathDelayExpression> {
let (s, a) = path_delay_expression(s)?;
Ok((s, TPathDelayExpression { nodes: (a,) }))
}
#[parser]
pub fn path_delay_expression(s: Span) -> IResult<Span, PathDelayExpression> {
let (s, a) = constant_mintypmax_expression(s)?;
Ok((s, PathDelayExpression { nodes: (a,) }))
}
#[parser]
pub fn edge_sensitive_path_declaration(s: Span) -> IResult<Span, EdgeSensitivePathDeclaration> {
alt((
edge_sensitive_path_declaration_parallel,
edge_sensitive_path_declaration_full,
))(s)
}
#[parser]
pub fn edge_sensitive_path_declaration_parallel(
s: Span,
) -> IResult<Span, EdgeSensitivePathDeclaration> {
let (s, a) = parallel_edge_sensitive_path_description(s)?;
let (s, b) = symbol("=")(s)?;
let (s, c) = path_delay_value(s)?;
Ok((
s,
EdgeSensitivePathDeclaration::Parallel(EdgeSensitivePathDeclarationParallel {
nodes: (a, b, c),
}),
))
}
#[parser]
pub fn edge_sensitive_path_declaration_full(
s: Span,
) -> IResult<Span, EdgeSensitivePathDeclaration> {
let (s, a) = full_edge_sensitive_path_description(s)?;
let (s, b) = symbol("=")(s)?;
let (s, c) = path_delay_value(s)?;
Ok((
s,
EdgeSensitivePathDeclaration::Full(EdgeSensitivePathDeclarationFull { nodes: (a, b, c) }),
))
}
#[parser]
pub fn parallel_edge_sensitive_path_description(
s: Span,
) -> IResult<Span, ParallelEdgeSensitivePathDescription> {
let (s, a) = paren(tuple((
opt(edge_identifier),
specify_input_terminal_descriptor,
opt(polarity_operator),
symbol("=>"),
paren(tuple((
specify_output_terminal_descriptor,
opt(polarity_operator),
symbol(":"),
data_source_expression,
))),
)))(s)?;
Ok((s, ParallelEdgeSensitivePathDescription { nodes: (a,) }))
}
#[parser]
pub fn full_edge_sensitive_path_description(
s: Span,
) -> IResult<Span, FullEdgeSensitivePathDescription> {
let (s, a) = paren(tuple((
opt(edge_identifier),
list_of_path_inputs,
opt(polarity_operator),
symbol("*>"),
paren(tuple((
list_of_path_outputs,
opt(polarity_operator),
symbol(":"),
data_source_expression,
))),
)))(s)?;
Ok((s, FullEdgeSensitivePathDescription { nodes: (a,) }))
}
#[parser]
pub fn data_source_expression(s: Span) -> IResult<Span, DataSourceExpression> {
let (s, a) = expression(s)?;
Ok((s, DataSourceExpression { nodes: (a,) }))
}
#[parser]
pub fn edge_identifier(s: Span) -> IResult<Span, EdgeIdentifier> {
alt((
map(symbol("posedge"), |x| EdgeIdentifier::Posedge(x)),
map(symbol("negedge"), |x| EdgeIdentifier::Negedge(x)),
map(symbol("edge"), |x| EdgeIdentifier::Edge(x)),
))(s)
}
#[parser]
pub fn state_dependent_path_declaration(s: Span) -> IResult<Span, StateDependentPathDeclaration> {
alt((
state_dependent_path_declaration_if_simple,
state_dependent_path_declaration_if_edge_sensitive,
state_dependent_path_declaration_if_none,
))(s)
}
#[parser]
pub fn state_dependent_path_declaration_if_simple(
s: Span,
) -> IResult<Span, StateDependentPathDeclaration> {
let (s, a) = symbol("if")(s)?;
let (s, b) = paren(module_path_expression)(s)?;
let (s, c) = simple_path_declaration(s)?;
Ok((
s,
StateDependentPathDeclaration::IfSimple(StateDependentPathDeclarationIfSimple {
nodes: (a, b, c),
}),
))
}
#[parser]
pub fn state_dependent_path_declaration_if_edge_sensitive(
s: Span,
) -> IResult<Span, StateDependentPathDeclaration> {
let (s, a) = symbol("if")(s)?;
let (s, b) = paren(module_path_expression)(s)?;
let (s, c) = edge_sensitive_path_declaration(s)?;
Ok((
s,
StateDependentPathDeclaration::IfEdgeSensitive(
StateDependentPathDeclarationIfEdgeSensitive { nodes: (a, b, c) },
),
))
}
#[parser]
pub fn state_dependent_path_declaration_if_none(
s: Span,
) -> IResult<Span, StateDependentPathDeclaration> {
let (s, a) = symbol("ifnone")(s)?;
let (s, b) = simple_path_declaration(s)?;
Ok((
s,
StateDependentPathDeclaration::IfNone(StateDependentPathDeclarationIfNone {
nodes: (a, b),
}),
))
}
#[parser]
pub fn polarity_operator(s: Span) -> IResult<Span, PolarityOperator> {
alt((
map(symbol("+"), |x| PolarityOperator { nodes: (x,) }),
map(symbol("-"), |x| PolarityOperator { nodes: (x,) }),
))(s)
} }

View File

@ -0,0 +1,207 @@
use crate::ast::*;
use crate::parser::*;
use nom::branch::*;
use nom::combinator::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug, Node)]
pub struct TimecheckCondition<'a> {
pub nodes: (MintypmaxExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct ControlledReferenceEvent<'a> {
pub nodes: (ControlledTimingCheckEvent<'a>,),
}
#[derive(Debug, Node)]
pub struct DataEvent<'a> {
pub nodes: (TimingCheckEvent<'a>,),
}
#[derive(Debug, Node)]
pub enum DelayedData<'a> {
TerminalIdentifier(TerminalIdentifier<'a>),
WithMintypmax(DelayedDataWithMintypmax<'a>),
}
#[derive(Debug, Node)]
pub struct DelayedDataWithMintypmax<'a> {
pub nodes: (
TerminalIdentifier<'a>,
Bracket<'a, ConstantMintypmaxExpression<'a>>,
),
}
#[derive(Debug, Node)]
pub enum DelayedReference<'a> {
TerminalIdentifier(TerminalIdentifier<'a>),
WithMintypmax(DelayedReferenceWithMintypmax<'a>),
}
#[derive(Debug, Node)]
pub struct DelayedReferenceWithMintypmax<'a> {
pub nodes: (
TerminalIdentifier<'a>,
Bracket<'a, ConstantMintypmaxExpression<'a>>,
),
}
#[derive(Debug, Node)]
pub struct EndEdgeOffset<'a> {
pub nodes: (MintypmaxExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct EventBasedFlag<'a> {
pub nodes: (ConstantExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct Notifier<'a> {
pub nodes: (VariableIdentifier<'a>,),
}
#[derive(Debug, Node)]
pub struct ReferenceEvent<'a> {
pub nodes: (TimingCheckEvent<'a>,),
}
#[derive(Debug, Node)]
pub struct RemainActiveFlag<'a> {
pub nodes: (ConstantMintypmaxExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct TimestampCondition<'a> {
pub nodes: (MintypmaxExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct StartEdgeOffset<'a> {
pub nodes: (MintypmaxExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct Threshold<'a> {
pub nodes: (ConstantExpression<'a>,),
}
#[derive(Debug, Node)]
pub struct TimingCheckLimit<'a> {
pub nodes: (Expression<'a>,),
}
// -----------------------------------------------------------------------------
#[parser]
pub fn timecheck_condition(s: Span) -> IResult<Span, TimecheckCondition> {
let (s, a) = mintypmax_expression(s)?;
Ok((s, TimecheckCondition { nodes: (a,) }))
}
#[parser]
pub fn controlled_referecne_event(s: Span) -> IResult<Span, ControlledReferenceEvent> {
let (s, a) = controlled_timing_check_event(s)?;
Ok((s, ControlledReferenceEvent { nodes: (a,) }))
}
#[parser]
pub fn data_event(s: Span) -> IResult<Span, DataEvent> {
let (s, a) = timing_check_event(s)?;
Ok((s, DataEvent { nodes: (a,) }))
}
#[parser]
pub fn delayed_data(s: Span) -> IResult<Span, DelayedData> {
alt((
map(terminal_identifier, |x| DelayedData::TerminalIdentifier(x)),
delayed_data_with_mintypmax,
))(s)
}
#[parser]
pub fn delayed_data_with_mintypmax(s: Span) -> IResult<Span, DelayedData> {
let (s, a) = terminal_identifier(s)?;
let (s, b) = bracket(constant_mintypmax_expression)(s)?;
Ok((
s,
DelayedData::WithMintypmax(DelayedDataWithMintypmax { nodes: (a, b) }),
))
}
#[parser]
pub fn delayed_reference(s: Span) -> IResult<Span, DelayedReference> {
alt((
map(terminal_identifier, |x| {
DelayedReference::TerminalIdentifier(x)
}),
delayed_reference_with_mintypmax,
))(s)
}
#[parser]
pub fn delayed_reference_with_mintypmax(s: Span) -> IResult<Span, DelayedReference> {
let (s, a) = terminal_identifier(s)?;
let (s, b) = bracket(constant_mintypmax_expression)(s)?;
Ok((
s,
DelayedReference::WithMintypmax(DelayedReferenceWithMintypmax { nodes: (a, b) }),
))
}
#[parser]
pub fn end_edge_offset(s: Span) -> IResult<Span, EndEdgeOffset> {
let (s, a) = mintypmax_expression(s)?;
Ok((s, EndEdgeOffset { nodes: (a,) }))
}
#[parser]
pub fn event_based_flag(s: Span) -> IResult<Span, EventBasedFlag> {
let (s, a) = constant_expression(s)?;
Ok((s, EventBasedFlag { nodes: (a,) }))
}
#[parser]
pub fn notifier(s: Span) -> IResult<Span, Notifier> {
let (s, a) = variable_identifier(s)?;
Ok((s, Notifier { nodes: (a,) }))
}
#[parser]
pub fn referecne_event(s: Span) -> IResult<Span, ReferenceEvent> {
let (s, a) = timing_check_event(s)?;
Ok((s, ReferenceEvent { nodes: (a,) }))
}
#[parser]
pub fn remain_active_flag(s: Span) -> IResult<Span, RemainActiveFlag> {
let (s, a) = constant_mintypmax_expression(s)?;
Ok((s, RemainActiveFlag { nodes: (a,) }))
}
#[parser]
pub fn timestamp_condition(s: Span) -> IResult<Span, TimestampCondition> {
let (s, a) = mintypmax_expression(s)?;
Ok((s, TimestampCondition { nodes: (a,) }))
}
#[parser]
pub fn start_edge_offset(s: Span) -> IResult<Span, StartEdgeOffset> {
let (s, a) = mintypmax_expression(s)?;
Ok((s, StartEdgeOffset { nodes: (a,) }))
}
#[parser]
pub fn threshold(s: Span) -> IResult<Span, Threshold> {
let (s, a) = constant_expression(s)?;
Ok((s, Threshold { nodes: (a,) }))
}
#[parser]
pub fn timing_check_limit(s: Span) -> IResult<Span, TimingCheckLimit> {
let (s, a) = expression(s)?;
Ok((s, TimingCheckLimit { nodes: (a,) }))
}

View File

@ -0,0 +1,580 @@
use crate::ast::*;
use crate::parser::*;
use nom::branch::*;
use nom::combinator::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug, Node)]
pub enum SystemTimingCheck<'a> {
SetupTimingCheck(SetupTimingCheck<'a>),
HoldTimingCheck(HoldTimingCheck<'a>),
SetupholdTimingCheck(SetupholdTimingCheck<'a>),
RecoveryTimingCheck(RecoveryTimingCheck<'a>),
RemovalTimingCheck(RemovalTimingCheck<'a>),
RecremTimingCheck(RecremTimingCheck<'a>),
SkewTimingCheck(SkewTimingCheck<'a>),
TimeskewTimingCheck(TimeskewTimingCheck<'a>),
FullskewTimingCheck(FullskewTimingCheck<'a>),
PeriodTimingCheck(PeriodTimingCheck<'a>),
WidthTimingCheck(WidthTimingCheck<'a>),
NochargeTimingCheck(NochargeTimingCheck<'a>),
}
#[derive(Debug, Node)]
pub struct SetupTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
DataEvent<'a>,
Symbol<'a>,
ReferenceEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct HoldTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct SetupholdTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(
Symbol<'a>,
Option<Notifier<'a>>,
Option<(
Symbol<'a>,
Option<TimestampCondition<'a>>,
Option<(
Symbol<'a>,
Option<TimecheckCondition<'a>>,
Option<(
Symbol<'a>,
Option<DelayedReference<'a>>,
Option<(Symbol<'a>, Option<DelayedData<'a>>)>,
)>,
)>,
)>,
)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct RecoveryTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct RemovalTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct RecremTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(
Symbol<'a>,
Option<Notifier<'a>>,
Option<(
Symbol<'a>,
Option<TimestampCondition<'a>>,
Option<(
Symbol<'a>,
Option<TimecheckCondition<'a>>,
Option<(
Symbol<'a>,
Option<DelayedReference<'a>>,
Option<(Symbol<'a>, Option<DelayedData<'a>>)>,
)>,
)>,
)>,
)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct SkewTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct TimeskewTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(
Symbol<'a>,
Option<Notifier<'a>>,
Option<(
Symbol<'a>,
Option<EventBasedFlag<'a>>,
Option<(Symbol<'a>, Option<RemainActiveFlag<'a>>)>,
)>,
)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct FullskewTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(
Symbol<'a>,
Option<Notifier<'a>>,
Option<(
Symbol<'a>,
Option<EventBasedFlag<'a>>,
Option<(Symbol<'a>, Option<RemainActiveFlag<'a>>)>,
)>,
)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct PeriodTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ControlledReferenceEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct WidthTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ControlledReferenceEvent<'a>,
Symbol<'a>,
TimingCheckLimit<'a>,
Symbol<'a>,
Threshold<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct NochargeTimingCheck<'a> {
pub nodes: (
Symbol<'a>,
Paren<
'a,
(
ReferenceEvent<'a>,
Symbol<'a>,
DataEvent<'a>,
Symbol<'a>,
StartEdgeOffset<'a>,
Symbol<'a>,
EndEdgeOffset<'a>,
Option<(Symbol<'a>, Option<Notifier<'a>>)>,
),
>,
Symbol<'a>,
),
}
// -----------------------------------------------------------------------------
#[parser]
pub fn system_timing_check(s: Span) -> IResult<Span, SystemTimingCheck> {
alt((
map(setup_timing_check, |x| {
SystemTimingCheck::SetupTimingCheck(x)
}),
map(hold_timing_check, |x| SystemTimingCheck::HoldTimingCheck(x)),
map(setuphold_timing_check, |x| {
SystemTimingCheck::SetupholdTimingCheck(x)
}),
map(recovery_timing_check, |x| {
SystemTimingCheck::RecoveryTimingCheck(x)
}),
map(removal_timing_check, |x| {
SystemTimingCheck::RemovalTimingCheck(x)
}),
map(recrem_timing_check, |x| {
SystemTimingCheck::RecremTimingCheck(x)
}),
map(skew_timing_check, |x| SystemTimingCheck::SkewTimingCheck(x)),
map(timeskew_timing_check, |x| {
SystemTimingCheck::TimeskewTimingCheck(x)
}),
map(fullskew_timing_check, |x| {
SystemTimingCheck::FullskewTimingCheck(x)
}),
map(period_timing_check, |x| {
SystemTimingCheck::PeriodTimingCheck(x)
}),
map(width_timing_check, |x| {
SystemTimingCheck::WidthTimingCheck(x)
}),
map(nocharge_timing_check, |x| {
SystemTimingCheck::NochargeTimingCheck(x)
}),
))(s)
}
#[parser]
pub fn setup_timing_check(s: Span) -> IResult<Span, SetupTimingCheck> {
let (s, a) = symbol("$setup")(s)?;
let (s, b) = paren(tuple((
data_event,
symbol(","),
referecne_event,
symbol(","),
timing_check_limit,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, SetupTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn hold_timing_check(s: Span) -> IResult<Span, HoldTimingCheck> {
let (s, a) = symbol("$setup")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, HoldTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn setuphold_timing_check(s: Span) -> IResult<Span, SetupholdTimingCheck> {
let (s, a) = symbol("$setuphold")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
symbol(","),
timing_check_limit,
opt(triple(
symbol(","),
opt(notifier),
opt(triple(
symbol(","),
opt(timestamp_condition),
opt(triple(
symbol(","),
opt(timecheck_condition),
opt(triple(
symbol(","),
opt(delayed_reference),
opt(pair(symbol(","), opt(delayed_data))),
)),
)),
)),
)),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, SetupholdTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn recovery_timing_check(s: Span) -> IResult<Span, RecoveryTimingCheck> {
let (s, a) = symbol("$recovery")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, RecoveryTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn removal_timing_check(s: Span) -> IResult<Span, RemovalTimingCheck> {
let (s, a) = symbol("$removal")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, RemovalTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn recrem_timing_check(s: Span) -> IResult<Span, RecremTimingCheck> {
let (s, a) = symbol("$recrem")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
symbol(","),
timing_check_limit,
opt(triple(
symbol(","),
opt(notifier),
opt(triple(
symbol(","),
opt(timestamp_condition),
opt(triple(
symbol(","),
opt(timecheck_condition),
opt(triple(
symbol(","),
opt(delayed_reference),
opt(pair(symbol(","), opt(delayed_data))),
)),
)),
)),
)),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, RecremTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn skew_timing_check(s: Span) -> IResult<Span, SkewTimingCheck> {
let (s, a) = symbol("$skew")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, SkewTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn timeskew_timing_check(s: Span) -> IResult<Span, TimeskewTimingCheck> {
let (s, a) = symbol("$timeskew")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
opt(triple(
symbol(","),
opt(notifier),
opt(triple(
symbol(","),
opt(event_based_flag),
opt(pair(symbol(","), opt(remain_active_flag))),
)),
)),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, TimeskewTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn fullskew_timing_check(s: Span) -> IResult<Span, FullskewTimingCheck> {
let (s, a) = symbol("$fullskew")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
timing_check_limit,
symbol(","),
timing_check_limit,
opt(triple(
symbol(","),
opt(notifier),
opt(triple(
symbol(","),
opt(event_based_flag),
opt(pair(symbol(","), opt(remain_active_flag))),
)),
)),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, FullskewTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn period_timing_check(s: Span) -> IResult<Span, PeriodTimingCheck> {
let (s, a) = symbol("$period")(s)?;
let (s, b) = paren(tuple((
controlled_referecne_event,
symbol(","),
timing_check_limit,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, PeriodTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn width_timing_check(s: Span) -> IResult<Span, WidthTimingCheck> {
let (s, a) = symbol("$width")(s)?;
let (s, b) = paren(tuple((
controlled_referecne_event,
symbol(","),
timing_check_limit,
symbol(","),
threshold,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, WidthTimingCheck { nodes: (a, b, c) }))
}
#[parser]
pub fn nocharge_timing_check(s: Span) -> IResult<Span, NochargeTimingCheck> {
let (s, a) = symbol("$nocharge")(s)?;
let (s, b) = paren(tuple((
referecne_event,
symbol(","),
data_event,
symbol(","),
start_edge_offset,
symbol(","),
end_edge_offset,
opt(pair(symbol(","), opt(notifier))),
)))(s)?;
let (s, c) = symbol(";")(s)?;
Ok((s, NochargeTimingCheck { nodes: (a, b, c) }))
}

View File

@ -0,0 +1,224 @@
use crate::ast::*;
use crate::parser::*;
use nom::branch::*;
use nom::combinator::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug, Node)]
pub struct TimingCheckEvent<'a> {
pub nodes: (
Option<TimingCheckEventControl<'a>>,
SpecifyTerminalDescriptor<'a>,
Option<(Symbol<'a>, TimingCheckCondition<'a>)>,
),
}
#[derive(Debug, Node)]
pub struct ControlledTimingCheckEvent<'a> {
pub nodes: (
TimingCheckEventControl<'a>,
SpecifyTerminalDescriptor<'a>,
Option<(Symbol<'a>, TimingCheckCondition<'a>)>,
),
}
#[derive(Debug, Node)]
pub enum TimingCheckEventControl<'a> {
Posedge(Symbol<'a>),
Negedge(Symbol<'a>),
Edge(Symbol<'a>),
EdgeControlSpecifier(EdgeControlSpecifier<'a>),
}
#[derive(Debug, Node)]
pub enum SpecifyTerminalDescriptor<'a> {
SpecifyInputTerminalDescriptor(SpecifyInputTerminalDescriptor<'a>),
SpecifyOutputTerminalDescriptor(SpecifyOutputTerminalDescriptor<'a>),
}
#[derive(Debug, Node)]
pub struct EdgeControlSpecifier<'a> {
pub nodes: (
Symbol<'a>,
Bracket<'a, List<Symbol<'a>, EdgeDescriptor<'a>>>,
),
}
#[derive(Debug, Node)]
pub struct EdgeDescriptor<'a> {
pub nodes: (Symbol<'a>,),
}
#[derive(Debug, Node)]
pub enum TimingCheckCondition<'a> {
ScalarTimingCheckCondition(ScalarTimingCheckCondition<'a>),
Paren(TimingCheckConditionParen<'a>),
}
#[derive(Debug, Node)]
pub struct TimingCheckConditionParen<'a> {
pub nodes: (Paren<'a, ScalarTimingCheckCondition<'a>>,),
}
#[derive(Debug, Node)]
pub enum ScalarTimingCheckCondition<'a> {
Expression(Expression<'a>),
Unary(ScalarTimingCheckConditionUnary<'a>),
Binary(ScalarTimingCheckConditionBinary<'a>),
}
#[derive(Debug, Node)]
pub struct ScalarTimingCheckConditionUnary<'a> {
pub nodes: (Symbol<'a>, Expression<'a>),
}
#[derive(Debug, Node)]
pub struct ScalarTimingCheckConditionBinary<'a> {
pub nodes: (Expression<'a>, Symbol<'a>, ScalarConstant<'a>),
}
#[derive(Debug, Node)]
pub struct ScalarConstant<'a> {
pub nodes: (Symbol<'a>,),
}
// -----------------------------------------------------------------------------
#[parser]
pub fn timing_check_event(s: Span) -> IResult<Span, TimingCheckEvent> {
let (s, a) = opt(timing_check_event_control)(s)?;
let (s, b) = specify_terminal_descriptor(s)?;
let (s, c) = opt(pair(symbol("&&&"), timing_check_condition))(s)?;
Ok((s, TimingCheckEvent { nodes: (a, b, c) }))
}
#[parser]
pub fn controlled_timing_check_event(s: Span) -> IResult<Span, ControlledTimingCheckEvent> {
let (s, a) = timing_check_event_control(s)?;
let (s, b) = specify_terminal_descriptor(s)?;
let (s, c) = opt(pair(symbol("&&&"), timing_check_condition))(s)?;
Ok((s, ControlledTimingCheckEvent { nodes: (a, b, c) }))
}
#[parser]
pub fn timing_check_event_control(s: Span) -> IResult<Span, TimingCheckEventControl> {
alt((
map(symbol("posedge"), |x| TimingCheckEventControl::Posedge(x)),
map(symbol("negedge"), |x| TimingCheckEventControl::Negedge(x)),
map(symbol("edge"), |x| TimingCheckEventControl::Edge(x)),
map(edge_control_specifier, |x| {
TimingCheckEventControl::EdgeControlSpecifier(x)
}),
))(s)
}
#[parser]
pub fn specify_terminal_descriptor(s: Span) -> IResult<Span, SpecifyTerminalDescriptor> {
alt((
map(specify_input_terminal_descriptor, |x| {
SpecifyTerminalDescriptor::SpecifyInputTerminalDescriptor(x)
}),
map(specify_output_terminal_descriptor, |x| {
SpecifyTerminalDescriptor::SpecifyOutputTerminalDescriptor(x)
}),
))(s)
}
#[parser]
pub fn edge_control_specifier(s: Span) -> IResult<Span, EdgeControlSpecifier> {
let (s, a) = symbol("edge")(s)?;
let (s, b) = bracket(list(symbol(","), edge_descriptor))(s)?;
Ok((s, EdgeControlSpecifier { nodes: (a, b) }))
}
#[parser]
pub fn edge_descriptor(s: Span) -> IResult<Span, EdgeDescriptor> {
alt((
map(symbol("01"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("10"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("x0"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("x1"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("X0"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("X1"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("z0"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("z1"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("Z0"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("Z1"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("0x"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("1x"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("0X"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("1X"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("0z"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("1z"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("0Z"), |x| EdgeDescriptor { nodes: (x,) }),
map(symbol("1Z"), |x| EdgeDescriptor { nodes: (x,) }),
))(s)
}
#[parser]
pub fn timing_check_condition(s: Span) -> IResult<Span, TimingCheckCondition> {
alt((
map(scalar_timing_check_condition, |x| {
TimingCheckCondition::ScalarTimingCheckCondition(x)
}),
timing_check_condition_paren,
))(s)
}
#[parser]
pub fn timing_check_condition_paren(s: Span) -> IResult<Span, TimingCheckCondition> {
let (s, a) = paren(scalar_timing_check_condition)(s)?;
Ok((
s,
TimingCheckCondition::Paren(TimingCheckConditionParen { nodes: (a,) }),
))
}
#[parser]
pub fn scalar_timing_check_condition(s: Span) -> IResult<Span, ScalarTimingCheckCondition> {
alt((
map(expression, |x| ScalarTimingCheckCondition::Expression(x)),
scalar_timing_check_condition_unary,
scalar_timing_check_condition_binary,
))(s)
}
#[parser]
pub fn scalar_timing_check_condition_unary(s: Span) -> IResult<Span, ScalarTimingCheckCondition> {
let (s, a) = symbol("~")(s)?;
let (s, b) = expression(s)?;
Ok((
s,
ScalarTimingCheckCondition::Unary(ScalarTimingCheckConditionUnary { nodes: (a, b) }),
))
}
#[parser]
pub fn scalar_timing_check_condition_binary(s: Span) -> IResult<Span, ScalarTimingCheckCondition> {
let (s, a) = expression(s)?;
let (s, b) = alt((symbol("==="), symbol("=="), symbol("!=="), symbol("!=")))(s)?;
let (s, c) = scalar_constant(s)?;
Ok((
s,
ScalarTimingCheckCondition::Binary(ScalarTimingCheckConditionBinary { nodes: (a, b, c) }),
))
}
#[parser]
pub fn scalar_constant(s: Span) -> IResult<Span, ScalarConstant> {
alt((
map(symbol("1'b0"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("1'b1"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("1'B0"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("1'B1"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("'b0"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("'b1"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("'B0"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("'B1"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("1"), |x| ScalarConstant { nodes: (x,) }),
map(symbol("0"), |x| ScalarConstant { nodes: (x,) }),
))(s)
}

View File

@ -1,4 +1,8 @@
pub mod udp_body;
pub mod udp_declaration; pub mod udp_declaration;
pub mod udp_instantiation; pub mod udp_instantiation;
pub mod udp_ports;
pub use udp_body::*;
pub use udp_declaration::*; pub use udp_declaration::*;
pub use udp_instantiation::*; pub use udp_instantiation::*;
pub use udp_ports::*;

View File

@ -0,0 +1,315 @@
use crate::ast::*;
use crate::parser::*;
use nom::branch::*;
use nom::combinator::*;
use nom::multi::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug, Node)]
pub enum UdpBody<'a> {
CombinationalBody(CombinationalBody<'a>),
SequentialBody(SequentialBody<'a>),
}
#[derive(Debug, Node)]
pub struct CombinationalBody<'a> {
pub nodes: (
Symbol<'a>,
CombinationalEntry<'a>,
Vec<CombinationalEntry<'a>>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct CombinationalEntry<'a> {
pub nodes: (LevelInputList<'a>, Symbol<'a>, OutputSymbol<'a>, Symbol<'a>),
}
#[derive(Debug, Node)]
pub struct SequentialBody<'a> {
pub nodes: (
Option<UdpInitialStatement<'a>>,
Symbol<'a>,
SequentialEntry<'a>,
Vec<SequentialEntry<'a>>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct UdpInitialStatement<'a> {
pub nodes: (
Symbol<'a>,
OutputPortIdentifier<'a>,
Symbol<'a>,
InitVal<'a>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct InitVal<'a> {
pub nodes: (Symbol<'a>,),
}
#[derive(Debug, Node)]
pub struct SequentialEntry<'a> {
pub nodes: (
SeqInputList<'a>,
Symbol<'a>,
CurrentState<'a>,
Symbol<'a>,
NextState<'a>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub enum SeqInputList<'a> {
LevelInputList(LevelInputList<'a>),
EdgeInputList(EdgeInputList<'a>),
}
#[derive(Debug, Node)]
pub struct LevelInputList<'a> {
pub nodes: (LevelSymbol<'a>, Vec<LevelSymbol<'a>>),
}
#[derive(Debug, Node)]
pub struct EdgeInputList<'a> {
pub nodes: (
Vec<LevelSymbol<'a>>,
EdgeIndicator<'a>,
Vec<LevelSymbol<'a>>,
),
}
#[derive(Debug, Node)]
pub enum EdgeIndicator<'a> {
Paren(EdgeIndicatorParen<'a>),
EdgeSymbol(EdgeSymbol<'a>),
}
#[derive(Debug, Node)]
pub struct EdgeIndicatorParen<'a> {
pub nodes: (Paren<'a, (LevelSymbol<'a>, LevelSymbol<'a>)>,),
}
#[derive(Debug, Node)]
pub struct CurrentState<'a> {
pub nodes: (LevelSymbol<'a>,),
}
#[derive(Debug, Node)]
pub enum NextState<'a> {
OutputSymbol(OutputSymbol<'a>),
Minus(Symbol<'a>),
}
#[derive(Debug, Node)]
pub struct OutputSymbol<'a> {
pub nodes: (Symbol<'a>,),
}
#[derive(Debug, Node)]
pub struct LevelSymbol<'a> {
pub nodes: (Symbol<'a>,),
}
#[derive(Debug, Node)]
pub struct EdgeSymbol<'a> {
pub nodes: (Symbol<'a>,),
}
// -----------------------------------------------------------------------------
#[parser]
pub fn udp_body(s: Span) -> IResult<Span, UdpBody> {
alt((
map(combinational_body, |x| UdpBody::CombinationalBody(x)),
map(sequential_body, |x| UdpBody::SequentialBody(x)),
))(s)
}
#[parser]
pub fn combinational_body(s: Span) -> IResult<Span, CombinationalBody> {
let (s, a) = symbol("table")(s)?;
let (s, b) = combinational_entry(s)?;
let (s, c) = many0(combinational_entry)(s)?;
let (s, d) = symbol("endtable")(s)?;
Ok((
s,
CombinationalBody {
nodes: (a, b, c, d),
},
))
}
#[parser]
pub fn combinational_entry(s: Span) -> IResult<Span, CombinationalEntry> {
let (s, a) = level_input_list(s)?;
let (s, b) = symbol(":")(s)?;
let (s, c) = output_symbol(s)?;
let (s, d) = symbol(";")(s)?;
Ok((
s,
CombinationalEntry {
nodes: (a, b, c, d),
},
))
}
#[parser]
pub fn sequential_body(s: Span) -> IResult<Span, SequentialBody> {
let (s, a) = opt(udp_initial_statement)(s)?;
let (s, b) = symbol("table")(s)?;
let (s, c) = sequential_entry(s)?;
let (s, d) = many0(sequential_entry)(s)?;
let (s, e) = symbol("endtable")(s)?;
Ok((
s,
SequentialBody {
nodes: (a, b, c, d, e),
},
))
}
#[parser]
pub fn udp_initial_statement(s: Span) -> IResult<Span, UdpInitialStatement> {
let (s, a) = symbol("initial")(s)?;
let (s, b) = output_port_identifier(s)?;
let (s, c) = symbol("=")(s)?;
let (s, d) = init_val(s)?;
let (s, e) = symbol(";")(s)?;
Ok((
s,
UdpInitialStatement {
nodes: (a, b, c, d, e),
},
))
}
#[parser]
pub fn init_val(s: Span) -> IResult<Span, InitVal> {
alt((
map(symbol("1'b0"), |x| InitVal { nodes: (x,) }),
map(symbol("1'b1"), |x| InitVal { nodes: (x,) }),
map(symbol("1'bx"), |x| InitVal { nodes: (x,) }),
map(symbol("1'bX"), |x| InitVal { nodes: (x,) }),
map(symbol("1'B0"), |x| InitVal { nodes: (x,) }),
map(symbol("1'B1"), |x| InitVal { nodes: (x,) }),
map(symbol("1'Bx"), |x| InitVal { nodes: (x,) }),
map(symbol("1'BX"), |x| InitVal { nodes: (x,) }),
map(symbol("1"), |x| InitVal { nodes: (x,) }),
map(symbol("0"), |x| InitVal { nodes: (x,) }),
))(s)
}
#[parser]
pub fn sequential_entry(s: Span) -> IResult<Span, SequentialEntry> {
let (s, a) = seq_input_list(s)?;
let (s, b) = symbol(":")(s)?;
let (s, c) = current_state(s)?;
let (s, d) = symbol(":")(s)?;
let (s, e) = next_state(s)?;
let (s, f) = symbol(";")(s)?;
Ok((
s,
SequentialEntry {
nodes: (a, b, c, d, e, f),
},
))
}
#[parser]
pub fn seq_input_list(s: Span) -> IResult<Span, SeqInputList> {
alt((
map(level_input_list, |x| SeqInputList::LevelInputList(x)),
map(edge_input_list, |x| SeqInputList::EdgeInputList(x)),
))(s)
}
#[parser]
pub fn level_input_list(s: Span) -> IResult<Span, LevelInputList> {
let (s, a) = level_symbol(s)?;
let (s, b) = many0(level_symbol)(s)?;
Ok((s, LevelInputList { nodes: (a, b) }))
}
#[parser]
pub fn edge_input_list(s: Span) -> IResult<Span, EdgeInputList> {
let (s, a) = many0(level_symbol)(s)?;
let (s, b) = edge_indicator(s)?;
let (s, c) = many0(level_symbol)(s)?;
Ok((s, EdgeInputList { nodes: (a, b, c) }))
}
#[parser]
pub fn edge_indicator(s: Span) -> IResult<Span, EdgeIndicator> {
alt((
edge_indicator_paren,
map(edge_symbol, |x| EdgeIndicator::EdgeSymbol(x)),
))(s)
}
#[parser]
pub fn edge_indicator_paren(s: Span) -> IResult<Span, EdgeIndicator> {
let (s, a) = paren(pair(level_symbol, level_symbol))(s)?;
Ok((s, EdgeIndicator::Paren(EdgeIndicatorParen { nodes: (a,) })))
}
#[parser]
pub fn current_state(s: Span) -> IResult<Span, CurrentState> {
let (s, a) = level_symbol(s)?;
Ok((s, CurrentState { nodes: (a,) }))
}
#[parser]
pub fn next_state(s: Span) -> IResult<Span, NextState> {
alt((
map(output_symbol, |x| NextState::OutputSymbol(x)),
map(symbol("-"), |x| NextState::Minus(x)),
))(s)
}
#[parser]
pub fn output_symbol(s: Span) -> IResult<Span, OutputSymbol> {
alt((
map(symbol("0"), |x| OutputSymbol { nodes: (x,) }),
map(symbol("1"), |x| OutputSymbol { nodes: (x,) }),
map(symbol("x"), |x| OutputSymbol { nodes: (x,) }),
map(symbol("X"), |x| OutputSymbol { nodes: (x,) }),
))(s)
}
#[parser]
pub fn level_symbol(s: Span) -> IResult<Span, LevelSymbol> {
alt((
map(symbol("0"), |x| LevelSymbol { nodes: (x,) }),
map(symbol("1"), |x| LevelSymbol { nodes: (x,) }),
map(symbol("x"), |x| LevelSymbol { nodes: (x,) }),
map(symbol("X"), |x| LevelSymbol { nodes: (x,) }),
map(symbol("?"), |x| LevelSymbol { nodes: (x,) }),
map(symbol("b"), |x| LevelSymbol { nodes: (x,) }),
map(symbol("B"), |x| LevelSymbol { nodes: (x,) }),
))(s)
}
#[parser]
pub fn edge_symbol(s: Span) -> IResult<Span, EdgeSymbol> {
alt((
map(symbol("r"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("R"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("f"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("F"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("p"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("P"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("n"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("N"), |x| EdgeSymbol { nodes: (x,) }),
map(symbol("*"), |x| EdgeSymbol { nodes: (x,) }),
))(s)
}

View File

@ -1,20 +1,199 @@
use crate::ast::*; use crate::ast::*;
use crate::parser::*; use crate::parser::*;
//use nom::branch::*; use nom::branch::*;
//use nom::combinator::*; use nom::combinator::*;
use nom::error::*; use nom::multi::*;
use nom::{Err, IResult}; use nom::sequence::*;
use nom::IResult;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[derive(Debug, Node)] #[derive(Debug, Node)]
pub struct UdpDeclaration<'a> { pub struct UdpNonansiDeclaration<'a> {
pub nodes: (Identifier<'a>,), pub nodes: (
Vec<AttributeInstance<'a>>,
Symbol<'a>,
UdpIdentifier<'a>,
Paren<'a, UdpPortList<'a>>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub struct UdpAnsiDeclaration<'a> {
pub nodes: (
Vec<AttributeInstance<'a>>,
Symbol<'a>,
UdpIdentifier<'a>,
Paren<'a, UdpDeclarationPortList<'a>>,
Symbol<'a>,
),
}
#[derive(Debug, Node)]
pub enum UdpDeclaration<'a> {
Nonansi(UdpDeclarationNonansi<'a>),
Ansi(UdpDeclarationAnsi<'a>),
ExternNonansi(UdpDeclarationExternNonansi<'a>),
ExternAnsi(UdpDeclarationExternAnsi<'a>),
Wildcard(UdpDeclarationWildcard<'a>),
}
#[derive(Debug, Node)]
pub struct UdpDeclarationNonansi<'a> {
pub nodes: (
UdpNonansiDeclaration<'a>,
UdpPortDeclaration<'a>,
Vec<UdpPortDeclaration<'a>>,
UdpBody<'a>,
Symbol<'a>,
Option<(Symbol<'a>, UdpIdentifier<'a>)>,
),
}
#[derive(Debug, Node)]
pub struct UdpDeclarationAnsi<'a> {
pub nodes: (
UdpAnsiDeclaration<'a>,
UdpBody<'a>,
Symbol<'a>,
Option<(Symbol<'a>, UdpIdentifier<'a>)>,
),
}
#[derive(Debug, Node)]
pub struct UdpDeclarationExternNonansi<'a> {
pub nodes: (Symbol<'a>, UdpNonansiDeclaration<'a>),
}
#[derive(Debug, Node)]
pub struct UdpDeclarationExternAnsi<'a> {
pub nodes: (Symbol<'a>, UdpAnsiDeclaration<'a>),
}
#[derive(Debug, Node)]
pub struct UdpDeclarationWildcard<'a> {
pub nodes: (
Vec<AttributeInstance<'a>>,
Symbol<'a>,
UdpIdentifier<'a>,
Paren<'a, Symbol<'a>>,
Symbol<'a>,
Vec<UdpPortDeclaration<'a>>,
UdpBody<'a>,
Symbol<'a>,
Option<(Symbol<'a>, UdpIdentifier<'a>)>,
),
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#[parser] #[parser]
pub fn udp_declaration(s: Span) -> IResult<Span, UdpDeclaration> { pub fn udp_nonansi_declaration(s: Span) -> IResult<Span, UdpNonansiDeclaration> {
Err(Err::Error(make_error(s, ErrorKind::Fix))) let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = symbol("primitive")(s)?;
let (s, c) = udp_identifier(s)?;
let (s, d) = paren(udp_port_list)(s)?;
let (s, e) = symbol(";")(s)?;
Ok((
s,
UdpNonansiDeclaration {
nodes: (a, b, c, d, e),
},
))
}
#[parser]
pub fn udp_ansi_declaration(s: Span) -> IResult<Span, UdpAnsiDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = symbol("primitive")(s)?;
let (s, c) = udp_identifier(s)?;
let (s, d) = paren(udp_declaration_port_list)(s)?;
let (s, e) = symbol(";")(s)?;
Ok((
s,
UdpAnsiDeclaration {
nodes: (a, b, c, d, e),
},
))
}
#[parser]
pub fn udp_declaration(s: Span) -> IResult<Span, UdpDeclaration> {
alt((
udp_declaration_nonansi,
udp_declaration_ansi,
udp_declaration_extern_nonansi,
udp_declaration_extern_ansi,
udp_declaration_wildcard,
))(s)
}
#[parser]
pub fn udp_declaration_nonansi(s: Span) -> IResult<Span, UdpDeclaration> {
let (s, a) = udp_nonansi_declaration(s)?;
let (s, b) = udp_port_declaration(s)?;
let (s, c) = many0(udp_port_declaration)(s)?;
let (s, d) = udp_body(s)?;
let (s, e) = symbol("endprimitive")(s)?;
let (s, f) = opt(pair(symbol(":"), udp_identifier))(s)?;
Ok((
s,
UdpDeclaration::Nonansi(UdpDeclarationNonansi {
nodes: (a, b, c, d, e, f),
}),
))
}
#[parser]
pub fn udp_declaration_ansi(s: Span) -> IResult<Span, UdpDeclaration> {
let (s, a) = udp_ansi_declaration(s)?;
let (s, b) = udp_body(s)?;
let (s, c) = symbol("endprimitive")(s)?;
let (s, d) = opt(pair(symbol(":"), udp_identifier))(s)?;
Ok((
s,
UdpDeclaration::Ansi(UdpDeclarationAnsi {
nodes: (a, b, c, d),
}),
))
}
#[parser]
pub fn udp_declaration_extern_nonansi(s: Span) -> IResult<Span, UdpDeclaration> {
let (s, a) = symbol("extern")(s)?;
let (s, b) = udp_nonansi_declaration(s)?;
Ok((
s,
UdpDeclaration::ExternNonansi(UdpDeclarationExternNonansi { nodes: (a, b) }),
))
}
#[parser]
pub fn udp_declaration_extern_ansi(s: Span) -> IResult<Span, UdpDeclaration> {
let (s, a) = symbol("extern")(s)?;
let (s, b) = udp_ansi_declaration(s)?;
Ok((
s,
UdpDeclaration::ExternAnsi(UdpDeclarationExternAnsi { nodes: (a, b) }),
))
}
#[parser]
pub fn udp_declaration_wildcard(s: Span) -> IResult<Span, UdpDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = symbol("primitive")(s)?;
let (s, c) = udp_identifier(s)?;
let (s, d) = paren(symbol(".*"))(s)?;
let (s, e) = symbol(";")(s)?;
let (s, f) = many0(udp_port_declaration)(s)?;
let (s, g) = udp_body(s)?;
let (s, h) = symbol("endprimitive")(s)?;
let (s, i) = opt(pair(symbol(":"), udp_identifier))(s)?;
Ok((
s,
UdpDeclaration::Wildcard(UdpDeclarationWildcard {
nodes: (a, b, c, d, e, f, g, h, i),
}),
))
} }

View File

@ -0,0 +1,154 @@
use crate::ast::*;
use crate::parser::*;
use nom::branch::*;
use nom::combinator::*;
use nom::multi::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug, Node)]
pub struct UdpPortList<'a> {
pub nodes: (
OutputPortIdentifier<'a>,
Symbol<'a>,
List<Symbol<'a>, InputPortIdentifier<'a>>,
),
}
#[derive(Debug, Node)]
pub struct UdpDeclarationPortList<'a> {
pub nodes: (
UdpOutputDeclaration<'a>,
Symbol<'a>,
List<Symbol<'a>, UdpInputDeclaration<'a>>,
),
}
#[derive(Debug, Node)]
pub enum UdpPortDeclaration<'a> {
UdpOutputDeclaration((UdpOutputDeclaration<'a>, Symbol<'a>)),
UdpInputDeclaration((UdpInputDeclaration<'a>, Symbol<'a>)),
UdpRegDeclaration((UdpRegDeclaration<'a>, Symbol<'a>)),
}
#[derive(Debug, Node)]
pub enum UdpOutputDeclaration<'a> {
Nonreg(UdpOutputDeclarationNonreg<'a>),
Reg(UdpOutputDeclarationReg<'a>),
}
#[derive(Debug, Node)]
pub struct UdpOutputDeclarationNonreg<'a> {
pub nodes: (Vec<AttributeInstance<'a>>, Symbol<'a>, PortIdentifier<'a>),
}
#[derive(Debug, Node)]
pub struct UdpOutputDeclarationReg<'a> {
pub nodes: (
Vec<AttributeInstance<'a>>,
Symbol<'a>,
Symbol<'a>,
PortIdentifier<'a>,
Option<(Symbol<'a>, ConstantExpression<'a>)>,
),
}
#[derive(Debug, Node)]
pub struct UdpInputDeclaration<'a> {
pub nodes: (
Vec<AttributeInstance<'a>>,
Symbol<'a>,
ListOfUdpPortIdentifiers<'a>,
),
}
#[derive(Debug, Node)]
pub struct UdpRegDeclaration<'a> {
pub nodes: (
Vec<AttributeInstance<'a>>,
Symbol<'a>,
VariableIdentifier<'a>,
),
}
// -----------------------------------------------------------------------------
#[parser]
pub fn udp_port_list(s: Span) -> IResult<Span, UdpPortList> {
let (s, a) = output_port_identifier(s)?;
let (s, b) = symbol(",")(s)?;
let (s, c) = list(symbol(","), input_port_identifier)(s)?;
Ok((s, UdpPortList { nodes: (a, b, c) }))
}
#[parser]
pub fn udp_declaration_port_list(s: Span) -> IResult<Span, UdpDeclarationPortList> {
let (s, a) = udp_output_declaration(s)?;
let (s, b) = symbol(",")(s)?;
let (s, c) = list(symbol(","), udp_input_declaration)(s)?;
Ok((s, UdpDeclarationPortList { nodes: (a, b, c) }))
}
#[parser]
pub fn udp_port_declaration(s: Span) -> IResult<Span, UdpPortDeclaration> {
alt((
map(pair(udp_output_declaration, symbol(";")), |x| {
UdpPortDeclaration::UdpOutputDeclaration(x)
}),
map(pair(udp_input_declaration, symbol(";")), |x| {
UdpPortDeclaration::UdpInputDeclaration(x)
}),
map(pair(udp_reg_declaration, symbol(";")), |x| {
UdpPortDeclaration::UdpRegDeclaration(x)
}),
))(s)
}
#[parser]
pub fn udp_output_declaration(s: Span) -> IResult<Span, UdpOutputDeclaration> {
alt((udp_output_declaration_nonreg, udp_output_declaration_reg))(s)
}
#[parser]
pub fn udp_output_declaration_nonreg(s: Span) -> IResult<Span, UdpOutputDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = symbol("output")(s)?;
let (s, c) = port_identifier(s)?;
Ok((
s,
UdpOutputDeclaration::Nonreg(UdpOutputDeclarationNonreg { nodes: (a, b, c) }),
))
}
#[parser]
pub fn udp_output_declaration_reg(s: Span) -> IResult<Span, UdpOutputDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = symbol("output")(s)?;
let (s, c) = symbol("reg")(s)?;
let (s, d) = port_identifier(s)?;
let (s, e) = opt(pair(symbol("="), constant_expression))(s)?;
Ok((
s,
UdpOutputDeclaration::Reg(UdpOutputDeclarationReg {
nodes: (a, b, c, d, e),
}),
))
}
#[parser]
pub fn udp_input_declaration(s: Span) -> IResult<Span, UdpInputDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = symbol("input")(s)?;
let (s, c) = list_of_udp_port_identifiers(s)?;
Ok((s, UdpInputDeclaration { nodes: (a, b, c) }))
}
#[parser]
pub fn udp_reg_declaration(s: Span) -> IResult<Span, UdpRegDeclaration> {
let (s, a) = many0(attribute_instance)(s)?;
let (s, b) = symbol("reg")(s)?;
let (s, c) = variable_identifier(s)?;
Ok((s, UdpRegDeclaration { nodes: (a, b, c) }))
}