Ваш код не работает, потому что вы делаете два назначения для internal_counter
. Это разрешено, но правило таково: последнее назначение «выигрывает» .
Итак, давайте пройдемся по коду, когда сброс активен:
if (reset)
internal_counter <= 0;
Это делает что internal_counter
сбрасывается (устанавливается в ноль).
Но позже мы получаем другое назначение:
internal_counter <= internal_counter + 1;
Поскольку это позднее / позади предыдущего назначения, оно "выигрывает". Здесь есть нет условия, поэтому этот всегда заменяет предыдущий if ...
. При этом код if...
становится лишним. Он никогда не выполняется, и инструмент синтеза удалит для этого все логины c.
Как уже отмечали другие: вам нужен раздел else
. Рекомендуется сбросить все переменные в разделе сброса:
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
begin
internal_counter <= 0;
led <= 1'b1;
counter_out <= 0;
end // reset section
else
begin // clocked section
internal_counter <= internal_counter + 1;
led <= 1'b0;
counter_out <= internal_counter;
end
end // clocked section
Теперь мы получили несколько общих замечаний:
Я предлагаю вам перейти к определениям портов ANSI. Это проще, так как вы держите все вместе. Если вам нужно изменить, например, ширину counter_out
, вы можете сделать это в одном месте:
module simple_counter (
input CLOCK_50 ,
input reset ,
output reg led,
output reg [31:0] counter_out
);
Ваш led
немного странный. Это высокий при сбросе, низкий в противном случае. Я предполагаю, что вы сделали это для отладки.
counter_out
всегда на одно значение за внутренним_счетчиком. Это то, что вы хотите? Это также стоит вам 32 дополнительных регистра. Я ожидал бы обойтись без внутреннего счетчика и использовать direct_out direct:
always @ (posedge CLOCK_50) // on positive clock edge
begin
if (reset)
begin
led <= 1'b1;
counter_out <= 0;
end // reset section
else
begin // clocked section
led <= 1'b0;
counter_out <= counter_out + 1;
end
end // clocked section