aboutsummaryrefslogtreecommitdiffstats
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.cc5
-rw-r--r--frontends/ast/ast.h2
-rw-r--r--frontends/ast/dpicall.cc17
-rw-r--r--frontends/ast/genrtlil.cc27
-rw-r--r--frontends/ast/simplify.cc70
-rw-r--r--frontends/rtlil/rtlil_lexer.l1
-rw-r--r--frontends/verific/verific.cc36
-rw-r--r--frontends/verilog/preproc.cc8
-rw-r--r--frontends/verilog/verilog_frontend.cc3
-rw-r--r--frontends/verilog/verilog_parser.y106
10 files changed, 203 insertions, 72 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index c8183580b..dc47420af 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -548,9 +548,9 @@ void AstNode::dumpVlog(FILE *f, std::string indent) const
break;
case AST_CASE:
- if (!children.empty() && children[0]->type == AST_CONDX)
+ if (children.size() > 1 && children[1]->type == AST_CONDX)
fprintf(f, "%s" "casex (", indent.c_str());
- else if (!children.empty() && children[0]->type == AST_CONDZ)
+ else if (children.size() > 1 && children[1]->type == AST_CONDZ)
fprintf(f, "%s" "casez (", indent.c_str());
else
fprintf(f, "%s" "case (", indent.c_str());
@@ -1511,6 +1511,7 @@ RTLIL::IdString AstModule::derive(RTLIL::Design *design, const dict<RTLIL::IdStr
}
} else {
+ modname = new_modname;
log("Found cached RTLIL representation for module `%s'.\n", modname.c_str());
}
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 1b8ed22ca..907392166 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -250,6 +250,7 @@ namespace AST
// simplify() creates a simpler AST by unrolling for-loops, expanding generate blocks, etc.
// it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param);
+ void replace_result_wire_name_in_function(const std::string &from, const std::string &to);
AstNode *readmem(bool is_readmemh, std::string mem_filename, AstNode *memory, int start_addr, int finish_addr, bool unconditional_init);
void expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map, bool original_scope = true);
void replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules);
@@ -264,6 +265,7 @@ namespace AST
// additional functionality for evaluating constant functions
struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; };
bool has_const_only_constructs(bool &recommend_const_eval);
+ bool has_const_only_constructs(std::set<std::string>& visited, bool &recommend_const_eval);
void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall);
AstNode *eval_const_function(AstNode *fcall);
bool is_simple_const_expr();
diff --git a/frontends/ast/dpicall.cc b/frontends/ast/dpicall.cc
index e241142d3..948c9083c 100644
--- a/frontends/ast/dpicall.cc
+++ b/frontends/ast/dpicall.cc
@@ -67,7 +67,7 @@ static ffi_fptr resolve_fn (std::string symbol_name)
AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname, const std::vector<std::string> &argtypes, const std::vector<AstNode*> &args)
{
AST::AstNode *newNode = nullptr;
- union { double f64; float f32; int32_t i32; } value_store [args.size() + 1];
+ union { double f64; float f32; int32_t i32; void *ptr; } value_store [args.size() + 1];
ffi_type *types [args.size() + 1];
void *values [args.size() + 1];
ffi_cif cif;
@@ -92,6 +92,11 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname,
value_store[i].i32 = args[i]->asInt(args[i]->is_signed);
values[i] = &value_store[i].i32;
types[i] = &ffi_type_sint32;
+ } else if (argtypes[i] == "chandle") {
+ log(" arg %d (%s): %llx\n", i, argtypes[i].c_str(), (unsigned long long)args[i]->asInt(false));
+ value_store[i].ptr = (void *)args[i]->asInt(args[i]->is_signed);
+ values[i] = &value_store[i].ptr;
+ types[i] = &ffi_type_pointer;
} else {
log_error("invalid argtype '%s' for argument %d.\n", argtypes[i].c_str(), i);
}
@@ -106,6 +111,9 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname,
} else if (rtype == "real") {
types[args.size()] = &ffi_type_double;
values[args.size()] = &value_store[args.size()].f64;
+ } else if (rtype == "chandle") {
+ types[args.size()] = &ffi_type_pointer;
+ values[args.size()] = &value_store[args.size()].ptr;
} else {
log_error("invalid rtype '%s'.\n", rtype.c_str());
}
@@ -123,6 +131,13 @@ AST::AstNode *AST::dpi_call(const std::string &rtype, const std::string &fname,
newNode = new AstNode(AST_REALVALUE);
newNode->realvalue = value_store[args.size()].f32;
log(" return realvalue: %g\n", newNode->asReal(true));
+ } else if (rtype == "chandle") {
+ uint64_t rawval = (uint64_t)value_store[args.size()].ptr;
+ std::vector<RTLIL::State> bits(64);
+ for (int i = 0; i < 64; i++)
+ bits.at(i) = (rawval & (1ULL << i)) ? RTLIL::State::S1 : RTLIL::State::S0;
+ newNode = AstNode::mkconst_bits(bits, false);
+ log(" return chandle: %llx\n", (unsigned long long)newNode->asInt(false));
} else {
newNode = AstNode::mkconst_int(value_store[args.size()].i32, false);
log(" return integer: %lld\n", (long long)newNode->asInt(true));
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index e878d0dd2..b8bfdf65e 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -106,6 +106,7 @@ static RTLIL::SigSpec binop2rtlil(AstNode *that, IdString type, int result_width
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", result_width);
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
+ wire->is_signed = that->is_signed;
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -140,6 +141,7 @@ static RTLIL::SigSpec mux2rtlil(AstNode *that, const RTLIL::SigSpec &cond, const
RTLIL::Wire *wire = current_module->addWire(cell->name.str() + "_Y", left.size());
wire->attributes[ID::src] = stringf("%s:%d.%d-%d.%d", that->filename.c_str(), that->location.first_line, that->location.first_column, that->location.last_line, that->location.last_column);
+ wire->is_signed = that->is_signed;
for (auto &attr : that->attributes) {
if (attr.second->type != AST_CONSTANT)
@@ -1721,8 +1723,29 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
}
if (child->type == AST_ARGUMENT) {
RTLIL::SigSpec sig;
- if (child->children.size() > 0)
- sig = child->children[0]->genRTLIL();
+ if (child->children.size() > 0) {
+ AstNode *arg = child->children[0];
+ int local_width_hint = -1;
+ bool local_sign_hint = false;
+ // don't inadvertently attempt to detect the width of interfaces
+ if (arg->type != AST_IDENTIFIER || !arg->id2ast || arg->id2ast->type != AST_CELL)
+ arg->detectSignWidth(local_width_hint, local_sign_hint);
+ sig = arg->genRTLIL(local_width_hint, local_sign_hint);
+ log_assert(local_sign_hint == arg->is_signed);
+ if (sig.is_wire()) {
+ // if the resulting SigSpec is a wire, its
+ // signedness should match that of the AstNode
+ log_assert(arg->is_signed == sig.as_wire()->is_signed);
+ } else if (arg->is_signed) {
+ // non-trivial signed nodes are indirected through
+ // signed wires to enable sign extension
+ RTLIL::IdString wire_name = NEW_ID;
+ RTLIL::Wire *wire = current_module->addWire(wire_name, arg->bits.size());
+ wire->is_signed = true;
+ current_module->connect(wire, sig);
+ sig = wire;
+ }
+ }
if (child->str.size() == 0) {
char buf[100];
snprintf(buf, 100, "$%d", ++port_counter);
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index fb6623f02..fc2976c83 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1205,6 +1205,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
current_block = this;
current_block_child = children[i];
}
+ if (!in_param_here && type == AST_FCALL) {
+ bool recommend_const_eval = false;
+ bool require_const_eval = has_const_only_constructs(recommend_const_eval);
+ in_param_here = recommend_const_eval || require_const_eval;
+ }
if ((type == AST_ALWAYS || type == AST_INITIAL) && children[i]->type == AST_BLOCK)
current_top_block = children[i];
if (i == 0 && child_0_is_self_determined)
@@ -1325,6 +1330,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (template_node->type == AST_STRUCT || template_node->type == AST_UNION) {
// replace with wire representing the packed structure
newNode = make_packed_struct(template_node, str);
+ // add original input/output attribute to resolved wire
+ newNode->is_input = this->is_input;
+ newNode->is_output = this->is_output;
current_scope[str] = this;
goto apply_newNode;
}
@@ -3170,6 +3178,8 @@ skip_dynamic_range_lvalue_expansion:;
if (all_args_const) {
AstNode *func_workspace = current_scope[str]->clone();
+ func_workspace->str = NEW_ID.str();
+ func_workspace->replace_result_wire_name_in_function(str, func_workspace->str);
newNode = func_workspace->eval_const_function(this);
delete func_workspace;
goto apply_newNode;
@@ -3337,6 +3347,25 @@ skip_dynamic_range_lvalue_expansion:;
wire->type = AST_LOCALPARAM;
wire->attributes.erase(ID::nosync);
wire->children.insert(wire->children.begin(), arg->clone());
+ // args without a range implicitly have width 1
+ if (wire->children.back()->type != AST_RANGE) {
+ // check if this wire is redeclared with an explicit size
+ bool uses_explicit_size = false;
+ for (const AstNode *other_child : decl->children)
+ if (other_child->type == AST_WIRE && child->str == other_child->str
+ && !other_child->children.empty()
+ && other_child->children.back()->type == AST_RANGE) {
+ uses_explicit_size = true;
+ break;
+ }
+ if (!uses_explicit_size) {
+ AstNode* range = new AstNode();
+ range->type = AST_RANGE;
+ wire->children.push_back(range);
+ range->children.push_back(mkconst_int(0, true));
+ range->children.push_back(mkconst_int(0, true));
+ }
+ }
continue;
}
AstNode *wire_id = new AstNode(AST_IDENTIFIER);
@@ -3427,7 +3456,14 @@ replace_fcall_later:;
if (current_scope[str]->children[0]->isConst())
newNode = current_scope[str]->children[0]->clone();
}
- else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
+ else if (at_zero && current_scope.count(str) > 0) {
+ AstNode *node = current_scope[str];
+ if (node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
+ newNode = mkconst_int(0, sign_hint, width_hint);
+ }
+ break;
+ case AST_MEMRD:
+ if (at_zero) {
newNode = mkconst_int(0, sign_hint, width_hint);
}
break;
@@ -3683,12 +3719,12 @@ apply_newNode:
return did_something;
}
-static void replace_result_wire_name_in_function(AstNode *node, std::string &from, std::string &to)
+void AstNode::replace_result_wire_name_in_function(const std::string &from, const std::string &to)
{
- for (auto &it : node->children)
- replace_result_wire_name_in_function(it, from, to);
- if (node->str == from)
- node->str = to;
+ for (AstNode *child : children)
+ child->replace_result_wire_name_in_function(from, to);
+ if (str == from && type != AST_FCALL && type != AST_TCALL)
+ str = to;
}
// replace a readmem[bh] TCALL ast node with a block of memory assignments
@@ -3881,7 +3917,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
name_map[child->str] = new_name;
if (child->type == AST_FUNCTION)
- replace_result_wire_name_in_function(child, child->str, new_name);
+ child->replace_result_wire_name_in_function(child->str, new_name);
else
child->str = new_name;
current_scope[new_name] = child;
@@ -4461,15 +4497,31 @@ bool AstNode::detect_latch(const std::string &var)
bool AstNode::has_const_only_constructs(bool &recommend_const_eval)
{
+ std::set<std::string> visited;
+ return has_const_only_constructs(visited, recommend_const_eval);
+}
+
+bool AstNode::has_const_only_constructs(std::set<std::string>& visited, bool &recommend_const_eval)
+{
+ if (type == AST_FUNCTION || type == AST_TASK)
+ {
+ if (visited.count(str))
+ {
+ recommend_const_eval = true;
+ return false;
+ }
+ visited.insert(str);
+ }
+
if (type == AST_FOR)
recommend_const_eval = true;
if (type == AST_WHILE || type == AST_REPEAT)
return true;
if (type == AST_FCALL && current_scope.count(str))
- if (current_scope[str]->has_const_only_constructs(recommend_const_eval))
+ if (current_scope[str]->has_const_only_constructs(visited, recommend_const_eval))
return true;
for (auto child : children)
- if (child->AstNode::has_const_only_constructs(recommend_const_eval))
+ if (child->AstNode::has_const_only_constructs(visited, recommend_const_eval))
return true;
return false;
}
diff --git a/frontends/rtlil/rtlil_lexer.l b/frontends/rtlil/rtlil_lexer.l
index 295455f53..beef220f6 100644
--- a/frontends/rtlil/rtlil_lexer.l
+++ b/frontends/rtlil/rtlil_lexer.l
@@ -86,7 +86,6 @@ USING_YOSYS_NAMESPACE
"\\"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
"$"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
-"."[0-9]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; }
[0-9]+'[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; }
-?[0-9]+ {
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc
index 31c77d39c..81e14ac41 100644
--- a/frontends/verific/verific.cc
+++ b/frontends/verific/verific.cc
@@ -51,12 +51,12 @@ USING_YOSYS_NAMESPACE
#include "VeriLibrary.h"
#include "VeriExtensions.h"
-#ifndef SYMBIOTIC_VERIFIC_API_VERSION
-# error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific."
+#ifndef YOSYSHQ_VERIFIC_API_VERSION
+# error "Only YosysHQ flavored Verific is supported. Please contact office@yosyshq.com for commercial support for Yosys+Verific."
#endif
-#if SYMBIOTIC_VERIFIC_API_VERSION < 20201001
-# error "Please update your version of Symbiotic EDA flavored Verific."
+#if YOSYSHQ_VERIFIC_API_VERSION < 20210101
+# error "Please update your version of YosysHQ flavored Verific."
#endif
#ifdef __clang__
@@ -1471,7 +1471,7 @@ void VerificImporter::import_netlist(RTLIL::Design *design, Netlist *nl, std::se
continue;
}
- if (inst->Type() == PRIM_SEDA_INITSTATE)
+ if (inst->Type() == PRIM_YOSYSHQ_INITSTATE)
{
SigBit initstate = module->Initstate(new_verific_id(inst));
SigBit sig_o = net_map_at(inst->GetOutput());
@@ -2199,7 +2199,7 @@ struct VerificPass : public Pass {
log("\n");
log(" verific -app <application>..\n");
log("\n");
- log("Execute SEDA formal application on loaded Verilog files.\n");
+ log("Execute YosysHQ formal application on loaded Verilog files.\n");
log("\n");
log("Application options:\n");
log("\n");
@@ -2250,11 +2250,11 @@ struct VerificPass : public Pass {
log(" WARNING: Templates only available in commercial build.\n");
log("\n");
#endif
- log("Use Symbiotic EDA Suite if you need Yosys+Verifc.\n");
- log("https://www.symbioticeda.com/seda-suite\n");
+ log("Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n");
+ log("https://www.yosyshq.com/\n");
log("\n");
- log("Contact office@symbioticeda.com for free evaluation\n");
- log("binaries of Symbiotic EDA Suite.\n");
+ log("Contact office@yosyshq.com for free evaluation\n");
+ log("binaries of YosysHQ Tabby CAD Suite.\n");
log("\n");
}
#ifdef YOSYS_ENABLE_VERIFIC
@@ -2265,11 +2265,11 @@ struct VerificPass : public Pass {
if (check_noverific_env())
log_cmd_error("This version of Yosys is built without Verific support.\n"
"\n"
- "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"
- "https://www.symbioticeda.com/seda-suite\n"
+ "Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n"
+ "https://www.yosyshq.com/\n"
"\n"
- "Contact office@symbioticeda.com for free evaluation\n"
- "binaries of Symbiotic EDA Suite.\n");
+ "Contact office@yosyshq.com for free evaluation\n"
+ "binaries of YosysHQ Tabby CAD Suite.\n");
log_header(design, "Executing VERIFIC (loading SystemVerilog and VHDL designs using Verific).\n");
@@ -2926,11 +2926,11 @@ struct VerificPass : public Pass {
void execute(std::vector<std::string>, RTLIL::Design *) override {
log_cmd_error("This version of Yosys is built without Verific support.\n"
"\n"
- "Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"
- "https://www.symbioticeda.com/seda-suite\n"
+ "Use YosysHQ Tabby CAD Suite if you need Yosys+Verific.\n"
+ "https://www.yosyshq.com/\n"
"\n"
- "Contact office@symbioticeda.com for free evaluation\n"
- "binaries of Symbiotic EDA Suite.\n");
+ "Contact office@yosyshq.com for free evaluation\n"
+ "binaries of YosysHQ Tabby CAD Suite.\n");
}
#endif
} VerificPass;
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index ea23139e2..c451c4c20 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -321,7 +321,6 @@ struct define_body_t
define_map_t::define_map_t()
{
add("YOSYS", "1");
- add(formal_mode ? "FORMAL" : "SYNTHESIS", "1");
}
// We must define this destructor here (rather than relying on the default), because we need to
@@ -391,13 +390,16 @@ static void input_file(std::istream &f, std::string filename)
// the argument list); false if we finished with ','.
static bool read_argument(std::string &dest)
{
+ skip_spaces();
std::vector<char> openers;
for (;;) {
- skip_spaces();
std::string tok = next_token(true);
if (tok == ")") {
- if (openers.empty())
+ if (openers.empty()) {
+ while (dest.size() && (dest.back() == ' ' || dest.back() == '\t'))
+ dest = dest.substr(0, dest.size() - 1);
return true;
+ }
if (openers.back() != '(')
log_error("Mismatched brackets in macro argument: %c and %c.\n",
openers.back(), tok[0]);
diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc
index 2e9c9b2e2..5319a45ad 100644
--- a/frontends/verilog/verilog_frontend.cc
+++ b/frontends/verilog/verilog_frontend.cc
@@ -446,6 +446,9 @@ struct VerilogFrontend : public Frontend {
}
break;
}
+
+ defines_map.add(formal_mode ? "FORMAL" : "SYNTHESIS", "1");
+
extra_args(f, filename, args, argidx);
log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str());
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 678ce6c87..8bd58d24c 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -282,7 +282,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
-%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
+%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list non_io_wire_type io_wire_type
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
%type <string> type_name
%type <ast> opt_enum_init enum_type struct_type non_wire_data_type
@@ -619,26 +619,19 @@ non_opt_delay:
delay:
non_opt_delay | %empty;
-wire_type:
- {
- astbuf3 = new AstNode(AST_WIRE);
- current_wire_rand = false;
- current_wire_const = false;
- } wire_type_token_list {
- $$ = astbuf3;
- SET_RULE_LOC(@$, @2, @$);
- };
+io_wire_type:
+ { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
+ wire_type_token_io wire_type_const_rand opt_wire_type_token wire_type_signedness
+ { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
-wire_type_token_list:
- wire_type_token |
- wire_type_token_list wire_type_token |
- wire_type_token_io |
- hierarchical_type_id {
- astbuf3->is_custom_type = true;
- astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
- astbuf3->children.back()->str = *$1;
- delete $1;
- };
+non_io_wire_type:
+ { astbuf3 = new AstNode(AST_WIRE); current_wire_rand = false; current_wire_const = false; }
+ wire_type_const_rand wire_type_token wire_type_signedness
+ { $$ = astbuf3; SET_RULE_LOC(@$, @2, @$); };
+
+wire_type:
+ io_wire_type |
+ non_io_wire_type;
wire_type_token_io:
TOK_INPUT {
@@ -652,8 +645,32 @@ wire_type_token_io:
astbuf3->is_output = true;
};
+wire_type_signedness:
+ TOK_SIGNED { astbuf3->is_signed = true; } |
+ TOK_UNSIGNED { astbuf3->is_signed = false; } |
+ %empty;
+
+wire_type_const_rand:
+ TOK_RAND TOK_CONST {
+ current_wire_rand = true;
+ current_wire_const = true;
+ } |
+ TOK_CONST {
+ current_wire_const = true;
+ } |
+ TOK_RAND {
+ current_wire_rand = true;
+ } |
+ %empty;
+
+opt_wire_type_token:
+ wire_type_token | %empty;
+
wire_type_token:
- TOK_WIRE {
+ hierarchical_type_id {
+ astbuf3->is_custom_type = true;
+ astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
+ astbuf3->children.back()->str = *$1;
} |
TOK_WOR {
astbuf3->is_wor = true;
@@ -661,20 +678,27 @@ wire_type_token:
TOK_WAND {
astbuf3->is_wand = true;
} |
+ // wires
+ TOK_WIRE {
+ } |
+ TOK_WIRE logic_type {
+ } |
+ // regs
TOK_REG {
astbuf3->is_reg = true;
} |
- TOK_LOGIC {
- astbuf3->is_logic = true;
+ TOK_VAR TOK_REG {
+ astbuf3->is_reg = true;
} |
+ // logics
TOK_VAR {
astbuf3->is_logic = true;
} |
- TOK_INTEGER {
- astbuf3->is_reg = true;
- astbuf3->range_left = 31;
- astbuf3->range_right = 0;
- astbuf3->is_signed = true;
+ TOK_VAR logic_type {
+ astbuf3->is_logic = true;
+ } |
+ logic_type {
+ astbuf3->is_logic = true;
} |
TOK_GENVAR {
astbuf3->type = AST_GENVAR;
@@ -682,15 +706,15 @@ wire_type_token:
astbuf3->is_signed = true;
astbuf3->range_left = 31;
astbuf3->range_right = 0;
+ };
+
+logic_type:
+ TOK_LOGIC {
} |
- TOK_SIGNED {
+ TOK_INTEGER {
+ astbuf3->range_left = 31;
+ astbuf3->range_right = 0;
astbuf3->is_signed = true;
- } |
- TOK_RAND {
- current_wire_rand = true;
- } |
- TOK_CONST {
- current_wire_const = true;
};
non_opt_range:
@@ -884,7 +908,11 @@ task_func_args:
task_func_port:
attr wire_type range {
+ bool prev_was_input = true;
+ bool prev_was_output = false;
if (albuf) {
+ prev_was_input = astbuf1->is_input;
+ prev_was_output = astbuf1->is_output;
delete astbuf1;
if (astbuf2 != NULL)
delete astbuf2;
@@ -893,6 +921,12 @@ task_func_port:
albuf = $1;
astbuf1 = $2;
astbuf2 = checkRange(astbuf1, $3);
+ if (!astbuf1->is_input && !astbuf1->is_output) {
+ if (!sv_mode)
+ frontend_verilog_yyerror("task/function argument direction missing");
+ astbuf1->is_input = prev_was_input;
+ astbuf1->is_output = prev_was_output;
+ }
} wire_name |
{
if (!astbuf1) {
@@ -1793,7 +1827,7 @@ type_name: TOK_ID // first time seen
;
typedef_decl:
- TOK_TYPEDEF wire_type range type_name range_or_multirange ';' {
+ TOK_TYPEDEF non_io_wire_type range type_name range_or_multirange ';' {
astbuf1 = $2;
astbuf2 = checkRange(astbuf1, $3);
if (astbuf2)