Skip to content

Commit 6def6bc

Browse files
committed
Sensitivity List linter: make heuristic for clocked process detection more general
1 parent 9901a28 commit 6def6bc

File tree

1 file changed

+76
-11
lines changed

1 file changed

+76
-11
lines changed

vhdl_lang/src/lint/sensitivity_list.rs

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ use crate::ast::{
3131
SensitivityList, SequentialStatement, SignalAttribute, UnitId, UnitKey, Waveform, WithRef,
3232
};
3333
use crate::data::{DiagnosticHandler, ErrorCode, Symbol};
34-
use crate::{Config, Diagnostic, EntityId, HasTokenSpan, SrcPos, TokenAccess, TokenSpan};
34+
use crate::{
35+
AnyEntKind, Config, Diagnostic, EntityId, HasTokenSpan, SrcPos, TokenAccess, TokenSpan,
36+
};
3537
use fnv::FnvHashMap;
3638
use itertools::Itertools;
3739
use std::collections::hash_map::Entry;
@@ -590,19 +592,33 @@ fn is_likely_clocked(root: &DesignRoot, expression: &Expression) -> bool {
590592
attribute.attr.item == AttributeDesignator::Signal(SignalAttribute::Event)
591593
}
592594
Name::CallOrIndexed(coi) => {
593-
if let Some(reference) = coi.name.item.get_suffix_reference() {
594-
let ent = root.get_ent(reference);
595-
if let Some(library_name) = ent.library_name() {
596-
if (library_name.name_utf8().to_lowercase() == "ieee"
597-
|| library_name.name_utf8().to_lowercase() == "std")
598-
&& (ent.designator.to_string().to_lowercase() == "rising_edge"
599-
|| ent.designator.to_string().to_lowercase() == "falling_edge")
600-
{
601-
return true;
595+
let Some(reference) = coi.name.item.get_suffix_reference() else {
596+
return false;
597+
};
598+
let ent = root.get_ent(reference);
599+
match ent.kind() {
600+
// Any function that has one argument and returns `boolean`
601+
// is considered clocked.
602+
// This is true, for example, for the standard
603+
// RISING_EDGE(signal S: BOOLEAN) return BOOLEAN; and
604+
// FALLING_EDGE(signal S: BOOLEAN) return BOOLEAN;
605+
// functions.
606+
AnyEntKind::Overloaded(ovl) => {
607+
// FIXME: This check could include check for a function
608+
// Currently, checks functions, procedures and other miscellaneous items
609+
let signature = ovl.signature();
610+
if signature.formals.len() != 1 {
611+
return false;
602612
}
613+
let Some(ret_type) = signature.return_type else {
614+
return false;
615+
};
616+
// FIXME: This should probably check that `ret_type` is the actual boolean type
617+
// and not the std boolean type
618+
ret_type.designator == Designator::Identifier(root.symbol_utf8("BOOLEAN"))
603619
}
620+
_ => false,
604621
}
605-
false
606622
}
607623
_ => false,
608624
},
@@ -847,4 +863,53 @@ end architecture;",
847863
let _ = root.search(&mut searcher);
848864
assert_eq!(idx.get(), 9);
849865
}
866+
867+
// GitHub issue: 378
868+
#[test]
869+
fn check_generic_clk_edge() {
870+
let mut builder = LibraryBuilder::new();
871+
872+
builder.code(
873+
"libname",
874+
"
875+
library ieee;
876+
use ieee.std_logic_1164.all;
877+
878+
entity generic_clk_edge_function_warning is
879+
generic (
880+
function active_edge(signal s: std_ulogic) return boolean
881+
);
882+
port (
883+
clk: in std_ulogic;
884+
data_out: out std_ulogic
885+
);
886+
end entity;
887+
888+
architecture behavioural of generic_clk_edge_function_warning is
889+
signal internal_signal: std_ulogic := '0';
890+
begin
891+
process (clk)
892+
begin
893+
if active_edge(clk) then -- Trigger: function call via generic
894+
internal_signal <= not internal_signal;
895+
end if;
896+
end process;
897+
898+
data_out <= internal_signal;
899+
end architecture;",
900+
);
901+
902+
builder.add_std_logic_1164();
903+
let (root, diagnostics) = builder.get_analyzed_root();
904+
check_no_diagnostics(&diagnostics);
905+
906+
let num_of_searches = Cell::new(0);
907+
let mut searcher = ProcessSearcher::new(|proc, ctx| {
908+
num_of_searches.set(num_of_searches.get() + 1);
909+
let diag = lint_sensitivity_list(&root, ctx, proc);
910+
assert_eq!(diag, Vec::default());
911+
});
912+
let _ = root.search(&mut searcher);
913+
assert_eq!(num_of_searches.get(), 1)
914+
}
850915
}

0 commit comments

Comments
 (0)