从按钮中保留输入以进行进一步的时钟周期(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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要直接使用“按下按钮”信号来表示此状态。相反,它应由另一个
reg
表示。如果在一个时钟周期中,“按下按钮”信号为1,则该状态应设置为1。
如果在时钟周期中,“按下按钮”信号为0,并且满足了“某些条件”,则该状态应设置为0。
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.
If in a clock cycle the "button pressed" signal is 0 and this "certain condition" is met, the state should be set to 0.