vvp: handle tranif enable changes that result from island resolution.
The tran island resolution tests and caches the state of all branch enable inputs before resolving the branch endpoint values. If a branch enable is connected directly to a branch endpoint, we need to update the cached stete and rerun the island resolution if any enable state changed. This fixes issue #1122.
This commit is contained in:
parent
615a01c6cd
commit
3b61c0088d
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008-2022 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2024 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
|
|
@ -47,6 +47,7 @@ struct vvp_island_branch_tran : public vvp_island_branch {
|
|||
unsigned width__, unsigned part__,
|
||||
unsigned offset__, bool resistive__);
|
||||
void run_test_enabled();
|
||||
bool rerun_test_enabled();
|
||||
void run_resolution();
|
||||
void run_output();
|
||||
|
||||
|
|
@ -91,6 +92,7 @@ void vvp_island_tran::run_island()
|
|||
tmp->run_test_enabled();
|
||||
}
|
||||
|
||||
rerun:
|
||||
// Now resolve all the branches in the island.
|
||||
for (vvp_island_branch*cur = branches_ ; cur ; cur = cur->next_branch) {
|
||||
vvp_island_branch_tran*tmp = dynamic_cast<vvp_island_branch_tran*>(cur);
|
||||
|
|
@ -104,6 +106,15 @@ void vvp_island_tran::run_island()
|
|||
assert(tmp);
|
||||
tmp->run_output();
|
||||
}
|
||||
|
||||
// Now check if the enable inputs have been affected by the resolution.
|
||||
bool enable_changed = false;
|
||||
for (vvp_island_branch*cur = branches_ ; cur ; cur = cur->next_branch) {
|
||||
vvp_island_branch_tran*tmp = dynamic_cast<vvp_island_branch_tran*>(cur);
|
||||
assert(tmp);
|
||||
enable_changed |= tmp->rerun_test_enabled();
|
||||
}
|
||||
if (enable_changed) goto rerun;
|
||||
}
|
||||
|
||||
static void count_drivers_(vvp_branch_ptr_t cur, bool other_side_visited,
|
||||
|
|
@ -230,6 +241,38 @@ void vvp_island_branch_tran::run_test_enabled()
|
|||
}
|
||||
}
|
||||
|
||||
bool vvp_island_branch_tran::rerun_test_enabled()
|
||||
{
|
||||
vvp_island_port*ep = en? dynamic_cast<vvp_island_port*> (en->fun) : NULL;
|
||||
|
||||
if (ep == 0)
|
||||
return false;
|
||||
|
||||
// We are only looking for changes resulting from running the island
|
||||
// resolution. If the outvalue is nil, we know that the enable port
|
||||
// is an .import, so won't be affected.
|
||||
if (ep->outvalue.size() == 0)
|
||||
return false;
|
||||
|
||||
vvp_bit4_t enable_val = ep->outvalue.value(0).value();
|
||||
|
||||
tran_state_t old_state = state;
|
||||
|
||||
switch (enable_val) {
|
||||
case BIT4_0:
|
||||
state = active_high ? tran_disabled : tran_enabled;
|
||||
break;
|
||||
case BIT4_1:
|
||||
state = active_high ? tran_enabled : tran_disabled;
|
||||
break;
|
||||
default:
|
||||
state = tran_unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
return state != old_state;
|
||||
}
|
||||
|
||||
// The IEEE standard does not specify the behaviour when a tranif control
|
||||
// input is 'x' or 'z'. We use the rules that are given for MOS switches.
|
||||
inline vvp_vector8_t resolve_ambiguous(const vvp_vector8_t&a,
|
||||
|
|
|
|||
Loading…
Reference in New Issue