Excellent contribution, I hadn't seen one like this in a long while! I've been wondering about getting an FPGA rev board, this is yet another reason. Thumbs up
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity RotoFractal is
port(CLOCK_50 : in std_logic;
VGAout: out unsigned(10 downto 0); -- r2,r1,r0, g2,g1,g0, b2,b1,b0, hsync, vsync
PS2_Clock: in std_logic;
PS2_Data: in std_logic
);
end RotoFractal;
architecture Behavioral of RotoFractal is
constant Black : unsigned(8 downto 0):="000000000";
constant White : unsigned(8 downto 0):="111111111";
constant Yellow : unsigned(8 downto 0):="111111000";
signal hcount : unsigned(10 downto 0):="00000000000";
signal vcount : unsigned(9 downto 0):="0000000000";
signal fraccount : unsigned(9 downto 0):="0000000000";
signal VGA, Out_Colour, ninecount : unsigned(8 downto 0):="000000000";
signal videoon, videov, videoh, hsync, vsync : std_ulogic:='0';
signal reset : std_ulogic:='0';
signal fraccountdir : std_ulogic:='1';
signal Yellow_Pixel, White_Pixel, Black_Pixel : std_ulogic:='0';
signal X0, X1, Y0, Y1 : unsigned(15 downto 0):="0000000000000000"; -- 65536 x 65536 virtual roto-plane
signal aa, bb : unsigned(7 downto 0);
signal aIN, bIN : unsigned(3 downto 0):="0000";
signal pOUT : unsigned(7 downto 0):="00000000";
function v4(a:unsigned;b:unsigned) return unsigned;
function v8(aa:unsigned;bb:unsigned) return unsigned;
function v4(a:unsigned;b:unsigned) return unsigned is
variable r0,r7 : std_ulogic:='0';
variable r2,r3,r4,r5,r6,t2 : unsigned(2 downto 0):="000";
variable r1,t3,t4,t5 : unsigned(1 downto 0):="00";
variable mid : unsigned(15 downto 0):="0000000000000000";
begin
mid(0) := a(0) and b(0);
mid(1) := a(1) and b(0);
mid(2) := a(0) and b(1);
mid(3) := a(2) and b(0);
mid(4) := a(1) and b(1);
mid(5) := a(0) and b(2);
mid(6) := a(3) and b(0);
mid(7) := a(2) and b(1);
mid(8) := a(1) and b(2);
mid(9) := a(0) and b(3);
mid(10) := a(3) and b(1);
mid(11) := a(2) and b(2);
mid(12) := a(1) and b(3);
mid(13) := a(3) and b(2);
mid(14) := a(2) and b(3);
mid(15) := a(3) and b(3);
r0:=mid(0);
r1(0):=mid(1) xor mid(2);
r1(1):=mid(1) and mid(2);
r2(0):=mid(3) xor mid(4) xor mid(5) xor r1(1);
r2(1):=(mid(3) and mid(4)) xor (mid(5) and r1(1)) xor (mid(3) and mid(5)) xor (mid(4) and r1(1)) xor (mid(3) and r1(1)) xor (mid(4) and mid(5));
r2(2):=mid(3) and mid(4) and mid(5) and r1(1);
t2(0):=mid(6) xor mid(7) xor mid(8) xor mid(9);
t2(1):=(mid(6) and mid(7)) xor (mid(8) and mid(9)) xor (mid(6) and mid(8)) xor (mid(7) and mid(9)) xor (mid(6) and mid(9)) xor (mid(7) and mid(8));
t2(2):=mid(6) and mid(7) and mid(8) and mid(9);
r3 := t2 + to_integer(r2(2 downto 1));
t3(0):=mid(10) xor mid(11) xor mid(12);
t3(1):=(mid(10) and mid(11)) or (mid(11) and mid(12)) or (mid(12) and mid(10));
r4 := '0'&t3 + to_integer(r3(2 downto 1));
t4(0):=mid(13) xor mid(14);
t4(1):=mid(13) and mid(14);
r5 := '0'&t4 + to_integer(r4(2 downto 1));
t5(0) :=mid(15);
r6 := '0'&t5 + to_integer(r5(2 downto 1));
r7 := r6(1);
return r7&r6(0)&r5(0)&r4(0)&r3(0)&r2(0)&r1(0)&r0;
end v4;
function v8(aa:unsigned;bb:unsigned) return unsigned is
variable pt1,pt3 : unsigned(7 downto 0);
variable pt2 : unsigned(8 downto 0);
variable aal,aah,bbl,bbh : unsigned(3 downto 0);
begin
aal := aa(3 downto 0);
aah := aa(7 downto 4);
bbl := bb(3 downto 0);
bbh := bb(7 downto 4);
pt1 := v4(aal,bbl);
pt2 := '0'&v4(aal,bbh)+v4(aah,bbl)+pt1(7 downto 4);
pt3 := v4(aah,bbh)+ pt2(8 downto 4);
return pt3&pt2(3 downto 0)&pt1(3 downto 0);
end v8;
begin
hcounter: process (CLOCK_50, reset)
begin
if reset='1' then
hcount <= "0000000000";
elsif (rising_edge(CLOCK_50)) then
hcount <= hcount + 1;
if hcount=1039 then
hcount <= "00000000000";
end if;
end if;
end process;
vcounter: process (CLOCK_50, reset)
begin
if reset='1' then
vcount <= "0000000001";
elsif (rising_edge(CLOCK_50)) then
if hcount = 1039 then
vcount <= vcount + 1;
if vcount = 665 then
vcount <= "0000000000";
ninecount<=ninecount+1;
if fraccountdir = '1' then
fraccount <= fraccount + 1;
if fraccount > 512 then
fraccountdir <= '0';
end if;
end if;
if fraccountdir = '0' then
fraccount <= fraccount - 1;
if fraccount <= 1 then
fraccountdir <= '1';
end if;
end if;
end if;
end if;
end if;
end process;
process (vcount)
begin
videov <= '1';
if vcount > 599 then
videov <= '0';
end if;
end process;
process (hcount)
begin
videoh <= '1';
if hcount > 799 then
videoh <= '0';
end if;
end process;
sync: process (CLOCK_50, reset)
begin
if reset='1' then
hsync <= '0';
vsync <= '0';
elsif (rising_edge(CLOCK_50)) then
hsync <= '1';
if (hcount <= 987 and hcount >= 855) then
hsync <= '0';
end if;
vsync <= '1';
if (vcount <= 645 and vcount >= 636) then
vsync <= '0';
end if;
end if;
end process;
PixelColourSelector: process (CLOCK_50,reset)
begin
if reset='1' then
Out_Colour <= Black;
elsif (rising_edge(CLOCK_50)) then
Out_Colour <= Black;
if Yellow_Pixel='1' then
Out_Colour <= Yellow;
end if;
if White_Pixel='1' then
Out_Colour <= White;
end if;
if Black_Pixel='1' then
Out_Colour <= Black;
end if;
end if;
end process;
DrawApp: process (CLOCK_50, reset)
variable tmp1 : unsigned(15 downto 0):="0000000000000000";
variable tmp2 : unsigned(15 downto 0):="0000000000000000";
variable tmp3 : unsigned(15 downto 0):="0000000000000000";
variable tmp4 : unsigned(15 downto 0):="0000000000000000";
variable Xe0 : unsigned(15 downto 0):="0000000000000000";
variable Ye0 : unsigned(15 downto 0):="0000000000000000";
begin
if (rising_edge(CLOCK_50)) then
Yellow_Pixel <= '0';
White_Pixel <='0';
Black_Pixel <='0';
-- Very simple RotoZoom, Boing Boing Boing
if vcount = 0 then
X0 <= "0000000000000000";
Y0 <= "0000000000000000";
X1 <= "0000000000000000";
Y1 <= "0000000000000000";
elsif hcount = 0 then
X0 <= X1 - 65280;
Y0 <= Y1 + 65280 - ninecount;
X1 <= X1 - 65280;
Y1 <= Y1 + 65280 + ninecount;
else
X0 <= X0 + 65280 + ninecount;
Y0 <= Y0 + 65280;
end if;
-- Draw Fractal Thing
Xe0 := X0/256;
Ye0 := Y0/256;
if Ye0 >= 0 and Ye0 <= 256 and Xe0 >= 0 and Xe0 <= 256 then
tmp1 := (v8(Xe0(7 downto 0),Xe0(7 downto 0)));
tmp2 := (v8(Ye0(7 downto 0),Ye0(7 downto 0)));
tmp3 := (v8(256-Xe0(7 downto 0),256-Xe0(7 downto 0)));
tmp4 := (v8(256-Ye0(7 downto 0),256-Ye0(7 downto 0)));
if ((tmp1+tmp2) and (tmp1+tmp4) and (tmp2+tmp3) and (tmp3+tmp4)) <= fraccount then
Yellow_Pixel <='1';
end if;
end if;
-- Draw border
White_Pixel <='0';
if vcount <= 8 or vcount >= 592 or
hcount <= 8 or hcount >= 792 then
White_Pixel <='1';
end if;
end if;
end process;
videoon <= videoh and videov;
VGA <= Out_Colour;
VGAout(10 downto 2) <= VGA and videoon&videoon&videoon&videoon&videoon&videoon&videoon&videoon&videoon;
VGAout(1 downto 0) <= hsync & vsync;
end Behavioral;
Thanks for the code (VHDL FTW), i'm waiting for a OV7660, i will try to do some motion sensor or maybe some filter effect, just need another screen. Your code will be a great help when i start this project.
That ain't any sine wave
BRAM LUT and call it a day. No reason to forgo it
That ain't any sine wave
Very nice, you created sine and cosine without a look-up table. Now if you remove the graphics you need no RAM and probably very little logic blocks. I'm still new to FPGAs as I haven't done a lot of electronics in the last months to be honest.