From 13b7a967c07c051a17cf7eb37b7291d4fe264727 Mon Sep 17 00:00:00 2001 From: dalance Date: Tue, 1 Aug 2023 10:35:52 +0900 Subject: [PATCH] Add modport member resolve --- .../src/handlers/create_symbol_table.rs | 8 ++++++++ crates/analyzer/src/symbol.rs | 5 ++++- crates/analyzer/src/symbol_table.rs | 13 ++++++++++++- crates/languageserver/src/server.rs | 1 + testcases/sv/38_modport.sv | 18 ++++++++++++++++++ testcases/vl/38_modport.vl | 18 ++++++++++++++++++ 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 testcases/sv/38_modport.sv create mode 100644 testcases/vl/38_modport.vl diff --git a/crates/analyzer/src/handlers/create_symbol_table.rs b/crates/analyzer/src/handlers/create_symbol_table.rs index 5f5542da..ed30e7a8 100644 --- a/crates/analyzer/src/handlers/create_symbol_table.rs +++ b/crates/analyzer/src/handlers/create_symbol_table.rs @@ -168,13 +168,21 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> { if let HandlerPoint::Before = self.point { let mut members = Vec::new(); let items: Vec = arg.modport_list.as_ref().into(); + + self.namespace + .push(arg.identifier.identifier_token.token.text); + for item in items { let member = ModportMember { name: item.identifier.identifier_token.token.text, direction: item.direction.as_ref().into(), }; members.push(member); + self.insert_symbol(&item.identifier.identifier_token, SymbolKind::ModportMember); } + + self.namespace.pop(); + let property = ModportProperty { members }; let kind = SymbolKind::Modport(property); self.insert_symbol(&arg.identifier.identifier_token, kind); diff --git a/crates/analyzer/src/symbol.rs b/crates/analyzer/src/symbol.rs index c18f5e35..312ab74d 100644 --- a/crates/analyzer/src/symbol.rs +++ b/crates/analyzer/src/symbol.rs @@ -85,6 +85,7 @@ pub enum SymbolKind { EnumMember(EnumMemberProperty), Modport(ModportProperty), Genvar, + ModportMember, } impl SymbolKind { @@ -105,6 +106,7 @@ impl SymbolKind { SymbolKind::EnumMember(_) => "enum member".to_string(), SymbolKind::Modport(_) => "modport".to_string(), SymbolKind::Genvar => "genvar".to_string(), + SymbolKind::ModportMember => "modport member".to_string(), } } } @@ -186,12 +188,13 @@ impl fmt::Display for SymbolKind { format!("modport ({} ports)", x.members.len()) } SymbolKind::Genvar => "genvar".to_string(), + SymbolKind::ModportMember => "modport member".to_string(), }; text.fmt(f) } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Direction { Input, Output, diff --git a/crates/analyzer/src/symbol_table.rs b/crates/analyzer/src/symbol_table.rs index d810bc56..88809fd5 100644 --- a/crates/analyzer/src/symbol_table.rs +++ b/crates/analyzer/src/symbol_table.rs @@ -1,7 +1,7 @@ use crate::evaluator::Evaluated; use crate::namespace::Namespace; use crate::namespace_table; -use crate::symbol::{Symbol, SymbolKind, TypeKind}; +use crate::symbol::{Direction, Symbol, SymbolKind, TypeKind}; use std::cell::RefCell; use std::collections::HashMap; use std::fmt; @@ -287,6 +287,17 @@ impl SymbolTable { } inner = true; } + SymbolKind::Port(ref x) if x.direction == Direction::Modport => { + if let Some(ref x) = x.r#type { + if let TypeKind::UserDefined(ref x) = x.kind { + namespace = Namespace::default(); + for x in x { + namespace.push(*x); + } + inner = true; + } + } + } _ => (), } } else if let Some(last_found) = last_found { diff --git a/crates/languageserver/src/server.rs b/crates/languageserver/src/server.rs index 163d183c..17bc3883 100644 --- a/crates/languageserver/src/server.rs +++ b/crates/languageserver/src/server.rs @@ -275,6 +275,7 @@ impl Server { veryl_analyzer::symbol::SymbolKind::EnumMember(_) => SymbolKind::ENUM_MEMBER, veryl_analyzer::symbol::SymbolKind::Modport(_) => SymbolKind::INTERFACE, veryl_analyzer::symbol::SymbolKind::Genvar => SymbolKind::VARIABLE, + veryl_analyzer::symbol::SymbolKind::ModportMember => SymbolKind::VARIABLE, }; let location = to_location(&symbol.token); #[allow(deprecated)] diff --git a/testcases/sv/38_modport.sv b/testcases/sv/38_modport.sv new file mode 100644 index 00000000..45d9510b --- /dev/null +++ b/testcases/sv/38_modport.sv @@ -0,0 +1,18 @@ +module veryl_testcase_Module38 ( + veryl_testcase_Interface38.master mst, + veryl_testcase_Interface38.slave slv +); + assign mst.a = slv.a; +endmodule + +interface veryl_testcase_Interface38; + logic a; + + modport master ( + output a + ); + + modport slave ( + input a + ); +endinterface diff --git a/testcases/vl/38_modport.vl b/testcases/vl/38_modport.vl new file mode 100644 index 00000000..6ff60705 --- /dev/null +++ b/testcases/vl/38_modport.vl @@ -0,0 +1,18 @@ +module Module38 ( + mst: modport Interface38::master, + slv: modport Interface38::slave , +) { + assign mst.a = slv.a; +} + +interface Interface38 { + var a: logic; + + modport master { + a: output, + } + + modport slave { + a: input, + } +}