Permalink
Browse files

Rework of automatic task/function support.

This patch splits any VVP net functor that needs to access both
statically and automatically allocated state into two sub-classes,
one for handling operations on statically allocated state, the
other for handling operations on automatically allocated state.
This undoes the increase in run-time memory use introduced when
automatic task/function support was first introduced.

This patch also fixes various issues with event handling in automatic
scopes. Event expressions in automatic scopes may now reference either
statically or automatically allocated variables or arrays, or part
selects or word selects thereof. More complex expressions (e.g.
containing arithmetic or logical operators, function calls, etc.) are
not currently supported.

This patch introduces some error checking for language constructs
that may not reference automatically allocated variables. Further
error checking will follow in a subsequent patch.
  • Loading branch information...
Martin Whitaker authored and steveicarus committed Oct 28, 2008
1 parent ea057a7 commit 18edf2f15f7279686453ca15a136ae2618c65200
Showing with 2,145 additions and 819 deletions.
  1. +1 −0 compiler.h
  2. +1 −2 elab_anet.cc
  3. +2 −2 elab_expr.cc
  4. +1 −1 elab_lval.cc
  5. +1 −2 elab_net.cc
  6. +1 −1 elab_sig.cc
  7. +3 −2 elaborate.cc
  8. +1 −1 eval.cc
  9. +3 −0 main.cc
  10. +6 −1 net_event.cc
  11. +9 −5 netmisc.h
  12. +27 −4 pform.cc
  13. +9 −1 symbol_search.cc
  14. +2 −2 vpi/sys_lxt.c
  15. +2 −2 vpi/sys_lxt2.c
  16. +2 −2 vpi/sys_vcd.c
  17. +1 −0 vpi_user.h
  18. +104 −76 vvp/arith.cc
  19. +56 −28 vvp/arith.h
  20. +153 −14 vvp/array.cc
  21. +2 −2 vvp/bufif.cc
  22. +2 −1 vvp/bufif.h
  23. +3 −29 vvp/compile.cc
  24. +1 −5 vvp/compile.h
  25. +6 −5 vvp/concat.cc
  26. +13 −9 vvp/delay.cc
  27. +8 −4 vvp/delay.h
  28. +4 −3 vvp/dff.cc
  29. +2 −1 vvp/dff.h
  30. +384 −122 vvp/event.cc
  31. +170 −19 vvp/event.h
  32. +4 −3 vvp/extend.cc
  33. +0 −2 vvp/lexor.lex
  34. +32 −23 vvp/logic.cc
  35. +18 −9 vvp/logic.h
  36. +8 −7 vvp/npmos.cc
  37. +4 −2 vvp/npmos.h
  38. +4 −10 vvp/parse.y
  39. +237 −27 vvp/part.cc
  40. +96 −10 vvp/part.h
  41. +12 −7 vvp/reduce.cc
  42. +8 −5 vvp/resolv.cc
  43. +6 −3 vvp/resolv.h
  44. +3 −3 vvp/schedule.cc
  45. +4 −3 vvp/ufunc.cc
  46. +1 −1 vvp/ufunc.h
  47. +1 −1 vvp/vpi_callback.cc
  48. +16 −2 vvp/vpi_event.cc
  49. +7 −2 vvp/vpi_priv.h
  50. +7 −2 vvp/vpi_real.cc
  51. +39 −23 vvp/vpi_scope.cc
  52. +10 −3 vvp/vpi_signal.cc
  53. +2 −2 vvp/vpi_tasks.cc
  54. +61 −38 vvp/vthread.cc
  55. +24 −14 vvp/vthread.h
  56. +8 −4 vvp/vvp_island.cc
  57. +336 −208 vvp/vvp_net.cc
  58. +201 −52 vvp/vvp_net.h
  59. +16 −7 vvp/words.cc
