为进一步的时钟周期保留来自按钮的输入(Verilog FPGA)

Retaining an input from a button for further clock cycles (Verilog FPGA)

在我当前的 FPGA Verilog 项目中,我需要在 FPGA 板上使用一个按钮,并使其在按下按钮后即使在释放按钮后输入仍保持为 1,直到满足特定条件遇见了

但是,我很难理解这在逻辑上是如何工作的。在硬件上,由于每个时钟周期都会检查按钮的输入,我将如何做到在最初按下按钮从按钮产生输入 1 之后,Verilog 在可预见的时钟周期内使用 1,直到满足条件?

上下文:对于 Verilog FPGA VGA 游戏项目,我正在尝试从几何破折号复制跳转,其中块在初始输入 1(点击屏幕)后进行完整跳转并保持 1(无论是否屏幕被按住或松开)直到跳跃完成并且方块接触到地板。下面是我设法实现的代码。

module game_top #(parameter
    
    FLR_POS = 11'd696,
    BLK_HGT = 11'd32,
    MAX_JMP = 11'd164)(
    
    input clk,
    input [4:0] btn,
    output [3:0] pix_r,
    output [3:0] pix_g,
    output [3:0] pix_b,
    output hsync,
    output vsync);
    
    wire pix_clk;           //internal wires and regs
    wire [3:0] draw_r;      //has to be a wire because combinational logic not using a clock in drawcon
    wire [3:0] draw_g;      //has to be a wire because combinational logic not using a clock in drawcon
    wire [3:0] draw_b;      //has to be a wire because combinational logic not using a clock in drawcon
    wire [10:0] curr_x;     //current location on screen x pos
    wire [10:0] curr_y;     //current location on screen x pos
    wire [10:0] obspos_x;
    wire [10:0] obspos_y;
    wire flag_1;
 
    reg game_clk = 0;
    reg [20:0] clk_div = 0;
    reg [10:0] blkpos_x = 11'd703; //center of screen 
    reg [10:0] blkpos_y = 11'd424;
    reg top = 0; 
           
    always@(posedge clk) begin
        if(clk_div == 100000000/120) begin //clk divider
            clk_div <= 20'd0;
            game_clk <= !game_clk;   //60hz produced
        end else begin 
            clk_div <= clk_div + 1;
        end
    end
    
    always@(posedge game_clk) begin     //button inputs, jump logic 
   
        if(btn[0]) begin                            // resets block to starting position
            blkpos_x <= 11'd503;
            blkpos_y <= FLR_POS - BLK_HGT;
        end

        // if the button is pressed block keeps raising and if released the block falls 
        // But if the block raises too high then it automatically starts falling to the floor ignoring button  

        else if(btn[1]) begin                       
            blkpos_x <= blkpos_x;                   
            if (blkpos_y > MAX_JMP) begin           
                blkpos_y <= blkpos_y - 11'd10;
            end   
            else begin
                top <= 11'd1;
            end     
        end
        
        else if (top == 1 || (btn[1] && top == 1)) begin    
            blkpos_x <= blkpos_x;                           
            if (blkpos_y + BLK_HGT <= FLR_POS) begin
                blkpos_y <= blkpos_y + 11'd10;
            end   
            else begin
                blkpos_y <= blkpos_y;
                top <= 11'd0;
            end   
        end

        else begin 
            blkpos_x <= blkpos_x;
            
            if (blkpos_y + BLK_HGT >= FLR_POS) begin
                blkpos_y <= blkpos_y;
            end
            else begin
                blkpos_y <= blkpos_y + 11'd10;
            end   
        end
    end

不要直接使用“按下按钮”信号来表示此状态。相反,它应该由另一个 reg.

表示

如果在一个时钟周期内“按钮按下”信号为1,则状态应设置为1。

until a certain condition is met.

如果在一个时钟周期内,“按钮按下”信号为0,并且满足这个“特定条件”,则状态应设置为0。