@jcm@wafrn.jcm.re asked
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity my_code is
generic(
WIDTH : integer := 640;
HEIGHT : integer := 480;
CONSOLE_COLUMNS : integer := WIDTH / 8;
CONSOLE_ROWS : integer := HEIGHT / 8
);
port(
clk : in std_logic;
rst : in std_logic;
px : in integer range 0 to WIDTH - 1;
py : in integer range 0 to HEIGHT - 1;
hsync : in std_logic;
vsync : in std_logic;
col : in integer range 0 to CONSOLE_COLUMNS - 1;
row : in integer range 0 to CONSOLE_ROWS - 1;
char : out integer range 0 to 127 := 0;
foreground_color : out std_logic_vector(23 downto 0) := (others => '0');
background_color : out std_logic_vector(23 downto 0) := (others => '1')
);
end my_code;
architecture rtl of my_code is
constant IMAGE_WIDTH : integer := 32;
constant IMAGE_HEIGHT : integer := 32;
type image_type is array (0 to IMAGE_HEIGHT-1) of std_logic_vector(0 to IMAGE_WIDTH-1);
constant image_open : image_type := (
"00000000000000000000000000000000",
"00000000000000000000000000000000",
"00000000000001111111000000000000",
"00000000000111111111110000000000",
"00000000011111111111111100000000",
"00000000111111111110011110000000",
"00000001111111111100001111000000",
"00000011111111111110011111100000",
"00000011111111111111111111100000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111000000",
"00000111111111111111111000000000",
"00000111111111111111000000000000",
"00000111111111111110000000000000",
"00000111111111111110000000000000",
"00000111111111111110000000000000",
"00000111111111111110000000000000",
"00000111111111111111000000000000",
"00000111111111111111111000000000",
"00000111111111111111111111000000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000011111111111111111111100000",
"00000011111111111111111111100000",
"00000001111111111111111111000000",
"00000000111111111111111110000000",
"00000000011111111111111100000000",
"00000000000111111111110000000000",
"00000000000001111111000000000000",
"00000000000000000000000000000000"
);
constant image_closed : image_type := (
"00000000000000000000000000000000",
"00000000000000000000000000000000",
"00000000000001111111000000000000",
"00000000000111111111110000000000",
"00000000011111111111111100000000",
"00000000111111111110011110000000",
"00000001111111111100001111000000",
"00000011111111111110011111100000",
"00000011111111111111111111100000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000011111111111111111111100000",
"00000011111111111111111111100000",
"00000001111111111111111111000000",
"00000000111111111111111110000000",
"00000000011111111111111100000000",
"00000000000111111111110000000000",
"00000000000001111111000000000000",
"00000000000000000000000000000000"
);
type grid_type is array (0 to HEIGHT/IMAGE_HEIGHT-1) of std_logic_vector(0 to WIDTH/IMAGE_WIDTH-1);
constant grid : grid_type := (
"11111111111111111111",
"10000000011000000001",
"10111111011011111101",
"10100000000000000101",
"10101111011011110101",
"10000000011000000001",
"11111111011011111111",
"10000000000000000001",
"11111111011011111111",
"10000000011000000001",
"10101111011011110101",
"10100000000000000101",
"10111111011011111101",
"10000000011000000001",
"11111111111111111111"
);
constant SPEED : integer := 2;
signal position_x : integer range -SPEED to WIDTH + SPEED := WIDTH/2;
signal position_y : integer range -SPEED to HEIGHT + SPEED := WIDTH/2;
signal direction : integer := 0;
signal image_x : integer range 0 to IMAGE_WIDTH-1;
signal image_y : integer range 0 to IMAGE_HEIGHT-1;
signal directional_image_x : integer range 0 to IMAGE_WIDTH-1;
signal directional_image_y : integer range 0 to IMAGE_HEIGHT-1;
signal debug_next_tile_x : integer;
signal debug_next_tile_y : integer;
signal random_bit : std_logic := '0';
signal frame_counter : unsigned(31 downto 0) := (others => '0');
component OSCG is
generic (
DIV : integer := 128
);
port (
OSC : out std_logic
);
end component;
begin
char <= 0;
foreground_color <= (others => '1');
image_x <= px - position_x;
image_y <= py - position_y;
with direction select
directional_image_x <=
image_x when 0,
image_y when 1,
(IMAGE_WIDTH - 1) - image_x when 2,
(IMAGE_HEIGHT - 1) - image_y when 3,
0 when others;
with direction select
directional_image_y <=
image_y when 0,
(IMAGE_WIDTH - 1) - image_x when 1,
image_y when 2,
image_x when 3,
0 when others;
background_color <=
x"FFFFFF" when grid(py/IMAGE_HEIGHT)(px/IMAGE_WIDTH) = '1' else
x"FFFF00" when frame_counter(4) = '0' and image_open(directional_image_y)(directional_image_x) = '1' and
px >= position_x and px < position_x + IMAGE_WIDTH and
py >= position_y and py < position_y + IMAGE_HEIGHT
else
x"FFFF00" when frame_counter(4) = '1' and image_closed(directional_image_y)(directional_image_x) = '1' and
px >= position_x and px < position_x + IMAGE_WIDTH and
py >= position_y and py < position_y + IMAGE_HEIGHT
else
--x"7F0000" when debug_next_tile_x = px/IMAGE_WIDTH and debug_next_tile_y = py/IMAGE_HEIGHT else
x"000000";
rng : OSCG port map (
OSC => random_bit
);
process(clk)
variable old_vsync : std_logic := '0';
variable next_direction : integer := 0;
variable next_x : integer range -SPEED to WIDTH + SPEED := 0;
variable next_y : integer range -SPEED to HEIGHT + SPEED := 0;
variable next_tile_x : integer := 0;
variable next_tile_y : integer := 0;
variable good : std_logic := '0';
begin
if rising_edge(clk) then
if vsync = '0' and old_vsync = '1' then
frame_counter <= frame_counter + 1;
good := '0';
if position_x mod IMAGE_WIDTH = 0 and position_y mod IMAGE_HEIGHT = 0 then
if random_bit = '1' then
next_direction := (next_direction + 1) mod 4;
else
next_direction := (next_direction + 3) mod 4;
end if;
end if;
end if;
old_vsync := vsync;
if good = '0' then
case next_direction is
when 0 =>
next_x := position_x + SPEED;
next_y := position_y;
when 1 =>
next_x := position_x;
next_y := position_y + SPEED;
when 2 =>
next_x := position_x - SPEED;
next_y := position_y;
when 3 =>
next_x := position_x;
next_y := position_y - SPEED;
when others =>
null;
end case;
next_tile_x := next_x / IMAGE_WIDTH;
next_tile_y := next_y / IMAGE_HEIGHT;
if next_direction = 0 and (next_x mod IMAGE_WIDTH) /= 0 then
next_tile_x := next_tile_x + 1;
elsif next_direction = 1 and (next_y mod IMAGE_HEIGHT) /= 0 then
next_tile_y := next_tile_y + 1;
end if;
debug_next_tile_x <= next_tile_x;
debug_next_tile_y <= next_tile_y;
if next_tile_y = 7 and next_tile_x = 0 and direction = 2 then
good := '1';
position_x <= 18*IMAGE_WIDTH;
position_y <= position_y;
direction <= 0;
elsif next_tile_y = 7 and next_tile_x = 19 and direction = 0 then
good := '1';
position_x <= 1*IMAGE_WIDTH;
position_y <= position_y;
direction <= 2;
elsif grid(next_tile_y)(next_tile_x) = '0' and next_direction /= ((direction + 2) mod 4) then
good := '1';
position_x <= next_x;
position_y <= next_y;
direction <= next_direction mod 4;
else
if random_bit = '1' then
next_direction := (next_direction + 1) mod 4;
else
next_direction := (next_direction + 3) mod 4;
end if;
end if;
end if;
end if;
end process;
end architecture;
Sucess!
Utilization
CellUsedAvailableUsage
DCCA2563.6%
EHXPLLL1250%
MULT18X18D2287.1%
OSCG11100%
TRELLIS_COMB1100242884.5%
TRELLIS_FF196242880.8%
TRELLIS_IO101975.1%
Timing
ClockAchievedConstraint
$glbnet$clkp36.51 MHz25 MHz
$glbnet$clkt261.37 MHz250 MHz
Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity my_code is
generic(
WIDTH : integer := 640;
HEIGHT : integer := 480;
CONSOLE_COLUMNS : integer := WIDTH / 8;
CONSOLE_ROWS : integer := HEIGHT / 8
);
port(
clk : in std_logic;
rst : in std_logic;
px : in integer range 0 to WIDTH - 1;
py : in integer range 0 to HEIGHT - 1;
hsync : in std_logic;
vsync : in std_logic;
col : in integer range 0 to CONSOLE_COLUMNS - 1;
row : in integer range 0 to CONSOLE_ROWS - 1;
char : out integer range 0 to 127 := 0;
foreground_color : out std_logic_vector(23 downto 0) := (others => '0');
background_color : out std_logic_vector(23 downto 0) := (others => '1')
);
end my_code;
architecture rtl of my_code is
constant IMAGE_WIDTH : integer := 32;
constant IMAGE_HEIGHT : integer := 32;
type image_type is array (0 to IMAGE_HEIGHT-1) of std_logic_vector(0 to IMAGE_WIDTH-1);
constant image_open : image_type := (
"00000000000000000000000000000000",
"00000000000000000000000000000000",
"00000000000001111111000000000000",
"00000000000111111111110000000000",
"00000000011111111111111100000000",
"00000000111111111110011110000000",
"00000001111111111100001111000000",
"00000011111111111110011111100000",
"00000011111111111111111111100000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111000000",
"00000111111111111111111000000000",
"00000111111111111111000000000000",
"00000111111111111110000000000000",
"00000111111111111110000000000000",
"00000111111111111110000000000000",
"00000111111111111110000000000000",
"00000111111111111111000000000000",
"00000111111111111111111000000000",
"00000111111111111111111111000000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000011111111111111111111100000",
"00000011111111111111111111100000",
"00000001111111111111111111000000",
"00000000111111111111111110000000",
"00000000011111111111111100000000",
"00000000000111111111110000000000",
"00000000000001111111000000000000",
"00000000000000000000000000000000"
);
constant image_closed : image_type := (
"00000000000000000000000000000000",
"00000000000000000000000000000000",
"00000000000001111111000000000000",
"00000000000111111111110000000000",
"00000000011111111111111100000000",
"00000000111111111110011110000000",
"00000001111111111100001111000000",
"00000011111111111110011111100000",
"00000011111111111111111111100000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000111111111111111111111110000",
"00000011111111111111111111100000",
"00000011111111111111111111100000",
"00000001111111111111111111000000",
"00000000111111111111111110000000",
"00000000011111111111111100000000",
"00000000000111111111110000000000",
"00000000000001111111000000000000",
"00000000000000000000000000000000"
);
type grid_type is array (0 to HEIGHT/IMAGE_HEIGHT-1) of std_logic_vector(0 to WIDTH/IMAGE_WIDTH-1);
constant grid : grid_type := (
"11111111111111111111",
"10000000011000000001",
"10111111011011111101",
"10100000000000000101",
"10101111011011110101",
"10000000011000000001",
"11111111011011111111",
"10000000000000000001",
"11111111011011111111",
"10000000011000000001",
"10101111011011110101",
"10100000000000000101",
"10111111011011111101",
"10000000011000000001",
"11111111111111111111"
);
constant SPEED : integer := 2;
signal position_x : integer range -SPEED to WIDTH + SPEED := WIDTH/2;
signal position_y : integer range -SPEED to HEIGHT + SPEED := WIDTH/2;
signal direction : integer := 0;
signal image_x : integer range 0 to IMAGE_WIDTH-1;
signal image_y : integer range 0 to IMAGE_HEIGHT-1;
signal directional_image_x : integer range 0 to IMAGE_WIDTH-1;
signal directional_image_y : integer range 0 to IMAGE_HEIGHT-1;
signal debug_next_tile_x : integer;
signal debug_next_tile_y : integer;
signal random_bit : std_logic := '0';
signal frame_counter : unsigned(31 downto 0) := (others => '0');
component OSCG is
generic (
DIV : integer := 128
);
port (
OSC : out std_logic
);
end component;
begin
char <= 0;
foreground_color <= (others => '1');
image_x <= px - position_x;
image_y <= py - position_y;
with direction select
directional_image_x <=
image_x when 0,
image_y when 1,
(IMAGE_WIDTH - 1) - image_x when 2,
(IMAGE_HEIGHT - 1) - image_y when 3,
0 when others;
with direction select
directional_image_y <=
image_y when 0,
(IMAGE_WIDTH - 1) - image_x when 1,
image_y when 2,
image_x when 3,
0 when others;
background_color <=
x"FFFFFF" when grid(py/IMAGE_HEIGHT)(px/IMAGE_WIDTH) = '1' else
x"FFFF00" when frame_counter(4) = '0' and image_open(directional_image_y)(directional_image_x) = '1' and
px >= position_x and px < position_x + IMAGE_WIDTH and
py >= position_y and py < position_y + IMAGE_HEIGHT
else
x"FFFF00" when frame_counter(4) = '1' and image_closed(directional_image_y)(directional_image_x) = '1' and
px >= position_x and px < position_x + IMAGE_WIDTH and
py >= position_y and py < position_y + IMAGE_HEIGHT
else
--x"7F0000" when debug_next_tile_x = px/IMAGE_WIDTH and debug_next_tile_y = py/IMAGE_HEIGHT else
x"000000";
rng : OSCG port map (
OSC => random_bit
);
process(clk)
variable old_vsync : std_logic := '0';
variable next_direction : integer := 0;
variable next_x : integer range -SPEED to WIDTH + SPEED := 0;
variable next_y : integer range -SPEED to HEIGHT + SPEED := 0;
variable next_tile_x : integer := 0;
variable next_tile_y : integer := 0;
variable good : std_logic := '0';
begin
if rising_edge(clk) then
if vsync = '0' and old_vsync = '1' then
frame_counter <= frame_counter + 1;
good := '0';
if position_x mod IMAGE_WIDTH = 0 and position_y mod IMAGE_HEIGHT = 0 then
if random_bit = '1' then
next_direction := (next_direction + 1) mod 4;
else
next_direction := (next_direction + 3) mod 4;
end if;
end if;
end if;
old_vsync := vsync;
if good = '0' then
case next_direction is
when 0 =>
next_x := position_x + SPEED;
next_y := position_y;
when 1 =>
next_x := position_x;
next_y := position_y + SPEED;
when 2 =>
next_x := position_x - SPEED;
next_y := position_y;
when 3 =>
next_x := position_x;
next_y := position_y - SPEED;
when others =>
null;
end case;
next_tile_x := next_x / IMAGE_WIDTH;
next_tile_y := next_y / IMAGE_HEIGHT;
if next_direction = 0 and (next_x mod IMAGE_WIDTH) /= 0 then
next_tile_x := next_tile_x + 1;
elsif next_direction = 1 and (next_y mod IMAGE_HEIGHT) /= 0 then
next_tile_y := next_tile_y + 1;
end if;
debug_next_tile_x <= next_tile_x;
debug_next_tile_y <= next_tile_y;
if next_tile_y = 7 and next_tile_x = 0 and direction = 2 then
good := '1';
position_x <= 18*IMAGE_WIDTH;
position_y <= position_y;
direction <= 0;
elsif next_tile_y = 7 and next_tile_x = 19 and direction = 0 then
good := '1';
position_x <= 1*IMAGE_WIDTH;
position_y <= position_y;
direction <= 2;
elsif grid(next_tile_y)(next_tile_x) = '0' and next_direction /= ((direction + 2) mod 4) then
good := '1';
position_x <= next_x;
position_y <= next_y;
direction <= next_direction mod 4;
else
if random_bit = '1' then
next_direction := (next_direction + 1) mod 4;
else
next_direction := (next_direction + 3) mod 4;
end if;
end if;
end if;
end if;
end process;
end architecture;
#FPGA #Icepi-Zero #HDL #VHDL