View
@@ -87,6 +87,7 @@ extern bool debug_eval_tree;
extern bool debug_elaborate;
extern bool debug_synth2;
extern bool debug_optimizer;
+extern bool debug_automatic;
/* Path to a directory useful for finding subcomponents. */
extern const char*basedir;
View
@@ -115,7 +115,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
const NetExpr*par = 0;
NetEvent* eve = 0;
- symbol_search(des, scope, path_, sig, mem, par, eve);
+ symbol_search(this, des, scope, path_, sig, mem, par, eve);
if (mem != 0) {
@@ -211,4 +211,3 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
* Check lvalue of procedural continuous assign (PR#29)
*
*/
-
View
@@ -1641,7 +1641,7 @@ unsigned PEIdent::test_width(Design*des, NetScope*scope,
const NetExpr*ex1, *ex2;
- symbol_search(des, scope, path_, net, par, eve, ex1, ex2);
+ symbol_search(0, des, scope, path_, net, par, eve, ex1, ex2);
// If there is a part/bit select expression, then process it
// here. This constrains the results no matter what kind the
@@ -1754,7 +1754,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
const NetExpr*ex1, *ex2;
- NetScope*found_in = symbol_search(des, scope, path_,
+ NetScope*found_in = symbol_search(this, des, scope, path_,
net, par, eve,
ex1, ex2);
View
@@ -152,7 +152,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
const NetExpr*par = 0;
NetEvent* eve = 0;
- symbol_search(des, scope, path_, reg, par, eve);
+ symbol_search(this, des, scope, path_, reg, par, eve);
if (reg == 0) {
cerr << get_fileline() << ": error: Could not find variable ``"
<< path_ << "'' in ``" << scope_path(scope) <<
View
@@ -374,7 +374,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
const NetExpr*par = 0;
NetEvent* eve = 0;
- symbol_search(des, scope, path_, sig, par, eve);
+ symbol_search(this, des, scope, path_, sig, par, eve);
if (eve != 0) {
cerr << get_fileline() << ": error: named events (" << path_
@@ -631,4 +631,3 @@ NetNet* PEIdent::elaborate_port(Design*des, NetScope*scope) const
return sig;
}
-
View
@@ -266,7 +266,7 @@ bool PEIdent::elaborate_sig(Design*des, NetScope*scope) const
if (error_implicit)
return true;
- symbol_search(des, scope, path_, sig, par, eve);
+ symbol_search(this, des, scope, path_, sig, par, eve);
if (eve != 0)
return false;
View
@@ -2861,7 +2861,8 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
const NetExpr*par = 0;
NetEvent* eve = 0;
- NetScope*found_in = symbol_search(des, scope, id->path(),
+ NetScope*found_in = symbol_search(this, des, scope,
+ id->path(),
sig, par, eve);
if (found_in && eve) {
@@ -3463,7 +3464,7 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
const NetExpr*par = 0;
NetEvent* eve = 0;
- NetScope*found_in = symbol_search(des, scope, event_,
+ NetScope*found_in = symbol_search(this, des, scope, event_,
sig, par, eve);
if (found_in == 0) {
View
@@ -185,7 +185,7 @@ verinum* PEIdent::eval_const(Design*des, NetScope*scope) const
return new verinum(scope->genvar_tmp_val);
}
- symbol_search(des, scope, path_, net, expr, eve);
+ symbol_search(this, des, scope, path_, net, expr, eve);
if (expr == 0)
return 0;
View
@@ -124,6 +124,7 @@ bool debug_eval_tree = false;
bool debug_elaborate = false;
bool debug_synth2 = false;
bool debug_optimizer = false;
+bool debug_automatic = false;
/*
* Verbose messages enabled.
@@ -392,6 +393,8 @@ static void read_iconfig_file(const char*ipath)
} else if (strcmp(cp,"optimizer") == 0) {
debug_optimizer = true;
cerr << "debug: Enable optimizer debug" << endl;
+ } else if (strcmp(cp,"automatic") == 0) {
+ debug_automatic = true;
} else {
}
View
@@ -173,6 +173,12 @@ void NetEvent::find_similar_event(list<NetEvent*>&event_list)
if (tmp == this)
continue;
+ /* For automatic tasks, the VVP runtime holds state for events
+ in the automatically allocated context. This means we can't
+ merge similar events in different automatic tasks. */
+ if (scope()->is_auto() && (tmp->scope() != scope()))
+ continue;
+
if ((*idx).second != probe_count)
continue;
@@ -553,4 +559,3 @@ NetProc* NetEvWait::statement()
* Simulate named event trigger and waits.
*
*/
-
View
@@ -36,21 +36,25 @@
* ex2 is the lsb expression for the range. If there is no range, then
* these values are set to 0.
*/
-extern NetScope* symbol_search(Design*des,
- NetScope*start, pform_name_t path,
+extern NetScope* symbol_search(const LineInfo*li,
+ Design*des,
+ NetScope*start,
+ pform_name_t path,
NetNet*&net, /* net/reg */
const NetExpr*&par,/* parameter */
NetEvent*&eve, /* named event */
const NetExpr*&ex1, const NetExpr*&ex2);
-inline NetScope* symbol_search(Design*des,
- NetScope*start, const pform_name_t&path,
+inline NetScope* symbol_search(const LineInfo*li,
+ Design*des,
+ NetScope*start,
+ const pform_name_t&path,
NetNet*&net, /* net/reg */
const NetExpr*&par,/* parameter */
NetEvent*&eve /* named event */)
{
const NetExpr*ex1, *ex2;
- return symbol_search(des, start, path, net, par, eve, ex1, ex2);
+ return symbol_search(li, des, start, path, net, par, eve, ex1, ex2);
}
/*
View
@@ -110,11 +110,12 @@ PTask* pform_push_task_scope(char*name, bool is_auto)
PTask*task;
if (pform_cur_generate) {
task = new PTask(task_name, pform_cur_generate->lexical_scope,
- is_auto);
+ is_auto || debug_automatic);
pform_cur_generate->tasks[task->pscope_name()] = task;
pform_cur_generate->lexical_scope = task;
} else {
- task = new PTask(task_name, lexical_scope, is_auto);
+ task = new PTask(task_name, lexical_scope,
+ is_auto || debug_automatic);
pform_cur_module->tasks[task->pscope_name()] = task;
lexical_scope = task;
}
@@ -129,11 +130,12 @@ PFunction* pform_push_function_scope(char*name, bool is_auto)
PFunction*func;
if (pform_cur_generate) {
func = new PFunction(func_name, pform_cur_generate->lexical_scope,
- is_auto);
+ is_auto || debug_automatic);
pform_cur_generate->funcs[func->pscope_name()] = func;
pform_cur_generate->lexical_scope = func;
} else {
- func = new PFunction(func_name, lexical_scope, is_auto);
+ func = new PFunction(func_name, lexical_scope,
+ is_auto || debug_automatic);
pform_cur_module->funcs[func->pscope_name()] = func;
lexical_scope = func;
}
@@ -181,6 +183,20 @@ static LexicalScope*pform_get_cur_scope()
return lexical_scope;
}
+static bool pform_at_module_level()
+{
+ if (pform_cur_generate)
+ if (pform_cur_generate->lexical_scope)
+ return false;
+ else
+ return true;
+ else
+ if (lexical_scope->pscope_parent())
+ return false;
+ else
+ return true;
+}
+
PWire*pform_get_wire_in_scope(perm_string name)
{
/* Note that if we are processing a generate, then the
@@ -1293,6 +1309,13 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
void pform_make_reginit(const struct vlltype&li,
perm_string name, PExpr*expr)
{
+ if (! pform_at_module_level()) {
+ VLerror(li, "variable declaration assignments are only "
+ "allowed at the module level.");
+ delete expr;
+ return;
+ }
+
PWire*cur = pform_get_wire_in_scope(name);
if (cur == 0) {
VLerror(li, "internal error: reginit to non-register?");
View
@@ -28,7 +28,8 @@
/*
* Search for the hierarchical name.
*/
-NetScope*symbol_search(Design*des, NetScope*scope, pform_name_t path,
+NetScope*symbol_search(const LineInfo*li, Design*des, NetScope*scope,
+ pform_name_t path,
NetNet*&net,
const NetExpr*&par,
NetEvent*&eve,
@@ -57,6 +58,13 @@ NetScope*symbol_search(Design*des, NetScope*scope, pform_name_t path,
return 0;
scope = des->find_scope(scope, path_list);
+
+ if (scope->is_auto() && li) {
+ cerr << li->get_fileline() << ": error: Hierarchical "
+ "reference to automatically allocated item "
+ "`" << key << "' in path `" << path << "'" << endl;
+ des->errors += 1;
+ }
}
while (scope) {
View
@@ -546,7 +546,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
case vpiTimeVar:
case vpiReg: type = "reg"; }
- if (skip) break;
+ if (skip || vpi_get(vpiAutomatic, item)) break;
name = vpi_get_str(vpiName, item);
nexus_id = vpi_get(_vpiNexusId, item);
@@ -593,7 +593,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
case vpiRealVar:
- if (skip) break;
+ if (skip || vpi_get(vpiAutomatic, item)) break;
name = vpi_get_str(vpiName, item);
{ char*tmp = create_full_name(name);
View
@@ -552,7 +552,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
case vpiTimeVar:
case vpiReg: type = "reg"; }
- if (skip) break;
+ if (skip || vpi_get(vpiAutomatic, item)) break;
name = vpi_get_str(vpiName, item);
nexus_id = vpi_get(_vpiNexusId, item);
@@ -603,7 +603,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
case vpiRealVar:
- if (skip) break;
+ if (skip || vpi_get(vpiAutomatic, item)) break;
name = vpi_get_str(vpiName, item);
{ char*tmp = create_full_name(name);
View
@@ -513,7 +513,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
break;
}
- if (skip) break;
+ if (skip || vpi_get(vpiAutomatic, item)) break;
name = vpi_get_str(vpiName, item);
prefix = is_escaped_id(name) ? "\\" : "";
@@ -578,7 +578,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
break;
}
- if (skip) break;
+ if (skip || vpi_get(vpiAutomatic, item)) break;
/* Declare the variable in the VCD file. */
name = vpi_get_str(vpiName, item);
View
@@ -348,6 +348,7 @@ typedef struct t_vpi_delay {
# define vpiSysFuncReal vpiRealFunc
# define vpiSysFuncTime vpiTimeFunc
# define vpiSysFuncSized vpiSizedFunc
+#define vpiAutomatic 50
#define vpiConstantSelect 53
#define vpiSigned 65
/* IVL private properties */
Oops, something went wrong.

0 comments on commit 18edf2f

Please sign in to comment.