24-битный счетчик - PullRequest
       5

24-битный счетчик

4 голосов
/ 28 октября 2011

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

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

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

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

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

спасибо

Ответы [ 3 ]

4 голосов
/ 28 октября 2011

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

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 State Machine":

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

3 голосов
/ 28 октября 2011

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

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

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

... или ...

nextCount  = count + 1;
if count == 10000000 then
  resetCount = 1;
2 голосов
/ 29 октября 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, так что вы можете использовать их как Rosetta Stone для изучения VHDL.

...