Home > Software engineering >  Retaining an input from a button for further clock cycles (Verilog FPGA)
Retaining an input from a button for further clock cycles (Verilog FPGA)

Time:04-18

In my current FPGA Verilog project, I am required to use a button on the FPGA board and make it such that once the button has been pressed the input remains 1 even after the button has been released until a certain condition is met.

However, I'm struggling to understand how this would work logically. On hardware since the input of the button is being checked every clock cycle how would I make it such that after the initial button press of producing an input of 1 from the button, Verilog uses 1 for the foreseeable clock cycles until a condition is met?

Context: For a Verilog FPGA VGA game project I'm trying to replicate the jump from geometry dash where the block does the full jump after an initial input 1 (tap on the screen) and remains 1 (regardless of whether the screen is held or released) until the jump is complete and the block is touching the floor. Below is a code for what I've managed to achieve.

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

CodePudding user response:

Don't use the "button pressed" signal directly to represent this state. Instead, it should be represented by another reg.

If in one clock cycle the "button pressed" signal is 1, the state should be set to 1.

until a certain condition is met.

If in a clock cycle the "button pressed" signal is 0 and this "certain condition" is met, the state should be set to 0.

  • Related