Skip to content

Commit

Permalink
Fill out checker port connection handling
Browse files Browse the repository at this point in the history
  • Loading branch information
MikePopoloski committed May 20, 2023
1 parent f5c3dc8 commit aee6bbf
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 129 deletions.
6 changes: 6 additions & 0 deletions include/slang/ast/expressions/MiscExpressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

namespace slang::ast {

class AssertionPortSymbol;

/// Common base class for both NamedValueExpression and HierarchicalValueExpression.
class SLANG_EXPORT ValueExpressionBase : public Expression {
public:
Expand Down Expand Up @@ -216,6 +218,10 @@ class SLANG_EXPORT AssertionInstanceExpression : public Expression {

static Expression& bindPort(const Symbol& symbol, SourceRange range, const ASTContext& context);

static bool checkAssertionArg(const syntax::PropertyExprSyntax& propExpr,
const AssertionPortSymbol& formal, const ASTContext& context,
ActualArg& result, bool isRecursiveProp);

void serializeTo(ASTSerializer& serializer) const;

static bool isKind(ExpressionKind kind) { return kind == ExpressionKind::AssertionInstance; }
Expand Down
31 changes: 28 additions & 3 deletions include/slang/ast/symbols/InstanceSymbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//------------------------------------------------------------------------------
#pragma once

#include "slang/ast/ASTContext.h"
#include "slang/ast/Scope.h"
#include "slang/ast/SemanticFacts.h"
#include "slang/ast/Symbol.h"
Expand All @@ -17,6 +18,7 @@
namespace slang::ast {

class AssertionExpr;
class AttributeSymbol;
class CheckerSymbol;
class Definition;
class Expression;
Expand Down Expand Up @@ -272,12 +274,24 @@ class SLANG_EXPORT CheckerInstanceSymbol : public InstanceSymbolBase, public Sco
public:
const CheckerSymbol& checker;
const AssertionInstanceDetails& assertionDetails;
bool isProcedural;

CheckerInstanceSymbol(Compilation& compilation, std::string_view name, SourceLocation loc,
const CheckerSymbol& checker,
const AssertionInstanceDetails& assertionDetails) :
const CheckerSymbol& checker, AssertionInstanceDetails& assertionDetails,
const ASTContext& originalContext, bool isProcedural) :
InstanceSymbolBase(SymbolKind::CheckerInstance, name, loc),
Scope(compilation, this), checker(checker), assertionDetails(assertionDetails) {}
Scope(compilation, this), checker(checker), assertionDetails(assertionDetails),
isProcedural(isProcedural), originalContext(originalContext) {
assertionDetails.prevContext = &this->originalContext;
}

struct Connection {
not_null<const Symbol*> formal;
std::variant<const Expression*, const AssertionExpr*, const TimingControl*> actual;
std::span<const AttributeSymbol* const> attributes;
};

std::span<const Connection> getPortConnections() const;

static void fromSyntax(const CheckerSymbol& checker,
const syntax::HierarchyInstantiationSyntax& syntax,
Expand All @@ -288,9 +302,20 @@ class SLANG_EXPORT CheckerInstanceSymbol : public InstanceSymbolBase, public Sco
const ASTContext& context, SmallVectorBase<const Symbol*>& results,
SmallVectorBase<const Symbol*>& implicitNets, bool isFromBind);

static CheckerInstanceSymbol& fromSyntax(
Compilation& compilation, const ASTContext& context, const CheckerSymbol& checker,
const syntax::HierarchicalInstanceSyntax& syntax,
std::span<const syntax::AttributeInstanceSyntax* const> attributes,
SmallVectorBase<int32_t>& path, bool isProcedural);

void serializeTo(ASTSerializer& serializer) const;

static bool isKind(SymbolKind kind) { return kind == SymbolKind::CheckerInstance; }

private:
ASTContext originalContext;
std::span<Connection> connections;
mutable bool connectionsResolved = false;
};

} // namespace slang::ast
7 changes: 7 additions & 0 deletions source/ast/ElabVisitors.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,13 @@ struct DiagnosticVisitor : public ASTVisitor<DiagnosticVisitor, false, false> {
symbol.getDelay();
}

void handle(const CheckerInstanceSymbol& symbol) {
if (!handleDefault(symbol))
return;

symbol.getPortConnections();
}

void handle(const ClockingBlockSymbol& symbol) {
if (!handleDefault(symbol))
return;
Expand Down
16 changes: 10 additions & 6 deletions source/ast/expressions/MiscExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,10 +577,10 @@ static std::tuple<const SequenceExprSyntax*, const ExpressionSyntax*> decomposeP
return {seqExpr, regExpr};
}

static bool checkAssertionArg(const PropertyExprSyntax& propExpr, const AssertionPortSymbol& formal,
const ASTContext& context,
AssertionInstanceExpression::ActualArg& result,
bool isRecursiveProp) {
bool AssertionInstanceExpression::checkAssertionArg(const PropertyExprSyntax& propExpr,
const AssertionPortSymbol& formal,
const ASTContext& context, ActualArg& result,
bool isRecursiveProp) {
auto [seqExpr, regExpr] = decomposePropExpr(propExpr);

ASTContext ctx = context;
Expand Down Expand Up @@ -667,9 +667,13 @@ static bool checkAssertionArg(const PropertyExprSyntax& propExpr, const Assertio
return false;
}

auto formalParent = formal.getParentScope();
SLANG_ASSERT(formalParent);

// Local var formals that are output or inout must bind only to another local var.
if (formal.direction == ArgumentDirection::InOut ||
formal.direction == ArgumentDirection::Out) {
if ((formal.direction == ArgumentDirection::InOut ||
formal.direction == ArgumentDirection::Out) &&
formalParent->asSymbol().kind != SymbolKind::Checker) {
auto sym = bound.getSymbolReference();
if (!sym || sym->kind != SymbolKind::LocalAssertionVar) {
ctx.addDiag(diag::AssertionOutputLocalVar, bound.sourceRange);
Expand Down
Loading

0 comments on commit aee6bbf

Please sign in to comment.