为进一步的时钟周期保留来自按钮的输入(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。
在我当前的 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。