///|
/// Return module names in source declaration order.
pub fn SemanticIndex::module_names(self : SemanticIndex) -> Array[String] {
let names : Array[String] = []
for mod in self.modules {
names.push(mod.name)
}
names
}
///|
/// Return the number of module declarations, including duplicate names.
pub fn SemanticIndex::module_count(self : SemanticIndex) -> Int {
self.modules.length()
}
///|
/// Return names of signals visible in one indexed module.
pub fn SemanticIndex::signal_names(
self : SemanticIndex,
module_name : String,
) -> Array[String] {
match self.find_module(module_name) {
Some(mod) => {
let names : Array[String] = []
for signal in mod.signals {
names.push(signal.name)
}
names
}
None => []
}
}
///|
/// Return names of signals with at least one recorded driver.
pub fn SemanticIndex::driven_signals(
self : SemanticIndex,
module_name : String,
) -> Array[String] {
match self.find_module(module_name) {
Some(mod) => {
let names : Array[String] = []
for signal in mod.signals {
if signal.has_driver() {
names.push(signal.name)
}
}
names
}
None => []
}
}
///|
/// Return names of internal signals which have no recorded driver.
pub fn SemanticIndex::undriven_signals(
self : SemanticIndex,
module_name : String,
) -> Array[String] {
match self.find_module(module_name) {
Some(mod) => {
let names : Array[String] = []
for signal in mod.signals {
if !signal.from_port && !signal.has_driver() {
names.push(signal.name)
}
}
names
}
None => []
}
}
///|
/// Count hierarchy children of one module.
pub fn SemanticIndex::fanout(self : SemanticIndex, module_name : String) -> Int {
let mut count = 0
for edge in self.graph.edges() {
let (parent, _) = edge
if parent == module_name {
count += 1
}
}
count
}
///|
/// Return modules which instantiate at least one other module.
pub fn SemanticIndex::hierarchy_parents(self : SemanticIndex) -> Array[String] {
let parents : Array[String] = []
for edge in self.graph.edges() {
let (parent, _) = edge
if !parents.contains(parent) {
parents.push(parent)
}
}
parents
}
///|
/// Return modules which are not referenced as a child by another module.
pub fn SemanticIndex::hierarchy_roots(self : SemanticIndex) -> Array[String] {
let children : Array[String] = []
for edge in self.graph.edges() {
let (_, child) = edge
if !children.contains(child) {
children.push(child)
}
}
let roots : Array[String] = []
for mod in self.modules {
if !children.contains(mod.name) && !roots.contains(mod.name) {
roots.push(mod.name)
}
}
roots
}
///|
/// Return unresolved instance issues without exposing the whole issue list.
pub fn SemanticIndex::unresolved_instances(self : SemanticIndex) -> Int {
let mut count = 0
for issue in self.issues {
if issue.code == "RTL102" {
count += 1
}
}
count
}
///|
/// Return whether the index contains a named module.
pub fn SemanticIndex::has_module(self : SemanticIndex, name : String) -> Bool {
self.find_module(name) is Some(_)
}
///|
/// Return whether the graph contains a particular directed edge.
pub fn SemanticIndex::has_edge(
self : SemanticIndex,
parent : String,
child : String,
) -> Bool {
for edge in self.graph.edges() {
let (edge_parent, edge_child) = edge
if edge_parent == parent && edge_child == child {
return true
}
}
false
}
///|
/// Produce a compact, stable index summary for logs and diagnostics.
pub fn SemanticIndex::summary(self : SemanticIndex) -> String {
"modules=" +
self.module_count().to_string() +
", edges=" +
self.graph.edges().length().to_string() +
", unresolved_instances=" +
self.unresolved_instances().to_string()
}