Merge branch 'master' into vvp-net-out-rework
This commit is contained in:
commit
6e1d7b6210
|
|
@ -66,6 +66,11 @@ other tools.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -gverilog-ams\fI|-fP-gno-verilog-ams
|
.B -gverilog-ams\fI|-fP-gno-verilog-ams
|
||||||
Enable or disable (default) support for Verilog-AMS.
|
Enable or disable (default) support for Verilog-AMS.
|
||||||
|
Very little Verilog-AMS specific functionality is currently supported.
|
||||||
|
.TP 8
|
||||||
|
.B -gsystem-verilog\fI|-fP-gno-system-verilog
|
||||||
|
Enable or disable (default) support for SystemVerilog.
|
||||||
|
Very little SystemVerilog specific functionality is currently supported.
|
||||||
.TP 8
|
.TP 8
|
||||||
.B -gspecify\fI|\fP-gno-specify
|
.B -gspecify\fI|\fP-gno-specify
|
||||||
Enable or disable (default) specify block support. When enabled,
|
Enable or disable (default) specify block support. When enabled,
|
||||||
|
|
|
||||||
|
|
@ -626,6 +626,9 @@ int process_generation(const char*name)
|
||||||
else if (strcmp(name,"system-verilog") == 0)
|
else if (strcmp(name,"system-verilog") == 0)
|
||||||
gen_system_verilog = "system-verilog";
|
gen_system_verilog = "system-verilog";
|
||||||
|
|
||||||
|
else if (strcmp(name,"no-system-verilog") == 0)
|
||||||
|
gen_verilog_ams = "no-system-verilog";
|
||||||
|
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "Unknown/Unsupported Language generation "
|
fprintf(stderr, "Unknown/Unsupported Language generation "
|
||||||
"%s\n\n", name);
|
"%s\n\n", name);
|
||||||
|
|
@ -636,6 +639,7 @@ int process_generation(const char*name)
|
||||||
"Other generation flags:\n"
|
"Other generation flags:\n"
|
||||||
" specify | no-specify\n"
|
" specify | no-specify\n"
|
||||||
" verilog-ams | no-verilog-ams\n"
|
" verilog-ams | no-verilog-ams\n"
|
||||||
|
" system-verilog | no-system-verilog\n"
|
||||||
" std-include | no-std-include\n"
|
" std-include | no-std-include\n"
|
||||||
" relative-include | no-relative-include\n"
|
" relative-include | no-relative-include\n"
|
||||||
" xtypes | no-xtypes\n"
|
" xtypes | no-xtypes\n"
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,14 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||||
name_component_t name_tail = path_.back();
|
name_component_t name_tail = path_.back();
|
||||||
oldpath.pop_back();
|
oldpath.pop_back();
|
||||||
|
|
||||||
|
if (path_.size() > 1) {
|
||||||
|
cerr << get_fileline() << ": error: parameter r-value expression "
|
||||||
|
"does not support hierarchical references `" << path_
|
||||||
|
<< "`." << endl;
|
||||||
|
des->errors += 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
NetScope*pscope = scope;
|
NetScope*pscope = scope;
|
||||||
if (path_.size() > 0) {
|
if (path_.size() > 0) {
|
||||||
list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
|
list<hname_t> tmp = eval_scope_path(des, scope, oldpath);
|
||||||
|
|
@ -229,8 +237,9 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||||
ivl_assert(*this, pscope);
|
ivl_assert(*this, pscope);
|
||||||
}
|
}
|
||||||
if (ex == 0) {
|
if (ex == 0) {
|
||||||
cerr << get_fileline() << ": error: identifier ``" << name_tail.name <<
|
cerr << get_fileline() << ": error: identifier `"
|
||||||
"'' is not a parameter in "<< scope_path(scope)<< "." << endl;
|
<< name_tail.name << "` is not a parameter in "
|
||||||
|
<< scope_path(scope)<< "." << endl;
|
||||||
des->errors += 1;
|
des->errors += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1353,10 +1353,17 @@ static void do_expand(int use_args)
|
||||||
struct include_stack_t*isp;
|
struct include_stack_t*isp;
|
||||||
int head = 0;
|
int head = 0;
|
||||||
int tail = 0;
|
int tail = 0;
|
||||||
|
const char *cp;
|
||||||
|
unsigned escapes = 0;
|
||||||
|
char *str_buf = 0;
|
||||||
|
|
||||||
if (cur_macro->keyword)
|
if (cur_macro->keyword)
|
||||||
{
|
{
|
||||||
fprintf(yyout, "%s", cur_macro->value);
|
fprintf(yyout, "%s", cur_macro->value);
|
||||||
|
if (do_expand_stringify_flag) {
|
||||||
|
do_expand_stringify_flag = 0;
|
||||||
|
fputc('"', yyout);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1385,6 +1392,43 @@ static void do_expand(int use_args)
|
||||||
isp->ebs = 0;
|
isp->ebs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Escape some characters if we are making a string version. */
|
||||||
|
for (cp = isp->str; (cp = strpbrk(cp, "\"\\")); cp += 1, escapes += 1);
|
||||||
|
if (escapes && isp->stringify_flag) {
|
||||||
|
unsigned idx = 0;
|
||||||
|
str_buf = (char *) malloc(strlen(isp->str)+3*escapes+1);
|
||||||
|
for (cp = isp->str; *cp; cp += 1) {
|
||||||
|
if (*cp == '"') {
|
||||||
|
str_buf[idx] = '\\';
|
||||||
|
str_buf[idx+1] = '0';
|
||||||
|
str_buf[idx+2] = '4';
|
||||||
|
str_buf[idx+3] = '2';
|
||||||
|
idx += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*cp == '\\') {
|
||||||
|
str_buf[idx] = '\\';
|
||||||
|
str_buf[idx+1] = '1';
|
||||||
|
str_buf[idx+2] = '3';
|
||||||
|
str_buf[idx+3] = '4';
|
||||||
|
idx += 4;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
str_buf[idx] = *cp;
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
str_buf[idx] = 0;
|
||||||
|
idx += 1;
|
||||||
|
if (use_args) exp_buf_free += isp->ebs;
|
||||||
|
exp_buf_grow_to_fit(idx);
|
||||||
|
head = exp_buf_size - exp_buf_free;
|
||||||
|
exp_buf_free -= idx;
|
||||||
|
strcpy(&exp_buf[head], str_buf);
|
||||||
|
isp->str = &exp_buf[head];
|
||||||
|
isp->ebs = idx;
|
||||||
|
free(str_buf);
|
||||||
|
}
|
||||||
|
|
||||||
isp->next = istack;
|
isp->next = istack;
|
||||||
istack->yybs = YY_CURRENT_BUFFER;
|
istack->yybs = YY_CURRENT_BUFFER;
|
||||||
istack = isp;
|
istack = isp;
|
||||||
|
|
@ -1808,4 +1852,5 @@ void destroy_lexor()
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
free(def_buf);
|
free(def_buf);
|
||||||
|
free(exp_buf);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -416,6 +416,7 @@ const char *human_readable_op(const char op, bool unary)
|
||||||
case '-': type = "-"; break;
|
case '-': type = "-"; break;
|
||||||
case '*': type = "*"; break;
|
case '*': type = "*"; break;
|
||||||
case '/': type = "/"; break;
|
case '/': type = "/"; break;
|
||||||
|
case '%': type = "%"; break;
|
||||||
|
|
||||||
case '<': type = "<"; break;
|
case '<': type = "<"; break;
|
||||||
case '>': type = ">"; break;
|
case '>': type = ">"; break;
|
||||||
|
|
|
||||||
49
parse.y
49
parse.y
|
|
@ -80,6 +80,22 @@ static stack<PBlock*> current_block_stack;
|
||||||
const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL };
|
const static struct str_pair_t pull_strength = { PGate::PULL, PGate::PULL };
|
||||||
const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
const static struct str_pair_t str_strength = { PGate::STRONG, PGate::STRONG };
|
||||||
|
|
||||||
|
static list<pair<perm_string,PExpr*> >* make_port_list(char*id, PExpr*expr)
|
||||||
|
{
|
||||||
|
list<pair<perm_string,PExpr*> >*tmp = new list<pair<perm_string,PExpr*> >;
|
||||||
|
tmp->push_back(make_pair(lex_strings.make(id), expr));
|
||||||
|
delete[]id;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
static list<pair<perm_string,PExpr*> >* make_port_list(list<pair<perm_string,
|
||||||
|
PExpr*> >*tmp,
|
||||||
|
char*id, PExpr*expr)
|
||||||
|
{
|
||||||
|
tmp->push_back(make_pair(lex_strings.make(id), expr));
|
||||||
|
delete[]id;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
static list<perm_string>* list_from_identifier(char*id)
|
static list<perm_string>* list_from_identifier(char*id)
|
||||||
{
|
{
|
||||||
list<perm_string>*tmp = new list<perm_string>;
|
list<perm_string>*tmp = new list<perm_string>;
|
||||||
|
|
@ -146,6 +162,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
||||||
strdup. They can be put into lists with the texts type. */
|
strdup. They can be put into lists with the texts type. */
|
||||||
char*text;
|
char*text;
|
||||||
list<perm_string>*perm_strings;
|
list<perm_string>*perm_strings;
|
||||||
|
|
||||||
|
list<pair<perm_string,PExpr*> >*port_list;
|
||||||
|
|
||||||
pform_name_t*pform_name;
|
pform_name_t*pform_name;
|
||||||
|
|
||||||
ivl_discipline_t discipline;
|
ivl_discipline_t discipline;
|
||||||
|
|
@ -260,7 +279,9 @@ static PECallFunction*make_call_function(perm_string tn, PExpr*arg1, PExpr*arg2)
|
||||||
%type <expr> udp_initial_expr_opt
|
%type <expr> udp_initial_expr_opt
|
||||||
|
|
||||||
%type <text> register_variable net_variable real_variable
|
%type <text> register_variable net_variable real_variable
|
||||||
%type <perm_strings> register_variable_list net_variable_list real_variable_list list_of_identifiers
|
%type <perm_strings> register_variable_list net_variable_list
|
||||||
|
%type <perm_strings> real_variable_list list_of_identifiers
|
||||||
|
%type <port_list> list_of_port_identifiers
|
||||||
|
|
||||||
%type <net_decl_assign> net_decl_assign net_decl_assigns
|
%type <net_decl_assign> net_decl_assign net_decl_assigns
|
||||||
|
|
||||||
|
|
@ -1647,6 +1668,17 @@ list_of_identifiers
|
||||||
{ $$ = list_from_identifier($1, $3); }
|
{ $$ = list_from_identifier($1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
list_of_port_identifiers
|
||||||
|
: IDENTIFIER
|
||||||
|
{ $$ = make_port_list($1, 0); }
|
||||||
|
| IDENTIFIER '=' expression
|
||||||
|
{ $$ = make_port_list($1, $3); }
|
||||||
|
| list_of_port_identifiers ',' IDENTIFIER
|
||||||
|
{ $$ = make_port_list($1, $3, 0); }
|
||||||
|
| list_of_port_identifiers ',' IDENTIFIER '=' expression
|
||||||
|
{ $$ = make_port_list($1, $3, $5); }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/* The list_of_ports and list_of_port_declarations rules are the
|
/* The list_of_ports and list_of_port_declarations rules are the
|
||||||
port list formats for module ports. The list_of_ports_opt rule is
|
port list formats for module ports. The list_of_ports_opt rule is
|
||||||
|
|
@ -1991,9 +2023,20 @@ module_item
|
||||||
SR_BOTH);
|
SR_BOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
| K_output var_type signed_opt range_opt list_of_identifiers ';'
|
| K_output var_type signed_opt range_opt list_of_port_identifiers ';'
|
||||||
{ pform_makewire(@1, $4, $3, $5, $2, NetNet::POUTPUT,
|
{ list<pair<perm_string,PExpr*> >::const_iterator pp;
|
||||||
|
list<perm_string>*tmp = new list<perm_string>;
|
||||||
|
for (pp = $5->begin(); pp != $5->end(); pp++) {
|
||||||
|
tmp->push_back((*pp).first);
|
||||||
|
}
|
||||||
|
pform_makewire(@1, $4, $3, tmp, $2, NetNet::POUTPUT,
|
||||||
IVL_VT_NO_TYPE, 0, SR_BOTH);
|
IVL_VT_NO_TYPE, 0, SR_BOTH);
|
||||||
|
for (pp = $5->begin(); pp != $5->end(); pp++) {
|
||||||
|
if ((*pp).second) {
|
||||||
|
pform_make_reginit(@1, (*pp).first, (*pp).second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete $5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* var_type declaration (reg variables) cannot be input or output,
|
/* var_type declaration (reg variables) cannot be input or output,
|
||||||
|
|
|
||||||
|
|
@ -696,16 +696,7 @@ static void real_value(vpiHandle ref, p_vpi_value vp)
|
||||||
assert((ref->vpi_type->type_code == vpiConstant) ||
|
assert((ref->vpi_type->type_code == vpiConstant) ||
|
||||||
(ref->vpi_type->type_code == vpiParameter));
|
(ref->vpi_type->type_code == vpiParameter));
|
||||||
|
|
||||||
switch (vp->format) {
|
vpip_real_get_value(rfp->value, vp);
|
||||||
case vpiObjTypeVal:
|
|
||||||
vp->format = vpiRealVal;
|
|
||||||
case vpiRealVal:
|
|
||||||
vp->value.real = rfp->value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "vvp error: unsupported format %d.\n", vp->format);
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct __vpirt vpip_real_rt = {
|
static const struct __vpirt vpip_real_rt = {
|
||||||
|
|
|
||||||
|
|
@ -984,7 +984,7 @@ bool of_ASSIGN_V0X1(vthread_t thr, vvp_code_t cp)
|
||||||
if (off >= (long)sig->size()) return true;
|
if (off >= (long)sig->size()) return true;
|
||||||
else if (off < 0 ) {
|
else if (off < 0 ) {
|
||||||
// We fell off the LSB end.
|
// We fell off the LSB end.
|
||||||
if ((unsigned)-off > wid ) return true;
|
if ((unsigned)-off >= wid ) return true;
|
||||||
// Trim the bits before the LSB
|
// Trim the bits before the LSB
|
||||||
wid += off;
|
wid += off;
|
||||||
bit -= off;
|
bit -= off;
|
||||||
|
|
@ -1021,7 +1021,7 @@ bool of_ASSIGN_V0X1D(vthread_t thr, vvp_code_t cp)
|
||||||
if (off >= (long)sig->size()) return true;
|
if (off >= (long)sig->size()) return true;
|
||||||
else if (off < 0 ) {
|
else if (off < 0 ) {
|
||||||
// We fell off the LSB end.
|
// We fell off the LSB end.
|
||||||
if ((unsigned)-off > wid ) return true;
|
if ((unsigned)-off >= wid ) return true;
|
||||||
// Trim the bits before the LSB
|
// Trim the bits before the LSB
|
||||||
wid += off;
|
wid += off;
|
||||||
bit -= off;
|
bit -= off;
|
||||||
|
|
@ -1060,7 +1060,7 @@ bool of_ASSIGN_V0X1E(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
} else if (off < 0 ) {
|
} else if (off < 0 ) {
|
||||||
// We fell off the LSB end.
|
// We fell off the LSB end.
|
||||||
if ((unsigned)-off > wid ) {
|
if ((unsigned)-off >= wid ) {
|
||||||
thr->event = 0;
|
thr->event = 0;
|
||||||
thr->ecount = 0;
|
thr->ecount = 0;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue