Pass to the targets if an implicit T0 trigger event is needed.
This commit is contained in:
parent
585a0232cb
commit
84d0df8a8a
|
|
@ -4208,6 +4208,9 @@ NetProc* PEventStatement::elaborate_st(Design*des, NetScope*scope,
|
||||||
if (synthesis || search_funcs_) {
|
if (synthesis || search_funcs_) {
|
||||||
rem_out = true;
|
rem_out = true;
|
||||||
}
|
}
|
||||||
|
// If this is an always_comp/latch then we need an implicit T0
|
||||||
|
// trigger of the event expression.
|
||||||
|
if (search_funcs_) wa->set_t0_trigger();
|
||||||
NexusSet*nset = enet->nex_input(rem_out, search_funcs_);
|
NexusSet*nset = enet->nex_input(rem_out, search_funcs_);
|
||||||
if (nset == 0) {
|
if (nset == 0) {
|
||||||
cerr << get_fileline() << ": error: Unable to elaborate:"
|
cerr << get_fileline() << ": error: Unable to elaborate:"
|
||||||
|
|
@ -6111,7 +6114,7 @@ bool Design::check_proc_delay() const
|
||||||
|
|
||||||
for (const NetProcTop*pr = procs_ ; pr ; pr = pr->next_) {
|
for (const NetProcTop*pr = procs_ ; pr ; pr = pr->next_) {
|
||||||
/* If this is an always block and we have no or zero delay then
|
/* If this is an always block and we have no or zero delay then
|
||||||
* a runtime infinite loop will happen. If we possible have some
|
* a runtime infinite loop will happen. If we possibly have some
|
||||||
* delay then print a warning that an infinite loop is possible.
|
* delay then print a warning that an infinite loop is possible.
|
||||||
*/
|
*/
|
||||||
if ((pr->type() == IVL_PR_ALWAYS) ||
|
if ((pr->type() == IVL_PR_ALWAYS) ||
|
||||||
|
|
|
||||||
1
ivl.def
1
ivl.def
|
|
@ -294,6 +294,7 @@ ivl_stmt_lval
|
||||||
ivl_stmt_lvals
|
ivl_stmt_lvals
|
||||||
ivl_stmt_lwidth
|
ivl_stmt_lwidth
|
||||||
ivl_stmt_name
|
ivl_stmt_name
|
||||||
|
ivl_stmt_needs_t0_trigger
|
||||||
ivl_stmt_nevent
|
ivl_stmt_nevent
|
||||||
ivl_stmt_opcode
|
ivl_stmt_opcode
|
||||||
ivl_stmt_parm
|
ivl_stmt_parm
|
||||||
|
|
|
||||||
|
|
@ -2105,6 +2105,7 @@ extern unsigned ivl_stmt_lineno(ivl_statement_t net);
|
||||||
* handle disable statements.
|
* handle disable statements.
|
||||||
*
|
*
|
||||||
* ivl_stmt_events
|
* ivl_stmt_events
|
||||||
|
* ivl_stmt_needs_t0_trigger
|
||||||
* ivl_stmt_nevent
|
* ivl_stmt_nevent
|
||||||
* Statements that have event arguments (TRIGGER and WAIT) make
|
* Statements that have event arguments (TRIGGER and WAIT) make
|
||||||
* those event objects available through these methods.
|
* those event objects available through these methods.
|
||||||
|
|
@ -2232,6 +2233,7 @@ extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net);
|
||||||
/* IVL_ST_DELAY */
|
/* IVL_ST_DELAY */
|
||||||
extern uint64_t ivl_stmt_delay_val(ivl_statement_t net);
|
extern uint64_t ivl_stmt_delay_val(ivl_statement_t net);
|
||||||
/* IVL_ST_WAIT IVL_ST_TRIGGER */
|
/* IVL_ST_WAIT IVL_ST_TRIGGER */
|
||||||
|
extern unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net);
|
||||||
extern unsigned ivl_stmt_nevent(ivl_statement_t net);
|
extern unsigned ivl_stmt_nevent(ivl_statement_t net);
|
||||||
extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx);
|
extern ivl_event_t ivl_stmt_events(ivl_statement_t net, unsigned idx);
|
||||||
/* IVL_ST_CONTRIB */
|
/* IVL_ST_CONTRIB */
|
||||||
|
|
|
||||||
|
|
@ -3398,10 +3398,12 @@ class NetEvWait : public NetProc {
|
||||||
|
|
||||||
void add_event(NetEvent*tgt);
|
void add_event(NetEvent*tgt);
|
||||||
void replace_event(NetEvent*orig, NetEvent*repl);
|
void replace_event(NetEvent*orig, NetEvent*repl);
|
||||||
|
inline void set_t0_trigger() { has_t0_trigger_ = true; };
|
||||||
|
|
||||||
inline unsigned nevents() const { return events_.size(); }
|
inline unsigned nevents() const { return events_.size(); }
|
||||||
inline const NetEvent*event(unsigned idx) const { return events_[idx]; }
|
inline const NetEvent*event(unsigned idx) const { return events_[idx]; }
|
||||||
inline NetEvent*event(unsigned idx) { return events_[idx]; }
|
inline NetEvent*event(unsigned idx) { return events_[idx]; }
|
||||||
|
inline bool has_t0_trigger() const { return has_t0_trigger_; };
|
||||||
|
|
||||||
NetProc*statement();
|
NetProc*statement();
|
||||||
|
|
||||||
|
|
@ -3442,6 +3444,7 @@ class NetEvWait : public NetProc {
|
||||||
NetProc*statement_;
|
NetProc*statement_;
|
||||||
// Events that I might wait for.
|
// Events that I might wait for.
|
||||||
std::vector<NetEvent*>events_;
|
std::vector<NetEvent*>events_;
|
||||||
|
bool has_t0_trigger_;
|
||||||
};
|
};
|
||||||
|
|
||||||
ostream& operator << (ostream&out, const NetEvWait&obj);
|
ostream& operator << (ostream&out, const NetEvWait&obj);
|
||||||
|
|
|
||||||
10
t-dll-api.cc
10
t-dll-api.cc
|
|
@ -2815,6 +2815,16 @@ extern "C" uint64_t ivl_stmt_delay_val(ivl_statement_t net)
|
||||||
return net->u_.delay_.value;
|
return net->u_.delay_.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" unsigned ivl_stmt_needs_t0_trigger(ivl_statement_t net)
|
||||||
|
{
|
||||||
|
assert(net);
|
||||||
|
if (net->type_ == IVL_ST_WAIT) {
|
||||||
|
return net->u_.wait_.needs_t0_trigger;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net)
|
extern "C" unsigned ivl_stmt_nevent(ivl_statement_t net)
|
||||||
{
|
{
|
||||||
assert(net);
|
assert(net);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
|
* Copyright (c) 2000-2017 Stephen Williams (steve@icarus.com)
|
||||||
*
|
*
|
||||||
* This source code is free software; you can redistribute it
|
* This source code is free software; you can redistribute it
|
||||||
* and/or modify it in source code form under the terms of the GNU
|
* and/or modify it in source code form under the terms of the GNU
|
||||||
|
|
@ -847,12 +847,15 @@ bool dll_target::proc_wait(const NetEvWait*net)
|
||||||
|
|
||||||
/* This is a wait fork statement. */
|
/* This is a wait fork statement. */
|
||||||
if ((net->nevents() == 1) && (net->event(0) == 0)) {
|
if ((net->nevents() == 1) && (net->event(0) == 0)) {
|
||||||
|
stmt_cur_->u_.wait_.needs_t0_trigger = 0;
|
||||||
stmt_cur_->u_.wait_.event = 0;
|
stmt_cur_->u_.wait_.event = 0;
|
||||||
stmt_cur_->type_ = IVL_ST_WAIT;
|
stmt_cur_->type_ = IVL_ST_WAIT;
|
||||||
stmt_cur_->u_.wait_.stmt_->type_ = IVL_ST_NOOP;
|
stmt_cur_->u_.wait_.stmt_->type_ = IVL_ST_NOOP;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stmt_cur_->u_.wait_.needs_t0_trigger = net->has_t0_trigger();
|
||||||
|
|
||||||
// This event processing code is also in the NB assign above.
|
// This event processing code is also in the NB assign above.
|
||||||
if (net->nevents() > 1) {
|
if (net->nevents() > 1) {
|
||||||
stmt_cur_->u_.wait_.events = (ivl_event_t*)
|
stmt_cur_->u_.wait_.events = (ivl_event_t*)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue