Skip to content

Commit

Permalink
implicit_case_default works for most implicit declarations, still nee…
Browse files Browse the repository at this point in the history
…d to implement default case support
  • Loading branch information
ShreChinno committed Mar 15, 2024
1 parent 1c0a7d0 commit 5073475
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 30 deletions.
98 changes: 78 additions & 20 deletions src/syntaxrules/implicit_case_default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use sv_parser::{unwrap_node, Locate, NodeEvent, RefNode, SyntaxTree};
#[derive(Default)]
pub struct ImplicitCaseDefault {
under_always_construct: bool,
implicit_variables: Vec<String>,
case_variables: Vec<String>,
under_case_statement: bool,

lhs_variables: Vec<String>,
case_variables: Vec<String>
}

impl SyntaxRule for ImplicitCaseDefault {
Expand All @@ -16,7 +18,7 @@ impl SyntaxRule for ImplicitCaseDefault {
event: &NodeEvent,
_option: &ConfigOption,
) -> SyntaxRuleResult {
// println!("Syntax Tree: {}", syntax_tree);
//println!("{}", syntax_tree);

let node = match event {
NodeEvent::Enter(x) => {
Expand All @@ -25,27 +27,78 @@ impl SyntaxRule for ImplicitCaseDefault {
self.under_always_construct = true;
}

RefNode::BlockItemDeclaration(x) => {
let var = unwrap_node!(*x, VariableDeclAssignment).unwrap();
let id = get_identifier(var);
let id = syntax_tree.get_str(&id).unwrap();

self.implicit_variables.push(String::from(id));

println!("LHS Variables: {:?}", self.implicit_variables);
RefNode::CaseItemNondefault(_) => {
self.under_case_statement = true;
}

_ => (),
}
x
}

NodeEvent::Leave(x) => {
if let RefNode::AlwaysConstruct(_) = x {
self.under_always_construct = false;
match x {
RefNode::AlwaysConstruct(_) => {
self.under_always_construct = false;
self.lhs_variables.clear();
self.case_variables.clear();

}

RefNode::CaseItemNondefault(_) => {
self.under_case_statement = false;
}

_ => ()
}
return SyntaxRuleResult::Pass;
}
};

//println!("{}", node);

// match implicit declarations
match (self.under_always_construct, self.under_case_statement, node) {
(true, false, RefNode::BlockItemDeclaration(x)) => {
let var = unwrap_node!(*x, VariableDeclAssignment).unwrap();
let id = get_identifier(var);
let id = syntax_tree.get_str(&id).unwrap();
self.lhs_variables.push(String::from(id));
}

_ => ()
}

// match case statement declarations
match (self.under_always_construct, self.under_case_statement, node) {
(true, true, RefNode::BlockingAssignment(x)) => {
let var = unwrap_node!(*x, VariableLvalueIdentifier).unwrap();
let id = get_identifier(var);
let id = syntax_tree.get_str(&id).unwrap();

if self.lhs_variables.contains(&id.to_string()) {
return SyntaxRuleResult::Pass
} else {
return SyntaxRuleResult::Fail
}
}

(true, true, RefNode::BlockItemDeclaration(x)) => {
let var = unwrap_node!(*x, VariableDeclAssignment).unwrap();
let id = get_identifier(var);
let id = syntax_tree.get_str(&id).unwrap();

if self.lhs_variables.contains(&id.to_string()) {
return SyntaxRuleResult::Pass
} else {
return SyntaxRuleResult::Fail
}
}

_ => ()
}

/*
match (self.under_always_construct, node) {
(true, RefNode::CaseStatementNormal(x)) => {
let a = unwrap_node!(*x, CaseItemDefault);
Expand All @@ -59,24 +112,29 @@ impl SyntaxRule for ImplicitCaseDefault {
println!("Case variable: {id}");
// check if id is in implicit_variables
if self.implicit_variables.contains(&id.to_string()) {
// check if id is in lhs_variables
if self.lhs_variables.contains(&id.to_string()) {
SyntaxRuleResult::Pass
} else {
SyntaxRuleResult::Fail
}
}
}
_ => SyntaxRuleResult::Pass,
}
_ => {
SyntaxRuleResult::Pass
}
}*/

return SyntaxRuleResult::Pass
}

fn name(&self) -> String {
String::from("implicit_case_default")
}

fn hint(&self, _option: &ConfigOption) -> String {
String::from("Signal driven in `case` statement does not have a default value.")
String::from("Signal driven in `case` statement does not have a default value. Define a default case or implicitly define before `case` statement.")
}

fn reason(&self) -> String {
Expand All @@ -90,4 +148,4 @@ fn get_identifier(node: RefNode) -> Option<Locate> {
Some(RefNode::EscapedIdentifier(x)) => Some(x.nodes.0),
_ => None,
}
}
}
19 changes: 9 additions & 10 deletions testcases/syntaxrules/pass/implicit_case_default.sv
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
module M;
always_comb
always_comb begin
y = 0;
z = 0;
//w = 0;
case(x)
1: y = 1; // case default is implicit
2: begin
z = 1;
w = 1;
end
endcase
endmodule
////////////////////////////////////////////////////////////////////////////////
module M;
always_comb
case(x)
1: y = 1;
default: y = 0;
endcase
endmodule
end
endmodule

0 comments on commit 5073475

Please sign in to comment.