Блок кода внутри блока always выполняется без изменения входа в списке чувствительности

Всякий раз, когда входом в список чувствительности является переменная (которая является входом для модуля; кнопка на ПЛИС), блок кода выполняется независимо от того, изменилось ли значение этой переменной или нет, даже если блок кода внутри блока always должно выполняться только при изменении значения переменной, данной ему в качестве параметра в его списке чувствительности; отсюда и название списка чувствительности.

Блок кода выглядит следующим образом:

always @(in)
  begin
    count = count + 1;
  end

in: ввод от кнопки на ПЛИС

Наш блок кода в чем-то неправильный, или список чувствительности должен включать только posedge или negedge?


person lili    schedule 13.12.2016    source источник
comment
Что вы хотите точно посчитать? Количество раз, когда кнопка in была нажата, или количество раз, когда ее состояние изменялось (вкл. / Выкл.).   -  person Krouitch    schedule 13.12.2016
comment
@Krouitch, сколько раз его состояние менялось   -  person lili    schedule 13.12.2016
comment
Вы уже используете FPGA или моделируете систему?   -  person Krouitch    schedule 13.12.2016
comment
@Krouitch уже на ПЛИС   -  person lili    schedule 13.12.2016
comment
Я предполагаю, что на in есть сбои, которые запускают захват. Есть ли комбинаторные схемы на входном сигнале? Я имею ввиду между кнопкой и эффективным in в списке чувствительности   -  person Krouitch    schedule 13.12.2016
comment
Кроуич, вероятно, прав в том, что если вы видите, что счетчик увеличивается сразу, а не один раз, это может быть связано с ошибками при вводе кнопок. Обратите внимание, что FPGA не так хороши для синтеза такой асинхронной логики, поскольку выполнение точных требований асинхронной логики НАМНОГО сложнее и может быть невозможно на вашей цели (то есть без сбоев, обеспечения правильного времени и т. Д.).   -  person Unn    schedule 13.12.2016


Ответы (1)


Я не знаком с правилами / практикой написания асинхронной логики, но вот мои 2 цента на работу с нажатиями кнопок:

Попробуйте написать модуль противодействия, чтобы определять, когда кнопка нажата, затем используйте результат модуля противодействия в качестве сигнала включения для вашего счетчика. Список чувствительности счетчика в этом случае будет основан на posedge clk.

Вот объяснение, почему вам нужен модуль противодействия.

Модуль противодействия работает следующим образом: скажем, чтобы зарегистрировать нажатие кнопки, кнопку удерживают в течение 3 мс и отпускают еще 3 мс. (Не стесняйтесь играть со временем.) Следовательно, нам понадобится две фишки: нажата и отпущена. Нажатый счетчик считает до 3 мс, а затем устанавливает условие, позволяющее счетчику сброса начать отсчет. Когда счетчик отпускания достигает 3 мс, кнопка регистрируется как нажатая.

module debounce(
  clk,
  button_input,
  button_pressed
    );

  // Input and output ports
  input clk, button_input;
  output button_pressed;

  reg button_pressed;

  // Signals for pressed and released counters
  reg [15:0] pressed_out, pressed_next_out, released_out, released_next_out;
  reg pressed_enable, pressed_reset, released_enable, released_reset;
  reg pressed_ok, released_ok;

  // Counter for when button is pressed down
  // Increment counter
  always @ (*) begin
    if (button_input) begin
      pressed_next_out = pressed_out + 1'b1;
     end else begin
       pressed_next_out = 16'h00000;
    end     
  end

  // Flop incremented value
  always @ (posedge clk) 
     pressed_out <= pressed_next_out;

  // Check if button was pressed (3ms) 
  always @ (posedge clk) begin
     if (&pressed_out) begin
        pressed_ok <= 1;
     end else if (released_ok) begin
        pressed_ok <= 0;
     end
  end

    // Counter for when button is released
    // Increment counter 
   always @ (*) begin
     if (~button_input && pressed_ok) begin
       released_next_out = released_out + 1'b1;
      end else begin
        released_next_out = 16'b0;
     end        
   end

    // Flop incremented value
    always @ (posedge clk)
       released_out <= released_next_out;

    // Check if button was released (3ms)
    always @ (posedge clk) begin
        if (&released_out) begin
           released_ok <= 1;
        end else begin
           released_ok <= 0;
        end
    end

    // Check if button was pressed and released
    always @ (posedge clk) 
       button_pressed <= pressed_ok && released_ok;

endmodule
person Community    schedule 16.12.2016