24-битный конечный автомат счетчика

Я пытаюсь создать счетчик в verilog, который подсчитывает, сколько тактов было, и после десяти миллионов он сбрасывается и запускается снова.

Я создал 24-битный модуль сумматора вместе с другим модулем, содержащим 24 D-триггера, для хранения количества циклов, выдаваемых сумматором.

Затем я хочу иметь конечный автомат, который находится в состоянии подсчета, пока не пройдет десять миллионов циклов, а затем он перейдет в состояние сброса.

Это звучит правильно? Проблема в том, что я не уверен, как реализовать конечный автомат.

Может ли кто-нибудь указать мне веб-сайт/книгу, которая могла бы помочь мне в этом?

Спасибо


person user1018684    schedule 28.10.2011    source источник


Ответы (3)


Как уже упоминал Пол С., нет необходимости в конечном автомате, если вы хотите, чтобы ваш счетчик продолжал считать после переполнения. Вы можете сделать что-то вроде этого (не проверено, могут содержать опечатки):

module overflow_counter (
  clk,
  reset,
  enable,
  ctr_out
);

// Port definitions
input clk, reset, enable;
output [23:0] ctr_out;

// Register definitions
reg [23:0] reg_ctr;

// Assignments
assign ctr_out = reg_ctr;

// Counter behaviour - Asynchronous active-high reset
initial reg_ctr <= 0;
always @ (posedge clk or posedge reset)
begin
  if (reset)                 reg_ctr <= 0;
  else if (enable)
  begin
    if (reg_ctr == 10000000) reg_ctr <= 0;
    else                     reg_ctr <= reg_ctr + 1;
  end
end

endmodule

Конечно, обычно вы использовали бы параметры, поэтому вам не нужно создавать собственный модуль каждый раз, когда вам нужен счетчик переполнения. Я оставлю это вам ;).

[Изменить] А вот несколько документов, которые помогут вам с FSM. Я только что искал в Google «конечный автомат Verilog»:

Первую часть не читал, так что ничего сказать не могу. Второй показывает различные стили кодирования FSM, среди которых стиль 3 всегда блокирует стиль, который я настоятельно рекомендую, потому что его намного проще отлаживать (переходы состояний и вывод FSM аккуратно разделены). Ссылка не работает, поэтому вот кэшированный результат Google.

person AVH    schedule 28.10.2011

Вам не нужна государственная машина. У вас уже есть состояние в счетчике. Все, что вам нужно сделать, это определить значение, которое вы хотите обернуть, и загрузить 0 в свой счетчик в этот момент.

В псевдокоде:

if count == 10000000 then
  nextCount = 0;
else
  nextCount = count + 1;

...or...

nextCount  = count + 1;
if count == 10000000 then
  resetCount = 1;
person Paul S    schedule 28.10.2011

Конечные автоматы не так уж сложны. Используйте localparam (с шириной, не забудьте ширину, она здесь не показана, потому что это всего один бит), чтобы определить метки для ваших состояний. Затем создайте две reg-переменные (state_reg, state_next). Переменная _reg — это ваш фактический регистр. Переменная _next представляет собой "регистр проводов" (проводник, который может быть назначен внутри комбинационного всегда блока). Следует помнить две вещи: выполнять X_next = X_reg; в комбинационном всегда блоке (а затем остальную часть комбинационной логики) и X_reg <= X_next; в последовательном всегда блоке. Вы можете проявить фантазию для особых случаев, но если вы будете придерживаться этих простых правил, все должно работать. Я стараюсь не использовать инстанцирование для очень простых вещей, таких как сумматоры, поскольку Verilog отлично поддерживает сумматоры.

Поскольку я работаю с ПЛИС, я присваиваю своим регистрам начальные значения и не использую сигнал сброса. Я не уверен, но для дизайна ASIC, я думаю, все наоборот.

localparam STATE_RESET = 1'b0, STATE_COUNT = 1'b1;

reg [23:0] cntr_reg = 24'd0, cntr_next;
reg state_reg = STATE_COUNT, state_next;

always @* begin
    cntr_next = cntr_reg; // statement not required since we handle all cases
    if (cntr_reg == 24'd10_000_000)
        cntr_next = 24'd0;
    else
        cntr_next = cntr_reg + 24'd1;
    state_next = state_reg; // statement required since we don't handle all cases
    case (state_reg)
        STATE_COUNT: if (cntr_reg == 24'd10_000_000) state_next = STATE_RESET;
    endcase
end

always @(posedge clk) begin
    cntr_reg <= cntr_next;
    state_reg <= state_next;
end

Я нашел эту книгу очень полезной. Существует также версия книги VHDL, так что вы можете использовать обе книги одновременно в качестве Розеттского камня для изучения VHDL.

person Nathan Farrington    schedule 29.10.2011
comment
Я не вижу, чего государство достигает в вашем примере. От этого ничего не зависит. Если этот код поместить в FPGA, синтезатор оптимизирует код, связанный с состоянием. - person AVH; 29.10.2011
comment
Я отвечал на исходный вопрос. - person Nathan Farrington; 30.10.2011