at main 89 lines 3.2 kB view raw
1-- ======================================================================== 2-- Trail 3-- Stores 16 world-space positions (updated every 3 frames = ~0.8 s at 60 Hz). 4-- Combinationally checks each pixel against stored positions (radius 4 box). 5-- trail_on fires for any pixel within 4 world-pixels of any stored dot. 6-- ======================================================================== 7 8library IEEE; 9use IEEE.STD_LOGIC_1164.all; 10use IEEE.STD_LOGIC_ARITH.all; 11use IEEE.STD_LOGIC_UNSIGNED.all; 12 13entity trail is 14 port( 15 vert_sync : in std_logic; 16 char_x : in std_logic_vector(10 downto 0); 17 char_y : in std_logic_vector(10 downto 0); 18 pixel_column : in std_logic_vector(9 downto 0); 19 pixel_row : in std_logic_vector(9 downto 0); 20 cam_x : in std_logic_vector(10 downto 0); 21 cam_y : in std_logic_vector(10 downto 0); 22 trail_on : out std_logic 23 ); 24end trail; 25 26architecture behavior of trail is 27 28 constant TRAIL_LEN : integer := 16; 29 constant TRAIL_DIV : integer := 3; -- update once every 3 frames 30 constant TRAIL_RADIUS : integer := 4; -- Chebyshev radius in world-pixels 31 32 type pos_arr_t is array(0 to TRAIL_LEN-1) of std_logic_vector(10 downto 0); 33 34 signal tx : pos_arr_t := (others => (others => '0')); 35 signal ty : pos_arr_t := (others => (others => '0')); 36 signal trail_valid : std_logic_vector(TRAIL_LEN-1 downto 0) := (others => '0'); 37 signal frame_ctr : integer range 0 to TRAIL_DIV-1 := 0; 38 39begin 40 41 -- Shift register: push new position every TRAIL_DIV frames 42 shift : process 43 begin 44 wait until vert_sync'event and vert_sync = '1'; 45 46 if frame_ctr = TRAIL_DIV - 1 then 47 for i in TRAIL_LEN-1 downto 1 loop 48 tx(i) <= tx(i-1); 49 ty(i) <= ty(i-1); 50 trail_valid(i) <= trail_valid(i-1); 51 end loop; 52 tx(0) <= char_x; 53 ty(0) <= char_y; 54 trail_valid(0) <= '1'; 55 frame_ctr <= 0; 56 else 57 frame_ctr <= frame_ctr + 1; 58 end if; 59 end process shift; 60 61 -- Pixel check: is current pixel within TRAIL_RADIUS of any valid trail dot? 62 check : process(pixel_column, pixel_row, cam_x, cam_y, tx, ty, trail_valid) 63 variable wci, wri : integer; 64 variable xi, yi : integer; 65 variable dx, dy : integer; 66 variable hit : std_logic; 67 begin 68 wci := CONV_INTEGER('0' & pixel_column) + CONV_INTEGER(cam_x); 69 wri := CONV_INTEGER('0' & pixel_row) + CONV_INTEGER(cam_y); 70 hit := '0'; 71 72 for i in 0 to TRAIL_LEN-1 loop 73 if trail_valid(i) = '1' then 74 xi := CONV_INTEGER(tx(i)); 75 yi := CONV_INTEGER(ty(i)); 76 dx := wci - xi; 77 dy := wri - yi; 78 if dx < 0 then dx := -dx; end if; 79 if dy < 0 then dy := -dy; end if; 80 if dx <= TRAIL_RADIUS and dy <= TRAIL_RADIUS then 81 hit := '1'; 82 end if; 83 end if; 84 end loop; 85 86 trail_on <= hit; 87 end process check; 88 89end behavior;