Add behavioral_statements

This commit is contained in:
dalance 2019-07-05 20:36:08 +09:00
parent 317f18d845
commit a96769c02e
8 changed files with 1269 additions and 65 deletions

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

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

View File

@ -45,9 +45,11 @@ pub fn continuous_assign(s: &str) -> IResult<&str, ContinuousAssign> {
} }
pub fn continuous_assign_net(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, x) = opt(drive_strength)(s)?;
let (s, y) = opt(delay3)(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(( Ok((
s, 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> { pub fn continuous_assign_variable(s: &str) -> IResult<&str, ContinuousAssign> {
let (s, _) = symbol("assign")(s)?;
let (s, x) = opt(delay_control)(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(( Ok((
s, 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> { pub fn net_alias(s: &str) -> IResult<&str, NetAlias> {
let (s, _) = symbol("alias")(s)?; let (s, _) = symbol("alias")(s)?;
let (s, x) = net_lvalue(s)?; let (s, x) = net_lvalue(s)?;

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

View File

@ -1,16 +1,26 @@
pub mod assertion_statements;
pub mod case_statements; pub mod case_statements;
pub mod clocking_block;
pub mod conditional_statements; pub mod conditional_statements;
pub mod continuous_assignment_and_net_alias_statements; pub mod continuous_assignment_and_net_alias_statements;
pub mod looping_statements;
pub mod parallel_and_sequential_blocks; pub mod parallel_and_sequential_blocks;
pub mod patterns; pub mod patterns;
pub mod procedural_blocks_and_assignments; pub mod procedural_blocks_and_assignments;
pub mod randsequence;
pub mod statements; pub mod statements;
pub mod subroutine_call_statements;
pub mod timing_control_statements; pub mod timing_control_statements;
pub use assertion_statements::*;
pub use case_statements::*; pub use case_statements::*;
pub use clocking_block::*;
pub use conditional_statements::*; pub use conditional_statements::*;
pub use continuous_assignment_and_net_alias_statements::*; pub use continuous_assignment_and_net_alias_statements::*;
pub use looping_statements::*;
pub use parallel_and_sequential_blocks::*; pub use parallel_and_sequential_blocks::*;
pub use patterns::*; pub use patterns::*;
pub use procedural_blocks_and_assignments::*; pub use procedural_blocks_and_assignments::*;
pub use randsequence::*;
pub use statements::*; pub use statements::*;
pub use subroutine_call_statements::*;
pub use timing_control_statements::*; pub use timing_control_statements::*;

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

View File

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

View File

@ -48,11 +48,6 @@ pub struct DataType<'a> {
pub raw: Vec<&'a str>, pub raw: Vec<&'a str>,
} }
#[derive(Debug)]
pub struct ClockingEvent<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)] #[derive(Debug)]
pub struct ConstraintBlock<'a> { pub struct ConstraintBlock<'a> {
pub raw: Vec<&'a str>, pub raw: Vec<&'a str>,
@ -88,31 +83,6 @@ pub struct BlockItemDeclaration<'a> {
pub raw: Vec<&'a str>, 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)] #[derive(Debug)]
pub struct ExpectPropertyStatement<'a> { pub struct ExpectPropertyStatement<'a> {
pub raw: Vec<&'a str>, pub raw: Vec<&'a str>,
@ -128,11 +98,6 @@ pub struct DelayValue<'a> {
pub raw: Vec<&'a str>, pub raw: Vec<&'a str>,
} }
#[derive(Debug)]
pub struct CycleDelay<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)] #[derive(Debug)]
pub struct EdgeIdentifier<'a> { pub struct EdgeIdentifier<'a> {
pub raw: Vec<&'a str>, pub raw: Vec<&'a str>,
@ -143,6 +108,46 @@ pub struct IntegerAtomType<'a> {
pub raw: Vec<&'a str>, 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> { pub fn class_scope(s: &str) -> IResult<&str, Scope> {
Ok((s, Scope::ClassScope)) Ok((s, Scope::ClassScope))
} }
@ -167,10 +172,6 @@ pub fn data_type(s: &str) -> IResult<&str, DataType> {
Ok((s, DataType { raw: vec![] })) 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> { pub fn constraint_block(s: &str) -> IResult<&str, ConstraintBlock> {
Ok((s, ConstraintBlock { raw: vec![] })) Ok((s, ConstraintBlock { raw: vec![] }))
} }
@ -203,26 +204,6 @@ pub fn block_item_declaration(s: &str) -> IResult<&str, BlockItemDeclaration> {
Ok((s, BlockItemDeclaration { raw: vec![] })) 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> { pub fn expect_property_statement(s: &str) -> IResult<&str, ExpectPropertyStatement> {
Ok((s, ExpectPropertyStatement { raw: vec![] })) Ok((s, ExpectPropertyStatement { raw: vec![] }))
} }
@ -235,10 +216,6 @@ pub fn delay_value(s: &str) -> IResult<&str, DelayValue> {
Ok((s, DelayValue { raw: vec![] })) 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> { pub fn edge_identifier(s: &str) -> IResult<&str, EdgeIdentifier> {
Ok((s, EdgeIdentifier { raw: vec![] })) 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> { pub fn integer_atom_type(s: &str) -> IResult<&str, IntegerAtomType> {
Ok((s, IntegerAtomType { raw: vec![] })) 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![] }))
}