Merge branch 'steveicarus:master' into fix-issue-1344
This commit is contained in:
commit
612936aa1b
|
|
@ -35,16 +35,19 @@ Makefile
|
|||
/_pli_types.h
|
||||
config.h
|
||||
/tgt-pcb/pcb_config.h
|
||||
/tgt-pcb/fp.cc
|
||||
/tgt-pcb/fp.h
|
||||
/tgt-pcb/fp.output
|
||||
/tgt-pcb/fp_lex.cc
|
||||
/tgt-vvp/vvp_config.h
|
||||
/tgt-vhdl/vhdl_config.h
|
||||
/vhdlpp/vhdlpp_config.h
|
||||
/vpi/vpi_config.h
|
||||
stamp-*-h
|
||||
/version.h
|
||||
/version_tag.h
|
||||
/version_base.h
|
||||
|
||||
/driver-vpi/iverilog-vpi.man
|
||||
/driver-vpi/res.rc
|
||||
/driver/iverilog.man
|
||||
/vvp/libvvp.pc
|
||||
/vvp/vvp.man
|
||||
|
||||
# Directories
|
||||
autom4te.cache
|
||||
|
|
@ -56,8 +59,6 @@ dep
|
|||
*.vpi
|
||||
/cadpli/cadpli.vpl
|
||||
|
||||
/tgt-blif/Makefile
|
||||
|
||||
# lex, yacc and gperf output
|
||||
/driver/cflexor.c
|
||||
/driver/cfparse.c
|
||||
|
|
@ -66,14 +67,6 @@ dep
|
|||
|
||||
/ivlpp/lexor.c
|
||||
|
||||
/vhdlpp/lexor.cc
|
||||
/vhdlpp/lexor_keyword.cc
|
||||
/vhdlpp/parse.cc
|
||||
/vhdlpp/parse.h
|
||||
/vhdlpp/parse.output
|
||||
/vhdlpp/vhdlpp_config.h
|
||||
/vhdlpp/vhdlpp
|
||||
|
||||
/lexor.cc
|
||||
/lexor_keyword.cc
|
||||
/parse.cc
|
||||
|
|
@ -82,6 +75,17 @@ dep
|
|||
/syn-rules.cc
|
||||
/syn-rules.output
|
||||
|
||||
/tgt-pcb/fp.cc
|
||||
/tgt-pcb/fp.h
|
||||
/tgt-pcb/fp.output
|
||||
/tgt-pcb/fp_lex.cc
|
||||
|
||||
/vhdlpp/lexor.cc
|
||||
/vhdlpp/lexor_keyword.cc
|
||||
/vhdlpp/parse.cc
|
||||
/vhdlpp/parse.h
|
||||
/vhdlpp/parse.output
|
||||
|
||||
/vpi/sdf_lexor.c
|
||||
/vpi/sdf_parse.c
|
||||
/vpi/sdf_parse.h
|
||||
|
|
@ -101,17 +105,13 @@ dep
|
|||
# Program created files
|
||||
/vvp/tables.cc
|
||||
|
||||
/iverilog-vpi.man
|
||||
/driver-vpi/res.rc
|
||||
/driver/iverilog.man
|
||||
/vvp/vvp.man
|
||||
|
||||
# The executables.
|
||||
*.exe
|
||||
/driver/iverilog
|
||||
/iverilog-vpi
|
||||
/driver-vpi/iverilog-vpi
|
||||
/ivl
|
||||
/ivlpp/ivlpp
|
||||
/vhdlpp/vhdlpp
|
||||
/vvp/vvp
|
||||
|
||||
/ivl.exp
|
||||
|
|
@ -119,3 +119,4 @@ dep
|
|||
|
||||
# Check output
|
||||
/check.vvp
|
||||
/driver/top.vvp
|
||||
|
|
|
|||
|
|
@ -812,6 +812,10 @@ result is pushed back on the vec4 stack.
|
|||
|
||||
This opcode multiplies two real words together.
|
||||
|
||||
* %neg/wr
|
||||
|
||||
This opcode negates the real value on top of the real stack.
|
||||
|
||||
* %nand
|
||||
|
||||
Perform the bitwise NAND of two vec4 vectors, and push the result. Each
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|||
INSTALL_DATA = @INSTALL_DATA@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
YACC_CONFLICT_FLAGS = -Werror=conflicts-sr -Werror=conflicts-rr
|
||||
MAN = @MAN@
|
||||
PS2PDF = @PS2PDF@
|
||||
GROFF = @GROFF@
|
||||
|
|
@ -241,10 +242,10 @@ parse.o: parse.cc
|
|||
|
||||
# Use pattern rules to avoid parallel build issues (see pr3462585)
|
||||
parse%cc parse%h: $(srcdir)/parse%y
|
||||
$(YACC) --verbose -t -p VL --defines=parse.h -o parse.cc $<
|
||||
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p VL --defines=parse.h -o parse.cc $<
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -t -p syn_ -o $@ $<
|
||||
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p syn_ -o $@ $<
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
$(LEX) -s -t $< > $@
|
||||
|
|
|
|||
41
PExpr.cc
41
PExpr.cc
|
|
@ -108,6 +108,16 @@ PEAssignPattern::~PEAssignPattern()
|
|||
{
|
||||
}
|
||||
|
||||
bool PEAssignPattern::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = false;
|
||||
for (const auto *parm : parms_) {
|
||||
if (parm)
|
||||
flag = parm->has_aa_term(des, scope) || flag;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
|
|
@ -261,26 +271,47 @@ PECallFunction::PECallFunction(perm_string n, const list<named_pexpr_t> &parms)
|
|||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const vector<named_pexpr_t> &parms)
|
||||
: path_(method), parms_(parms), chain_prefix_(chain_prefix), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const list<named_pexpr_t> &parms)
|
||||
: path_(method), parms_(parms.begin(), parms.end()),
|
||||
chain_prefix_(chain_prefix), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::~PECallFunction()
|
||||
{
|
||||
delete chain_prefix_;
|
||||
}
|
||||
|
||||
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
{
|
||||
if (chain_prefix_) {
|
||||
chain_prefix_->declare_implicit_nets(scope, type);
|
||||
}
|
||||
for (const auto &parm : parms_) {
|
||||
if (parm.parm)
|
||||
if (parm.parm) {
|
||||
parm.parm->declare_implicit_nets(scope, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = false;
|
||||
if (chain_prefix_ && chain_prefix_->has_aa_term(des, scope)) {
|
||||
return true;
|
||||
}
|
||||
for (const auto &parm : parms_) {
|
||||
if (parm.parm)
|
||||
flag |= parm.parm->has_aa_term(des, scope);
|
||||
if (parm.parm && parm.parm->has_aa_term(des, scope)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
return false;
|
||||
}
|
||||
|
||||
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
|
||||
|
|
|
|||
69
PExpr.h
69
PExpr.h
|
|
@ -37,6 +37,7 @@ class NetExpr;
|
|||
class NetScope;
|
||||
class PPackage;
|
||||
struct symbol_search_results;
|
||||
class netclass_t;
|
||||
|
||||
/*
|
||||
* The PExpr class hierarchy supports the description of
|
||||
|
|
@ -208,6 +209,8 @@ class PEAssignPattern : public PExpr {
|
|||
|
||||
void dump(std::ostream&) const override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode) override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
|
|
@ -488,18 +491,12 @@ class PEIdent : public PExpr {
|
|||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid) const;
|
||||
NetExpr*elaborate_expr_param_idx_up_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_param_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_param_idx_up_do_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool up, bool need_const) const;
|
||||
NetExpr*elaborate_expr_net(Design*des,
|
||||
NetScope*scope,
|
||||
NetNet*net,
|
||||
|
|
@ -517,16 +514,11 @@ class PEIdent : public PExpr {
|
|||
NetESignal*net,
|
||||
NetScope*found,
|
||||
unsigned expr_wid) const;
|
||||
NetExpr*elaborate_expr_net_idx_up_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_net_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_net_idx_up_do_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool up, bool need_const) const;
|
||||
NetExpr*elaborate_expr_net_bit_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
|
|
@ -928,8 +920,18 @@ class PECallFunction : public PExpr {
|
|||
explicit PECallFunction(const pform_name_t &n, const std::list<named_pexpr_t> &parms);
|
||||
explicit PECallFunction(perm_string n, const std::list<named_pexpr_t> &parms);
|
||||
|
||||
// SystemVerilog: prefix().method(args) — prefix elaborates to a class handle.
|
||||
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const std::vector<named_pexpr_t> &parms);
|
||||
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const std::list<named_pexpr_t> &parms);
|
||||
|
||||
~PECallFunction() override;
|
||||
|
||||
// For chained-call resolution (path is only the final method name).
|
||||
const pform_scoped_name_t& peek_path(void) const { return path_; }
|
||||
const PExpr* peek_chain_prefix(void) const { return chain_prefix_; }
|
||||
|
||||
virtual void dump(std::ostream &) const override;
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
|
||||
|
|
@ -948,6 +950,8 @@ class PECallFunction : public PExpr {
|
|||
private:
|
||||
pform_scoped_name_t path_;
|
||||
std::vector<named_pexpr_t> parms_;
|
||||
// If non-null, this call is prefix().tail_name(...) (SV method chain).
|
||||
PExpr* chain_prefix_ = nullptr;
|
||||
|
||||
// For system functions.
|
||||
bool is_overridden_;
|
||||
|
|
@ -985,7 +989,26 @@ class PECallFunction : public PExpr {
|
|||
unsigned elaborate_arguments_(Design*des, NetScope*scope,
|
||||
const NetFuncDef*def, bool need_const,
|
||||
std::vector<NetExpr*>&parms,
|
||||
unsigned parm_off) const;
|
||||
unsigned parm_off,
|
||||
const std::vector<named_pexpr_t>*src_parms = nullptr) const;
|
||||
|
||||
NetExpr* elaborate_class_method_net_(Design*des, NetScope*scope,
|
||||
NetNet*net, const netclass_t*class_type,
|
||||
perm_string method_name,
|
||||
const std::vector<named_pexpr_t>*src_parms) const;
|
||||
|
||||
NetExpr* elaborate_class_method_net_this_(Design*des, NetScope*scope,
|
||||
NetExpr* this_expr,
|
||||
const netclass_t*class_type,
|
||||
perm_string method_name,
|
||||
const std::vector<named_pexpr_t>*src_parms) const;
|
||||
|
||||
NetExpr* elaborate_expr_method_chained_(Design*des, NetScope*scope,
|
||||
symbol_search_results&search_results) const;
|
||||
|
||||
NetExpr* elaborate_expr_chain_(Design*des, NetScope*scope, unsigned flags) const;
|
||||
|
||||
unsigned test_width_chain_(Design*des, NetScope*scope, width_mode_t&mode);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@
|
|||
# include <list>
|
||||
# include <map>
|
||||
# include <valarray>
|
||||
# include <vector>
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PClass;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
class PProcess;
|
||||
|
|
@ -92,9 +94,11 @@ class PGenerate : public PNamedItem, public LexicalScope {
|
|||
std::list<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
||||
// Tasks instantiated within this scheme.
|
||||
// Definitions instantiated within this scheme.
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*>funcs;
|
||||
std::map<perm_string,PClass*> classes;
|
||||
std::vector<PClass*> classes_lexical;
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
std::list<PGenerate*> generate_schemes;
|
||||
|
|
|
|||
28
Statement.h
28
Statement.h
|
|
@ -40,6 +40,8 @@ class NetCAssign;
|
|||
class NetDeassign;
|
||||
class NetForce;
|
||||
class NetScope;
|
||||
class NetNet;
|
||||
class netdarray_t;
|
||||
|
||||
/*
|
||||
* The PProcess is the root of a behavioral process. Each process gets
|
||||
|
|
@ -261,16 +263,42 @@ class PCallTask : public Statement {
|
|||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names = {}) const;
|
||||
NetProc*elaborate_sys_task_property_method_(Design*des, NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names = {}) const;
|
||||
NetProc*elaborate_queue_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const;
|
||||
NetProc*elaborate_queue_property_method_(Design*des, NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const;
|
||||
NetProc*elaborate_method_func_(NetScope*scope,
|
||||
NetNet*net,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
NetProc*elaborate_method_property_func_(NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
NetProc*elaborate_queue_method_expr_(Design*des, NetScope*scope,
|
||||
NetExpr*queue_base,
|
||||
const netdarray_t*use_darray,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const;
|
||||
NetProc*elaborate_method_func_expr_(NetScope*scope,
|
||||
NetExpr*queue_base,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
bool test_task_calls_ok_(Design*des, const NetScope*scope) const;
|
||||
|
||||
PPackage*package_;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2025 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||
|
||||
timestamp='2025-07-10'
|
||||
timestamp='2026-05-17'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
|
@ -60,7 +60,7 @@ version="\
|
|||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2025 Free Software Foundation, Inc.
|
||||
Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
|
@ -150,7 +150,7 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
|||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case $UNAME_SYSTEM in
|
||||
Linux|GNU|GNU/*)
|
||||
Ironclad|Linux|GNU|GNU/*)
|
||||
LIBC=unknown
|
||||
|
||||
set_cc_for_build
|
||||
|
|
@ -167,6 +167,8 @@ Linux|GNU|GNU/*)
|
|||
LIBC=gnu
|
||||
#elif defined(__LLVM_LIBC__)
|
||||
LIBC=llvm
|
||||
#elif defined(__mlibc__)
|
||||
LIBC=mlibc
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
/* First heuristic to detect musl libc. */
|
||||
|
|
@ -1186,6 +1188,9 @@ EOF
|
|||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
sw_64:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
tile*:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
|
|
@ -1598,10 +1603,10 @@ EOF
|
|||
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
|
||||
;;
|
||||
x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-pc-ironclad-mlibc
|
||||
GUESS=$UNAME_MACHINE-pc-ironclad-$LIBC
|
||||
;;
|
||||
*:[Ii]ronclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-ironclad-mlibc
|
||||
GUESS=$UNAME_MACHINE-unknown-ironclad-$LIBC
|
||||
;;
|
||||
esac
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2025 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale
|
||||
|
||||
timestamp='2025-07-10'
|
||||
timestamp='2026-05-17'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
|
|
@ -76,7 +76,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
|||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2025 Free Software Foundation, Inc.
|
||||
Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
|
@ -1432,6 +1432,7 @@ case $cpu-$vendor in
|
|||
| sparcv9v \
|
||||
| spu \
|
||||
| sv1 \
|
||||
| sw_64 \
|
||||
| sx* \
|
||||
| tahoe \
|
||||
| thumbv7* \
|
||||
|
|
@ -1525,7 +1526,7 @@ EOF
|
|||
;;
|
||||
ironclad*)
|
||||
kernel=ironclad
|
||||
os=`echo "$basic_os" | sed -e 's|ironclad|mlibc|'`
|
||||
os=`echo "$basic_os" | sed -e 's|ironclad|gnu|'`
|
||||
;;
|
||||
linux*)
|
||||
kernel=linux
|
||||
|
|
@ -2220,7 +2221,7 @@ case $kernel-$os-$obj in
|
|||
;;
|
||||
uclinux-uclibc*- | uclinux-gnu*- )
|
||||
;;
|
||||
ironclad-mlibc*-)
|
||||
ironclad-gnu*- | ironclad-mlibc*- )
|
||||
;;
|
||||
managarm-mlibc*- | managarm-kernel*- )
|
||||
;;
|
||||
|
|
|
|||
|
|
@ -1138,7 +1138,7 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
|
|||
if (rval())
|
||||
o << *rval() << ";" << endl;
|
||||
else
|
||||
o << "rval elaboration error>;" << endl;
|
||||
o << "<rval elaboration error>;" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
814
elab_expr.cc
814
elab_expr.cc
File diff suppressed because it is too large
Load Diff
13
elab_lval.cc
13
elab_lval.cc
|
|
@ -298,6 +298,15 @@ NetAssign_*PEIdent::elaborate_lval_var_(Design *des, NetScope *scope,
|
|||
// Past this point, we should have taken care of the cases
|
||||
// where the name is a member/method of a struct/class.
|
||||
// XXXX ivl_assert(*this, method_name.nil());
|
||||
if (!tail_path.empty()) {
|
||||
cerr << get_fileline() << ": error: Variable "
|
||||
<< reg->name()
|
||||
<< " does not have a field named: "
|
||||
<< tail_path << "." << endl;
|
||||
des->errors += 1;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ivl_assert(*this, tail_path.empty());
|
||||
|
||||
bool need_const_idx = is_cassign || is_force;
|
||||
|
|
@ -883,8 +892,10 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
|||
calculate_up_do_width_(des, scope, wid);
|
||||
|
||||
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
if (!base)
|
||||
return false;
|
||||
|
||||
if (base && base->expr_type() == IVL_VT_REAL) {
|
||||
if (base->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: Indexed part select base "
|
||||
"expression for ";
|
||||
cerr << lv->sig()->name() << "[" << *base;
|
||||
|
|
|
|||
|
|
@ -1322,6 +1322,10 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
|||
|
||||
collect_scope_signals(scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
elaborate_scope_classes(des, scope, classes_lexical);
|
||||
|
||||
// Run through the defparams for this scope and save the result
|
||||
// in a table for later final override.
|
||||
|
||||
|
|
@ -1662,6 +1666,8 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
|
|||
|
||||
collect_scope_signals(scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
||||
|
|
@ -1682,6 +1688,8 @@ void PTask::elaborate_scope(Design*des, NetScope*scope) const
|
|||
|
||||
collect_scope_signals(scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
||||
|
|
@ -1732,6 +1740,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
|||
|
||||
collect_scope_signals(my_scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, my_scope, enum_sets);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, my_scope, events);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -404,11 +404,6 @@ void netclass_t::elaborate_sig(Design*des, PClass*pclass)
|
|||
<< " type=" << *use_type << endl;
|
||||
}
|
||||
|
||||
if (dynamic_cast<const netqueue_t *> (use_type)) {
|
||||
cerr << cur->second.get_fileline() << ": sorry: "
|
||||
<< "Queues inside classes are not yet supported." << endl;
|
||||
des->errors++;
|
||||
}
|
||||
set_property(cur->first, cur->second.qual, use_type);
|
||||
|
||||
if (! cur->second.qual.test_static())
|
||||
|
|
@ -607,6 +602,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
|||
|
||||
elaborate_sig_funcs(des, scope, funcs);
|
||||
elaborate_sig_tasks(des, scope, tasks);
|
||||
elaborate_sig_classes(des, scope, classes);
|
||||
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
|
|
|
|||
281
elaborate.cc
281
elaborate.cc
|
|
@ -47,6 +47,7 @@
|
|||
# include "netenum.h"
|
||||
# include "netvector.h"
|
||||
# include "netdarray.h"
|
||||
# include "netqueue.h"
|
||||
# include "netparray.h"
|
||||
# include "netscalar.h"
|
||||
# include "netclass.h"
|
||||
|
|
@ -3250,15 +3251,6 @@ NetProc* PAssignNB::elaborate(Design*des, NetScope*scope) const
|
|||
NetEvWait*event = 0;
|
||||
if (count_ != 0 || event_ != 0) {
|
||||
if (count_ != 0) {
|
||||
if (scope->is_auto() && count_->has_aa_term(des, scope)) {
|
||||
cerr << get_fileline() << ": error: automatically "
|
||||
"allocated variables may not be referenced "
|
||||
"in intra-assignment event controls of "
|
||||
"non-blocking assignments." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_assert(*this, event_ != 0);
|
||||
count = elab_and_eval(des, scope, count_, -1);
|
||||
if (count == 0) {
|
||||
|
|
@ -4073,19 +4065,66 @@ NetProc* PCallTask::elaborate_sys_task_method_(Design*des, NetScope*scope,
|
|||
return sys;
|
||||
}
|
||||
|
||||
/*
|
||||
* This private method is called to elaborate queue push methods. The
|
||||
* sys_task_name is the internal system-task name to use.
|
||||
*/
|
||||
NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const
|
||||
NetProc* PCallTask::elaborate_sys_task_property_method_(Design*des, NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const
|
||||
{
|
||||
NetESignal*sig = new NetESignal(net);
|
||||
sig->set_line(*this);
|
||||
NetEProperty*prop = new NetEProperty(net, property_idx, 0);
|
||||
prop->set_line(*this);
|
||||
|
||||
unsigned nparms = parms_.size();
|
||||
|
||||
vector<NetExpr*>argv (1 + nparms);
|
||||
argv[0] = prop;
|
||||
|
||||
if (method_name == "delete") {
|
||||
const netclass_t*cls = dynamic_cast<const netclass_t*>(net->net_type());
|
||||
ivl_assert(*this, cls);
|
||||
ivl_type_t pt = cls->get_prop_type(property_idx);
|
||||
bool is_queue = pt && pt->base_type() == IVL_VT_QUEUE;
|
||||
if (is_queue) {
|
||||
if (nparms > 1) {
|
||||
cerr << get_fileline() << ": error: queue delete() "
|
||||
<< "method takes zero or one argument." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
} else if (nparms > 0) {
|
||||
cerr << get_fileline() << ": error: darray delete() "
|
||||
<< "method takes no arguments." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
} else if (parm_names.size() != parms_.size()) {
|
||||
cerr << get_fileline() << ": error: " << method_name
|
||||
<< "() method takes " << parm_names.size() << " arguments, got "
|
||||
<< parms_.size() << "." << endl;
|
||||
des->errors++;
|
||||
}
|
||||
|
||||
auto args = map_named_args(des, parm_names, parms_);
|
||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
|
||||
argv[idx + 1] = elab_sys_task_arg(des, scope, method_name,
|
||||
idx, args[idx]);
|
||||
}
|
||||
|
||||
NetSTask*sys = new NetSTask(sys_task_name, IVL_SFUNC_AS_TASK_IGNORE, argv);
|
||||
sys->set_line(*this);
|
||||
return sys;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common implementation for queue push/insert methods. The queue_base
|
||||
* expression is either a NetESignal or NetEProperty; use_darray
|
||||
* supplies the element type.
|
||||
*/
|
||||
NetProc* PCallTask::elaborate_queue_method_expr_(Design*des, NetScope*scope,
|
||||
NetExpr*queue_base,
|
||||
const netdarray_t*use_darray,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const
|
||||
{
|
||||
unsigned nparms = parms_.size();
|
||||
// insert() requires two arguments.
|
||||
if ((method_name == "insert") && (nparms != 2)) {
|
||||
|
|
@ -4099,21 +4138,10 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
|
|||
<< "() method requires a single argument." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// Get the context width if this is a logic type.
|
||||
ivl_variable_type_t base_type = net->darray_type()->element_base_type();
|
||||
int context_width = -1;
|
||||
switch (base_type) {
|
||||
case IVL_VT_BOOL:
|
||||
case IVL_VT_LOGIC:
|
||||
context_width = net->darray_type()->element_width();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vector<NetExpr*>argv (nparms+1);
|
||||
argv[0] = sig;
|
||||
ivl_type_t element_type = use_darray->element_type();
|
||||
unsigned expected_nparms = method_name == "insert" ? 2 : 1;
|
||||
vector<NetExpr*>argv (expected_nparms+1);
|
||||
argv[0] = queue_base;
|
||||
|
||||
auto args = map_named_args(des, parm_names, parms_);
|
||||
if (method_name != "insert") {
|
||||
|
|
@ -4123,8 +4151,8 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
|
|||
<< "() methods first argument is missing." << endl;
|
||||
des->errors += 1;
|
||||
} else {
|
||||
argv[1] = elab_and_eval(des, scope, args[0], context_width,
|
||||
false, false, base_type);
|
||||
argv[1] = elaborate_rval_expr(des, scope, element_type,
|
||||
args[0]);
|
||||
}
|
||||
} else {
|
||||
if (nparms == 0 || !args[0]) {
|
||||
|
|
@ -4133,8 +4161,9 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
|
|||
<< "() methods first argument is missing." << endl;
|
||||
des->errors += 1;
|
||||
} else {
|
||||
argv[1] = elab_and_eval(des, scope, args[0], context_width,
|
||||
false, false, IVL_VT_LOGIC);
|
||||
argv[1] = elaborate_rval_expr(des, scope,
|
||||
netvector_t::integer_type(),
|
||||
args[0]);
|
||||
}
|
||||
|
||||
if (nparms < 2 || !args[1]) {
|
||||
|
|
@ -4143,8 +4172,8 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
|
|||
<< "() methods second argument is missing." << endl;
|
||||
des->errors += 1;
|
||||
} else {
|
||||
argv[2] = elab_and_eval(des, scope, args[1], context_width,
|
||||
false, false, base_type);
|
||||
argv[2] = elaborate_rval_expr(des, scope, element_type,
|
||||
args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4153,14 +4182,55 @@ NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
|
|||
return sys;
|
||||
}
|
||||
|
||||
/*
|
||||
* This private method is called to elaborate queue push methods. The
|
||||
* sys_task_name is the internal system-task name to use.
|
||||
*/
|
||||
NetProc* PCallTask::elaborate_queue_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const
|
||||
{
|
||||
NetESignal*sig = new NetESignal(net);
|
||||
sig->set_line(*this);
|
||||
|
||||
const netdarray_t*use_darray = net->darray_type();
|
||||
ivl_assert(*this, use_darray);
|
||||
|
||||
return elaborate_queue_method_expr_(des, scope, sig, use_darray,
|
||||
method_name, sys_task_name,
|
||||
parm_names);
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_queue_property_method_(Design*des, NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const
|
||||
{
|
||||
const netclass_t*cls = dynamic_cast<const netclass_t*>(net->net_type());
|
||||
ivl_assert(*this, cls);
|
||||
ivl_type_t ptype = cls->get_prop_type(property_idx);
|
||||
const netdarray_t*use_darray = dynamic_cast<const netdarray_t*>(ptype);
|
||||
ivl_assert(*this, use_darray);
|
||||
|
||||
NetEProperty*prop = new NetEProperty(net, property_idx, 0);
|
||||
prop->set_line(*this);
|
||||
|
||||
return elaborate_queue_method_expr_(des, scope, prop, use_darray,
|
||||
method_name, sys_task_name,
|
||||
parm_names);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used for array/queue function methods called as tasks.
|
||||
*/
|
||||
NetProc* PCallTask::elaborate_method_func_(NetScope*scope,
|
||||
NetNet*net,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const
|
||||
NetProc* PCallTask::elaborate_method_func_expr_(NetScope*scope,
|
||||
NetExpr*queue_base,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const
|
||||
{
|
||||
if (!void_cast_) {
|
||||
cerr << get_fileline() << ": warning: method function '"
|
||||
|
|
@ -4170,9 +4240,7 @@ NetProc* PCallTask::elaborate_method_func_(NetScope*scope,
|
|||
// Generate the function.
|
||||
NetESFunc*sys_expr = new NetESFunc(sys_task_name, type, 1);
|
||||
sys_expr->set_line(*this);
|
||||
NetESignal*arg = new NetESignal(net);
|
||||
arg->set_line(*net);
|
||||
sys_expr->parm(0, arg);
|
||||
sys_expr->parm(0, queue_base);
|
||||
// Create a L-value that matches the function return type.
|
||||
NetNet*tmp;
|
||||
tmp = new NetNet(scope, scope->local_symbol(), NetNet::REG, type);
|
||||
|
|
@ -4184,6 +4252,30 @@ NetProc* PCallTask::elaborate_method_func_(NetScope*scope,
|
|||
return cur;
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_method_func_(NetScope*scope,
|
||||
NetNet*net,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const
|
||||
{
|
||||
NetESignal*arg = new NetESignal(net);
|
||||
arg->set_line(*this);
|
||||
return elaborate_method_func_expr_(scope, arg, type,
|
||||
method_name, sys_task_name);
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_method_property_func_(NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const
|
||||
{
|
||||
NetEProperty*prop = new NetEProperty(net, property_idx, 0);
|
||||
prop->set_line(*this);
|
||||
return elaborate_method_func_expr_(scope, prop, type,
|
||||
method_name, sys_task_name);
|
||||
}
|
||||
|
||||
NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag) const
|
||||
{
|
||||
|
|
@ -4232,13 +4324,93 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
<< net->name() << ".data_type() --> " << net->data_type() << endl;
|
||||
}
|
||||
|
||||
// Class handle with one path_tail component: queue/darray property method
|
||||
// e.g. c.q.push_back(x) => sr.path_tail = {q}, method_name = push_back
|
||||
if (sr.path_tail.size() == 1) {
|
||||
const netclass_t*cls = dynamic_cast<const netclass_t*>(sr.type);
|
||||
if (!cls && net->net_type()) {
|
||||
cls = dynamic_cast<const netclass_t*>(net->net_type());
|
||||
}
|
||||
if (cls) {
|
||||
perm_string prop_name = sr.path_tail.front().name;
|
||||
int pidx = cls->property_idx_from_name(prop_name);
|
||||
if (pidx >= 0) {
|
||||
ivl_type_t ptype = cls->get_prop_type(pidx);
|
||||
if (ptype && dynamic_cast<const netqueue_t*>(ptype)) {
|
||||
const netdarray_t*use_darray = dynamic_cast<const netdarray_t*>(ptype);
|
||||
ivl_assert(*this, use_darray);
|
||||
|
||||
if (method_name == "push_back") {
|
||||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("item")
|
||||
};
|
||||
return elaborate_queue_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_queue_method$push_back",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "push_front") {
|
||||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("item")
|
||||
};
|
||||
return elaborate_queue_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_queue_method$push_front",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "insert") {
|
||||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("index"),
|
||||
perm_string::literal("item")
|
||||
};
|
||||
return elaborate_queue_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_queue_method$insert",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "pop_front") {
|
||||
return elaborate_method_property_func_(scope, net, pidx,
|
||||
use_darray->element_type(),
|
||||
method_name,
|
||||
"$ivl_queue_method$pop_front");
|
||||
}
|
||||
if (method_name == "pop_back") {
|
||||
return elaborate_method_property_func_(scope, net, pidx,
|
||||
use_darray->element_type(),
|
||||
method_name,
|
||||
"$ivl_queue_method$pop_back");
|
||||
}
|
||||
if (method_name == "size") {
|
||||
return elaborate_method_property_func_(scope, net, pidx,
|
||||
&netvector_t::atom2s32,
|
||||
method_name, "$size");
|
||||
}
|
||||
} else if (ptype && ptype->base_type() == IVL_VT_DARRAY) {
|
||||
if (method_name == "delete") {
|
||||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("index")
|
||||
};
|
||||
return elaborate_sys_task_property_method_(des, scope, net, pidx,
|
||||
method_name,
|
||||
"$ivl_darray_method$delete",
|
||||
parm_names);
|
||||
}
|
||||
if (method_name == "size") {
|
||||
return elaborate_method_property_func_(scope, net, pidx,
|
||||
&netvector_t::atom2s32,
|
||||
method_name, "$size");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Is this a method of a "string" type?
|
||||
if (dynamic_cast<const netstring_t*>(net->net_type())) {
|
||||
if (method_name == "itoa") {
|
||||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("i")
|
||||
};
|
||||
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_string_method$itoa",
|
||||
parm_names);
|
||||
|
|
@ -4246,7 +4418,6 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("i")
|
||||
};
|
||||
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_string_method$hextoa",
|
||||
parm_names);
|
||||
|
|
@ -4254,7 +4425,6 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("i")
|
||||
};
|
||||
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_string_method$octtoa",
|
||||
parm_names);
|
||||
|
|
@ -4262,7 +4432,6 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("i")
|
||||
};
|
||||
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_string_method$bintoa",
|
||||
parm_names);
|
||||
|
|
@ -4270,7 +4439,6 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("r")
|
||||
};
|
||||
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_string_method$realtoa",
|
||||
parm_names);
|
||||
|
|
@ -4283,7 +4451,6 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("index")
|
||||
};
|
||||
|
||||
return elaborate_sys_task_method_(des, scope, net, method_name,
|
||||
"$ivl_darray_method$delete",
|
||||
parm_names);
|
||||
|
|
@ -4320,7 +4487,6 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
}
|
||||
|
||||
if (net->queue_type()) {
|
||||
const netdarray_t*use_darray = net->darray_type();
|
||||
if (method_name == "push_back") {
|
||||
static const std::vector<perm_string> parm_names = {
|
||||
perm_string::literal("item")
|
||||
|
|
@ -4347,11 +4513,13 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope,
|
|||
"$ivl_queue_method$insert",
|
||||
parm_names);
|
||||
} else if (method_name == "pop_front") {
|
||||
const netdarray_t*use_darray = net->darray_type();
|
||||
return elaborate_method_func_(scope, net,
|
||||
use_darray->element_type(),
|
||||
method_name,
|
||||
"$ivl_queue_method$pop_front");
|
||||
} else if (method_name == "pop_back") {
|
||||
const netdarray_t*use_darray = net->darray_type();
|
||||
return elaborate_method_func_(scope, net,
|
||||
use_darray->element_type(),
|
||||
method_name,
|
||||
|
|
@ -7237,6 +7405,7 @@ bool PGenerate::elaborate_(Design*des, NetScope*scope) const
|
|||
if (result_flag) {
|
||||
elaborate_functions(des, scope, funcs);
|
||||
elaborate_tasks(des, scope, tasks);
|
||||
elaborate_classes(des, scope, classes);
|
||||
|
||||
for (const auto gt : gates) gt->elaborate(des, scope);
|
||||
|
||||
|
|
|
|||
20
eval_tree.cc
20
eval_tree.cc
|
|
@ -26,6 +26,7 @@
|
|||
# include <cmath>
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "ivl_assert.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
|
|
@ -2182,6 +2183,25 @@ static bool get_array_info(const NetExpr*arg, long dim,
|
|||
left = range.get_msb();
|
||||
right = range.get_lsb();
|
||||
return false;
|
||||
}
|
||||
/* Class property (e.g. queue field): size is dynamic; defer to runtime
|
||||
* instead of folding to all-X in evaluate_array_funcs_. */
|
||||
if (const NetEProperty*prop = dynamic_cast<const NetEProperty*>(arg)) {
|
||||
const NetNet*obj = prop->get_sig();
|
||||
const netclass_t*cls = dynamic_cast<const netclass_t*>(obj->net_type());
|
||||
if (cls == 0) return true;
|
||||
ivl_type_t ptype = cls->get_prop_type(prop->property_idx());
|
||||
if (ptype == 0) return true;
|
||||
switch (ptype->base_type()) {
|
||||
case IVL_VT_DARRAY:
|
||||
case IVL_VT_QUEUE:
|
||||
case IVL_VT_STRING:
|
||||
defer = true;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* The argument must be a signal that has enough dimensions. */
|
||||
const NetESignal*esig = dynamic_cast<const NetESignal*>(arg);
|
||||
|
|
|
|||
1
ivl.def
1
ivl.def
|
|
@ -337,6 +337,7 @@ ivl_type_packed_width
|
|||
ivl_type_prop_name
|
||||
ivl_type_prop_type
|
||||
ivl_type_properties
|
||||
ivl_type_queue_max
|
||||
ivl_type_signed
|
||||
|
||||
ivl_udp_init
|
||||
|
|
|
|||
|
|
@ -2400,6 +2400,10 @@ extern int ivl_type_properties(ivl_type_t net);
|
|||
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
||||
extern ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx);
|
||||
|
||||
/* Maximum element count for a queue type (0 = unbounded). Only valid
|
||||
* when ivl_type_base(net) == IVL_VT_QUEUE. */
|
||||
extern unsigned ivl_type_queue_max(ivl_type_t net);
|
||||
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN__)
|
||||
# define DLLEXPORT __declspec(dllexport)
|
||||
|
|
|
|||
|
|
@ -2368,6 +2368,8 @@ void reset_lexor(FILE* out, char* paths[])
|
|||
isp->stringify_flag = 0;
|
||||
isp->comment = NULL;
|
||||
|
||||
yyout = out;
|
||||
|
||||
if (isp->file == 0) {
|
||||
perror(paths[0]);
|
||||
error_count += 1;
|
||||
|
|
@ -2382,8 +2384,6 @@ void reset_lexor(FILE* out, char* paths[])
|
|||
}
|
||||
}
|
||||
|
||||
yyout = out;
|
||||
|
||||
yyrestart(isp->file);
|
||||
|
||||
assert(istack == 0);
|
||||
|
|
|
|||
|
|
@ -1,18 +1,5 @@
|
|||
./ivltests/br1005.v:2: sorry: Queues inside classes are not yet supported.
|
||||
./ivltests/br1005.v:15: error: Enable of unknown task ``a.q.push_back''.
|
||||
./ivltests/br1005.v:16: error: Enable of unknown task ``a.q.push_back''.
|
||||
./ivltests/br1005.v:17: error: Enable of unknown task ``a.q.push_back''.
|
||||
./ivltests/br1005.v:18: error: Enable of unknown task ``a.q.push_back''.
|
||||
./ivltests/br1005.v:19: sorry: Method name nesting is not supported yet.
|
||||
./ivltests/br1005.v:19: : method path: q.pop_front
|
||||
./ivltests/br1005.v:19: error: Object test.a has no method "q.pop_front(...)".
|
||||
./ivltests/br1005.v:22: sorry: Method name nesting is not supported yet.
|
||||
./ivltests/br1005.v:22: : method path: q.pop_front
|
||||
./ivltests/br1005.v:22: error: Object test.a has no method "q.pop_front(...)".
|
||||
./ivltests/br1005.v:25: sorry: Method name nesting is not supported yet.
|
||||
./ivltests/br1005.v:25: : method path: q.pop_front
|
||||
./ivltests/br1005.v:25: error: Object test.a has no method "q.pop_front(...)".
|
||||
./ivltests/br1005.v:28: sorry: Method name nesting is not supported yet.
|
||||
./ivltests/br1005.v:28: : method path: q.pop_front
|
||||
./ivltests/br1005.v:28: error: Object test.a has no method "q.pop_front(...)".
|
||||
9 error(s) during elaboration.
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
PASSED
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
./ivltests/br_gh1175c.v:3: syntax error
|
||||
./ivltests/br_gh1175c.v:3: errors in UDP table
|
||||
./ivltests/br_gh1175c.v:1: error: Invalid table for UDP primitive id_0.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
./ivltests/br_gh1175d.v:3: syntax error
|
||||
./ivltests/br_gh1175d.v:3: errors in UDP table
|
||||
./ivltests/br_gh1175d.v:1: error: Invalid table for UDP primitive id_0.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
./ivltests/br_gh1175e.v:3: syntax error
|
||||
./ivltests/br_gh1175e.v:3: errors in UDP table
|
||||
./ivltests/br_gh1175e.v:1: error: Invalid table for UDP primitive id_0.
|
||||
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@
|
|||
./ivltests/br_gh72b_fail.v:8: error: too few arguments for `macro2
|
||||
./ivltests/br_gh72b_fail.v:9: error: too few arguments for `macro2
|
||||
./ivltests/br_gh72b_fail.v:10: error: too many arguments for `macro2
|
||||
Preprocessor failed with 5 errors.
|
||||
Preprocessor failed with 5 error(s).
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ivltests/udp_empty_table_fail.v:7: error: Empty UDP table.
|
||||
ivltests/udp_empty_table_fail.v:3: error: Invalid table for UDP primitive udp_empty_table_fail.
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// Check that classes declared inside generate blocks can be used.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
if (1) begin : g
|
||||
class C;
|
||||
int value;
|
||||
|
||||
function new(int value);
|
||||
this.value = value;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
C c = new(42);
|
||||
end
|
||||
|
||||
for (genvar i = 0; i < 2; i = i + 1) begin : h
|
||||
class C;
|
||||
int value;
|
||||
|
||||
function new(int value);
|
||||
this.value = value + i;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
C c = new(10);
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check(g.c.value, 42);
|
||||
`check(h[0].c.value, 10);
|
||||
`check(h[1].c.value, 11);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Check that enum literals declared inside generate blocks are available in
|
||||
// the generated scope.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(val, exp) do begin \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
end while (0)
|
||||
|
||||
if (1) begin : g
|
||||
typedef enum logic [3:0] {
|
||||
A = 4'd1,
|
||||
B = 4'd2
|
||||
} EN_T;
|
||||
|
||||
EN_T e = A;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
#1;
|
||||
`check(e, A);
|
||||
|
||||
e = B;
|
||||
`check(e, B);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Check that enum literals declared inside named blocks are available in
|
||||
// the block scope.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(val, exp) do begin \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
end while (0)
|
||||
|
||||
initial begin : b
|
||||
typedef enum logic [3:0] {
|
||||
A = 4'd1,
|
||||
B = 4'd2
|
||||
} EN_T;
|
||||
|
||||
static EN_T e = A;
|
||||
|
||||
failed = 1'b0;
|
||||
|
||||
#1;
|
||||
`check(e, A);
|
||||
|
||||
e = B;
|
||||
`check(e, B);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Check that enum literals declared inside tasks are available in the task
|
||||
// scope.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(val, exp) do begin \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
end while (0)
|
||||
|
||||
task check_task_enum;
|
||||
typedef enum logic [3:0] {
|
||||
A = 4'd1,
|
||||
B = 4'd2
|
||||
} EN_T;
|
||||
|
||||
static EN_T e = A;
|
||||
|
||||
`check(e, A);
|
||||
|
||||
e = B;
|
||||
`check(e, B);
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
#1;
|
||||
check_task_enum();
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Check that enum literals declared inside functions are available in the
|
||||
// function scope.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(val, exp) do begin \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
end while (0)
|
||||
|
||||
function logic [3:0] check_func_enum;
|
||||
typedef enum logic [3:0] {
|
||||
A = 4'd1,
|
||||
B = 4'd2
|
||||
} EN_T;
|
||||
|
||||
static EN_T e = A;
|
||||
|
||||
e = B;
|
||||
check_func_enum = e;
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
#1;
|
||||
`check(check_func_enum(), 4'd2);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Regression test for GitHub issue #670.
|
||||
// Check that a class function can have the same name as the class.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
class test;
|
||||
int value;
|
||||
|
||||
function void test();
|
||||
value = 32'd42;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
initial begin
|
||||
test tst;
|
||||
|
||||
failed = 1'b0;
|
||||
tst = new;
|
||||
tst.test();
|
||||
|
||||
`check(tst.value, 32'd42, "Class function name did not hide class name");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// Check that case statement muxes work with array word inputs.
|
||||
|
||||
module test;
|
||||
|
||||
reg [7:0] mem [0:3];
|
||||
reg [1:0] sel;
|
||||
reg [7:0] out;
|
||||
reg failed;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
always @* begin
|
||||
case (sel)
|
||||
2'd0: out = mem[0];
|
||||
2'd1: out = mem[1];
|
||||
2'd2: out = mem[2];
|
||||
2'd3: out = mem[3];
|
||||
endcase
|
||||
end
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
mem[0] = 8'h12;
|
||||
mem[1] = 8'h34;
|
||||
mem[2] = 8'h56;
|
||||
mem[3] = 8'h78;
|
||||
|
||||
sel = 2'd0;
|
||||
#1 `check(out, 8'h12);
|
||||
|
||||
sel = 2'd1;
|
||||
#1 `check(out, 8'h34);
|
||||
|
||||
sel = 2'd2;
|
||||
#1 `check(out, 8'h56);
|
||||
|
||||
sel = 2'd3;
|
||||
#1 `check(out, 8'h78);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// Check that final context is preserved when elaborating nested blocks.
|
||||
|
||||
module test;
|
||||
|
||||
task t;
|
||||
endtask
|
||||
|
||||
final begin : nested
|
||||
t;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Check that function context is preserved when elaborating nested blocks.
|
||||
|
||||
module test;
|
||||
|
||||
reg x;
|
||||
integer y;
|
||||
|
||||
function integer f;
|
||||
input a;
|
||||
begin : nested
|
||||
x <= a;
|
||||
f = 0;
|
||||
end
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
y = f(1'b1);
|
||||
$display("FAILED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// Check that non-blocking event control repeat counts can use automatic terms.
|
||||
|
||||
module test;
|
||||
|
||||
reg clk;
|
||||
reg failed;
|
||||
reg [3:0] result;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
task automatic schedule_update;
|
||||
input integer count;
|
||||
begin
|
||||
result <= repeat(count) @(posedge clk) 4'ha;
|
||||
end
|
||||
endtask
|
||||
|
||||
always #5 clk = ~clk;
|
||||
|
||||
initial begin
|
||||
clk = 1'b0;
|
||||
failed = 1'b0;
|
||||
result = 4'h0;
|
||||
|
||||
schedule_update(2);
|
||||
|
||||
@(posedge clk);
|
||||
#1;
|
||||
`check(result, 4'h0);
|
||||
|
||||
@(posedge clk);
|
||||
#1;
|
||||
`check(result, 4'ha);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Regression test: comparing a `string` parameter to a string constant of
|
||||
// a different length must constant-fold cleanly instead of tripping the
|
||||
// "lv.len() == rv.len()" assertion in the NetEBComp evaluation functions.
|
||||
// Covers ==, !=, ===, !==, ==? and !=? with the string operand on either
|
||||
// side and both shorter and longer than the other operand.
|
||||
|
||||
module main #(parameter string Target = "A",
|
||||
parameter string Long = "ABC");
|
||||
|
||||
integer errors = 0;
|
||||
|
||||
// Equality / inequality, parameter shorter than the literal.
|
||||
if (Target == "AA") initial begin errors += 1; $display("FAILED: Target == \"AA\""); end
|
||||
if (Target != "A") initial begin errors += 1; $display("FAILED: Target != \"A\""); end
|
||||
|
||||
// Literal on the left.
|
||||
if ("AA" == Target) initial begin errors += 1; $display("FAILED: \"AA\" == Target"); end
|
||||
|
||||
// Parameter longer than the literal.
|
||||
if (Long == "AB") initial begin errors += 1; $display("FAILED: Long == \"AB\""); end
|
||||
if (Long != "ABC") initial begin errors += 1; $display("FAILED: Long != \"ABC\""); end
|
||||
|
||||
// Two string parameters of different lengths.
|
||||
if (Target == Long) initial begin errors += 1; $display("FAILED: Target == Long"); end
|
||||
|
||||
// Case equality.
|
||||
if (Target === "AA") initial begin errors += 1; $display("FAILED: Target === \"AA\""); end
|
||||
if (Target !== "A") initial begin errors += 1; $display("FAILED: Target !== \"A\""); end
|
||||
|
||||
// Wildcard equality.
|
||||
if (Target ==? "AA") initial begin errors += 1; $display("FAILED: Target ==? \"AA\""); end
|
||||
if (Target !=? "A") initial begin errors += 1; $display("FAILED: Target !=? \"A\""); end
|
||||
|
||||
initial #1 if (errors == 0) $display("PASSED");
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// Check that blocking intra-assignment delays can assign real values.
|
||||
|
||||
module test;
|
||||
real r;
|
||||
reg failed;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
r = #1 1.25;
|
||||
if (r != 1.25) begin
|
||||
$display("FAILED(%0d). Expected 1.25, got %0.2f", `__LINE__, r);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Check that the vvp code generator preserves the sign of a negative zero
|
||||
// real constant. The sign used to be detected with (value < 0), which is
|
||||
// false for IEEE 754 -0.0, so a -0.0 constant was emitted as +0.0 and the
|
||||
// compiled value no longer matched the runtime real value.
|
||||
|
||||
module test;
|
||||
|
||||
real nz;
|
||||
real pz;
|
||||
|
||||
initial begin
|
||||
nz = -0.0;
|
||||
pz = 0.0;
|
||||
|
||||
// The sign bit is the only thing that tells -0.0 from +0.0.
|
||||
if ($realtobits(nz) !== 64'h8000_0000_0000_0000) begin
|
||||
$display("FAILED: -0.0 stored as %h", $realtobits(nz));
|
||||
$finish;
|
||||
end
|
||||
|
||||
if ($realtobits(pz) !== 64'h0000_0000_0000_0000) begin
|
||||
$display("FAILED: 0.0 stored as %h", $realtobits(pz));
|
||||
$finish;
|
||||
end
|
||||
|
||||
// The reciprocal makes the sign observable: 1.0/-0.0 is -inf.
|
||||
if (1.0 / nz >= 0.0) begin
|
||||
$display("FAILED: 1.0/-0.0 = %g", 1.0 / nz);
|
||||
$finish;
|
||||
end
|
||||
|
||||
$display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that unary real minus preserves infinities.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
real inf;
|
||||
real result;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %h, got %h", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
inf = $bitstoreal(64'h7ff0000000000000);
|
||||
|
||||
result = -inf;
|
||||
`check($realtobits(result), 64'hfff0000000000000);
|
||||
|
||||
result = -result;
|
||||
`check($realtobits(result), 64'h7ff0000000000000);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that unary real minus preserves NaN bits.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
real nan;
|
||||
real result;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %h, got %h", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
nan = $bitstoreal(64'h7ff8000000000001);
|
||||
|
||||
result = -nan;
|
||||
`check($realtobits(result), 64'hfff8000000000001);
|
||||
|
||||
result = -result;
|
||||
`check($realtobits(result), 64'h7ff8000000000001);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that unary real minus preserves the sign of zero.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
real zero;
|
||||
real result;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %h, got %h", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
zero = 0.0;
|
||||
|
||||
result = -zero;
|
||||
`check($realtobits(result), 64'h8000000000000000);
|
||||
|
||||
result = -result;
|
||||
`check($realtobits(result), 64'h0000000000000000);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Check that assignment patterns cannot reference automatic variables in
|
||||
// procedural force statements.
|
||||
|
||||
module test;
|
||||
|
||||
reg [3:0] result;
|
||||
|
||||
task automatic t;
|
||||
input [3:0] value;
|
||||
begin
|
||||
force result = '{value[3], value[2], value[1], value[0]};
|
||||
end
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
t(4'ha);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that bogus member access on procedural l-values reports an error.
|
||||
|
||||
module test;
|
||||
logic r;
|
||||
|
||||
initial begin
|
||||
r.bad = 1'b1;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Chained call: function returns class handle, then method on result (a().b()).
|
||||
|
||||
module test;
|
||||
|
||||
class C;
|
||||
function int f;
|
||||
f = 7;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
function C get_c;
|
||||
get_c = new;
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
int x;
|
||||
x = get_c().f();
|
||||
if (x !== 7) begin
|
||||
$display("FAILED");
|
||||
end else begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// Check that a class property can have the same name as the class.
|
||||
|
||||
module test;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(val, exp) do \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
while(0)
|
||||
|
||||
class C;
|
||||
int C;
|
||||
|
||||
function int get;
|
||||
return C;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
C obj;
|
||||
|
||||
initial begin
|
||||
obj = new;
|
||||
|
||||
obj.C = 23;
|
||||
|
||||
`check(obj.get(), 23);
|
||||
`check(obj.C, 23);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Check that multi-dimensional packed vector class properties are supported.
|
||||
|
||||
module test;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(val, exp) do begin \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0h, got %0h", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
end while (0)
|
||||
|
||||
class C;
|
||||
logic [1:0][3:0] x;
|
||||
bit [0:1][0:3] y;
|
||||
endclass
|
||||
|
||||
C c;
|
||||
|
||||
initial begin
|
||||
c = new;
|
||||
|
||||
c.x = 8'h5a;
|
||||
c.y = 8'hc3;
|
||||
`check(c.x, 8'h5a);
|
||||
`check(c.y, 8'hc3);
|
||||
|
||||
c.x += 8'h01;
|
||||
c.y ^= 8'hff;
|
||||
`check(c.x, 8'h5b);
|
||||
`check(c.y, 8'h3c);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Check that a class property can have the same name as an outer type.
|
||||
|
||||
module test;
|
||||
|
||||
typedef int T;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(val, exp) do \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
while(0)
|
||||
|
||||
class C;
|
||||
int T;
|
||||
|
||||
function int get;
|
||||
return T;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
C obj;
|
||||
|
||||
initial begin
|
||||
obj = new;
|
||||
|
||||
obj.T = 11;
|
||||
|
||||
`check(obj.get(), 11);
|
||||
`check(obj.T, 11);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Check that a class property can shadow a wildcard-imported type name.
|
||||
|
||||
package P;
|
||||
|
||||
typedef int T;
|
||||
|
||||
endpackage
|
||||
|
||||
module test;
|
||||
|
||||
import P::*;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(val, exp) do \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, `"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
while(0)
|
||||
|
||||
class C;
|
||||
int T;
|
||||
|
||||
function int get;
|
||||
return T;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
C obj;
|
||||
|
||||
initial begin
|
||||
obj = new;
|
||||
|
||||
obj.T = 47;
|
||||
|
||||
`check(obj.get(), 47);
|
||||
`check(obj.T, 47);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
// Regression: queue-typed class properties — push_front/push_back and
|
||||
// pop_front/pop_back. (VVP asm must recognize %store/prop/qf/* and
|
||||
// %qpop/prop/*; opcode_table must stay lexicographically sorted.)
|
||||
|
||||
module test;
|
||||
|
||||
bit failed = 1'b0;
|
||||
|
||||
`define check(val, exp) do \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). expected %0d, got %0d", `__LINE__, exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
while(0)
|
||||
|
||||
class C;
|
||||
int q[$];
|
||||
endclass
|
||||
|
||||
C c;
|
||||
int t;
|
||||
|
||||
initial begin
|
||||
c = new;
|
||||
c.q.push_back(1);
|
||||
c.q.push_front(0);
|
||||
c.q.push_back(2);
|
||||
t = c.q.pop_back();
|
||||
`check(t, 32'd2);
|
||||
`check(c.q.size(), 32'd2);
|
||||
t = c.q.pop_front();
|
||||
`check(t, 32'd0);
|
||||
`check(c.q[0], 32'd1);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Check that using a class task as an expression reports an error.
|
||||
|
||||
module test;
|
||||
|
||||
class C;
|
||||
task t;
|
||||
endtask
|
||||
endclass
|
||||
|
||||
C c;
|
||||
|
||||
initial begin
|
||||
int x;
|
||||
c = new;
|
||||
x = c.t();
|
||||
$display("FAILED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that invalid indexed part-select l-value bases report an error.
|
||||
|
||||
module test;
|
||||
reg [31:0] a;
|
||||
|
||||
initial begin
|
||||
a[does_not_exist -: 2] = 2'b00;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Check variable selects of packed arrays with negative bounds.
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
reg [-8:-1][3:0] a;
|
||||
reg signed [2:0] i;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %b, got %b", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
a = '0;
|
||||
|
||||
i = -1;
|
||||
a[i] = 4'ha;
|
||||
i = -2;
|
||||
a[i] = 4'h5;
|
||||
|
||||
`check(a[-1], 4'ha);
|
||||
`check(a[-2], 4'h5);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Check that assignment patterns are supported for queue method arguments.
|
||||
|
||||
module test;
|
||||
|
||||
bit failed;
|
||||
bit [1:0][3:0] q[$];
|
||||
|
||||
`define check(val, exp) do begin \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0h, got %0h", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end \
|
||||
end while (0)
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
q.push_back('{4'h1, 4'h2});
|
||||
q.push_front('{4'h3, 4'h4});
|
||||
q.insert(1, '{4'h5, 4'h6});
|
||||
|
||||
`check(q.size(), 3);
|
||||
`check(q[0], 8'h34);
|
||||
`check(q[1], 8'h56);
|
||||
`check(q[2], 8'h12);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that queue insert() rejects too few arguments.
|
||||
|
||||
module test;
|
||||
int q[$];
|
||||
|
||||
initial begin
|
||||
q.insert(0);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that queue insert() rejects too many arguments.
|
||||
|
||||
module test;
|
||||
int q[$];
|
||||
|
||||
initial begin
|
||||
q.insert(0, 1, 2);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that queue push_back() rejects too few arguments.
|
||||
|
||||
module test;
|
||||
int q[$];
|
||||
|
||||
initial begin
|
||||
q.push_back();
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that queue push_back() rejects too many arguments.
|
||||
|
||||
module test;
|
||||
int q[$];
|
||||
|
||||
initial begin
|
||||
q.push_back(1, 2);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that queue push_front() rejects too few arguments.
|
||||
|
||||
module test;
|
||||
int q[$];
|
||||
|
||||
initial begin
|
||||
q.push_front();
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
// Check that queue push_front() rejects too many arguments.
|
||||
|
||||
module test;
|
||||
int q[$];
|
||||
|
||||
initial begin
|
||||
q.push_front(1, 2);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// Check that string substr() rejects too few arguments.
|
||||
|
||||
module test;
|
||||
string s;
|
||||
string t;
|
||||
|
||||
initial begin
|
||||
t = s.substr(0);
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// Check that nature name fields can shadow visible type identifiers.
|
||||
|
||||
typedef int ACCESS_NAME;
|
||||
typedef int IDT_NAME;
|
||||
typedef int DDT_NAME;
|
||||
|
||||
nature type_id_nature;
|
||||
units = "V";
|
||||
access = ACCESS_NAME;
|
||||
idt_nature = IDT_NAME;
|
||||
ddt_nature = DDT_NAME;
|
||||
endnature
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// Check that attribute names can match visible type identifiers.
|
||||
|
||||
typedef int ATTR;
|
||||
|
||||
(* ATTR = 1 *)
|
||||
module test;
|
||||
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Check that $attribute targets can match visible type identifiers.
|
||||
|
||||
primitive ATTR_TYPE (out, in);
|
||||
output out;
|
||||
input in;
|
||||
|
||||
table
|
||||
0 : 0;
|
||||
1 : 1;
|
||||
endtable
|
||||
endprimitive
|
||||
|
||||
typedef int ATTR_TYPE;
|
||||
|
||||
$attribute(ATTR_TYPE, "test", "true")
|
||||
|
||||
module test;
|
||||
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Check that block labels can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
reg value;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
value = 0;
|
||||
|
||||
begin : T
|
||||
value = value + 1;
|
||||
end : T
|
||||
|
||||
if (value !== 1) begin
|
||||
$display("FAILED(%0d). block labels did not hide typedefs", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// Check that a config name can shadow a visible type identifier.
|
||||
|
||||
typedef int CFG_NAME;
|
||||
|
||||
config CFG_NAME;
|
||||
design test;
|
||||
endconfig
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Check that discipline names can match visible type identifiers.
|
||||
|
||||
nature potential_nature;
|
||||
units = "V";
|
||||
access = POTENTIAL_ACCESS;
|
||||
endnature
|
||||
|
||||
nature flow_nature;
|
||||
units = "A";
|
||||
access = FLOW_ACCESS;
|
||||
endnature
|
||||
|
||||
typedef int DISCIPLINE_NAME;
|
||||
|
||||
discipline DISCIPLINE_NAME;
|
||||
potential potential_nature;
|
||||
flow flow_nature;
|
||||
domain continuous;
|
||||
enddiscipline
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// Check that discipline nature references can match visible type identifiers.
|
||||
|
||||
nature potential_nature;
|
||||
units = "V";
|
||||
access = POTENTIAL_ACCESS;
|
||||
endnature
|
||||
|
||||
nature flow_nature;
|
||||
units = "A";
|
||||
access = FLOW_ACCESS;
|
||||
endnature
|
||||
|
||||
typedef int potential_nature;
|
||||
typedef int flow_nature;
|
||||
|
||||
discipline electrical;
|
||||
potential potential_nature;
|
||||
flow flow_nature;
|
||||
domain continuous;
|
||||
enddiscipline
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Check that enum item names can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
typedef int U;
|
||||
typedef int V;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
enum {
|
||||
T = 3,
|
||||
U[2] = 5,
|
||||
V[3:4] = 9
|
||||
} e;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
e = T;
|
||||
|
||||
`check(e, 3, "Enum item name did not hide typedef");
|
||||
`check(U0, 5, "Enum item sequence name did not hide typedef");
|
||||
`check(U1, 6, "Enum item sequence value mismatch");
|
||||
`check(V3, 9, "Enum item range name did not hide typedef");
|
||||
`check(V4, 10, "Enum item range value mismatch");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that event names can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
reg seen;
|
||||
|
||||
event T;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
seen = 1'b0;
|
||||
|
||||
#1 -> T;
|
||||
#1;
|
||||
|
||||
if (seen !== 1'b1) begin
|
||||
$display("FAILED(%0d). Event T was not triggered", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
always @T seen = 1'b1;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Check that for loop variables can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
int unsigned values [3];
|
||||
|
||||
initial begin
|
||||
int unsigned total;
|
||||
|
||||
failed = 1'b0;
|
||||
total = 0;
|
||||
|
||||
for (int unsigned T = 0; T < 3; T += 1) begin
|
||||
total += T;
|
||||
values[T] = 10 + T;
|
||||
end
|
||||
|
||||
if (total != 3 || values[0] != 10 ||
|
||||
values[1] != 11 || values[2] != 12) begin
|
||||
$display("FAILED(%0d). for loop variable did not hide typedef", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Check that foreach array expressions can shadow visible type identifiers.
|
||||
|
||||
typedef int A;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
// The array declaration follows the foreach loop, so the lexer only sees
|
||||
// the visible typedef when parsing the array expression name.
|
||||
foreach (A[]) begin
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
int unsigned A [3];
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Check that foreach loop variables can shadow visible type identifiers.
|
||||
|
||||
typedef int I;
|
||||
typedef int J;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
int array [2][2];
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
foreach (array[I,J]) begin
|
||||
array[I][J] = I * 10 + J;
|
||||
end
|
||||
|
||||
if (array[0][0] != 0 || array[0][1] != 1 ||
|
||||
array[1][0] != 10 || array[1][1] != 11) begin
|
||||
$display("FAILED(%0d). foreach indices did not hide typedefs", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Check that fork block labels can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
reg value;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
value = 1'b0;
|
||||
|
||||
fork : T
|
||||
value = 1'b1;
|
||||
join : T
|
||||
|
||||
if (value !== 1'b1) begin
|
||||
$display("FAILED(%0d). fork label did not hide typedef", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// Check that function names can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
typedef int U;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
function int T(input int value);
|
||||
return value + 32'd1;
|
||||
endfunction
|
||||
|
||||
function U;
|
||||
U = 1'b1;
|
||||
endfunction
|
||||
|
||||
class C;
|
||||
function int T(input int value);
|
||||
return value + 32'd2;
|
||||
endfunction
|
||||
|
||||
function int C(input int value);
|
||||
return value + 32'd3;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
initial begin
|
||||
C c;
|
||||
|
||||
failed = 1'b0;
|
||||
c = new;
|
||||
|
||||
`check(T(32'd41), 32'd42, "Function name did not hide typedef");
|
||||
`check(U(), 1'b1, "Implicit function name did not hide typedef");
|
||||
`check(c.T(32'd40), 32'd42, "Class function name did not hide typedef");
|
||||
`check(c.C(32'd39), 32'd42, "Class function name did not hide class name");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Check that generate block labels can shadow visible type identifiers.
|
||||
|
||||
typedef int G;
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
if (1) begin : G
|
||||
localparam int VALUE = 1;
|
||||
end : G
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
if (G.VALUE != 1) begin
|
||||
$display("FAILED(%0d). generate labels did not hide typedefs", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Check that a genvar name can shadow a visible type identifier.
|
||||
|
||||
typedef int G;
|
||||
|
||||
module test;
|
||||
reg failed;
|
||||
|
||||
genvar G;
|
||||
generate
|
||||
for (G = 0; G < 2; G = G + 1) begin : gen_block
|
||||
localparam int VALUE = G;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
if (gen_block[0].VALUE != 0 || gen_block[1].VALUE != 1) begin
|
||||
$display("FAILED(%0d). genvar name did not hide typedef", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Check that a modport name can shadow a visible type identifier.
|
||||
|
||||
typedef int M;
|
||||
|
||||
interface type_id_modport_ifc;
|
||||
logic value;
|
||||
|
||||
modport M(input value);
|
||||
endinterface
|
||||
|
||||
module test;
|
||||
|
||||
type_id_modport_ifc i_ifc();
|
||||
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// Check that a modport simple port selector can shadow a visible typedef name.
|
||||
|
||||
interface I;
|
||||
typedef int T;
|
||||
logic value;
|
||||
|
||||
modport m(input .T(value));
|
||||
endinterface
|
||||
|
||||
module test;
|
||||
|
||||
I i();
|
||||
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// Check that a module name can shadow a visible type identifier.
|
||||
|
||||
package p;
|
||||
typedef int M;
|
||||
endpackage
|
||||
|
||||
import p::*;
|
||||
|
||||
module M;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
M i();
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Check that a named constructor argument selector can match a visible typedef name.
|
||||
|
||||
module test;
|
||||
|
||||
class C;
|
||||
integer value;
|
||||
|
||||
function new(input integer T, input integer B);
|
||||
value = T + B;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
typedef int T;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
C c;
|
||||
|
||||
failed = 1'b0;
|
||||
c = new(.T(40), .B(2));
|
||||
`check(c.value, 42);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that a named function argument selector can match a visible typedef name.
|
||||
|
||||
module test;
|
||||
|
||||
function integer f(input integer T, input integer B);
|
||||
f = T + B;
|
||||
endfunction
|
||||
|
||||
typedef int T;
|
||||
|
||||
reg failed;
|
||||
integer value;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
value = f(.T(40), .B(2));
|
||||
`check(value, 42);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Check that a named parameter override selector can match a visible typedef name.
|
||||
|
||||
module M #(parameter integer T = 0) (output [31:0] Y);
|
||||
assign Y = T;
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
|
||||
typedef int T;
|
||||
|
||||
reg failed;
|
||||
wire [31:0] y;
|
||||
|
||||
M #(.T(32'd42)) i_m(.Y(y));
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
#1;
|
||||
`check(y, 32'd42);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Check that a named port connection selector can match a visible typedef name.
|
||||
|
||||
module M(input [3:0] T, output [3:0] Y);
|
||||
assign Y = T;
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
|
||||
typedef int T;
|
||||
|
||||
reg failed;
|
||||
reg [3:0] value;
|
||||
wire [3:0] y;
|
||||
|
||||
M i_m(.T(value), .Y(y));
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0h, got %0h", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
value = 4'ha;
|
||||
#1;
|
||||
`check(y, 4'ha);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that a named task argument selector can match a visible typedef name.
|
||||
|
||||
module test;
|
||||
|
||||
task t(input integer T, output integer result);
|
||||
result = T;
|
||||
endtask
|
||||
|
||||
typedef int T;
|
||||
|
||||
reg failed;
|
||||
integer value;
|
||||
|
||||
`define check(val, exp) \
|
||||
if (val !== exp) begin \
|
||||
$display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, \
|
||||
`"val`", exp, val); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
t(.T(42), .result(value));
|
||||
`check(value, 42);
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// Check that nature names can match visible type identifiers.
|
||||
|
||||
typedef int NATURE_NAME;
|
||||
|
||||
nature NATURE_NAME;
|
||||
units = "V";
|
||||
access = NATURE_ACCESS;
|
||||
endnature
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
// Check that net names can shadow visible type identifiers.
|
||||
|
||||
typedef logic [7:0] T;
|
||||
typedef int U;
|
||||
typedef logic [5:0] V;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
module net_name(output reg failed);
|
||||
wire T = 1'b1;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check(T, 1'b1, "wire T did not declare a one-bit net");
|
||||
end
|
||||
endmodule
|
||||
|
||||
module net_list(output reg failed);
|
||||
wire T, U;
|
||||
|
||||
assign T = 1'b0;
|
||||
assign U = 1'b1;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check(T, 1'b0, "type identifier net list first value mismatch");
|
||||
`check(U, 1'b1, "type identifier net list continuation mismatch");
|
||||
end
|
||||
endmodule
|
||||
|
||||
module net_array(output reg failed);
|
||||
wire T [1:0];
|
||||
|
||||
assign T[0] = 1'b0;
|
||||
assign T[1] = 1'b1;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check(T[0], 1'b0, "type identifier net array first value mismatch");
|
||||
`check(T[1], 1'b1, "type identifier net array second value mismatch");
|
||||
end
|
||||
endmodule
|
||||
|
||||
module net_type(output reg failed);
|
||||
wire T x = 8'ha5;
|
||||
wire T [1:0] y = 16'h5aa5;
|
||||
wire V v0, V;
|
||||
wire T T;
|
||||
|
||||
assign v0 = 6'h2a;
|
||||
assign V = 6'h15;
|
||||
assign T = 8'h3c;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check($bits(x), 8, "typed net declaration width regressed");
|
||||
`check(x, 8'ha5, "typed net declaration value regressed");
|
||||
`check($bits(y), 16, "typed packed net declaration width regressed");
|
||||
`check(y, 16'h5aa5, "typed packed net declaration value regressed");
|
||||
`check($bits(v0), 6, "type identifier net declaration list first width mismatch");
|
||||
`check($bits(V), 6, "type identifier net declaration list did not allow typedef name as continuation");
|
||||
`check(V, 6'h15, "type identifier net declaration list value mismatch");
|
||||
`check($bits(T), 8, "type-name net declaration did not keep typedef type");
|
||||
`check(T, 8'h3c, "type-name net declaration value mismatch");
|
||||
end
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
reg failed;
|
||||
wire f0;
|
||||
wire f1;
|
||||
wire f2;
|
||||
wire f3;
|
||||
|
||||
net_name m0(f0);
|
||||
net_list m1(f1);
|
||||
net_array m2(f2);
|
||||
net_type m3(f3);
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
#1;
|
||||
|
||||
`check(f0, 1'b0, "wire T module failed");
|
||||
`check(f1, 1'b0, "wire T, U module failed");
|
||||
`check(f2, 1'b0, "wire T array module failed");
|
||||
`check(f3, 1'b0, "typed wire T module failed");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// Check that package import and export items can name a type identifier.
|
||||
|
||||
package type_id_name_pkg;
|
||||
typedef logic [3:0] T;
|
||||
endpackage
|
||||
|
||||
package type_id_name_export_pkg;
|
||||
import type_id_name_pkg::T;
|
||||
export type_id_name_pkg::T;
|
||||
endpackage
|
||||
|
||||
module test;
|
||||
import type_id_name_export_pkg::T;
|
||||
|
||||
reg failed;
|
||||
T value;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
value = 4'ha;
|
||||
|
||||
if ($bits(value) != 4 || value != 4'ha) begin
|
||||
$display("FAILED(%0d). Imported type mismatch", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Check that package names can shadow visible type identifiers.
|
||||
|
||||
package p;
|
||||
typedef int T;
|
||||
endpackage
|
||||
|
||||
import p::*;
|
||||
|
||||
package T;
|
||||
parameter int VALUE = 23;
|
||||
endpackage
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
if (T::VALUE !== 23) begin
|
||||
$display("FAILED(%0d). Package name did not hide typedef", `__LINE__);
|
||||
failed = 1'b1;
|
||||
end
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Check that parameter declaration names can shadow visible type identifiers.
|
||||
|
||||
typedef int L;
|
||||
typedef int P;
|
||||
typedef int Q;
|
||||
typedef int R;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
parameter P = 7, R = 13;
|
||||
localparam Q = 11, L = 17;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check(P, 7, "parameter name did not hide typedef");
|
||||
`check(R, 13, "parameter list continuation did not hide typedef");
|
||||
`check(Q, 11, "localparam name did not hide typedef");
|
||||
`check(L, 17, "localparam list continuation did not hide typedef");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// Check that parameter port declaration names can shadow visible type identifiers.
|
||||
|
||||
typedef int P;
|
||||
typedef int Q;
|
||||
typedef int R;
|
||||
typedef logic [7:0] T;
|
||||
typedef int TP;
|
||||
|
||||
package p;
|
||||
typedef logic [5:0] PT;
|
||||
endpackage
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
module M #(
|
||||
parameter int P = 5,
|
||||
Q = 9,
|
||||
int R = 13,
|
||||
T typed_value = 8'ha5,
|
||||
T T = 8'h3c,
|
||||
p::PT pkg_value = 6'h2a,
|
||||
parameter type TP = logic [5:0]
|
||||
) (output reg failed);
|
||||
|
||||
TP type_param_value;
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
type_param_value = 6'h15;
|
||||
|
||||
`check(P, 5, "parameter port typed value mismatch");
|
||||
`check(Q, 9, "parameter port untyped continuation mismatch");
|
||||
`check(R, 13, "parameter port atomic type continuation mismatch");
|
||||
`check($bits(typed_value), 8, "parameter port typedef type continuation width mismatch");
|
||||
`check(typed_value, 8'ha5, "parameter port typedef type continuation value mismatch");
|
||||
`check($bits(T), 8, "parameter port type-name continuation did not keep typedef type");
|
||||
`check(T, 8'h3c, "parameter port type-name continuation value mismatch");
|
||||
`check($bits(pkg_value), 6, "parameter port package type continuation width mismatch");
|
||||
`check(pkg_value, 6'h2a, "parameter port package type continuation value mismatch");
|
||||
`check($bits(type_param_value), 6, "parameter port type parameter mismatch");
|
||||
`check(type_param_value, 6'h15, "parameter port type parameter value mismatch");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module N #(P = 3, T typed_value = 8'h5a) (output reg failed);
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check(P, 3, "omitted parameter keyword mismatch");
|
||||
`check($bits(typed_value), 8, "omitted parameter keyword typedef width mismatch");
|
||||
`check(typed_value, 8'h5a, "omitted parameter keyword typedef value mismatch");
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
wire failed_m;
|
||||
wire failed_n;
|
||||
|
||||
M i_m(failed_m);
|
||||
N i_n(failed_n);
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
#1;
|
||||
|
||||
`check(failed_m, 1'b0, "parameter port module failed");
|
||||
`check(failed_n, 1'b0, "omitted parameter keyword module failed");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Check that typed parameter declaration names can shadow visible type identifiers.
|
||||
|
||||
typedef int P;
|
||||
typedef logic [7:0] T;
|
||||
typedef logic [6:0] U;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
parameter int P = 13;
|
||||
parameter T typed_value = 8'ha5;
|
||||
parameter T T = 8'h3c;
|
||||
parameter U u0 = 7'h2a, U = 7'h15;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
`check(P, 13, "typed parameter name did not hide typedef");
|
||||
`check($bits(typed_value), 8, "typed parameter width mismatch");
|
||||
`check(typed_value, 8'ha5, "typed parameter value mismatch");
|
||||
`check($bits(T), 8, "type-name parameter did not keep typedef type");
|
||||
`check(T, 8'h3c, "type-name parameter value mismatch");
|
||||
`check($bits(u0), 7, "parameter list first declaration did not keep typedef type");
|
||||
`check(u0, 7'h2a, "parameter list first value mismatch");
|
||||
`check($bits(U), 7, "parameter list continuation did not allow typedef name as parameter name");
|
||||
`check(U, 7'h15, "parameter list continuation value mismatch");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Check that type parameter declaration names can shadow visible type identifiers.
|
||||
|
||||
typedef int TP;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
parameter type TP = logic [3:0];
|
||||
|
||||
TP type_param_value;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
type_param_value = 4'hc;
|
||||
|
||||
`check($bits(type_param_value), 4, "type parameter name did not hide typedef");
|
||||
`check(type_param_value, 4'hc, "type parameter value mismatch");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
// Check that module port names can shadow visible type identifiers.
|
||||
|
||||
typedef logic [3:0] T;
|
||||
|
||||
package p;
|
||||
typedef logic [5:0] PT;
|
||||
endpackage
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
module ansi_name(input T);
|
||||
endmodule
|
||||
|
||||
module ansi_type(input T x);
|
||||
endmodule
|
||||
|
||||
module ansi_name_dim(input T [1:0]);
|
||||
endmodule
|
||||
|
||||
module ansi_type_dim(input T [1:0] x);
|
||||
endmodule
|
||||
|
||||
module ansi_name_list(input T, U);
|
||||
endmodule
|
||||
|
||||
module ansi_type_list(input T x, y);
|
||||
endmodule
|
||||
|
||||
module ansi_type_list_shadow(input T x, T);
|
||||
endmodule
|
||||
|
||||
module ansi_type_name(input T T, output logic ok);
|
||||
initial ok = ($bits(T) == 4);
|
||||
endmodule
|
||||
|
||||
module ansi_type_redecl(input n, T x);
|
||||
endmodule
|
||||
|
||||
module ansi_type_redecl_dim(input n, T [1:0] x);
|
||||
endmodule
|
||||
|
||||
module ansi_name_redecl_dim(input n, T [1:0]);
|
||||
endmodule
|
||||
|
||||
module ansi_pkg_type_redecl(input n, p::PT x);
|
||||
endmodule
|
||||
|
||||
module ansi_pkg_type_redecl_dim(input n, p::PT [1:0] x);
|
||||
endmodule
|
||||
|
||||
module decl_name(T);
|
||||
input T;
|
||||
endmodule
|
||||
|
||||
module decl_type(x);
|
||||
input T x;
|
||||
endmodule
|
||||
|
||||
module decl_type_dim(x);
|
||||
input T [1:0] x;
|
||||
endmodule
|
||||
|
||||
module decl_external(.T(x));
|
||||
input x;
|
||||
endmodule
|
||||
|
||||
module decl_name_list(T, U);
|
||||
input T, U;
|
||||
endmodule
|
||||
|
||||
module decl_type_list(x, y);
|
||||
input T x, y;
|
||||
endmodule
|
||||
|
||||
module decl_type_list_shadow(x, T);
|
||||
input T x, T;
|
||||
endmodule
|
||||
|
||||
module decl_type_name(T, ok);
|
||||
input T T;
|
||||
output logic ok;
|
||||
|
||||
initial ok = ($bits(T) == 4);
|
||||
endmodule
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
logic n;
|
||||
T t;
|
||||
logic n_dim [1:0];
|
||||
T [1:0] t_dim;
|
||||
logic n0, n1;
|
||||
T t0, t1;
|
||||
logic rn;
|
||||
T rt;
|
||||
T [1:0] rt_dim;
|
||||
logic rn_dim;
|
||||
logic rt_name_dim [1:0];
|
||||
logic rp_n;
|
||||
logic [5:0] rp_t;
|
||||
logic rp_dim_n;
|
||||
logic [1:0][5:0] rp_t_dim;
|
||||
logic d_n;
|
||||
T d_t;
|
||||
T [1:0] d_t_dim;
|
||||
logic d_ext;
|
||||
logic d_n0, d_n1;
|
||||
T d_t0, d_t1;
|
||||
T s_t0, s_t1;
|
||||
T d_s_t0, d_s_t1;
|
||||
T p_tn;
|
||||
T d_p_tn;
|
||||
logic p_tn_ok;
|
||||
logic d_p_tn_ok;
|
||||
|
||||
ansi_name m0(n);
|
||||
ansi_type m1(t);
|
||||
ansi_name_dim m2(n_dim);
|
||||
ansi_type_dim m3(t_dim);
|
||||
ansi_name_list m4(n0, n1);
|
||||
ansi_type_list m5(t0, t1);
|
||||
ansi_type_list_shadow m17(s_t0, s_t1);
|
||||
ansi_type_name m19(p_tn, p_tn_ok);
|
||||
ansi_type_redecl m12(rn, rt);
|
||||
ansi_type_redecl_dim m13(rn, rt_dim);
|
||||
ansi_name_redecl_dim m14(rn_dim, rt_name_dim);
|
||||
ansi_pkg_type_redecl m15(rp_n, rp_t);
|
||||
ansi_pkg_type_redecl_dim m16(rp_dim_n, rp_t_dim);
|
||||
decl_name m6(d_n);
|
||||
decl_type m7(d_t);
|
||||
decl_type_dim m8(d_t_dim);
|
||||
decl_external m9(d_ext);
|
||||
decl_name_list m10(d_n0, d_n1);
|
||||
decl_type_list m11(d_t0, d_t1);
|
||||
decl_type_list_shadow m18(d_s_t0, d_s_t1);
|
||||
decl_type_name m20(d_p_tn, d_p_tn_ok);
|
||||
|
||||
initial begin
|
||||
failed = 1'b0;
|
||||
|
||||
n = 1'b1;
|
||||
t = 4'ha;
|
||||
n_dim[0] = 1'b0;
|
||||
n_dim[1] = 1'b1;
|
||||
t_dim[0] = 4'h3;
|
||||
t_dim[1] = 4'hc;
|
||||
n0 = 1'b0;
|
||||
n1 = 1'b1;
|
||||
t0 = 4'h5;
|
||||
t1 = 4'ha;
|
||||
s_t0 = 4'h6;
|
||||
s_t1 = 4'h9;
|
||||
p_tn = 4'h3;
|
||||
rn = 1'b1;
|
||||
rt = 4'hc;
|
||||
rt_dim[0] = 4'h3;
|
||||
rt_dim[1] = 4'ha;
|
||||
rn_dim = 1'b0;
|
||||
rt_name_dim[0] = 1'b1;
|
||||
rt_name_dim[1] = 1'b0;
|
||||
rp_n = 1'b1;
|
||||
rp_t = 6'h2a;
|
||||
rp_dim_n = 1'b0;
|
||||
rp_t_dim[0] = 6'h15;
|
||||
rp_t_dim[1] = 6'h2a;
|
||||
d_n = 1'b1;
|
||||
d_t = 4'h6;
|
||||
d_t_dim[0] = 4'h7;
|
||||
d_t_dim[1] = 4'h8;
|
||||
d_ext = 1'b0;
|
||||
d_n0 = 1'b1;
|
||||
d_n1 = 1'b0;
|
||||
d_t0 = 4'h9;
|
||||
d_t1 = 4'h6;
|
||||
d_s_t0 = 4'h5;
|
||||
d_s_t1 = 4'ha;
|
||||
d_p_tn = 4'hc;
|
||||
|
||||
#1;
|
||||
|
||||
`check($bits(n), 1, "input T was not parsed as a port name");
|
||||
`check($bits(t), 4, "input T x was not parsed as a typed port");
|
||||
`check($bits(n_dim), 2, "input T [1:0] was not parsed as a port array");
|
||||
`check($bits(t_dim), 8, "input T [1:0] x was not parsed as a typed port array");
|
||||
`check($bits(n0), 1, "input T, U first port did not keep implicit type");
|
||||
`check($bits(n1), 1, "input T, U continuation did not keep implicit type");
|
||||
`check($bits(t0), 4, "input T x, y first port did not keep typedef type");
|
||||
`check($bits(t1), 4, "input T x, y continuation did not keep typedef type");
|
||||
`check(t0, 4'h5, "Typed port list first value mismatch");
|
||||
`check(t1, 4'ha, "Typed port list continuation mismatch");
|
||||
`check($bits(s_t0), 4, "input T x, T first port did not keep typedef type");
|
||||
`check($bits(s_t1), 4, "input T x, T continuation did not allow typedef name as port name");
|
||||
`check(s_t1, 4'h9, "Typed port list shadowing value mismatch");
|
||||
`check($bits(p_tn), 4, "input T T did not keep typedef type");
|
||||
`check(p_tn_ok, 1'b1, "input T T was not available as a typed port");
|
||||
`check($bits(rn), 1, "input n, T x first port did not keep implicit type");
|
||||
`check($bits(rt), 4, "input n, T x second port did not keep typedef type");
|
||||
`check(rt, 4'hc, "Inherited-direction typedef port value mismatch");
|
||||
`check($bits(rt_dim), 8, "input n, T [1:0] x did not keep typedef packed dimensions");
|
||||
`check(rt_dim[0], 4'h3, "Inherited-direction typedef packed array value mismatch");
|
||||
`check(rt_dim[1], 4'ha, "Inherited-direction typedef packed array value mismatch");
|
||||
`check($bits(rn_dim), 1, "input n, T [1:0] first port did not keep implicit type");
|
||||
`check($bits(rt_name_dim), 2, "input n, T [1:0] second port was not parsed as a port array");
|
||||
`check($bits(rp_t), 6, "input n, p::PT x second port did not keep package typedef type");
|
||||
`check(rp_t, 6'h2a, "Inherited-direction package typedef port value mismatch");
|
||||
`check($bits(rp_t_dim), 12, "input n, p::PT [1:0] x did not keep package typedef packed dimensions");
|
||||
`check(rp_t_dim[0], 6'h15, "Inherited-direction package typedef packed array value mismatch");
|
||||
`check(rp_t_dim[1], 6'h2a, "Inherited-direction package typedef packed array value mismatch");
|
||||
`check($bits(d_n), 1, "input T was not parsed as a port declaration name");
|
||||
`check($bits(d_t), 4, "input T x was not parsed as a typed port declaration");
|
||||
`check($bits(d_t_dim), 8, "input T [1:0] x was not parsed as a typed port declaration array");
|
||||
`check($bits(d_ext), 1, ".T(x) was not parsed as an external port name");
|
||||
`check($bits(d_n0), 1, "input T, U first declaration did not keep implicit type");
|
||||
`check($bits(d_n1), 1, "input T, U continuation declaration did not keep implicit type");
|
||||
`check($bits(d_t0), 4, "input T x, y first declaration did not keep typedef type");
|
||||
`check($bits(d_t1), 4, "input T x, y continuation declaration did not keep typedef type");
|
||||
`check(d_t0, 4'h9, "Typed port declaration list first value mismatch");
|
||||
`check(d_t1, 4'h6, "Typed port declaration list continuation mismatch");
|
||||
`check($bits(d_s_t0), 4, "input T x, T first declaration did not keep typedef type");
|
||||
`check($bits(d_s_t1), 4, "input T x, T declaration did not allow typedef name as port name");
|
||||
`check(d_s_t1, 4'ha, "Typed port declaration list shadowing value mismatch");
|
||||
`check($bits(d_p_tn), 4, "non-ANSI input T T did not keep typedef type");
|
||||
`check(d_p_tn_ok, 1'b1, "non-ANSI input T T was not available as a typed port");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// Check that a specparam name can shadow a visible type identifier.
|
||||
|
||||
typedef int SP_DELAY;
|
||||
|
||||
module test(input in, output out);
|
||||
specify
|
||||
specparam SP_DELAY = 1;
|
||||
(in => out) = SP_DELAY;
|
||||
endspecify
|
||||
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
// Check that task and function argument names can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
function int f_name(input T);
|
||||
return ($bits(T) == 1 && T === 1'b1) ? 32'd33 : -1;
|
||||
endfunction
|
||||
|
||||
function int f_type(input T value);
|
||||
return ($bits(value) == 32) ? value : -1;
|
||||
endfunction
|
||||
|
||||
function int f_type_list(input T value, T);
|
||||
return $bits(value) + $bits(T);
|
||||
endfunction
|
||||
|
||||
function int f_type_name(input T T);
|
||||
return $bits(T);
|
||||
endfunction
|
||||
|
||||
function int f_decl_name;
|
||||
input T;
|
||||
return $bits(T);
|
||||
endfunction
|
||||
|
||||
function int f_decl_type;
|
||||
input T value;
|
||||
return $bits(value);
|
||||
endfunction
|
||||
|
||||
function int f_decl_type_name;
|
||||
input T T;
|
||||
return $bits(T);
|
||||
endfunction
|
||||
|
||||
task t_name(input T, output int value);
|
||||
value = ($bits(T) == 1 && T === 1'b1) ? 32'd44 : -1;
|
||||
endtask
|
||||
|
||||
task t_type(input T value, output int result);
|
||||
result = ($bits(value) == 32) ? value : -1;
|
||||
endtask
|
||||
|
||||
task t_type_list(input T value, T, output int result);
|
||||
result = $bits(value) + $bits(T);
|
||||
endtask
|
||||
|
||||
task t_type_name(input T T, output int value);
|
||||
value = $bits(T);
|
||||
endtask
|
||||
|
||||
task t_decl_name;
|
||||
input T;
|
||||
output int value;
|
||||
value = $bits(T);
|
||||
endtask
|
||||
|
||||
task t_decl_type;
|
||||
input T value;
|
||||
output int result;
|
||||
result = $bits(value);
|
||||
endtask
|
||||
|
||||
task t_decl_type_name;
|
||||
input T T;
|
||||
output int value;
|
||||
value = $bits(T);
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
int r0;
|
||||
int r1;
|
||||
int r2;
|
||||
int r3;
|
||||
int r4;
|
||||
int r5;
|
||||
int r6;
|
||||
|
||||
failed = 1'b0;
|
||||
|
||||
t_name(1'b1, r0);
|
||||
t_type(32'd55, r1);
|
||||
t_type_list(32'd11, 32'd22, r2);
|
||||
t_decl_name(1'b1, r3);
|
||||
t_decl_type(32'd33, r4);
|
||||
t_type_name(32'd44, r5);
|
||||
t_decl_type_name(32'd55, r6);
|
||||
|
||||
`check(f_name(1'b1), 32'd33, "Function argument did not hide typedef");
|
||||
`check(f_type(32'd66), 32'd66, "Function typed argument regressed");
|
||||
`check(f_type_list(32'd11, 32'd22), 64, "Function typed argument list shadowing mismatch");
|
||||
`check(f_type_name(32'd33), 32, "Function type-name argument did not keep typedef type");
|
||||
`check(f_decl_name(1'b1), 1, "Function non-ANSI argument did not hide typedef");
|
||||
`check(f_decl_type(32'd66), 32, "Function non-ANSI typed argument regressed");
|
||||
`check(f_decl_type_name(32'd77), 32, "Function non-ANSI type-name argument did not keep typedef type");
|
||||
`check(r0, 32'd44, "Task argument did not hide typedef");
|
||||
`check(r1, 32'd55, "Task typed argument regressed");
|
||||
`check(r2, 64, "Task typed argument list shadowing mismatch");
|
||||
`check(r3, 1, "Task non-ANSI argument did not hide typedef");
|
||||
`check(r4, 32, "Task non-ANSI typed argument regressed");
|
||||
`check(r5, 32, "Task type-name argument did not keep typedef type");
|
||||
`check(r6, 32, "Task non-ANSI type-name argument did not keep typedef type");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
// Check that task names can shadow visible type identifiers.
|
||||
|
||||
typedef int T;
|
||||
typedef int U;
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
task T(input int value, output int result);
|
||||
result = value + 32'd1;
|
||||
endtask
|
||||
|
||||
task U;
|
||||
output int result;
|
||||
|
||||
result = 32'd33;
|
||||
endtask
|
||||
|
||||
class C;
|
||||
task T(input int value, output int result);
|
||||
result = value + 32'd2;
|
||||
endtask
|
||||
|
||||
task C(input int value, output int result);
|
||||
result = value + 32'd3;
|
||||
endtask
|
||||
endclass
|
||||
|
||||
initial begin
|
||||
C c;
|
||||
int r0;
|
||||
int r1;
|
||||
int r2;
|
||||
int r3;
|
||||
|
||||
failed = 1'b0;
|
||||
c = new;
|
||||
|
||||
T(32'd41, r0);
|
||||
U(r1);
|
||||
c.T(32'd40, r2);
|
||||
c.C(32'd39, r3);
|
||||
|
||||
`check(r0, 32'd42, "Task name did not hide typedef");
|
||||
`check(r1, 32'd33, "Non-ANSI task name did not hide typedef");
|
||||
`check(r2, 32'd42, "Class task name did not hide typedef");
|
||||
`check(r3, 32'd42, "Class task name did not hide class name");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Check that ANSI-style UDP names can shadow visible type identifiers.
|
||||
|
||||
package p;
|
||||
typedef int ANSI_UDP;
|
||||
typedef int Y;
|
||||
typedef int I0;
|
||||
typedef int I1;
|
||||
endpackage
|
||||
|
||||
import p::*;
|
||||
|
||||
primitive ANSI_UDP (output Y, input I0, input I1);
|
||||
table
|
||||
00 : 0;
|
||||
01 : 0;
|
||||
10 : 0;
|
||||
11 : 1;
|
||||
endtable
|
||||
endprimitive
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Check that old-style UDP names can shadow visible type identifiers.
|
||||
|
||||
package p;
|
||||
typedef int OLD_UDP;
|
||||
typedef int Q;
|
||||
typedef int A;
|
||||
typedef int B;
|
||||
endpackage
|
||||
|
||||
import p::*;
|
||||
|
||||
primitive OLD_UDP (Q, A, B);
|
||||
output reg Q;
|
||||
input A, B;
|
||||
initial Q = 0;
|
||||
|
||||
table
|
||||
00 : ? : 0;
|
||||
01 : ? : 0;
|
||||
10 : ? : 0;
|
||||
11 : ? : 1;
|
||||
endtable
|
||||
endprimitive
|
||||
|
||||
module test;
|
||||
initial begin
|
||||
$display("PASSED");
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
// Check that variable names can shadow visible type identifiers.
|
||||
|
||||
typedef logic [7:0] T;
|
||||
typedef int V;
|
||||
typedef int W;
|
||||
typedef logic [6:0] A;
|
||||
typedef logic [5:0] B;
|
||||
typedef logic [4:0] C;
|
||||
typedef logic [3:0] D;
|
||||
typedef logic [2:0] E;
|
||||
typedef logic [1:0] F;
|
||||
typedef logic [2:0] G;
|
||||
typedef logic [3:0] H;
|
||||
typedef logic [4:0] I;
|
||||
typedef logic [2:0] P;
|
||||
bit X;
|
||||
|
||||
package p;
|
||||
var C;
|
||||
var D x, D;
|
||||
var P P;
|
||||
endpackage
|
||||
|
||||
module test;
|
||||
|
||||
reg failed;
|
||||
|
||||
`define check(value, expected, error) \
|
||||
if ((value) !== (expected)) begin \
|
||||
$display("FAILED(%0d). %s", `__LINE__, error); \
|
||||
$display(" expected %0h, got %0h", expected, value); \
|
||||
failed = 1'b1; \
|
||||
end
|
||||
|
||||
typedef logic [3:0] X;
|
||||
|
||||
T outer;
|
||||
T a, b;
|
||||
A a0, A;
|
||||
E E;
|
||||
int T, U;
|
||||
var V;
|
||||
var B b0, B;
|
||||
var F F;
|
||||
X x;
|
||||
|
||||
function int f;
|
||||
int T;
|
||||
|
||||
T = 32'd11;
|
||||
return T;
|
||||
endfunction
|
||||
|
||||
function int f_type_name;
|
||||
H H;
|
||||
|
||||
H = 4'ha;
|
||||
return $bits(H) + H;
|
||||
endfunction
|
||||
|
||||
task t(output int value);
|
||||
int T;
|
||||
|
||||
T = 32'd22;
|
||||
value = T;
|
||||
endtask
|
||||
|
||||
task t_type_name(output int value);
|
||||
I I;
|
||||
|
||||
I = 5'h15;
|
||||
value = $bits(I) + I;
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
int r;
|
||||
int r_type_name;
|
||||
int tr_type_name;
|
||||
var W;
|
||||
|
||||
failed = 1'b0;
|
||||
|
||||
outer = 8'ha5;
|
||||
a = 8'h33;
|
||||
b = 8'hcc;
|
||||
a0 = 7'h2a;
|
||||
A = 7'h15;
|
||||
E = 3'h5;
|
||||
T = 32'd23;
|
||||
U = 32'd41;
|
||||
V = 1'b1;
|
||||
b0 = 6'h2a;
|
||||
B = 6'h15;
|
||||
F = 2'h2;
|
||||
W = 1'b0;
|
||||
x = 4'hc;
|
||||
t(r);
|
||||
t_type_name(tr_type_name);
|
||||
|
||||
begin : block_scope
|
||||
int T;
|
||||
|
||||
T = 32'd7;
|
||||
`check(T, 32'd7, "Block declaration did not hide typedef");
|
||||
end
|
||||
|
||||
begin : block_type_name
|
||||
G G;
|
||||
|
||||
G = 3'h3;
|
||||
`check($bits(G), 3, "Block type-name declaration did not keep typedef type");
|
||||
`check(G, 3'h3, "Block type-name declaration value mismatch");
|
||||
end
|
||||
|
||||
r_type_name = f_type_name();
|
||||
|
||||
`check(outer, 8'ha5, "Typedef value changed");
|
||||
`check(T, 32'd23, "Module declaration did not hide typedef");
|
||||
`check(U, 32'd41, "Declaration list continuation mismatch");
|
||||
`check($bits(V), 1, "Module var declaration did not hide typedef width");
|
||||
`check(V, 1'b1, "Module var declaration did not hide typedef value");
|
||||
`check($bits(W), 1, "Block var declaration did not hide typedef width");
|
||||
`check(W, 1'b0, "Block var declaration did not hide typedef value");
|
||||
`check(a, 8'h33, "Type declaration list first value mismatch");
|
||||
`check(b, 8'hcc, "Type declaration list continuation mismatch");
|
||||
`check($bits(a0), 7, "Type declaration list did not keep typedef type");
|
||||
`check($bits(A), 7, "Type declaration list did not allow typedef name as continuation");
|
||||
`check(A, 7'h15, "Type declaration list shadowing value mismatch");
|
||||
`check($bits(E), 3, "Type-name declaration did not keep typedef type");
|
||||
`check(E, 3'h5, "Type-name declaration value mismatch");
|
||||
`check($bits(b0), 6, "Var declaration list did not keep typedef type");
|
||||
`check($bits(B), 6, "Var declaration list did not allow typedef name as continuation");
|
||||
`check(B, 6'h15, "Var declaration list shadowing value mismatch");
|
||||
`check($bits(F), 2, "Var type-name declaration did not keep typedef type");
|
||||
`check(F, 2'h2, "Var type-name declaration value mismatch");
|
||||
`check($bits(p::C), 1, "Package var declaration did not hide typedef width");
|
||||
`check($bits(p::x), 4, "Package type declaration list first width mismatch");
|
||||
`check($bits(p::D), 4, "Package type declaration list did not allow typedef name as continuation");
|
||||
`check($bits(p::P), 3, "Package type-name declaration did not keep typedef type");
|
||||
`check(f(), 32'd11, "Function declaration did not hide typedef");
|
||||
`check(r_type_name, 14, "Function type-name declaration mismatch");
|
||||
`check(r, 32'd22, "Task declaration did not hide typedef");
|
||||
`check(tr_type_name, 26, "Task type-name declaration mismatch");
|
||||
`check($bits(x), 4, "Local typedef did not hide outer identifier");
|
||||
`check(x, 4'hc, "Local typedef value mismatch");
|
||||
|
||||
if (!failed) begin
|
||||
$display("PASSED");
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// Check that an ANSI-style UDP output initializer requires a reg output.
|
||||
|
||||
primitive udp_ansi_initial_nonreg_fail (output o = 1'b0, input i);
|
||||
table
|
||||
0 : 0;
|
||||
1 : 1;
|
||||
endtable
|
||||
endprimitive
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue