Прежде всего, не забывайте свои begin
- end
s вокруг разделов кода:
else begin
r_reg[0]=data;
r_reg = r_reg<<1;
end
Без этого только r_reg[0]=data
будет в предложении else
if
заявление.Это будет работать, но считается плохим стилем из-за операторов блокировки в описании последовательной логики ...
Во-вторых, для моделирования последовательных блоков используйте неблокирующие назначения (<=
), иначе ваши вычисления могут «провалиться».'(Google неблокирует против блокировки для получения дополнительной информации).Ваш пример может очень хорошо сработать (вы пробовали это в симуляторе?), Но если все усложняется и добавляется больше переменных, то все может сломаться.
always @(posedge clk or negedge reset)
begin
if(!reset)
r_reg <= 0;
else begin // This is horrible! Don't write code like this!
r_reg[0] = data; // blocking
r_reg <= r_reg<<1; // non-blocking
end
end
По вышеуказанной причине иногда рекомендуется, чтобы комбо-логика была отделена от последовательной логики, чтобы вы могли записывать неблокирующие назначения в регистры в последовательных блоках и блокировать в комбо-блоках, и вам никогда не придется беспокоиться опланирование.
Чтобы кодировать таким образом, вам нужно вычислить, каким должен быть следующий вывод, используя текущее состояние, отсюда шина r_next
в ответе.Я думаю, что это также помогает инструменту синтеза, если все триггеры отделены от окружающей комбо-логики таким образом.
Кроме того, если ваш сброс активен на низком уровне (т.е. сбрасывается LOW
), он долженбыть названным таковым, например resetb
или reset_n
.