166 lines
5.5 KiB
VHDL
166 lines
5.5 KiB
VHDL
----------------------------------------------------------------------------------
|
|
-- Company:
|
|
-- Engineer:
|
|
--
|
|
-- Create Date: 30.11.2021 10:35:30
|
|
-- Design Name:
|
|
-- Module Name: Gene_Snake - Behavioral
|
|
-- Project Name:
|
|
-- Target Devices:
|
|
-- Tool Versions:
|
|
-- Description:
|
|
--
|
|
-- Dependencies:
|
|
--
|
|
-- Revision:
|
|
-- Revision 0.01 - File Created
|
|
-- Additional Comments:
|
|
--
|
|
----------------------------------------------------------------------------------
|
|
-- a faire:
|
|
-- - faire bouger le snake
|
|
-- - ajouter une clk
|
|
|
|
library IEEE;
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
|
|
|
-- Uncomment the following library declaration if using
|
|
-- arithmetic functions with Signed or Unsigned values
|
|
use IEEE.NUMERIC_STD.ALL;
|
|
|
|
library ourTypes;
|
|
use ourTypes.types.all;
|
|
|
|
-- Uncomment the following library declaration if instantiating
|
|
-- any Xilinx leaf cells in this code.
|
|
--library UNISIM;
|
|
--use UNISIM.VComponents.all;
|
|
|
|
entity Gene_Snake is
|
|
generic( addressSize : integer:=10);
|
|
Port ( X : in unsigned (9 downto 0);
|
|
Y : in unsigned (8 downto 0);
|
|
clk: in std_logic;
|
|
reset: in std_logic;
|
|
|
|
currentSnake : in pos;
|
|
updateOrder : in std_logic;
|
|
listRef : in unsigned(addressSize-1 downto 0);
|
|
|
|
colorOut : out color;
|
|
|
|
currentAddress : out unsigned(addressSize-1 downto 0);
|
|
matAddress : out unsigned(addressSize-1 downto 0);
|
|
|
|
ROMAddress : out unsigned(SPRITES_ADDRESS_SIZE-1 downto 0) := (others => '0');
|
|
ROMData : in std_logic_vector(SPRITES_DATA_SIZE-1 downto 0)
|
|
);
|
|
end Gene_Snake;
|
|
|
|
architecture Behavioral of Gene_Snake is
|
|
|
|
-- D???claration des signaux
|
|
signal snakeHere: std_logic := '0'; --1 si on doit afficher le pixel 0 sinon
|
|
signal dx : signed(1 downto 0) := to_signed(-1,2);
|
|
signal dy : signed(1 downto 0) := to_signed(-1,2);
|
|
signal running : std_logic := '0';
|
|
signal startUpdate : std_logic := '0';
|
|
signal snakeColor : color := (r => "00000", g => "000000", b => "00000", a => "00000000");
|
|
|
|
begin
|
|
|
|
|
|
-- Process de calcul d'affichage
|
|
process(X,Y,clk,reset,running,dx,dy,updateOrder,currentSnake,snakeHere)
|
|
variable sX : integer; --position par rapport au sprites
|
|
variable sY : integer;
|
|
variable sOff : integer; --offset dans la memoire des sprites
|
|
begin
|
|
if(updateOrder'event and updateOrder = '1') then --si on as un signal sur pxl_clk (i.e. on vient de changer de pixel)
|
|
if(snakeHere = '1') then
|
|
--snakeColor.R <= (others => '1');
|
|
--snakeColor.G <= (others => '1');
|
|
--snakeColor.B <= (others => '1');
|
|
--snakeColor.A <= (others => '1');
|
|
snakeColor <= to_color(ROMData);
|
|
else
|
|
snakeColor.R <= (others => '0');
|
|
snakeColor.G <= (others => '0');
|
|
snakeColor.B <= (others => '0');
|
|
snakeColor.A <= (others => '0');
|
|
end if;
|
|
startUpdate <= '1'; --on marque qu'il faut refaire une update (on doit separer en deux signaux parce que sinon on aurait un edit sur deux clk differentes). C'est pas très élégant mais j'ai pas trouvé mieux
|
|
end if;
|
|
|
|
--c'est gênant, on doit verifier les cases tout autour (3x3=9) mais on as que 5 clk pour le faire (125/25=5), donc on est baisé. Faudrait garder le isDefined de tout les snakes alentours dans chaque snake.
|
|
if(reset = '0') then
|
|
running <= '0';
|
|
snakeHere <= '0';
|
|
snakecolor <= (others => (others => '0'));
|
|
elsif(clk'event and clk = '1') then
|
|
if(startUpdate = '1') then
|
|
running <= '1';
|
|
snakeHere <= '0';
|
|
dx <= to_signed(-1,2);
|
|
dy <= to_signed(-1,2);
|
|
end if;
|
|
if(running = '1') then
|
|
if(currentSnake.isDefined = '1') then
|
|
if(X>=currentSnake.X-8 and X<currentSnake.X+8 and Y>=currentSnake.Y-8 and Y<currentSnake.Y+8) then
|
|
snakeHere <= '1';
|
|
-- |-1 si dirX=-1; 1 si dirX=0 ou 1 | | position relative au centre | |pour passer de coords (-8:7) ou (-7:8) à (0:15)|
|
|
sX := to_integer(currentSnake.dirX or "01") * (to_integer(X) - to_integer(currentSnake.X)) + 8 + to_integer(shift_right(currentSnake.dirX,1));
|
|
sY := to_integer(currentSnake.dirY or "01") * (to_integer(Y) - to_integer(currentSnake.Y)) + 8 + to_integer(shift_right(currentSnake.dirY,1));
|
|
if(listRef = 0) then
|
|
sOff := HEAD_SPRITE_OFFSET;
|
|
elsif(listRef = 3) then
|
|
sOff := TAIL_SPRITE_OFFSET;
|
|
else
|
|
sOff := BODY_SPRITE_OFFSET;
|
|
end if;
|
|
case currentSnake.dirY(1) is
|
|
when '1' => ROMAddress <= to_unsigned(sX*16+sY+sOff,SPRITES_ADDRESS_SIZE);
|
|
when '0' => ROMAddress <= to_unsigned(sY*16+sX+sOff,SPRITES_ADDRESS_SIZE);
|
|
when others => NULL;
|
|
end case;
|
|
end if;
|
|
end if;
|
|
|
|
if(dx /= 1) then
|
|
dx <= dx + 1;
|
|
else
|
|
dx <= to_signed(-1,2);
|
|
dy <= dy + 1;
|
|
end if;
|
|
|
|
if(dy = 2) then
|
|
dy <= to_signed(-1,2);
|
|
running <= '0';
|
|
end if;
|
|
end if;
|
|
|
|
|
|
if(running = '1') then
|
|
startUpdate <= '0';
|
|
end if;
|
|
|
|
end if;
|
|
end process;
|
|
|
|
process(X,Y,dx,dy)
|
|
variable mX : integer;
|
|
variable mY : integer;
|
|
variable mInd : integer;
|
|
begin
|
|
mX := to_integer(X)/16;
|
|
mY := to_integer(Y)/16;
|
|
mInd := mY*40 + mX;
|
|
matAddress <= TO_UNSIGNED(mInd,SNAKE_ADDRESS_SIZE); --+to_integer(dy))*40+shift_right(X,4)+to_integer(dx);
|
|
--matAddress <= '0' & X/16;--resize(shift_right(Y,4)*40+shift_right(X,4),SNAKE_ADDRESS_SIZE);
|
|
end process;
|
|
|
|
currentAddress <= listRef;
|
|
|
|
colorOut <= snakeColor;
|
|
end Behavioral;
|