Skip to content

Commit

Permalink
Merge pull request #731 from taichi-ishitani/reset_prefix_suffix
Browse files Browse the repository at this point in the history
Allow to add prefix/suffix to `clock`/`reset` signals
  • Loading branch information
dalance committed May 26, 2024
2 parents 5a49bbb + 86a29cb commit 198811b
Show file tree
Hide file tree
Showing 14 changed files with 356 additions and 57 deletions.
9 changes: 5 additions & 4 deletions Veryl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ license = "MIT"
repository = "https://github.com/veryl-lang/veryl"

[build]
clock_type = "posedge"
reset_type = "async_low"
filelist_type = "absolute"
target = {type = "directory", path = "testcases/sv"}
clock_type = "posedge"
reset_type = "async_low"
reset_low_suffix = "_n"
filelist_type = "absolute"
target = {type = "directory", path = "testcases/sv"}

[format]
indent_width = 4
Expand Down
16 changes: 9 additions & 7 deletions crates/analyzer/src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::symbol_table;
use crate::type_dag;
use itertools::Itertools;
use std::path::Path;
use veryl_metadata::{Lint, Metadata};
use veryl_metadata::{Build, Lint, Metadata};
use veryl_parser::resource_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_token::{Token, TokenSource};
Expand All @@ -26,9 +26,9 @@ pub struct AnalyzerPass1<'a> {
}

impl<'a> AnalyzerPass1<'a> {
pub fn new(text: &'a str, lint_opt: &'a Lint) -> Self {
pub fn new(text: &'a str, build_opt: &'a Build, lint_opt: &'a Lint) -> Self {
AnalyzerPass1 {
handlers: Pass1Handlers::new(text, lint_opt),
handlers: Pass1Handlers::new(text, build_opt, lint_opt),
}
}
}
Expand All @@ -44,9 +44,9 @@ pub struct AnalyzerPass2<'a> {
}

impl<'a> AnalyzerPass2<'a> {
pub fn new(text: &'a str, lint_opt: &'a Lint) -> Self {
pub fn new(text: &'a str, build_opt: &'a Build, lint_opt: &'a Lint) -> Self {
AnalyzerPass2 {
handlers: Pass2Handlers::new(text, lint_opt),
handlers: Pass2Handlers::new(text, build_opt, lint_opt),
}
}
}
Expand Down Expand Up @@ -180,6 +180,7 @@ impl<'a> AnalyzerPass3<'a> {
}

pub struct Analyzer {
build_opt: Build,
lint_opt: Lint,
}

Expand Down Expand Up @@ -216,6 +217,7 @@ impl Analyzer {
}
}
Analyzer {
build_opt: metadata.build.clone(),
lint_opt: metadata.lint.clone(),
}
}
Expand All @@ -230,7 +232,7 @@ impl Analyzer {
let mut ret = Vec::new();

namespace_table::set_default(&[project_name.into()]);
let mut pass1 = AnalyzerPass1::new(text, &self.lint_opt);
let mut pass1 = AnalyzerPass1::new(text, &self.build_opt, &self.lint_opt);
pass1.veryl(input);
ret.append(&mut pass1.handlers.get_errors());

Expand All @@ -247,7 +249,7 @@ impl Analyzer {
let mut ret = Vec::new();

namespace_table::set_default(&[project_name.into()]);
let mut pass2 = AnalyzerPass2::new(text, &self.lint_opt);
let mut pass2 = AnalyzerPass2::new(text, &self.build_opt, &self.lint_opt);
pass2.veryl(input);
ret.append(&mut pass2.handlers.get_errors());

Expand Down
8 changes: 4 additions & 4 deletions crates/analyzer/src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use create_reference::*;
use create_symbol_table::*;

use crate::analyzer_error::AnalyzerError;
use veryl_metadata::Lint;
use veryl_metadata::{Build, Lint};
use veryl_parser::veryl_walker::Handler;

use self::{check_assignment::CheckAssignment, create_type_dag::CreateTypeDag};
Expand All @@ -44,15 +44,15 @@ pub struct Pass1Handlers<'a> {
}

impl<'a> Pass1Handlers<'a> {
pub fn new(text: &'a str, lint_opt: &'a Lint) -> Self {
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),
check_statement: CheckStatement::new(text),
create_symbol_table: CreateSymbolTable::new(text),
create_symbol_table: CreateSymbolTable::new(text, build_opt),
}
}

Expand Down Expand Up @@ -93,7 +93,7 @@ pub struct Pass2Handlers<'a> {
}

