У меня проблемы с пониманием того, как я могу предотвратить создание защелок в проекте Verilog. Я понимаю, что создаются защелки, потому что я не указываю, что происходит со всеми сигналами в каждом операторе case. Однако я не знаю, есть ли способ избежать этого (кроме драконовского метода, который я использовал в данный момент).
В настоящее время у меня есть два регистра сдвига, register X
и register R
. Каждый из этих регистров сдвига имеет 5-битную шину управления, управляемую из конечного автомата. Чтобы упростить управление этими регистрами сдвига, я надеялся использовать побитовые операции для установки и сброса битов шины управления.
Например, в состоянии done
мне нужно сбросить бит shiftRight
для register R
. Для этого я могу выполнить следующую побитовую операцию:
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftRight;
Это работает отлично. Ниже вы можете увидеть все сигналы и побитовые операции, которые я определил для шины управления регистром. Однако, поскольку мне не нужно изменять все шины управления регистрами для обоих регистров в каждом состоянии, я получаю защелки. Например, в состоянии done
ниже мне нужно только изменить шину управления регистром для register R
. В результате создается защелка для register X
шины управления.
В данный момент я решил эту проблему, просто установив все биты для обеих шин управления регистром в каждом состоянии конечного автомата, отбросив мою идею выполнять побитовые операции над сигналами.
Однако я считаю, что метод побитовой операции чище - я хотел бы знать, есть ли для меня возможность продолжать использовать этот метод, не имея дело с защелками. Это делает код намного проще для чтения и изменения.
Как всегда, спасибо за любую помощь.
// Register Control Bus Signals
// bit # - purpose
// 0 - reset (rst)
// 1 - load (ld)
// 2 - shift left (sl)
// 3 - shift right (sr)
// 4 - auxilary 1 (mux select)
parameter register_ctrl_reset = 5'b00001;
parameter register_ctrl_load = 5'b00010;
parameter register_ctrl_shiftLeft = 5'b00100;
parameter register_ctrl_shiftRight = 5'b01000;
parameter register_ctrl_auxilary = 5'b10000;
parameter register_ctrl_width = 5;
output reg [register_ctrl_width-1:0] xRegisterControlBus;
output reg [register_ctrl_width-1:0] rRegisterControlBus;
Предыдущее решение:
always@(currentState, ryCompareOut)
begin
case(currentState)
shiftRight:
begin
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftLeft;
xRegisterControlBus = xRegisterControlBus & ~register_ctrl_shiftLeft;
rRegisterControlBus = rRegisterControlBus | register_ctrl_shiftRight;
end
done:
begin
rRegisterControlBus = rRegisterControlBus & ~register_ctrl_shiftRight;
end
endcase
end