sv-parser/src/parser/specify_section/system_timing_check_commands.rs
2019-07-19 13:03:07 +09:00

581 lines
16 KiB
Rust

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) }))
}