impl<'a> Pass2Handlers<'a> {
pub fn new(text: &'a str, _lint_opt: &'a Lint) -> Self {
pub fn new(text: &'a str, _build_opt: &'a Build, _lint_opt: &'a Lint) -> Self {
Self {
check_enum: CheckEnum::new(text),
check_function: CheckFunction::new(text),
Expand Down
53 changes: 52 additions & 1 deletion crates/analyzer/src/handlers/create_symbol_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use crate::symbol::{
use crate::symbol_path::{GenericSymbolPath, SymbolPath};
use crate::symbol_table;
use std::collections::{HashMap, HashSet};
use veryl_metadata::ClockType;
use veryl_metadata::{Build, ResetType};
use veryl_parser::doc_comment_table;
use veryl_parser::resource_table::{self, StrId};
use veryl_parser::veryl_grammar_trait::*;
Expand All @@ -27,6 +29,7 @@ use veryl_parser::ParolError;
pub struct CreateSymbolTable<'a> {
pub errors: Vec<AnalyzerError>,
text: &'a str,
build_opt: Build,
point: HandlerPoint,
namespace: Namespace,
module_namspace_depth: usize,
Expand Down Expand Up @@ -55,9 +58,10 @@ enum StructOrUnion {
}

impl<'a> CreateSymbolTable<'a> {
pub fn new(text: &'a str) -> Self {
pub fn new(text: &'a str, build_opt: &'a Build) -> Self {
Self {
text,
build_opt: build_opt.clone(),
..Default::default()
}
}
Expand Down Expand Up @@ -105,6 +109,37 @@ impl<'a> CreateSymbolTable<'a> {
id
}

fn get_signal_prefix_suffix(&self, kind: TypeKind) -> (Option<String>, Option<String>) {
match kind {
TypeKind::Clock => match self.build_opt.clock_type {
ClockType::PosEdge => {
let prefix = self.build_opt.clock_posedge_prefix.clone();
let suffix = self.build_opt.clock_posedge_suffix.clone();
return (prefix, suffix);
}
ClockType::NegEdge => {
let prefix = self.build_opt.clock_negedge_prefix.clone();
let suffix = self.build_opt.clock_negedge_suffix.clone();
return (prefix, suffix);
}
},
TypeKind::Reset => match self.build_opt.reset_type {
ResetType::AsyncHigh | ResetType::SyncHigh => {
let prefix = self.build_opt.reset_high_prefix.clone();
let suffix = self.build_opt.reset_high_suffix.clone();
return (prefix, suffix);
}
ResetType::AsyncLow | ResetType::SyncLow => {
let prefix = self.build_opt.reset_low_prefix.clone();
let suffix = self.build_opt.reset_low_suffix.clone();
return (prefix, suffix);
}
},
_ => {}
}
(None, None)
}

fn is_default_clock_candidate(&self, kind: SymbolKind) -> bool {
if *self.affiniation.last().unwrap() != VariableAffiniation::Module
|| self.namespace.depth() != self.module_namspace_depth
Expand Down Expand Up @@ -268,9 +303,12 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
if let HandlerPoint::Before = self.point {
let r#type: SymType = arg.array_type.as_ref().into();
let affiniation = self.affiniation.last().cloned().unwrap();
let (prefix, suffix) = self.get_signal_prefix_suffix(r#type.kind.clone());
let property = VariableProperty {
r#type,
affiniation,
prefix,
suffix,
};
let kind = SymbolKind::Variable(property);

Expand Down Expand Up @@ -300,6 +338,8 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
let property = VariableProperty {
r#type,
affiniation,
prefix: None,
suffix: None,
};
let kind = SymbolKind::Variable(property);
self.insert_symbol(&arg.identifier.identifier_token.token, kind, false);
Expand All @@ -315,9 +355,12 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
if let HandlerPoint::Before = self.point {
let r#type: SymType = arg.array_type.as_ref().into();
let affiniation = self.affiniation.last().cloned().unwrap();
let (prefix, suffix) = self.get_signal_prefix_suffix(r#type.kind.clone());
let property = VariableProperty {
r#type,
affiniation,
prefix,
suffix,
};
let kind = SymbolKind::Variable(property);

Expand All @@ -338,9 +381,12 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
if let HandlerPoint::Before = self.point {
let r#type: SymType = arg.array_type.as_ref().into();
let affiniation = self.affiniation.last().cloned().unwrap();
let (prefix, suffix) = self.get_signal_prefix_suffix(r#type.kind.clone());
let property = VariableProperty {
r#type,
affiniation,
prefix,
suffix,
};
let kind = SymbolKind::Variable(property);

Expand Down Expand Up @@ -663,16 +709,21 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
PortDeclarationItemGroup::DirectionArrayType(x) => {
let r#type: SymType = x.array_type.as_ref().into();
let direction: SymDirection = x.direction.as_ref().into();
let (prefix, suffix) = self.get_signal_prefix_suffix(r#type.kind.clone());
PortProperty {
token,
r#type: Some(r#type),
direction,
prefix,
suffix,
}
}
PortDeclarationItemGroup::InterfacePortDeclarationItemOpt(_) => PortProperty {
token,
r#type: None,
direction: SymDirection::Interface,
prefix: None,
suffix: None,
},
};
let kind = SymbolKind::Port(property);
Expand Down
8 changes: 8 additions & 0 deletions crates/analyzer/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@ impl From<&syntax_tree::ArrayType> for Type {
pub struct VariableProperty {
pub r#type: Type,
pub affiniation: VariableAffiniation,
pub prefix: Option<String>,
pub suffix: Option<String>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand All @@ -655,6 +657,8 @@ pub struct PortProperty {
pub token: Token,
pub r#type: Option<Type>,
pub direction: Direction,
pub prefix: Option<String>,
pub suffix: Option<String>,
}

#[derive(Debug, Clone)]
Expand All @@ -681,13 +685,17 @@ impl From<&syntax_tree::PortDeclarationItem> for Port {
token,
r#type: Some(r#type),
direction,
prefix: None,
suffix: None,
}
}
syntax_tree::PortDeclarationItemGroup::InterfacePortDeclarationItemOpt(_) => {
PortProperty {
token,
r#type: None,
direction: Direction::Interface,
prefix: None,
suffix: None,
}
}
};
Expand Down
66 changes: 65 additions & 1 deletion crates/emitter/src/aligner.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::emitter::{symbol_string, SymbolContext};
use std::collections::HashMap;
use veryl_analyzer::symbol::GenericMap;
use veryl_analyzer::symbol::{GenericMap, SymbolKind};
use veryl_analyzer::symbol_table;
use veryl_metadata::{Build, BuiltinType, Metadata};
use veryl_parser::resource_table::StrId;
Expand Down Expand Up @@ -203,6 +203,20 @@ impl Aligner {
.implicit_parameter_types
.contains(&BuiltinType::Type)
}

fn identifier_with_prefix_suffix(
&mut self,
identifier: &Identifier,
prefix: &Option<String>,
suffix: &Option<String>,
) {
if prefix.is_some() || suffix.is_some() {
let token = identifier.identifier_token.append(prefix, suffix);
self.veryl_token(&token);
} else {
self.veryl_token(&identifier.identifier_token);
}
}
}

impl VerylWalker for Aligner {
Expand Down Expand Up @@ -293,6 +307,56 @@ impl VerylWalker for Aligner {
self.veryl_token(&arg.u64_token.replace("longint unsigned"));
}

/// Semantic action for non-terminal 'Identifier'
fn identifier(&mut self, arg: &Identifier) {
let (prefix, suffix) = if let Ok(found) = symbol_table::resolve(arg) {
match &found.found.kind {
SymbolKind::Port(x) => (x.prefix.clone(), x.suffix.clone()),
SymbolKind::Variable(x) => (x.prefix.clone(), x.suffix.clone()),
_ => (None, None),
}
} else {
(None, None)
};
self.identifier_with_prefix_suffix(arg, &prefix, &suffix);
}

/// Semantic action for non-terminal 'HierarchicalIdentifier'
fn hierarchical_identifier(&mut self, arg: &HierarchicalIdentifier) {
let list_len = &arg.hierarchical_identifier_list0.len();
let (prefix, suffix) = if let Ok(found) = symbol_table::resolve(arg) {
match &found.found.kind {
SymbolKind::Port(x) => (x.prefix.clone(), x.suffix.clone()),
SymbolKind::Variable(x) => (x.prefix.clone(), x.suffix.clone()),
_ => (None, None),
}
} else {
unreachable!()
};

if *list_len == 0 {
self.identifier_with_prefix_suffix(&arg.identifier, &prefix, &suffix);
} else {
self.identifier(&arg.identifier);
}

for x in &arg.hierarchical_identifier_list {
self.select(&x.select);
}

for (i, x) in arg.hierarchical_identifier_list0.iter().enumerate() {
self.dot(&x.dot);
if (i + 1) == *list_len {
self.identifier_with_prefix_suffix(&x.identifier, &prefix, &suffix);
} else {
self.identifier(&x.identifier);
}
for x in &x.hierarchical_identifier_list0_list {
self.select(&x.select);
}
}
}

/// Semantic action for non-terminal 'ScopedIdentifier'
fn scoped_identifier(&mut self, arg: &ScopedIdentifier) {
if let Ok(symbol) = symbol_table::resolve(arg) {
Expand Down

0 comments on commit 198811b

Please sign in to comment.