Add blocks/continuous_assignments/proceduals

This commit is contained in:
dalance 2019-07-04 21:21:35 +09:00
parent f610e12339
commit df36220bc4
6 changed files with 555 additions and 10 deletions

112
src/blocks.rs Normal file
View File

@ -0,0 +1,112 @@
use crate::identifiers::*;
use crate::utils::*;
use nom::branch::*;
use nom::combinator::*;
use nom::multi::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug)]
pub enum ActionBlock<'a> {
Statement(StatementOrNull<'a>),
Else(ActionBlockElse<'a>),
}
#[derive(Debug)]
pub struct ActionBlockElse<'a> {
pub statement: Option<Statement<'a>>,
pub else_statement: StatementOrNull<'a>,
}
#[derive(Debug)]
pub struct SeqBlock<'a> {
pub beg_identifier: Option<Identifier<'a>>,
pub declaration: Vec<BlockItemDeclaration<'a>>,
pub statement: Vec<StatementOrNull<'a>>,
pub end_identifier: Option<Identifier<'a>>,
}
#[derive(Debug)]
pub struct ParBlock<'a> {
pub beg_identifier: Option<Identifier<'a>>,
pub declaration: Vec<BlockItemDeclaration<'a>>,
pub statement: Vec<StatementOrNull<'a>>,
pub keyword: JoinKeyword,
pub end_identifier: Option<Identifier<'a>>,
}
#[derive(Debug)]
pub enum JoinKeyword {
Join,
JoinAny,
JoinNone,
}
// -----------------------------------------------------------------------------
pub fn action_block(s: &str) -> IResult<&str, ActionBlock> {
alt((
map(statement_or_null, |x| ActionBlock::Statement(x)),
action_block_else,
))(s)
}
pub fn action_block_else(s: &str) -> IResult<&str, ActionBlock> {
let (s, statement) = opt(statement)(s)?;
let (s, _) = symbol("else")(s)?;
let (s, else_statement) = statement_or_null(s)?;
Ok((
s,
ActionBlock::Else(ActionBlockElse {
statement,
else_statement,
}),
))
}
pub fn seq_block(s: &str) -> IResult<&str, SeqBlock> {
let (s, _) = symbol("begin")(s)?;
let (s, beg_identifier) = opt(preceded(symbol(":"), block_identifier))(s)?;
let (s, declaration) = many0(block_item_declaration)(s)?;
let (s, statement) = many0(statement_or_null)(s)?;
let (s, _) = symbol("end")(s)?;
let (s, end_identifier) = opt(preceded(symbol(":"), block_identifier))(s)?;
Ok((
s,
SeqBlock {
beg_identifier,
declaration,
statement,
end_identifier,
},
))
}
pub fn par_block(s: &str) -> IResult<&str, ParBlock> {
let (s, _) = symbol("fork")(s)?;
let (s, beg_identifier) = opt(preceded(symbol(":"), block_identifier))(s)?;
let (s, declaration) = many0(block_item_declaration)(s)?;
let (s, statement) = many0(statement_or_null)(s)?;
let (s, keyword) = join_keyword(s)?;
let (s, end_identifier) = opt(preceded(symbol(":"), block_identifier))(s)?;
Ok((
s,
ParBlock {
beg_identifier,
declaration,
statement,
keyword,
end_identifier,
},
))
}
pub fn join_keyword(s: &str) -> IResult<&str, JoinKeyword> {
alt((
map(symbol("join_any"), |_| JoinKeyword::JoinAny),
map(symbol("join_none"), |_| JoinKeyword::JoinNone),
map(symbol("join"), |_| JoinKeyword::Join),
))(s)
}

View File

@ -0,0 +1,92 @@
use crate::expressions::*;
use crate::lvalues::*;
use crate::proceduals::*;
use crate::utils::*;
use nom::branch::*;
use nom::combinator::*;
use nom::multi::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug)]
pub enum ContinuousAssign<'a> {
Net(ContinuousAssignNet<'a>),
Variable(ContinuousAssignVariable<'a>),
}
#[derive(Debug)]
pub struct ContinuousAssignNet<'a> {
pub drive_strength: Option<DriveStrength<'a>>,
pub delay3: Option<Delay3<'a>>,
pub list: Vec<NetAssignment<'a>>,
}
#[derive(Debug)]
pub struct ContinuousAssignVariable<'a> {
pub delay_control: Option<DelayControl<'a>>,
pub list: Vec<VariableAssignment<'a>>,
}
#[derive(Debug)]
pub struct NetAlias<'a> {
pub lvalue: NetLvalue<'a>,
pub rvalue: Vec<NetLvalue<'a>>,
}
#[derive(Debug)]
pub struct NetAssignment<'a> {
pub lvalue: NetLvalue<'a>,
pub rvalue: Expression<'a>,
}
// -----------------------------------------------------------------------------
pub fn continuous_assign(s: &str) -> IResult<&str, ContinuousAssign> {
alt((continuous_assign_net, continuous_assign_variable))(s)
}
pub fn continuous_assign_net(s: &str) -> IResult<&str, ContinuousAssign> {
let (s, drive_strength) = opt(drive_strength)(s)?;
let (s, delay3) = opt(delay3)(s)?;
let (s, list) = many1(net_assignment)(s)?;
Ok((
s,
ContinuousAssign::Net(ContinuousAssignNet {
drive_strength,
delay3,
list,
}),
))
}
pub fn continuous_assign_variable(s: &str) -> IResult<&str, ContinuousAssign> {
let (s, delay_control) = opt(delay_control)(s)?;
let (s, list) = many1(variable_assignment)(s)?;
Ok((
s,
ContinuousAssign::Variable(ContinuousAssignVariable {
delay_control,
list,
}),
))
}
pub fn net_alias(s: &str) -> IResult<&str, NetAlias> {
let (s, _) = symbol("alias")(s)?;
let (s, lvalue) = net_lvalue(s)?;
let (s, rvalue) = many1(preceded(symbol("="), net_lvalue))(s)?;
Ok((s, NetAlias { lvalue, rvalue }))
}
pub fn net_assignment(s: &str) -> IResult<&str, NetAssignment> {
let (s, lvalue) = net_lvalue(s)?;
let (s, _) = symbol("=")(s)?;
let (s, rvalue) = expression(s)?;
Ok((s, NetAssignment { lvalue, rvalue }))
}

View File

