Add behavioral_statements
This commit is contained in:
parent
317f18d845
commit
a96769c02e
282
src/parser/behavioral_statements/assertion_statements.rs
Normal file
282
src/parser/behavioral_statements/assertion_statements.rs
Normal file
@ -0,0 +1,282 @@
|
||||
use crate::parser::*;
|
||||
use nom::branch::*;
|
||||
use nom::combinator::*;
|
||||
use nom::sequence::*;
|
||||
use nom::IResult;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AssertionItem<'a> {
|
||||
Concurrent(ConcurrentAssertionItem<'a>),
|
||||
Immediate(DeferredImmediateAssetionItem<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeferredImmediateAssetionItem<'a> {
|
||||
pub identifier: Option<Identifier<'a>>,
|
||||
pub statement: DeferredImmediateAssertionStatement<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProceduralAssertionStatement<'a> {
|
||||
Concurrent(ConcurrentAssertionStatement<'a>),
|
||||
Immediate(ImmediateAssetionStatement<'a>),
|
||||
Checker(CheckerInstantiation<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ImmediateAssetionStatement<'a> {
|
||||
Simple(SimpleImmediateAssertionStatement<'a>),
|
||||
Deferred(DeferredImmediateAssertionStatement<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SimpleImmediateAssertionStatement<'a> {
|
||||
Assert(SimpleImmediateAssertStatement<'a>),
|
||||
Assume(SimpleImmediateAssumeStatement<'a>),
|
||||
Cover(SimpleImmediateCoverStatement<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SimpleImmediateAssertStatement<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub block: ActionBlock<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SimpleImmediateAssumeStatement<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub block: ActionBlock<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SimpleImmediateCoverStatement<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub statement: StatementOrNull<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DeferredImmediateAssertionStatement<'a> {
|
||||
Assert(DeferredImmediateAssertStatement<'a>),
|
||||
Assume(DeferredImmediateAssumeStatement<'a>),
|
||||
Cover(DeferredImmediateCoverStatement<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeferredImmediateAssertStatement<'a> {
|
||||
pub timing: AssertTiming,
|
||||
pub expression: Expression<'a>,
|
||||
pub block: ActionBlock<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeferredImmediateAssumeStatement<'a> {
|
||||
pub timing: AssertTiming,
|
||||
pub expression: Expression<'a>,
|
||||
pub block: ActionBlock<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeferredImmediateCoverStatement<'a> {
|
||||
pub timing: AssertTiming,
|
||||
pub expression: Expression<'a>,
|
||||
pub statement: StatementOrNull<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AssertTiming {
|
||||
Zero,
|
||||
Final,
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub fn assertion_item(s: &str) -> IResult<&str, AssertionItem> {
|
||||
alt((
|
||||
map(concurrent_assertion_item, |x| AssertionItem::Concurrent(x)),
|
||||
map(deferred_immediate_assertion_item, |x| {
|
||||
AssertionItem::Immediate(x)
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn deferred_immediate_assertion_item(s: &str) -> IResult<&str, DeferredImmediateAssetionItem> {
|
||||
let (s, x) = opt(terminated(block_identifier, symbol(":")))(s)?;
|
||||
let (s, y) = deferred_immediate_assertion_statement(s)?;
|
||||
Ok((
|
||||
s,
|
||||
DeferredImmediateAssetionItem {
|
||||
identifier: x,
|
||||
statement: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn procedural_assertion_statement(s: &str) -> IResult<&str, ProceduralAssertionStatement> {
|
||||
alt((
|
||||
map(concurrent_assertion_statement, |x| {
|
||||
ProceduralAssertionStatement::Concurrent(x)
|
||||
}),
|
||||
map(immediate_assertion_statement, |x| {
|
||||
ProceduralAssertionStatement::Immediate(x)
|
||||
}),
|
||||
map(checker_instantiation, |x| {
|
||||
ProceduralAssertionStatement::Checker(x)
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn immediate_assertion_statement(s: &str) -> IResult<&str, ImmediateAssetionStatement> {
|
||||
alt((
|
||||
map(simple_immediate_assertion_statement, |x| {
|
||||
ImmediateAssetionStatement::Simple(x)
|
||||
}),
|
||||
map(deferred_immediate_assertion_statement, |x| {
|
||||
ImmediateAssetionStatement::Deferred(x)
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn simple_immediate_assertion_statement(
|
||||
s: &str,
|
||||
) -> IResult<&str, SimpleImmediateAssertionStatement> {
|
||||
alt((
|
||||
map(simple_immediate_assert_statement, |x| {
|
||||
SimpleImmediateAssertionStatement::Assert(x)
|
||||
}),
|
||||
map(simple_immediate_assume_statement, |x| {
|
||||
SimpleImmediateAssertionStatement::Assume(x)
|
||||
}),
|
||||
map(simple_immediate_cover_statement, |x| {
|
||||
SimpleImmediateAssertionStatement::Cover(x)
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn simple_immediate_assert_statement(s: &str) -> IResult<&str, SimpleImmediateAssertStatement> {
|
||||
let (s, _) = symbol("assert")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, y) = action_block(s)?;
|
||||
Ok((
|
||||
s,
|
||||
SimpleImmediateAssertStatement {
|
||||
expression: x,
|
||||
block: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn simple_immediate_assume_statement(s: &str) -> IResult<&str, SimpleImmediateAssumeStatement> {
|
||||
let (s, _) = symbol("assume")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, y) = action_block(s)?;
|
||||
Ok((
|
||||
s,
|
||||
SimpleImmediateAssumeStatement {
|
||||
expression: x,
|
||||
block: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn simple_immediate_cover_statement(s: &str) -> IResult<&str, SimpleImmediateCoverStatement> {
|
||||
let (s, _) = symbol("cover")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, y) = statement_or_null(s)?;
|
||||
Ok((
|
||||
s,
|
||||
SimpleImmediateCoverStatement {
|
||||
expression: x,
|
||||
statement: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn deferred_immediate_assertion_statement(
|
||||
s: &str,
|
||||
) -> IResult<&str, DeferredImmediateAssertionStatement> {
|
||||
alt((
|
||||
map(deferred_immediate_assert_statement, |x| {
|
||||
DeferredImmediateAssertionStatement::Assert(x)
|
||||
}),
|
||||
map(deferred_immediate_assume_statement, |x| {
|
||||
DeferredImmediateAssertionStatement::Assume(x)
|
||||
}),
|
||||
map(deferred_immediate_cover_statement, |x| {
|
||||
DeferredImmediateAssertionStatement::Cover(x)
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn deferred_immediate_assert_statement(
|
||||
s: &str,
|
||||
) -> IResult<&str, DeferredImmediateAssertStatement> {
|
||||
let (s, _) = symbol("assert")(s)?;
|
||||
let (s, x) = assert_timing(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, y) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, z) = action_block(s)?;
|
||||
Ok((
|
||||
s,
|
||||
DeferredImmediateAssertStatement {
|
||||
timing: x,
|
||||
expression: y,
|
||||
block: z,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn deferred_immediate_assume_statement(
|
||||
s: &str,
|
||||
) -> IResult<&str, DeferredImmediateAssumeStatement> {
|
||||
let (s, _) = symbol("assume")(s)?;
|
||||
let (s, x) = assert_timing(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, y) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, z) = action_block(s)?;
|
||||
Ok((
|
||||
s,
|
||||
DeferredImmediateAssumeStatement {
|
||||
timing: x,
|
||||
expression: y,
|
||||
block: z,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn deferred_immediate_cover_statement(
|
||||
s: &str,
|
||||
) -> IResult<&str, DeferredImmediateCoverStatement> {
|
||||
let (s, _) = symbol("cover")(s)?;
|
||||
let (s, x) = assert_timing(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, y) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, z) = statement_or_null(s)?;
|
||||
Ok((
|
||||
s,
|
||||
DeferredImmediateCoverStatement {
|
||||
timing: x,
|
||||
expression: y,
|
||||
statement: z,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn assert_timing(s: &str) -> IResult<&str, AssertTiming> {
|
||||
alt((
|
||||
map(symbol("#0"), |_| AssertTiming::Zero),
|
||||
map(symbol("final"), |_| AssertTiming::Final),
|
||||
))(s)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
331
src/parser/behavioral_statements/clocking_block.rs
Normal file
331
src/parser/behavioral_statements/clocking_block.rs
Normal file
@ -0,0 +1,331 @@
|
||||
use crate::parser::*;
|
||||
use nom::branch::*;
|
||||
use nom::combinator::*;
|
||||
use nom::multi::*;
|
||||
use nom::sequence::*;
|
||||
use nom::IResult;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClockingDeclaration<'a> {
|
||||
Local(ClockingDeclarationLocal<'a>),
|
||||
Global(ClockingDeclarationGlobal<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingDeclarationLocal<'a> {
|
||||
pub default: bool,
|
||||
pub beg_identifier: Option<Identifier<'a>>,
|
||||
pub event: ClockingEvent<'a>,
|
||||
pub item: Vec<ClockingItem<'a>>,
|
||||
pub end_identifier: Option<Identifier<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingDeclarationGlobal<'a> {
|
||||
pub beg_identifier: Option<Identifier<'a>>,
|
||||
pub event: ClockingEvent<'a>,
|
||||
pub end_identifier: Option<Identifier<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClockingEvent<'a> {
|
||||
Identifier(Identifier<'a>),
|
||||
Expression(EventExpression<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClockingItem<'a> {
|
||||
DefaultSkew(DefaultSkew<'a>),
|
||||
Direction(ClockingItemDirection<'a>),
|
||||
Assertion(ClockingItemAssertion<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingItemDirection<'a> {
|
||||
pub direction: ClockingDirection<'a>,
|
||||
pub assign: Vec<ClockingDeclAssign<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingItemAssertion<'a> {
|
||||
pub attribute: Vec<AttributeInstance<'a>>,
|
||||
pub declaration: AssertionItemDeclaration<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DefaultSkew<'a> {
|
||||
Input(ClockingSkew<'a>),
|
||||
Output(ClockingSkew<'a>),
|
||||
InputOutput((ClockingSkew<'a>, ClockingSkew<'a>)),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClockingDirection<'a> {
|
||||
Input(Option<ClockingSkew<'a>>),
|
||||
Output(Option<ClockingSkew<'a>>),
|
||||
InputOutput((Option<ClockingSkew<'a>>, Option<ClockingSkew<'a>>)),
|
||||
Inout,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingDeclAssign<'a> {
|
||||
pub identifier: Identifier<'a>,
|
||||
pub expression: Option<Expression<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClockingSkew<'a> {
|
||||
Edge((EdgeIdentifier<'a>, Option<DelayControl<'a>>)),
|
||||
Delay(DelayControl<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingDrive<'a> {
|
||||
pub lvalue: (HierarchicalIdentifier<'a>, Select<'a>),
|
||||
pub cycle_delay: Option<CycleDelay<'a>>,
|
||||
pub rvalue: Expression<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CycleDelay<'a> {
|
||||
Number(Number<'a>),
|
||||
Identifier(Identifier<'a>),
|
||||
Expression(Expression<'a>),
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub fn clocking_declaration(s: &str) -> IResult<&str, ClockingDeclaration> {
|
||||
alt((clocking_declaration_local, clocking_declaration_global))(s)
|
||||
}
|
||||
|
||||
pub fn clocking_declaration_local(s: &str) -> IResult<&str, ClockingDeclaration> {
|
||||
let (s, x) = opt(symbol("default"))(s)?;
|
||||
let (s, _) = symbol("clocking")(s)?;
|
||||
let (s, y) = opt(clocking_identifier)(s)?;
|
||||
let (s, z) = clocking_event(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
let (s, v) = many0(clocking_item)(s)?;
|
||||
let (s, _) = symbol("endclocking")(s)?;
|
||||
let (s, w) = opt(preceded(symbol(":"), clocking_identifier))(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ClockingDeclaration::Local(ClockingDeclarationLocal {
|
||||
default: x.is_some(),
|
||||
beg_identifier: y,
|
||||
event: z,
|
||||
item: v,
|
||||
end_identifier: w,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn clocking_declaration_global(s: &str) -> IResult<&str, ClockingDeclaration> {
|
||||
let (s, _) = opt(symbol("global"))(s)?;
|
||||
let (s, _) = symbol("clocking")(s)?;
|
||||
let (s, x) = opt(clocking_identifier)(s)?;
|
||||
let (s, y) = clocking_event(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
let (s, _) = symbol("endclocking")(s)?;
|
||||
let (s, z) = opt(preceded(symbol(":"), clocking_identifier))(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ClockingDeclaration::Global(ClockingDeclarationGlobal {
|
||||
beg_identifier: x,
|
||||
event: y,
|
||||
end_identifier: z,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn clocking_event(s: &str) -> IResult<&str, ClockingEvent> {
|
||||
alt((
|
||||
map(preceded(symbol("@"), identifier), |x| {
|
||||
ClockingEvent::Identifier(x)
|
||||
}),
|
||||
map(
|
||||
preceded(
|
||||
symbol("@"),
|
||||
delimited(symbol("("), event_expression, symbol(")")),
|
||||
),
|
||||
|x| ClockingEvent::Expression(x),
|
||||
),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn clocking_item(s: &str) -> IResult<&str, ClockingItem> {
|
||||
alt((
|
||||
clocking_item_default_skew,
|
||||
clocking_item_direction,
|
||||
clocking_item_assertion,
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn clocking_item_default_skew(s: &str) -> IResult<&str, ClockingItem> {
|
||||
let (s, _) = symbol("default")(s)?;
|
||||
let (s, x) = default_skew(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
Ok((s, ClockingItem::DefaultSkew(x)))
|
||||
}
|
||||
|
||||
pub fn clocking_item_direction(s: &str) -> IResult<&str, ClockingItem> {
|
||||
let (s, x) = clocking_direction(s)?;
|
||||
let (s, y) = list_of_clocking_decl_assign(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ClockingItem::Direction(ClockingItemDirection {
|
||||
direction: x,
|
||||
assign: y,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn clocking_item_assertion(s: &str) -> IResult<&str, ClockingItem> {
|
||||
let (s, x) = many0(attribute_instance)(s)?;
|
||||
let (s, y) = assertion_item_declaration(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ClockingItem::Assertion(ClockingItemAssertion {
|
||||
attribute: x,
|
||||
declaration: y,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn default_skew(s: &str) -> IResult<&str, DefaultSkew> {
|
||||
alt((
|
||||
default_skew_input,
|
||||
default_skew_output,
|
||||
default_skew_input_output,
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn default_skew_input(s: &str) -> IResult<&str, DefaultSkew> {
|
||||
let (s, _) = symbol("input")(s)?;
|
||||
let (s, x) = clocking_skew(s)?;
|
||||
Ok((s, DefaultSkew::Input(x)))
|
||||
}
|
||||
|
||||
pub fn default_skew_output(s: &str) -> IResult<&str, DefaultSkew> {
|
||||
let (s, _) = symbol("output")(s)?;
|
||||
let (s, x) = clocking_skew(s)?;
|
||||
Ok((s, DefaultSkew::Output(x)))
|
||||
}
|
||||
|
||||
pub fn default_skew_input_output(s: &str) -> IResult<&str, DefaultSkew> {
|
||||
let (s, _) = symbol("input")(s)?;
|
||||
let (s, x) = clocking_skew(s)?;
|
||||
let (s, _) = symbol("output")(s)?;
|
||||
let (s, y) = clocking_skew(s)?;
|
||||
Ok((s, DefaultSkew::InputOutput((x, y))))
|
||||
}
|
||||
|
||||
pub fn clocking_direction(s: &str) -> IResult<&str, ClockingDirection> {
|
||||
alt((
|
||||
clocking_direction_input,
|
||||
clocking_direction_output,
|
||||
clocking_direction_input_output,
|
||||
clocking_direction_inout,
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn clocking_direction_input(s: &str) -> IResult<&str, ClockingDirection> {
|
||||
let (s, _) = symbol("input")(s)?;
|
||||
let (s, x) = opt(clocking_skew)(s)?;
|
||||
Ok((s, ClockingDirection::Input(x)))
|
||||
}
|
||||
|
||||
pub fn clocking_direction_output(s: &str) -> IResult<&str, ClockingDirection> {
|
||||
let (s, _) = symbol("output")(s)?;
|
||||
let (s, x) = opt(clocking_skew)(s)?;
|
||||
Ok((s, ClockingDirection::Output(x)))
|
||||
}
|
||||
|
||||
pub fn clocking_direction_input_output(s: &str) -> IResult<&str, ClockingDirection> {
|
||||
let (s, _) = symbol("input")(s)?;
|
||||
let (s, x) = opt(clocking_skew)(s)?;
|
||||
let (s, _) = symbol("output")(s)?;
|
||||
let (s, y) = opt(clocking_skew)(s)?;
|
||||
Ok((s, ClockingDirection::InputOutput((x, y))))
|
||||
}
|
||||
|
||||
pub fn clocking_direction_inout(s: &str) -> IResult<&str, ClockingDirection> {
|
||||
let (s, _) = symbol("inout")(s)?;
|
||||
Ok((s, ClockingDirection::Inout))
|
||||
}
|
||||
|
||||
pub fn list_of_clocking_decl_assign(s: &str) -> IResult<&str, Vec<ClockingDeclAssign>> {
|
||||
many1(clocking_decl_assign)(s)
|
||||
}
|
||||
|
||||
pub fn clocking_decl_assign(s: &str) -> IResult<&str, ClockingDeclAssign> {
|
||||
let (s, x) = signal_identifier(s)?;
|
||||
let (s, y) = opt(preceded(symbol("="), expression))(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ClockingDeclAssign {
|
||||
identifier: x,
|
||||
expression: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn clocking_skew(s: &str) -> IResult<&str, ClockingSkew> {
|
||||
alt((clocking_skew_edge, clocking_skew_delay))(s)
|
||||
}
|
||||
|
||||
pub fn clocking_skew_edge(s: &str) -> IResult<&str, ClockingSkew> {
|
||||
let (s, x) = edge_identifier(s)?;
|
||||
let (s, y) = opt(delay_control)(s)?;
|
||||
Ok((s, ClockingSkew::Edge((x, y))))
|
||||
}
|
||||
|
||||
pub fn clocking_skew_delay(s: &str) -> IResult<&str, ClockingSkew> {
|
||||
let (s, x) = delay_control(s)?;
|
||||
Ok((s, ClockingSkew::Delay(x)))
|
||||
}
|
||||
|
||||
pub fn clocking_drive(s: &str) -> IResult<&str, ClockingDrive> {
|
||||
let (s, x) = clockvar_expression(s)?;
|
||||
let (s, _) = symbol("=")(s)?;
|
||||
let (s, y) = opt(cycle_delay)(s)?;
|
||||
let (s, z) = expression(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ClockingDrive {
|
||||
lvalue: x,
|
||||
cycle_delay: y,
|
||||
rvalue: z,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn cycle_delay(s: &str) -> IResult<&str, CycleDelay> {
|
||||
alt((
|
||||
map(preceded(symbol("##"), integral_number), |x| {
|
||||
CycleDelay::Number(x)
|
||||
}),
|
||||
map(preceded(symbol("##"), identifier), |x| {
|
||||
CycleDelay::Identifier(x)
|
||||
}),
|
||||
map(
|
||||
preceded(
|
||||
symbol("##"),
|
||||
delimited(symbol("("), expression, symbol(")")),
|
||||
),
|
||||
|x| CycleDelay::Expression(x),
|
||||
),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn clockvar(s: &str) -> IResult<&str, HierarchicalIdentifier> {
|
||||
hierarchical_identifier(s)
|
||||
}
|
||||
|
||||
pub fn clockvar_expression(s: &str) -> IResult<&str, (HierarchicalIdentifier, Select)> {
|
||||
pair(clockvar, select)(s)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
@ -45,9 +45,11 @@ pub fn continuous_assign(s: &str) -> IResult<&str, ContinuousAssign> {
|
||||
}
|
||||
|
||||
pub fn continuous_assign_net(s: &str) -> IResult<&str, ContinuousAssign> {
|
||||
let (s, _) = symbol("assign")(s)?;
|
||||
let (s, x) = opt(drive_strength)(s)?;
|
||||
let (s, y) = opt(delay3)(s)?;
|
||||
let (s, z) = many1(net_assignment)(s)?;
|
||||
let (s, z) = list_of_net_assignments(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
|
||||
Ok((
|
||||
s,
|
||||
@ -60,8 +62,10 @@ pub fn continuous_assign_net(s: &str) -> IResult<&str, ContinuousAssign> {
|
||||
}
|
||||
|
||||
pub fn continuous_assign_variable(s: &str) -> IResult<&str, ContinuousAssign> {
|
||||
let (s, _) = symbol("assign")(s)?;
|
||||
let (s, x) = opt(delay_control)(s)?;
|
||||
let (s, y) = many1(variable_assignment)(s)?;
|
||||
let (s, y) = list_of_variable_assignments(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
|
||||
Ok((
|
||||
s,
|
||||
@ -72,6 +76,14 @@ pub fn continuous_assign_variable(s: &str) -> IResult<&str, ContinuousAssign> {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn list_of_net_assignments(s: &str) -> IResult<&str, Vec<NetAssignment>> {
|
||||
separated_nonempty_list(symbol(","), net_assignment)(s)
|
||||
}
|
||||
|
||||
pub fn list_of_variable_assignments(s: &str) -> IResult<&str, Vec<VariableAssignment>> {
|
||||
separated_nonempty_list(symbol(","), variable_assignment)(s)
|
||||
}
|
||||
|
||||
pub fn net_alias(s: &str) -> IResult<&str, NetAlias> {
|
||||
let (s, _) = symbol("alias")(s)?;
|
||||
let (s, x) = net_lvalue(s)?;
|
||||
|
234
src/parser/behavioral_statements/looping_statements.rs
Normal file
234
src/parser/behavioral_statements/looping_statements.rs
Normal file
@ -0,0 +1,234 @@
|
||||
use crate::parser::*;
|
||||
use nom::branch::*;
|
||||
use nom::combinator::*;
|
||||
use nom::multi::*;
|
||||
use nom::sequence::*;
|
||||
use nom::IResult;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LoopStatement<'a> {
|
||||
Forever(LoopStatementForever<'a>),
|
||||
Repeat(LoopStatementRepeat<'a>),
|
||||
While(LoopStatementWhile<'a>),
|
||||
For(LoopStatementFor<'a>),
|
||||
DoWhile(LoopStatementDoWhile<'a>),
|
||||
Foreach(LoopStatementForeach<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoopStatementForever<'a> {
|
||||
pub statement: StatementOrNull<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoopStatementRepeat<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub statement: StatementOrNull<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoopStatementWhile<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub statement: StatementOrNull<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoopStatementFor<'a> {
|
||||
pub initilization: Option<ForInitialization<'a>>,
|
||||
pub expression: Option<Expression<'a>>,
|
||||
pub step: Option<Vec<ForStepAssignment<'a>>>,
|
||||
pub statement: StatementOrNull<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoopStatementDoWhile<'a> {
|
||||
pub statement: StatementOrNull<'a>,
|
||||
pub expression: Expression<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoopStatementForeach<'a> {
|
||||
pub identifier: ScopedIdentifier<'a>,
|
||||
pub variable: Vec<Option<Identifier<'a>>>,
|
||||
pub statement: Statement<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ForInitialization<'a> {
|
||||
Assignment(Vec<VariableAssignment<'a>>),
|
||||
Declaration(Vec<ForVariableDeclaration<'a>>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ForVariableDeclaration<'a> {
|
||||
pub var: bool,
|
||||
pub r#type: DataType<'a>,
|
||||
pub declaration: Vec<(Identifier<'a>, Expression<'a>)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ForStepAssignment<'a> {
|
||||
Operator(OperatorAssignment<'a>),
|
||||
IncOrDec(IncOrDecDeclaration<'a>),
|
||||
Subroutine(SubroutineCall<'a>),
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub fn loop_statement(s: &str) -> IResult<&str, LoopStatement> {
|
||||
alt((
|
||||
loop_statement_forever,
|
||||
loop_statement_repeat,
|
||||
loop_statement_while,
|
||||
loop_statement_for,
|
||||
loop_statement_do_while,
|
||||
loop_statement_foreach,
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn loop_statement_forever(s: &str) -> IResult<&str, LoopStatement> {
|
||||
let (s, _) = symbol("forever")(s)?;
|
||||
let (s, x) = statement_or_null(s)?;
|
||||
Ok((
|
||||
s,
|
||||
LoopStatement::Forever(LoopStatementForever { statement: x }),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn loop_statement_repeat(s: &str) -> IResult<&str, LoopStatement> {
|
||||
let (s, _) = symbol("repeat")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, y) = statement_or_null(s)?;
|
||||
Ok((
|
||||
s,
|
||||
LoopStatement::Repeat(LoopStatementRepeat {
|
||||
expression: x,
|
||||
statement: y,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn loop_statement_while(s: &str) -> IResult<&str, LoopStatement> {
|
||||
let (s, _) = symbol("while")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, y) = statement_or_null(s)?;
|
||||
Ok((
|
||||
s,
|
||||
LoopStatement::While(LoopStatementWhile {
|
||||
expression: x,
|
||||
statement: y,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn loop_statement_for(s: &str) -> IResult<&str, LoopStatement> {
|
||||
let (s, _) = symbol("for")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = opt(for_initialization)(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
let (s, y) = opt(expression)(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
let (s, z) = opt(for_step)(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, v) = statement_or_null(s)?;
|
||||
Ok((
|
||||
s,
|
||||
LoopStatement::For(LoopStatementFor {
|
||||
initilization: x,
|
||||
expression: y,
|
||||
step: z,
|
||||
statement: v,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn loop_statement_do_while(s: &str) -> IResult<&str, LoopStatement> {
|
||||
let (s, _) = symbol("do")(s)?;
|
||||
let (s, x) = statement_or_null(s)?;
|
||||
let (s, _) = symbol("while")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, y) = expression(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
Ok((
|
||||
s,
|
||||
LoopStatement::DoWhile(LoopStatementDoWhile {
|
||||
statement: x,
|
||||
expression: y,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn loop_statement_foreach(s: &str) -> IResult<&str, LoopStatement> {
|
||||
let (s, _) = symbol("foreach")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = ps_or_hierarchical_array_identifier(s)?;
|
||||
let (s, _) = symbol("[")(s)?;
|
||||
let (s, y) = loop_variables(s)?;
|
||||
let (s, _) = symbol("]")(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, z) = statement(s)?;
|
||||
Ok((
|
||||
s,
|
||||
LoopStatement::Foreach(LoopStatementForeach {
|
||||
identifier: x,
|
||||
variable: y,
|
||||
statement: z,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn for_initialization(s: &str) -> IResult<&str, ForInitialization> {
|
||||
alt((
|
||||
map(list_of_variable_assignments, |x| {
|
||||
ForInitialization::Assignment(x)
|
||||
}),
|
||||
map(
|
||||
separated_nonempty_list(symbol(","), for_variable_declaration),
|
||||
|x| ForInitialization::Declaration(x),
|
||||
),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn for_variable_declaration(s: &str) -> IResult<&str, ForVariableDeclaration> {
|
||||
let (s, x) = opt(symbol("var"))(s)?;
|
||||
let (s, y) = data_type(s)?;
|
||||
let (s, z) = separated_nonempty_list(
|
||||
symbol(","),
|
||||
pair(variable_identifier, preceded(symbol("="), expression)),
|
||||
)(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ForVariableDeclaration {
|
||||
var: x.is_some(),
|
||||
r#type: y,
|
||||
declaration: z,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn for_step(s: &str) -> IResult<&str, Vec<ForStepAssignment>> {
|
||||
separated_nonempty_list(symbol(","), for_step_assignment)(s)
|
||||
}
|
||||
|
||||
pub fn for_step_assignment(s: &str) -> IResult<&str, ForStepAssignment> {
|
||||
alt((
|
||||
map(operator_assignment, |x| ForStepAssignment::Operator(x)),
|
||||
map(inc_or_dec_declaration, |x| ForStepAssignment::IncOrDec(x)),
|
||||
map(function_subroutine_call, |x| {
|
||||
ForStepAssignment::Subroutine(x)
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn loop_variables(s: &str) -> IResult<&str, Vec<Option<Identifier>>> {
|
||||
separated_nonempty_list(symbol(","), opt(index_variable_identifier))(s)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
@ -1,16 +1,26 @@
|
||||
pub mod assertion_statements;
|
||||
pub mod case_statements;
|
||||
pub mod clocking_block;
|
||||
pub mod conditional_statements;
|
||||
pub mod continuous_assignment_and_net_alias_statements;
|
||||
pub mod looping_statements;
|
||||
pub mod parallel_and_sequential_blocks;
|
||||
pub mod patterns;
|
||||
pub mod procedural_blocks_and_assignments;
|
||||
pub mod randsequence;
|
||||
pub mod statements;
|
||||
pub mod subroutine_call_statements;
|
||||
pub mod timing_control_statements;
|
||||
pub use assertion_statements::*;
|
||||
pub use case_statements::*;
|
||||
pub use clocking_block::*;
|
||||
pub use conditional_statements::*;
|
||||
pub use continuous_assignment_and_net_alias_statements::*;
|
||||
pub use looping_statements::*;
|
||||
pub use parallel_and_sequential_blocks::*;
|
||||
pub use patterns::*;
|
||||
pub use procedural_blocks_and_assignments::*;
|
||||
pub use randsequence::*;
|
||||
pub use statements::*;
|
||||
pub use subroutine_call_statements::*;
|
||||
pub use timing_control_statements::*;
|
||||
|
293
src/parser/behavioral_statements/randsequence.rs
Normal file
293
src/parser/behavioral_statements/randsequence.rs
Normal file
@ -0,0 +1,293 @@
|
||||
use crate::parser::*;
|
||||
use nom::branch::*;
|
||||
use nom::combinator::*;
|
||||
use nom::multi::*;
|
||||
use nom::sequence::*;
|
||||
use nom::IResult;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RandsequenceStatement<'a> {
|
||||
pub identifier: Option<Identifier<'a>>,
|
||||
pub production: Vec<Production<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Production<'a> {
|
||||
pub r#type: Option<DataTypeOrVoid<'a>>,
|
||||
pub identifier: Identifier<'a>,
|
||||
pub tf_port_list: Option<TfPortList<'a>>,
|
||||
pub rs_rule: Vec<RsRule<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RsRule<'a> {
|
||||
pub production: RsProductionList<'a>,
|
||||
pub weight: Option<WeightSpecification<'a>>,
|
||||
pub block: Option<RsCodeBlock<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RsProductionList<'a> {
|
||||
Prod(Vec<RsProd<'a>>),
|
||||
Join((Option<Expression<'a>>, Vec<ProductionItem<'a>>)),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum WeightSpecification<'a> {
|
||||
Number(Number<'a>),
|
||||
Identifier(ScopedIdentifier<'a>),
|
||||
Expression(Expression<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RsCodeBlock<'a> {
|
||||
pub declaration: Vec<DataDeclaration<'a>>,
|
||||
pub statement: Vec<StatementOrNull<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RsProd<'a> {
|
||||
Item(ProductionItem<'a>),
|
||||
CodeBlock(RsCodeBlock<'a>),
|
||||
IfElse(RsIfElse<'a>),
|
||||
Repeat(RsRepeat<'a>),
|
||||
Case(RsCase<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProductionItem<'a> {
|
||||
pub identifier: Identifier<'a>,
|
||||
pub argument: Option<ListOfArguments<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RsIfElse<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub item: ProductionItem<'a>,
|
||||
pub else_item: Option<ProductionItem<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RsRepeat<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub item: ProductionItem<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RsCase<'a> {
|
||||
pub expression: Expression<'a>,
|
||||
pub item: Vec<RsCaseItem<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum RsCaseItem<'a> {
|
||||
NonDefault(RsCaseItemNondefault<'a>),
|
||||
Default(RsCaseItemDefault<'a>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RsCaseItemDefault<'a> {
|
||||
pub item: ProductionItem<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RsCaseItemNondefault<'a> {
|
||||
pub expression: Vec<Expression<'a>>,
|
||||
pub item: ProductionItem<'a>,
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub fn randsequence_statement(s: &str) -> IResult<&str, RandsequenceStatement> {
|
||||
let (s, _) = symbol("randsequence")(s)?;
|
||||
let (s, _) = symbol("(")(s)?;
|
||||
let (s, x) = opt(production_identifier)(s)?;
|
||||
let (s, _) = symbol(")")(s)?;
|
||||
let (s, y) = many1(production)(s)?;
|
||||
let (s, _) = symbol("endsequence")(s)?;
|
||||
Ok((
|
||||
s,
|
||||
RandsequenceStatement {
|
||||
identifier: x,
|
||||
production: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn production(s: &str) -> IResult<&str, Production> {
|
||||
let (s, x) = opt(data_type_or_void)(s)?;
|
||||
let (s, y) = production_identifier(s)?;
|
||||
let (s, z) = opt(delimited(symbol("("), tf_port_list, symbol(")")))(s)?;
|
||||
let (s, _) = symbol(":")(s)?;
|
||||
let (s, v) = separated_nonempty_list(symbol("|"), rs_rule)(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
Ok((
|
||||
s,
|
||||
Production {
|
||||
r#type: x,
|
||||
identifier: y,
|
||||
tf_port_list: z,
|
||||
rs_rule: v,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_rule(s: &str) -> IResult<&str, RsRule> {
|
||||
let (s, x) = rs_production_list(s)?;
|
||||
let (s, y) = opt(preceded(
|
||||
symbol(":="),
|
||||
pair(weight_specification, opt(rs_code_block)),
|
||||
))(s)?;
|
||||
|
||||
let (y, z) = if let Some((y, z)) = y {
|
||||
(Some(y), z)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
Ok((
|
||||
s,
|
||||
RsRule {
|
||||
production: x,
|
||||
weight: y,
|
||||
block: z,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_production_list(s: &str) -> IResult<&str, RsProductionList> {
|
||||
alt((rs_production_list_prod, rs_production_list_join))(s)
|
||||
}
|
||||
|
||||
pub fn rs_production_list_prod(s: &str) -> IResult<&str, RsProductionList> {
|
||||
let (s, x) = many1(rs_prod)(s)?;
|
||||
Ok((s, RsProductionList::Prod(x)))
|
||||
}
|
||||
|
||||
pub fn rs_production_list_join(s: &str) -> IResult<&str, RsProductionList> {
|
||||
let (s, _) = symbol("rand")(s)?;
|
||||
let (s, _) = symbol("join")(s)?;
|
||||
let (s, x) = opt(delimited(symbol("("), expression, symbol(")")))(s)?;
|
||||
let (s, y) = production_item(s)?;
|
||||
let (s, z) = many1(production_item)(s)?;
|
||||
|
||||
let mut y = vec![y];
|
||||
for z in z {
|
||||
y.push(z);
|
||||
}
|
||||
Ok((s, RsProductionList::Join((x, y))))
|
||||
}
|
||||
|
||||
pub fn weight_specification(s: &str) -> IResult<&str, WeightSpecification> {
|
||||
alt((
|
||||
map(integral_number, |x| WeightSpecification::Number(x)),
|
||||
map(ps_identifier, |x| WeightSpecification::Identifier(x)),
|
||||
map(delimited(symbol("("), expression, symbol(")")), |x| {
|
||||
WeightSpecification::Expression(x)
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn rs_code_block(s: &str) -> IResult<&str, RsCodeBlock> {
|
||||
let (s, _) = symbol("{")(s)?;
|
||||
let (s, x) = many0(data_declaration)(s)?;
|
||||
let (s, y) = many0(statement_or_null)(s)?;
|
||||
let (s, _) = symbol("}")(s)?;
|
||||
Ok((
|
||||
s,
|
||||
RsCodeBlock {
|
||||
declaration: x,
|
||||
statement: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_prod(s: &str) -> IResult<&str, RsProd> {
|
||||
alt((
|
||||
map(production_item, |x| RsProd::Item(x)),
|
||||
map(rs_code_block, |x| RsProd::CodeBlock(x)),
|
||||
map(rs_if_else, |x| RsProd::IfElse(x)),
|
||||
map(rs_repeat, |x| RsProd::Repeat(x)),
|
||||
map(rs_case, |x| RsProd::Case(x)),
|
||||
))(s)
|
||||
}
|
||||
|
||||
pub fn production_item(s: &str) -> IResult<&str, ProductionItem> {
|
||||
let (s, x) = production_identifier(s)?;
|
||||
let (s, y) = opt(delimited(symbol("("), list_of_arguments, symbol(")")))(s)?;
|
||||
Ok((
|
||||
s,
|
||||
ProductionItem {
|
||||
identifier: x,
|
||||
argument: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_if_else(s: &str) -> IResult<&str, RsIfElse> {
|
||||
let (s, _) = symbol("if")(s)?;
|
||||
let (s, x) = delimited(symbol("("), expression, symbol(")"))(s)?;
|
||||
let (s, y) = production_item(s)?;
|
||||
let (s, z) = opt(preceded(symbol("else"), production_item))(s)?;
|
||||
Ok((
|
||||
s,
|
||||
RsIfElse {
|
||||
expression: x,
|
||||
item: y,
|
||||
else_item: z,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_repeat(s: &str) -> IResult<&str, RsRepeat> {
|
||||
let (s, _) = symbol("repeat")(s)?;
|
||||
let (s, x) = delimited(symbol("("), expression, symbol(")"))(s)?;
|
||||
let (s, y) = production_item(s)?;
|
||||
Ok((
|
||||
s,
|
||||
RsRepeat {
|
||||
expression: x,
|
||||
item: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_case(s: &str) -> IResult<&str, RsCase> {
|
||||
let (s, _) = symbol("case")(s)?;
|
||||
let (s, x) = delimited(symbol("("), case_expression, symbol(")"))(s)?;
|
||||
let (s, y) = many1(rs_case_item)(s)?;
|
||||
Ok((
|
||||
s,
|
||||
RsCase {
|
||||
expression: x,
|
||||
item: y,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_case_item(s: &str) -> IResult<&str, RsCaseItem> {
|
||||
alt((rs_case_item_nondefault, rs_case_item_default))(s)
|
||||
}
|
||||
|
||||
pub fn rs_case_item_nondefault(s: &str) -> IResult<&str, RsCaseItem> {
|
||||
let (s, x) = separated_nonempty_list(symbol(","), case_item_expression)(s)?;
|
||||
let (s, _) = symbol(":")(s)?;
|
||||
let (s, y) = production_item(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
Ok((
|
||||
s,
|
||||
RsCaseItem::NonDefault(RsCaseItemNondefault {
|
||||
expression: x,
|
||||
item: y,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn rs_case_item_default(s: &str) -> IResult<&str, RsCaseItem> {
|
||||
let (s, _) = symbol("default")(s)?;
|
||||
let (s, _) = opt(symbol(":"))(s)?;
|
||||
let (s, x) = production_item(s)?;
|
||||
let (s, _) = symbol(";")(s)?;
|
||||
Ok((s, RsCaseItem::Default(RsCaseItemDefault { item: x })))
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
use crate::parser::*;
|
||||
use nom::branch::*;
|
||||
use nom::combinator::*;
|
||||
use nom::sequence::*;
|
||||
use nom::IResult;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SubroutineCallStatement<'a> {
|
||||
SubroutineCall(SubroutineCall<'a>),
|
||||
FunctionSubroutineCall(SubroutineCall<'a>),
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub fn subroutine_call_statement(s: &str) -> IResult<&str, SubroutineCallStatement> {
|
||||
alt((
|
||||
map(terminated(subroutine_call, symbol(";")), |x| {
|
||||
SubroutineCallStatement::SubroutineCall(x)
|
||||
}),
|
||||
map(
|
||||
delimited(
|
||||
tuple((symbol("void"), symbol("'"), symbol("("))),
|
||||
function_subroutine_call,
|
||||
pair(symbol(")"), symbol(";")),
|
||||
),
|
||||
|x| SubroutineCallStatement::FunctionSubroutineCall(x),
|
||||
),
|
||||
))(s)
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
@ -48,11 +48,6 @@ pub struct DataType<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingEvent<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConstraintBlock<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
@ -88,31 +83,6 @@ pub struct BlockItemDeclaration<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SubroutineCallStatement<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LoopStatement<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ProceduralAssertionStatement<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClockingDrive<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RandsequenceStatement<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExpectPropertyStatement<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
@ -128,11 +98,6 @@ pub struct DelayValue<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CycleDelay<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EdgeIdentifier<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
@ -143,6 +108,46 @@ pub struct IntegerAtomType<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IncOrDecDeclaration<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConcurrentAssertionItem<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConcurrentAssertionStatement<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CheckerInstantiation<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssertionItemDeclaration<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DataTypeOrVoid<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TfPortList<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DataDeclaration<'a> {
|
||||
pub raw: Vec<&'a str>,
|
||||
}
|
||||
|
||||
pub fn class_scope(s: &str) -> IResult<&str, Scope> {
|
||||
Ok((s, Scope::ClassScope))
|
||||
}
|
||||
@ -167,10 +172,6 @@ pub fn data_type(s: &str) -> IResult<&str, DataType> {
|
||||
Ok((s, DataType { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn clocking_event(s: &str) -> IResult<&str, ClockingEvent> {
|
||||
Ok((s, ClockingEvent { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn constraint_block(s: &str) -> IResult<&str, ConstraintBlock> {
|
||||
Ok((s, ConstraintBlock { raw: vec![] }))
|
||||
}
|
||||
@ -203,26 +204,6 @@ pub fn block_item_declaration(s: &str) -> IResult<&str, BlockItemDeclaration> {
|
||||
Ok((s, BlockItemDeclaration { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn subroutine_call_statement(s: &str) -> IResult<&str, SubroutineCallStatement> {
|
||||
Ok((s, SubroutineCallStatement { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn loop_statement(s: &str) -> IResult<&str, LoopStatement> {
|
||||
Ok((s, LoopStatement { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn procedural_assertion_statement(s: &str) -> IResult<&str, ProceduralAssertionStatement> {
|
||||
Ok((s, ProceduralAssertionStatement { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn clocking_drive(s: &str) -> IResult<&str, ClockingDrive> {
|
||||
Ok((s, ClockingDrive { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn randsequence_statement(s: &str) -> IResult<&str, RandsequenceStatement> {
|
||||
Ok((s, RandsequenceStatement { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn expect_property_statement(s: &str) -> IResult<&str, ExpectPropertyStatement> {
|
||||
Ok((s, ExpectPropertyStatement { raw: vec![] }))
|
||||
}
|
||||
@ -235,10 +216,6 @@ pub fn delay_value(s: &str) -> IResult<&str, DelayValue> {
|
||||
Ok((s, DelayValue { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn cycle_delay(s: &str) -> IResult<&str, CycleDelay> {
|
||||
Ok((s, CycleDelay { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn edge_identifier(s: &str) -> IResult<&str, EdgeIdentifier> {
|
||||
Ok((s, EdgeIdentifier { raw: vec![] }))
|
||||
}
|
||||
@ -246,3 +223,35 @@ pub fn edge_identifier(s: &str) -> IResult<&str, EdgeIdentifier> {
|
||||
pub fn integer_atom_type(s: &str) -> IResult<&str, IntegerAtomType> {
|
||||
Ok((s, IntegerAtomType { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn inc_or_dec_declaration(s: &str) -> IResult<&str, IncOrDecDeclaration> {
|
||||
Ok((s, IncOrDecDeclaration { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn concurrent_assertion_item(s: &str) -> IResult<&str, ConcurrentAssertionItem> {
|
||||
Ok((s, ConcurrentAssertionItem { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn concurrent_assertion_statement(s: &str) -> IResult<&str, ConcurrentAssertionStatement> {
|
||||
Ok((s, ConcurrentAssertionStatement { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn checker_instantiation(s: &str) -> IResult<&str, CheckerInstantiation> {
|
||||
Ok((s, CheckerInstantiation { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn assertion_item_declaration(s: &str) -> IResult<&str, AssertionItemDeclaration> {
|
||||
Ok((s, AssertionItemDeclaration { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn data_type_or_void(s: &str) -> IResult<&str, DataTypeOrVoid> {
|
||||
Ok((s, DataTypeOrVoid { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn tf_port_list(s: &str) -> IResult<&str, TfPortList> {
|
||||
Ok((s, TfPortList { raw: vec![] }))
|
||||
}
|
||||
|
||||
pub fn data_declaration(s: &str) -> IResult<&str, DataDeclaration> {
|
||||
Ok((s, DataDeclaration { raw: vec![] }))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user