我一直在为Spartan3e在VHDL中实现蛇游戏。Vhdl Snake - 如何实现尾部自动化
我已经写了一个在VGA屏幕上绘制单元格正方形的部分,并且可以在正方形中移动它。
问题是尾部执行 - 到目前为止,我手动添加了另一个细胞段到我的蛇,但我想自动化它(例如在java中简单地使单元队列和设置下一个位置g细胞作为细胞之前)。我不知道如何在vhdl中编写如此复杂的函数。
这是我的代码:
begin
process (clk, reset, endOfGame)
begin
if reset='1' or endOfGame=true then
ball_y_reg <= to_unsigned(231,10);
ball_x_reg <= to_unsigned(311,10);
ball_x_reg_cell<=to_unsigned(231,10);
ball_y_reg_cell<=to_unsigned(311,10);
-- velocity after reset schould be none
x_delta_reg <= ("0000000000");
y_delta_reg <= ("0000000000");
elsif (clk'event and clk='1') then
ball_x_reg_cell<=ball_x_next_cell;
ball_y_reg_cell<=ball_y_next_cell;
ball_x_reg <= ball_x_next;
ball_y_reg <= ball_y_next;
x_delta_reg <= x_delta_next;
y_delta_reg <= y_delta_next;
end if;
end process;
pix_x <= unsigned(pixel_x);
pix_y <= unsigned(pixel_y);
-- refr_tick: 1-clock tick asserted at start of v-sync
-- i.e., when the screen is refreshed (60 Hz)
refr_tick <= '1' when (pix_y=481) and (pix_x=0) else
'0';
----------------------------------------------
-- pixel within wall
wall_on <=
'1' when ((WALL_X_LEFTSIDE_L<=pix_x) and (pix_x<=WALL_X_LEFTSIDE_R)) or ((WALL_X_RIGHTSIDE_L<=pix_x) and (pix_x<=WALL_X_RIGHTSIDE_R)) or ((WALL_Y_UPSIDE_U<=pix_y) and (pix_y<=WALL_Y_UPSIDE_D)) or ((WALL_Y_DOWNSIDE_U<=pix_y) and (pix_y<=WALL_Y_DOWNSIDE_D)) else
'0';
-- wall rgb output
wall_rgb <= "001"; -- blue
----------------------------------------------
-- square ball
ball_x_l <= ball_x_reg;
ball_y_t <= ball_y_reg;
ball_x_r <= ball_x_l + BALL_SIZE - 1;
ball_y_b <= ball_y_t + BALL_SIZE - 1;
ball_x_l_cell <= ball_x_reg_cell;
ball_y_t_cell <= ball_y_reg_cell;
ball_x_r_cell <= ball_x_l_cell + BALL_SIZE - 1;
ball_y_b_cell <= ball_y_t_cell + BALL_SIZE - 1;
--tail
-- pixel within squared ball
sq_ball_on <=
'1' when ((ball_x_l<=pix_x) and (pix_x<=ball_x_r) and
(ball_y_t<=pix_y) and (pix_y<=ball_y_b))
or
((ball_x_l_cell<=pix_x) and (pix_x<=ball_x_r_cell) and
(ball_y_t_cell<=pix_y) and (pix_y<=ball_y_b_cell))
else
'0';
ball_x_next <= ball_x_reg + x_delta_reg
when refr_tick='1' else
ball_x_reg ;
ball_y_next <= ball_y_reg + y_delta_reg
when refr_tick='1' else
ball_y_reg ;
ball_x_next_cell <= ball_x_reg - BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_RIGHT
else ball_x_reg + BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_LEFT
else ball_x_reg when refr_tick='1'
else ball_x_reg_cell;
ball_y_next_cell <= ball_y_reg - BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_UP
else ball_y_reg + BALL_SIZE when refr_tick='1' and CURRENT_DIRECTION = DIR_DOWN
else ball_y_reg when refr_tick='1'
else ball_y_reg_cell;
-- new bar y-position
process(ball_y_reg, ball_y_b, ball_y_t, refr_tick, btn, ball_x_reg ,ball_x_r, ball_x_l, x_delta_reg, y_delta_reg)
begin
x_delta_next <= x_delta_reg;
y_delta_next <= y_delta_reg;
if refr_tick='1' then
if btn(1)='1' and ball_y_b<(MAX_Y-1-BALL_SIZE) then
if CURRENT_DIRECTION /= DIR_UP then
CURRENT_DIRECTION <= DIR_DOWN;
y_delta_next <= BALL_V_P; -- move down
x_delta_next <= (others=>'0');
end if;
elsif btn(0)='1' and ball_y_t > BALL_SIZE then
if CURRENT_DIRECTION /= DIR_DOWN then
CURRENT_DIRECTION <= DIR_UP;
y_delta_next <= BALL_V_N; -- move up
x_delta_next <= (others=>'0');
end if;
elsif btn(2)='1' and ball_x_r<(MAX_X-1-BALL_SIZE) then
if CURRENT_DIRECTION /= DIR_LEFT then
CURRENT_DIRECTION <= DIR_RIGHT;
x_delta_next <= BALL_V_P;
y_delta_next <= (others=>'0');
end if;
elsif btn(3)='1' and ball_x_l > BALL_SIZE then
if CURRENT_DIRECTION /= DIR_RIGHT then
CURRENT_DIRECTION <= DIR_LEFT;
x_delta_next <= BALL_V_N;
y_delta_next <= (others=>'0');
end if;
end if;
if ball_x_l < WALL_X_LEFTSIDE_R or ball_y_t < WALL_Y_UPSIDE_D or ball_y_b > WALL_Y_DOWNSIDE_U or ball_x_r > WALL_X_RIGHTSIDE_L then
endOfGame <= true;
CURRENT_DIRECTION <= IDLE;
else
endOfGame <= false;
end if;
end if;
end process;
“球X下一单元格” 份手动添加第二小区。
我一直在搜索包含类似问题的主题,但它没有涵盖在vhdl中。
感谢您的帮助!
感谢您的快速回答!我意识到vhdl语言的局限性,但是我正在询问实现技巧。我知道我必须使用包含正确和下一个位置,方向,可视性的记录数组。问题是,我如何通过并发语句来遍历记录数组,如我现在使用的单元格(段)。我需要做这样的操作,因为我必须面对动画。 –
这取决于您的性能需求。一个简单的循环可以在单个时钟周期内迭代阵列的范围,但是会阻止将该阵列实现为BlockRam并可能生成巨大的硬件。您可能正在查看状态机,并在每个时钟周期迭代一个单元。这取决于你的具体要求。 –