Skip to content

Commit

Permalink
Merge pull request #1010 from taichi-ishitani/fix_interface_port_with…
Browse files Browse the repository at this point in the history
…_direction

Report error for interface port with direction
  • Loading branch information
dalance authored Oct 10, 2024
2 parents f4e293c + efb0dd8 commit 6c2cfcd
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 8 deletions.
8 changes: 4 additions & 4 deletions crates/analyzer/src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ use self::{check_assignment::CheckAssignment, create_type_dag::CreateTypeDag};

pub struct Pass1Handlers<'a> {
check_attribute: CheckAttribute<'a>,
check_direction: CheckDirection<'a>,
check_embed_include: CheckEmbedInclude<'a>,
check_identifier: CheckIdentifier<'a>,
check_number: CheckNumber<'a>,
Expand All @@ -58,7 +57,6 @@ impl<'a> Pass1Handlers<'a> {
pub fn new(text: &'a str, build_opt: &'a Build, lint_opt: &'a Lint) -> Self {
Self {
check_attribute: CheckAttribute::new(text),
check_direction: CheckDirection::new(text),
check_embed_include: CheckEmbedInclude::new(text),
check_identifier: CheckIdentifier::new(text, lint_opt),
check_number: CheckNumber::new(text),
Expand All @@ -71,7 +69,6 @@ impl<'a> Pass1Handlers<'a> {
pub fn get_handlers(&mut self) -> Vec<&mut dyn Handler> {
vec![
&mut self.check_attribute as &mut dyn Handler,
&mut self.check_direction as &mut dyn Handler,
&mut self.check_embed_include as &mut dyn Handler,
&mut self.check_identifier as &mut dyn Handler,
&mut self.check_number as &mut dyn Handler,
Expand All @@ -84,7 +81,6 @@ impl<'a> Pass1Handlers<'a> {
pub fn get_errors(&mut self) -> Vec<AnalyzerError> {
let mut ret = Vec::new();
ret.append(&mut self.check_attribute.errors);
ret.append(&mut self.check_direction.errors);
ret.append(&mut self.check_embed_include.errors);
ret.append(&mut self.check_identifier.errors);
ret.append(&mut self.check_number.errors);
Expand All @@ -97,6 +93,7 @@ impl<'a> Pass1Handlers<'a> {

pub struct Pass2Handlers<'a> {
check_enum: CheckEnum<'a>,
check_direction: CheckDirection<'a>,
check_modport: CheckModport<'a>,
check_function: CheckFunction<'a>,
check_type: CheckType<'a>,
Expand All @@ -114,6 +111,7 @@ impl<'a> Pass2Handlers<'a> {
pub fn new(text: &'a str, _build_opt: &'a Build, _lint_opt: &'a Lint) -> Self {
Self {
check_enum: CheckEnum::new(text),
check_direction: CheckDirection::new(text),
check_modport: CheckModport::new(text),
check_function: CheckFunction::new(text),
check_type: CheckType::new(text),
Expand All @@ -131,6 +129,7 @@ impl<'a> Pass2Handlers<'a> {
pub fn get_handlers(&mut self) -> Vec<&mut dyn Handler> {
vec![
&mut self.check_enum as &mut dyn Handler,
&mut self.check_direction as &mut dyn Handler,
&mut self.check_modport as &mut dyn Handler,
&mut self.check_function as &mut dyn Handler,
&mut self.check_type as &mut dyn Handler,
Expand All @@ -148,6 +147,7 @@ impl<'a> Pass2Handlers<'a> {
pub fn get_errors(&mut self) -> Vec<AnalyzerError> {
let mut ret = Vec::new();
ret.append(&mut self.check_enum.errors);
ret.append(&mut self.check_direction.errors);
ret.append(&mut self.check_modport.errors);
ret.append(&mut self.check_function.errors);
ret.append(&mut self.check_type.errors);
Expand Down
50 changes: 46 additions & 4 deletions crates/analyzer/src/handlers/check_direction.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::analyzer_error::AnalyzerError;
use crate::symbol::SymbolKind;
use crate::symbol_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;
Expand All @@ -11,6 +13,7 @@ pub struct CheckDirection<'a> {
in_function: bool,
in_module: bool,
in_modport: bool,
is_interface_port: bool,
}

impl<'a> CheckDirection<'a> {
Expand All @@ -28,15 +31,28 @@ impl<'a> Handler for CheckDirection<'a> {
}
}

fn is_interface_type(arg: &ArrayType) -> bool {
if let ScalarTypeGroup::VariableTypeScalarTypeOpt(x) = &*arg.scalar_type.scalar_type_group {
if let VariableType::ScopedIdentifier(x) = x.variable_type.as_ref() {
let symbol = symbol_table::resolve(x.scoped_identifier.as_ref()).unwrap();
return matches!(symbol.found.kind, SymbolKind::Interface(_));
}
}

false
}

impl<'a> VerylGrammarTrait for CheckDirection<'a> {
fn port_declaration_item(&mut self, arg: &PortDeclarationItem) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
if let PortDeclarationItemGroup::PortTypeConcrete(x) =
arg.port_declaration_item_group.as_ref()
{
let x = x.port_type_concrete.as_ref();
let r#type = &x.array_type;

self.is_interface_port = is_interface_type(r#type);
if let Direction::Inout(_) = x.direction.as_ref() {
let r#type = &x.array_type;
let is_tri = r#type
.scalar_type
.scalar_type_list
Expand All @@ -58,8 +74,35 @@ impl<'a> VerylGrammarTrait for CheckDirection<'a> {
fn direction(&mut self, arg: &Direction) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
match arg {
Direction::Input(x) => {
if self.is_interface_port {
self.errors.push(AnalyzerError::invalid_direction(
"input",
self.text,
&x.input.input_token.token.into(),
));
}
}
Direction::Output(x) => {
if self.is_interface_port {
self.errors.push(AnalyzerError::invalid_direction(
"output",
self.text,
&x.output.output_token.token.into(),
));
}
}
Direction::Inout(x) => {
if self.is_interface_port {
self.errors.push(AnalyzerError::invalid_direction(
"inout",
self.text,
&x.inout.inout_token.token.into(),
));
}
}
Direction::Ref(x) => {
if !self.in_function {
if !self.in_function || self.is_interface_port {
self.errors.push(AnalyzerError::invalid_direction(
"ref",
self.text,
Expand All @@ -77,15 +120,14 @@ impl<'a> VerylGrammarTrait for CheckDirection<'a> {
}
}
Direction::Import(x) => {
if !self.in_modport {
if !self.in_modport || self.is_interface_port {
self.errors.push(AnalyzerError::invalid_direction(
"import",
self.text,
&x.import.import_token.token.into(),
));
}
}
_ => (),
}
}
Ok(())
Expand Down
16 changes: 16 additions & 0 deletions crates/analyzer/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,22 @@ fn invalid_direction() {

let errors = analyze(code);
assert!(matches!(errors[0], AnalyzerError::InvalidDirection { .. }));

let code = r#"
interface InterfaceG {
var value: logic;
modport mp {
value: input,
}
}
module ModuleG (
port_a: input InterfaceG
){}
"#;

let errors = analyze(code);
assert!(matches!(errors[0], AnalyzerError::InvalidDirection { .. }));
}

#[test]
Expand Down

0 comments on commit 6c2cfcd

Please sign in to comment.