Проектирование счетчика в Verilog с помощью кнопки ввода

#verilog

#verilog

Вопрос:

Я создаю некоторый счетчик, который подсчитывает 1, -1 и 2 по отношению к кнопкам ввода 001, 010, 100.

Вот мой код.

 module binary_counter(
        input clk,
        input resetn,
        input [2:0] push, 
        output [3:0] data_out
    );
    
    reg [3:0] data_temp_out;

    always @(posedge clk or negedge resetn) begin   
        if(~resetn) begin
            data_temp_out <= 4'b0;       // all 0
        end
                    
        else if(resetn == 1) begin    // else
            if(push == 3'b001) begin    
                data_temp_out <= data_temp_out  1;    // count  1
            end
            
            else if(push == 3'b010) begin   // count-1
                data_temp_out <= data_temp_out -1;
            end
            
            else if(push == 3'b100) begin   // count 3
                data_temp_out <= data_temp_out  3;
            end
        end
    end
    
    assign data_out = data_temp_out;
    
endmodule
  

С помощью некоторого верхнего модуля и заданного тактового сигнала я реализовал этот счетчик на плате FPGA. Он push[2:0] подключен к трем кнопкам. Проблема в том, что если я продолжаю нажимать на кнопку, количество продолжает расти.

Я хотел считать только при изменении ввода кнопки. Я имею в виду, что он имеет значение только 1, даже если я продолжаю нажимать button1 (001) и то же самое для ввода другой кнопки.

Можете ли вы дать мне подсказку или решение?

Ответ №1:

Потому что условие push == 3'b001 постоянно выполняется, когда вы продолжаете нажимать button1.

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

 reg [2:0] push_d;
wire push_chg;
always @(posedge clk or negedge resetn) begin
    if(~resetn) begin
        push_d <= 3'h0;
    end
    else begin
        push_d <= push;
    end
end
assign push_chg = (push != push_d);
  

Затем вычислите push значение, когда произойдет указанное выше событие.

             if(push_chg amp; (push == 3'b001)) begin
                ...
            end
  

Комментарии:

1. Я искренне благодарю вас всех. Но чего я не могу понять, так это того, что если я добавлю этот код в свой исходный код дизайна, я думаю, что произойдет то, что, поскольку приведенный вами код встречается на каждом положительном или отрицательном ребре при resetn, push_d равно push и сравните push != push_d . Я имею в виду, что порядок событий будет таким: кнопочный ввод -> push_d <= push -> push != push_d, и он всегда дает 0. Но для правильной работы порядок событий будет push_d <= push -> push input -> push != push_d . Является ли второй порядок правильным? Если это так, я не могу понять, почему это работает таким образом

2. Последовательность, которую вы дали push button input -> push_d <= push -> push != push_d , звучит как последовательно выполняемая программа. Нет, это схема, которая работает параллельно. push_d всегда задержка push на один цикл. Сравнивая, мы можем указать, когда push происходят изменения. Возможно, будет проще получить лучшее представление с помощью формы волны.