@ -3,6 +3,7 @@ use crate::identifiers::*;
use crate::lvalues::*;
use crate::operators::*;
use crate::primaries::*;
use crate::proceduals::*;
use crate::utils::*;
use nom::branch::*;
use nom::combinator::*;
@ -604,7 +605,6 @@ pub fn genvar_expression(s: &str) -> IResult<&str, ConstantExpression> {
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {

View File

@ -1,12 +1,15 @@
pub mod attributes;
pub mod blocks;
pub mod comments;
pub mod concatenations;
pub mod continuous_assignments;
pub mod expressions;
pub mod identifiers;
pub mod lvalues;
pub mod numbers;
pub mod operators;
pub mod primaries;
pub mod proceduals;
pub mod strings;
pub mod subroutine_calls;
pub mod utils;

257
src/proceduals.rs Normal file
View File

@ -0,0 +1,257 @@
use crate::continuous_assignments::*;
use crate::expressions::*;
use crate::identifiers::*;
use crate::lvalues::*;
use crate::operators::*;
use crate::primaries::*;
use crate::utils::*;
use nom::branch::*;
use nom::combinator::*;
use nom::sequence::*;
use nom::IResult;
// -----------------------------------------------------------------------------
#[derive(Debug)]
pub struct InitialConstruct<'a> {
pub statement: StatementOrNull<'a>,
}
#[derive(Debug)]
pub struct AlwaysConstruct<'a> {
pub keyword: AlwaysKeyword,
pub statement: Statement<'a>,
}
#[derive(Debug)]
pub enum AlwaysKeyword {
Always,
AlwaysComb,
AlwaysLatch,
AlwaysFf,
}
#[derive(Debug)]
pub struct FinalConstruct<'a> {
pub statement: FunctionStatement<'a>,
}
#[derive(Debug)]
pub enum BlockingAssignment<'a> {
Variable(BlockingAssignmentVariable<'a>),
NonrangeVariable(BlockingAssignmentNonrangeVariable<'a>),
HierarchicalVariable(BlockingAssignmentHierarchicalVariable<'a>),
Operator(OperatorAssignment<'a>),
}
#[derive(Debug)]
pub struct BlockingAssignmentVariable<'a> {
pub lvalue: VariableLvalue<'a>,
pub control: DelayOrEventControl<'a>,
pub rvalue: Expression<'a>,
}
#[derive(Debug)]
pub struct BlockingAssignmentNonrangeVariable<'a> {
pub lvalue: NonrangeVariableLvalue<'a>,
pub rvalue: DynamicArrayNew<'a>,
}
#[derive(Debug)]
pub struct BlockingAssignmentHierarchicalVariable<'a> {
pub scope: Option<Scope<'a>>,
pub lvalue: HierarchicalIdentifier<'a>,
pub select: Select<'a>,
pub rvalue: ClassNew<'a>,
}
#[derive(Debug)]
pub struct OperatorAssignment<'a> {
pub lvalue: VariableLvalue<'a>,
pub operator: Operator<'a>,
pub rvalue: Expression<'a>,
}
#[derive(Debug)]
pub struct NonblockingAssignment<'a> {
pub lvalue: VariableLvalue<'a>,
pub control: Option<DelayOrEventControl<'a>>,
pub rvalue: Expression<'a>,
}
#[derive(Debug)]
pub enum ProcedualContinuousAssignment<'a> {
Assign(VariableAssignment<'a>),
Deassign(VariableLvalue<'a>),
ForceVariable(VariableAssignment<'a>),
ForceNet(NetAssignment<'a>),
ReleaseVariable(VariableLvalue<'a>),
ReleaseNet(NetLvalue<'a>),
}
#[derive(Debug)]
pub struct VariableAssignment<'a> {
pub lvalue: VariableLvalue<'a>,
pub rvalue: Expression<'a>,
}
// -----------------------------------------------------------------------------
pub fn initial_construct(s: &str) -> IResult<&str, InitialConstruct> {
let (s, _) = symbol("initial")(s)?;
let (s, statement) = statement_or_null(s)?;
Ok((s, InitialConstruct { statement }))
}
pub fn always_construct(s: &str) -> IResult<&str, AlwaysConstruct> {
let (s, keyword) = always_keyword(s)?;
let (s, statement) = statement(s)?;
Ok((s, AlwaysConstruct { keyword, statement }))
}
pub fn always_keyword(s: &str) -> IResult<&str, AlwaysKeyword> {
alt((
map(symbol("always_comb"), |_| AlwaysKeyword::AlwaysComb),
map(symbol("always_latch"), |_| AlwaysKeyword::AlwaysLatch),
map(symbol("always_ff"), |_| AlwaysKeyword::AlwaysFf),
map(symbol("always"), |_| AlwaysKeyword::Always),
))(s)
}
pub fn final_construct(s: &str) -> IResult<&str, FinalConstruct> {
let (s, _) = symbol("final")(s)?;
let (s, statement) = function_statement(s)?;
Ok((s, FinalConstruct { statement }))
}
pub fn blocking_assignment(s: &str) -> IResult<&str, BlockingAssignment> {
alt((
blocking_assignment_variable,
blocking_assignment_nonrange_variable,
blocking_assignment_hierarchical_variable,
map(operator_assignment, |x| BlockingAssignment::Operator(x)),
))(s)
}
pub fn blocking_assignment_variable(s: &str) -> IResult<&str, BlockingAssignment> {
let (s, lvalue) = variable_lvalue(s)?;
let (s, _) = symbol("=")(s)?;
let (s, control) = delay_or_event_control(s)?;
let (s, rvalue) = expression(s)?;
Ok((
s,
BlockingAssignment::Variable(BlockingAssignmentVariable {
lvalue,
control,
rvalue,
}),
))
}
pub fn blocking_assignment_nonrange_variable(s: &str) -> IResult<&str, BlockingAssignment> {
let (s, lvalue) = nonrange_variable_lvalue(s)?;
let (s, _) = symbol("=")(s)?;
let (s, rvalue) = dynamic_array_new(s)?;
Ok((
s,
BlockingAssignment::NonrangeVariable(BlockingAssignmentNonrangeVariable { lvalue, rvalue }),
))
}
pub fn blocking_assignment_hierarchical_variable(s: &str) -> IResult<&str, BlockingAssignment> {
let (s, scope) = opt(alt((
terminated(implicit_class_handle, symbol(".")),
class_scope,
package_scope,
)))(s)?;
let (s, lvalue) = hierarchical_variable_identifier(s)?;
let (s, select) = select(s)?;
let (s, _) = symbol("=")(s)?;
let (s, rvalue) = class_new(s)?;
Ok((
s,
BlockingAssignment::HierarchicalVariable(BlockingAssignmentHierarchicalVariable {
scope,
lvalue,
select,
rvalue,
}),
))
}
pub fn operator_assignment(s: &str) -> IResult<&str, OperatorAssignment> {
let (s, lvalue) = variable_lvalue(s)?;
let (s, operator) = assignment_operator(s)?;
let (s, rvalue) = expression(s)?;
Ok((
s,
OperatorAssignment {
lvalue,
operator,
rvalue,
},
))
}
pub fn assignment_operator(s: &str) -> IResult<&str, Operator> {
alt((
map(symbol("="), |raw| Operator { raw }),
map(symbol("+="), |raw| Operator { raw }),
map(symbol("-="), |raw| Operator { raw }),
map(symbol("*="), |raw| Operator { raw }),
map(symbol("/="), |raw| Operator { raw }),
map(symbol("%="), |raw| Operator { raw }),
map(symbol("&="), |raw| Operator { raw }),
map(symbol("|="), |raw| Operator { raw }),
map(symbol("^="), |raw| Operator { raw }),
map(symbol("<<<="), |raw| Operator { raw }),
map(symbol(">>>="), |raw| Operator { raw }),
map(symbol("<<="), |raw| Operator { raw }),
map(symbol(">>="), |raw| Operator { raw }),
))(s)
}
pub fn nonblocking_assignment(s: &str) -> IResult<&str, NonblockingAssignment> {
let (s, lvalue) = variable_lvalue(s)?;
let (s, _) = symbol("<=")(s)?;
let (s, control) = opt(delay_or_event_control)(s)?;
let (s, rvalue) = expression(s)?;
Ok((
s,
NonblockingAssignment {
lvalue,
control,
rvalue,
},
))
}
pub fn procedual_continuous_assignment(s: &str) -> IResult<&str, ProcedualContinuousAssignment> {
alt((
map(preceded(symbol("assign"), variable_assignment), |x| {
ProcedualContinuousAssignment::Assign(x)
}),
map(preceded(symbol("deassign"), variable_lvalue), |x| {
ProcedualContinuousAssignment::Deassign(x)
}),
map(preceded(symbol("force"), variable_assignment), |x| {
ProcedualContinuousAssignment::ForceVariable(x)
}),
map(preceded(symbol("force"), net_assignment), |x| {
ProcedualContinuousAssignment::ForceNet(x)
}),
map(preceded(symbol("release"), variable_lvalue), |x| {
ProcedualContinuousAssignment::ReleaseVariable(x)
}),
map(preceded(symbol("release"), net_lvalue), |x| {
ProcedualContinuousAssignment::ReleaseNet(x)
}),
))(s)
}
pub fn variable_assignment(s: &str) -> IResult<&str, VariableAssignment> {
let (s, lvalue) = variable_lvalue(s)?;
let (s, _) = symbol("=")(s)?;
let (s, rvalue) = expression(s)?;
Ok((s, VariableAssignment { lvalue, rvalue }))
}

View File

@ -78,11 +78,6 @@ pub struct DataType<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct OperatorAssignment<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct OpenRangeList<'a> {
pub raw: Vec<&'a str>,
@ -103,6 +98,56 @@ pub struct SimpleType<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct DriveStrength<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct Delay3<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct DelayControl<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct StatementOrNull<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct Statement<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct FunctionStatement<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct DelayOrEventControl<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct DynamicArrayNew<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct ClassNew<'a> {
pub raw: Vec<&'a str>,
}
#[derive(Debug)]
pub struct BlockItemDeclaration<'a> {
pub raw: Vec<&'a str>,
}
pub fn class_scope(s: &str) -> IResult<&str, Scope> {
Ok((s, Scope::ClassScope))
}
@ -157,10 +202,6 @@ pub fn data_type(s: &str) -> IResult<&str, DataType> {
Ok((s, DataType { raw: vec![] }))
}
pub fn operator_assignment(s: &str) -> IResult<&str, OperatorAssignment> {
Ok((s, OperatorAssignment { raw: vec![] }))
}
pub fn open_range_list(s: &str) -> IResult<&str, OpenRangeList> {
Ok((s, OpenRangeList { raw: vec![] }))
}
@ -184,3 +225,43 @@ pub fn identifier_list(s: &str) -> IResult<&str, Vec<Identifier>> {
pub fn simple_type(s: &str) -> IResult<&str, SimpleType> {
Ok((s, SimpleType { raw: vec![] }))
}
pub fn drive_strength(s: &str) -> IResult<&str, DriveStrength> {
Ok((s, DriveStrength { raw: vec![] }))
}
pub fn delay3(s: &str) -> IResult<&str, Delay3> {
Ok((s, Delay3 { raw: vec![] }))
}
pub fn delay_control(s: &str) -> IResult<&str, DelayControl> {
Ok((s, DelayControl { raw: vec![] }))
}
pub fn statement_or_null(s: &str) -> IResult<&str, StatementOrNull> {
Ok((s, StatementOrNull { raw: vec![] }))
}
pub fn statement(s: &str) -> IResult<&str, Statement> {
Ok((s, Statement { raw: vec![] }))
}
pub fn function_statement(s: &str) -> IResult<&str, FunctionStatement> {
Ok((s, FunctionStatement { raw: vec![] }))
}
pub fn delay_or_event_control(s: &str) -> IResult<&str, DelayOrEventControl> {
Ok((s, DelayOrEventControl { raw: vec![] }))
}
pub fn dynamic_array_new(s: &str) -> IResult<&str, DynamicArrayNew> {
Ok((s, DynamicArrayNew { raw: vec![] }))
}
pub fn class_new(s: &str) -> IResult<&str, ClassNew> {
Ok((s, ClassNew { raw: vec![] }))
}
pub fn block_item_declaration(s: &str) -> IResult<&str, BlockItemDeclaration> {
Ok((s, BlockItemDeclaration { raw: vec![] }))
}