Я только что узнал об этой проблеме.
Предположим, я использую арбитр для арбитража вывода драйвера шины от нескольких инициаторов параллельных транзакций. Шина и инициаторы используют DecoupledIO. Известно, что Арбитр имеет приоритет в (0) над (1). Учитывая этот случай:
clock 1: in(0).valid = 0, in(1).valid = 1 -> out === in(1) out.valid = 1 out.ready = 0
clock 2: in(1).valid = 1, in(1).valid = 1 -> out === in(0) out.valid = 1 out.ready = 1
Таким образом, и часы 1, и часы 2 имеют bus.valid === 1 Если клиент на этой шине не может ответить в том же цикле, но в следующем цикле, out.ready, управляемый этим клиентом, фактически соответствует in(1), а НЕ in( 0) в часах 2.
Я ожидаю, что арбитр выберет in(0), если in(0) и in(1) станут действительными в один и тот же такт, но если in(1) становится действительным до in(0), арбитр продолжает выбирать in(1) ) до тех пор, пока не сработает in(1).
В этом случае LockingArbiter, RRArbiter ведут себя одинаково: ввод с более высоким приоритетом всегда может вытеснить ввод с более низким приоритетом до того, как ввод с более низким приоритетом будет заблокирован (когда count == 1, блокировки вообще нет).
Я как бы рассматриваю этот нестабильный вывод как проблему, похожую на ошибку Арбитра. Есть ли обходной путь для этого?