diff --git a/src/syntaxrules/implicit_case_default.rs b/src/syntaxrules/implicit_case_default.rs index 25c215d..947031a 100644 --- a/src/syntaxrules/implicit_case_default.rs +++ b/src/syntaxrules/implicit_case_default.rs @@ -5,7 +5,8 @@ use sv_parser::{unwrap_node, Locate, NodeEvent, RefNode, SyntaxTree}; #[derive(Default)] pub struct ImplicitCaseDefault { under_always_construct: bool, - under_case_statement: bool, + under_case_item: bool, + is_default: bool, lhs_variables: Vec, case_variables: Vec @@ -25,10 +26,11 @@ impl SyntaxRule for ImplicitCaseDefault { match x { RefNode::AlwaysConstruct(_) => { self.under_always_construct = true; + self.is_default = false; } RefNode::CaseItemNondefault(_) => { - self.under_case_statement = true; + self.under_case_item = true; } _ => (), @@ -40,13 +42,14 @@ impl SyntaxRule for ImplicitCaseDefault { match x { RefNode::AlwaysConstruct(_) => { self.under_always_construct = false; + self.is_default = false; self.lhs_variables.clear(); self.case_variables.clear(); } RefNode::CaseItemNondefault(_) => { - self.under_case_statement = false; + self.under_case_item = false; } _ => () @@ -56,9 +59,9 @@ impl SyntaxRule for ImplicitCaseDefault { }; //println!("{}", node); - + // match implicit declarations - match (self.under_always_construct, self.under_case_statement, node) { + match (self.under_always_construct, self.under_case_item, node) { (true, false, RefNode::BlockItemDeclaration(x)) => { let var = unwrap_node!(*x, VariableDeclAssignment).unwrap(); let id = get_identifier(var); @@ -69,14 +72,26 @@ impl SyntaxRule for ImplicitCaseDefault { _ => () } + // check if default + match (self.under_always_construct, node) { + (true, RefNode::CaseStatementNormal(x)) => { + let a = unwrap_node!(*x, CaseItemDefault); + if a.is_some() { + self.is_default = true; + } + } + + _ => () + } + // match case statement declarations - match (self.under_always_construct, self.under_case_statement, node) { + match (self.under_always_construct, self.under_case_item, 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()) { + if self.lhs_variables.contains(&id.to_string()) || self.is_default { return SyntaxRuleResult::Pass } else { return SyntaxRuleResult::Fail @@ -88,7 +103,7 @@ impl SyntaxRule for ImplicitCaseDefault { let id = get_identifier(var); let id = syntax_tree.get_str(&id).unwrap(); - if self.lhs_variables.contains(&id.to_string()) { + if self.lhs_variables.contains(&id.to_string()) || self.is_default { return SyntaxRuleResult::Pass } else { return SyntaxRuleResult::Fail @@ -98,34 +113,6 @@ impl SyntaxRule for ImplicitCaseDefault { _ => () } - /* - match (self.under_always_construct, node) { - (true, RefNode::CaseStatementNormal(x)) => { - let a = unwrap_node!(*x, CaseItemDefault); - if a.is_some() { - SyntaxRuleResult::Pass - } else { - // check if lvalues of case statement have an implicit definition - let var = unwrap_node!(*x, VariableLvalueIdentifier).unwrap(); - let id = get_identifier(var); - let id = syntax_tree.get_str(&id).unwrap(); - - println!("Case variable: {id}"); - - // check if id is in lhs_variables - if self.lhs_variables.contains(&id.to_string()) { - SyntaxRuleResult::Pass - } else { - SyntaxRuleResult::Fail - } - } - } - - _ => { - SyntaxRuleResult::Pass - } - }*/ - return SyntaxRuleResult::Pass } diff --git a/testcases/syntaxrules/fail/implicit_case_default.sv b/testcases/syntaxrules/fail/implicit_case_default.sv index 03b4a9c..40496c5 100644 --- a/testcases/syntaxrules/fail/implicit_case_default.sv +++ b/testcases/syntaxrules/fail/implicit_case_default.sv @@ -8,7 +8,6 @@ endmodule module M; always_comb begin a = 0; - case(x) 1: b = 0; endcase diff --git a/testcases/syntaxrules/pass/implicit_case_default.sv b/testcases/syntaxrules/pass/implicit_case_default.sv index a80a3c5..8e2f045 100644 --- a/testcases/syntaxrules/pass/implicit_case_default.sv +++ b/testcases/syntaxrules/pass/implicit_case_default.sv @@ -1,14 +1,30 @@ +module M; + always_comb + y = 0; + case(x) + 1: y = 1; // case default is implicit + endcase +endmodule +//////////////////////////////////////////////////////////////////////////////// module M; always_comb begin y = 0; z = 0; - //w = 0; + w = 0; case(x) - 1: y = 1; // case default is implicit + 1: y = 1; 2: begin z = 1; w = 1; end endcase end +endmodule +//////////////////////////////////////////////////////////////////////////////// +module M; + always_comb + case(x) + 1: y = 1; + default: y = 0; + endcase endmodule \ No newline at end of file