home.social

#vhdl — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #vhdl, aggregated by home.social.

  1. I built a browser IDE that runs real open-source EDA tools. Write VHDL or SystemVerilog, hit run: GHDL/Icarus simulates it, Yosys synthesizes it, and you see the waveform and the netlist cell by cell. No install.

    Free fundamentals curriculum + engineering-flavored challenges, and a playground.

    risingedge.pro/

  2. Which Verilog TMDS encoding library do you recommend that I use on the Ice Pi Zero? Here is my review of the options.

    wiki.pythonlinks.info/dvi-rtl-

    #Verilog #VHDL #tMDS #IcePiZero

  3. @[email protected] 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'); uart_data : out std_logic_vector(7 downto 0) := (others => '0'); uart_ready : in std_logic; uart_valid : out std_logic := '0' ); end my_code; architecture rtl of my_code is constant IMAGE_WIDTH : integer := 32; constant IMAGE_HEIGHT : integer := 25; type image_type is array (IMAGE_HEIGHT*IMAGE_WIDTH*12-1 downto 0) of std_logic; constant image : image_type := x"00000000000000000000000000000000000000000000000123400000000000111200000000000000000000000000000000000000000000000000000000000000000000000000044645700000000022344700000000000000000000000000000000000000000000000000000000000000000000000000056845700100000033556800100000000000000000000000000000000000000000000000000000000000000000000000145744611100000034555800000000000000000000000000000000000000000000000000000000000000000000000000033533522423422444633500011075364300000000000000000000000000000000000000000000000000000000000000012334568979b457345123000964eb7da73211100000000000000000000000000000000000000000000000000000000003448abaddadd8ab79a578211c86fa7fa7c86c867430000000000000000000000000000000000000000000000000000005788bcaddadd8ab8ab689777eddebae96f96f9696400000000000000000000000000000000000000000000000011122289a89a9cdadd9aaabb79a777cccca9d85d85b643100000000000000000000000000000000000000000000002217657659aaabcacdaddbcdbcd7ab456888866754532210000000000000000000000000000000000000000000000000332765765789acdadeaddadd9cd58923444522200000011133333300000000000000000000000000000000000000000011154377688978a9bcacd9cc7ac7ad347000000433999bbbddcaaa0000000000000000000000000000000000000000001223443452235679bcabc9bc9ab68b46a124444bbbeddeedddd7770000000000000000000000000000000000000005679bd7ac78b769678cdddeecddacc7ae47a567888cccdddccc8881110000000000001110000000000003333331111115668ab69b89c88a668bcddeecee9bc67b56a99bcccaaa999555111111000000555aaacccbbb333222777eeeeeeccccdddddbbb445abceefeffeeeeeeeeedeedeeddebbcbbcdddeeebbbbbbcccbbb666dddeffdeffffdddccceeedefbdfeffdefbeffff999cccdefadfbefcefdefcefbefbefdeeeefadfbefffffffcefeffcccfffadf4cfdeffffdefeffbdf4cfadf3cf3cfbefeeedddbdf3bf3cf4cf6cf3cf5cf4cf7cfcef4cf4cfdefdff5cfbefdddcccdef3cf9dfdef4cfbdf9df4cf7cf3cf4cf6cfefffffadf4cfadfcef9df4cfdefadf2bf9df4cf3cf8cfdef4cfcefccd888fff9df3bf9cf3af7bf6af5af5af7bfadf3afadffff8cf2bf3bfcefadf3bfadf8cf3bfbdf4bf9cf5bf7bf3afdefbbb444ddddef48f37f47f37f26f58f37f57fbcf89f47fcdf79f79fbdfeffbcf38f6af49f38fabf48fbcf9af27f37feefaaa000aaafff79f37fbcf57f37f8af37f68fccfddf57f89f58f9bfffffffbcf37fddfddf47f57f47fbcfddf37f47ffff999000344eeeddfbcfeffddfcdfdefabfeefffffffdefeefddfeefddeccdddf9afeeffffddfddfddfeeffffbcfbcffff77800000099aeeeeeeddeddeddeeeeeefdee89abbcddeccdddddde99a99aeeffffeefdddeeeddeddeccdcddeeefffddd45600000022456866845745745755767956822423544723534645723433477978a679446567457446346346568679558112"; constant SPEED : integer := 8; signal position_x : integer range -SPEED to WIDTH + SPEED := 0; signal position_y : integer range -SPEED to HEIGHT + SPEED := 0; signal random_bit : std_logic := '0'; signal color : std_logic_vector(23 downto 0) := x"FFFFFF"; component OSCG is generic ( DIV : integer := 128 ); port ( OSC : out std_logic ); end component; signal pos : integer range 0 to IMAGE_HEIGHT*IMAGE_WIDTH*12; signal r, g, b : std_logic_vector(3 downto 0); begin char <= 0; pos <= IMAGE_HEIGHT*IMAGE_WIDTH*12 - 1 - 12*(py - position_y)*(px - position_x); r <= image(pos) & image(pos - 1) & image(pos - 2) & image(pos - 3); g <= image(pos - 4) & image(pos - 5) & image(pos - 6) & image(pos - 7); b <= image(pos - 8) & image(pos - 9) & image(pos - 10) & image(pos - 11); background_color <= r & r & g & g & b & b when px >= position_x and px < position_x + IMAGE_WIDTH and py >= position_y and py < position_y + IMAGE_HEIGHT else x"000000"; foreground_color <= (others => '1'); rng : OSCG port map ( OSC => random_bit ); process(clk) variable old_vsync : std_logic := '0'; variable speed_x : integer range -SPEED to SPEED := SPEED; variable speed_y : integer range -SPEED to SPEED := SPEED; begin if rising_edge(clk) then if vsync = '0' and old_vsync = '1' then if position_x + speed_x + IMAGE_WIDTH >= WIDTH then speed_x := -SPEED; position_x <= WIDTH - IMAGE_WIDTH - 1; color <= color(22 downto 0) & random_bit; elsif position_x + speed_x < 0 then speed_x := SPEED; position_x <= 0; color <= color(22 downto 0) & random_bit; else position_x <= position_x + speed_x; end if; if position_y + speed_y + IMAGE_HEIGHT >= HEIGHT then speed_y := -SPEED; position_y <= HEIGHT - IMAGE_HEIGHT - 1; color <= color(22 downto 0) & random_bit; elsif position_y + speed_y < 0 then speed_y := SPEED; position_y <= 0; color <= color(22 downto 0) & random_bit; else position_y <= position_y + speed_y; end if; end if; old_vsync := vsync; end if; end process; end architecture;

    Success!

    UART Output

    
    


    UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%MULT18X18D2287.1%TRELLIS_COMB29372428812.1%TRELLIS_FF160242880.7%TRELLIS_IO111975.6%
    TimingClockAchievedConstraint$glbnet$clkp30.03 MHz25 MHz$glbnet$clkt341.41 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');
    
            uart_data : out std_logic_vector(7 downto 0) := (others => '0');
            uart_ready : in std_logic;
            uart_valid : out std_logic := '0'
        );
    end my_code;
    
    architecture rtl of my_code is
        constant IMAGE_WIDTH : integer := 32;
        constant IMAGE_HEIGHT : integer := 25;
    
        type image_type is array (IMAGE_HEIGHT*IMAGE_WIDTH*12-1 downto 0) of std_logic;
        constant image : image_type := x"00000000000000000000000000000000000000000000000123400000000000111200000000000000000000000000000000000000000000000000000000000000000000000000044645700000000022344700000000000000000000000000000000000000000000000000000000000000000000000000056845700100000033556800100000000000000000000000000000000000000000000000000000000000000000000000145744611100000034555800000000000000000000000000000000000000000000000000000000000000000000000000033533522423422444633500011075364300000000000000000000000000000000000000000000000000000000000000012334568979b457345123000964eb7da73211100000000000000000000000000000000000000000000000000000000003448abaddadd8ab79a578211c86fa7fa7c86c867430000000000000000000000000000000000000000000000000000005788bcaddadd8ab8ab689777eddebae96f96f9696400000000000000000000000000000000000000000000000011122289a89a9cdadd9aaabb79a777cccca9d85d85b643100000000000000000000000000000000000000000000002217657659aaabcacdaddbcdbcd7ab456888866754532210000000000000000000000000000000000000000000000000332765765789acdadeaddadd9cd58923444522200000011133333300000000000000000000000000000000000000000011154377688978a9bcacd9cc7ac7ad347000000433999bbbddcaaa0000000000000000000000000000000000000000001223443452235679bcabc9bc9ab68b46a124444bbbeddeedddd7770000000000000000000000000000000000000005679bd7ac78b769678cdddeecddacc7ae47a567888cccdddccc8881110000000000001110000000000003333331111115668ab69b89c88a668bcddeecee9bc67b56a99bcccaaa999555111111000000555aaacccbbb333222777eeeeeeccccdddddbbb445abceefeffeeeeeeeeedeedeeddebbcbbcdddeeebbbbbbcccbbb666dddeffdeffffdddccceeedefbdfeffdefbeffff999cccdefadfbefcefdefcefbefbefdeeeefadfbefffffffcefeffcccfffadf4cfdeffffdefeffbdf4cfadf3cf3cfbefeeedddbdf3bf3cf4cf6cf3cf5cf4cf7cfcef4cf4cfdefdff5cfbefdddcccdef3cf9dfdef4cfbdf9df4cf7cf3cf4cf6cfefffffadf4cfadfcef9df4cfdefadf2bf9df4cf3cf8cfdef4cfcefccd888fff9df3bf9cf3af7bf6af5af5af7bfadf3afadffff8cf2bf3bfcefadf3bfadf8cf3bfbdf4bf9cf5bf7bf3afdefbbb444ddddef48f37f47f37f26f58f37f57fbcf89f47fcdf79f79fbdfeffbcf38f6af49f38fabf48fbcf9af27f37feefaaa000aaafff79f37fbcf57f37f8af37f68fccfddf57f89f58f9bfffffffbcf37fddfddf47f57f47fbcfddf37f47ffff999000344eeeddfbcfeffddfcdfdefabfeefffffffdefeefddfeefddeccdddf9afeeffffddfddfddfeeffffbcfbcffff77800000099aeeeeeeddeddeddeeeeeefdee89abbcddeccdddddde99a99aeeffffeefdddeeeddeddeccdcddeeefffddd45600000022456866845745745755767956822423544723534645723433477978a679446567457446346346568679558112";
    
        constant SPEED : integer := 8;
    
        signal position_x : integer range -SPEED to WIDTH + SPEED := 0;
        signal position_y : integer range -SPEED to HEIGHT + SPEED := 0;
    
        signal random_bit : std_logic := '0';
        signal color : std_logic_vector(23 downto 0) := x"FFFFFF";
    
        component OSCG is
            generic (
                DIV : integer := 128
            );
            port (
                OSC : out std_logic
            );
        end component;
    
        signal pos : integer range 0 to IMAGE_HEIGHT*IMAGE_WIDTH*12;
        signal r, g, b : std_logic_vector(3 downto 0);
    begin
        char <= 0;
    
        pos <= IMAGE_HEIGHT*IMAGE_WIDTH*12 - 1 - 12*(py - position_y)*(px - position_x);
        r <= image(pos) & image(pos - 1) & image(pos - 2) & image(pos - 3);
        g <= image(pos - 4) & image(pos - 5) & image(pos - 6) & image(pos - 7);
        b <= image(pos - 8) & image(pos - 9) & image(pos - 10) & image(pos - 11);
    
        background_color <= r & r & g & g & b & b
            when
                px >= position_x and px < position_x + IMAGE_WIDTH and
                py >= position_y and py < position_y + IMAGE_HEIGHT
            else x"000000";
        foreground_color <= (others => '1');
    
        rng : OSCG port map (
            OSC => random_bit
        );
    
        process(clk)
            variable old_vsync : std_logic := '0';
            variable speed_x : integer range -SPEED to SPEED := SPEED;
            variable speed_y : integer range -SPEED to SPEED := SPEED;
        begin
            if rising_edge(clk) then
                if vsync = '0' and old_vsync = '1' then
                    if position_x + speed_x + IMAGE_WIDTH >= WIDTH then
                        speed_x := -SPEED;
                        position_x <= WIDTH - IMAGE_WIDTH - 1;
    
                        color <= color(22 downto 0) & random_bit;
                    elsif position_x + speed_x < 0 then
                        speed_x := SPEED;
                        position_x <= 0;
    
                        color <= color(22 downto 0) & random_bit;
                    else
                        position_x <= position_x + speed_x;
                    end if;
    
                    if position_y + speed_y + IMAGE_HEIGHT >= HEIGHT then
                        speed_y := -SPEED;
                        position_y <= HEIGHT - IMAGE_HEIGHT - 1;
    
                        color <= color(22 downto 0) & random_bit;
                    elsif position_y + speed_y < 0 then
                        speed_y := SPEED;
                        position_y <= 0;
    
                        color <= color(22 downto 0) & random_bit;
                    else
                        position_y <= position_y + speed_y;
                    end if;
                end if;
                old_vsync := vsync;
            end if;
        end process;
    end architecture;
    


    #FPGA #Icepi-Zero #HDL #VHDL
  4. @[email protected]

    I am pleased to announce that @icepi-zero-bot is back up and running. :waffy_party:

    Now inside my Kubernetes cluster on more powerful hardware, so you should hopefully see some faster synthesis times and slightly nicer videos!
    I think I secured it pretty well, but if someone manages to do something naughty, please don't nom-nom all my data :pleading_face:
    Also, please don't break my FPGA on purporse, oki? :3

    Sadly, I still need to figure out Spade support, because I couldn't find any prebuilt arm64 binaries for it :(

    So, if you want to write cool SystemVerilog/VHDL/Amaranth/Veryl code, have it run on a real FPGA and output video (no need to implement DVI yourself, dw), which is then recorded and posted, check out @icepi-zero-bot's profile! The profile description contains tons of explanations and templates.

    Soon, I will hopefully add Spade support back and also implement a UART interface, so you can also output text! The support for that in the bot is already there, I just need to implement a UART transmitter in VHDL and think of a cute and easy interface.



    RE: https://wafrn.jcm.re/fediverse/post/83972345-09e4-47d9-99d3-4a3885a2a198
    #fedibot #FPGA #HDL #VHDL #Verilog #SystemVerilog #Amaranth #Veryl
  5. @[email protected]

    I am pleased to announce that @icepi-zero-bot is back up and running. :waffy_party:

    Now inside my Kubernetes cluster on more powerful hardware, so you should hopefully see some faster synthesis times and slightly nicer videos!
    I think I secured it pretty well, but if someone manages to do something naughty, please don't nom-nom all my data :pleading_face:
    Also, please don't break my FPGA on purporse, oki? :3

    Sadly, I still need to figure out Spade support, because I couldn't find any prebuilt arm64 binaries for it :(

    So, if you want to write cool SystemVerilog/VHDL/Amaranth/Veryl code, have it run on a real FPGA and output video (no need to implement DVI yourself, dw), which is then recorded and posted, check out @icepi-zero-bot's profile! The profile description contains tons of explanations and templates.

    Soon, I will hopefully add Spade support back and also implement a UART interface, so you can also output text! The support for that in the bot is already there, I just need to implement a UART transmitter in VHDL and think of a cute and easy interface.



    RE: https://wafrn.jcm.re/fediverse/post/83972345-09e4-47d9-99d3-4a3885a2a198
    #fedibot #FPGA #HDL #VHDL #Verilog #SystemVerilog #Amaranth #Veryl
  6. @[email protected]

    @[email protected] 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 := 117; constant IMAGE_HEIGHT : integer := 52; type image_type is array (0 to IMAGE_HEIGHT-1) of std_logic_vector(0 to IMAGE_WIDTH-1); constant image : image_type := ( "000000000111111111111111111111111111111111111111111111000000000000000000011111111111111111111111111111111100000000000", "000000000111111111111111111111111111111111111111111111000000000000000000111111111111111111111111111111111111100000000", "000000000111111111111111111111111111111111111111111111000000000000000001111111111111111111111111111111111111111000000", "000000000111111111111111111111111111111111111111111111100000000000000011111111111111111111111111111111111111111110000", "000000001111111111111111111111111111111111111111111111100000000000000011111111111111111111111111111111111111111111000", "000000001111111111111111111111111111111111111111111111100000000000000111111111111111111111111111111111111111111111100", "000000001111111111111111111111111111111111111111111111110000000000001111111111111111111111111111111111111111111111110", "000000001111111111110000000111111111111111111111111111110000000000011111111111111111111111110000000111111111111111111", "000000011111111111110000000000111111111111111111111111110000000000011111111111111111111111110000000000111111111111111", "000000011111111111110000000000011111111111111111111111111000000000111111111111111111111111110000000000011111111111111", "000000011111111111100000000000001111111111111111111111111000000001111111111111011111111111100000000000001111111111111", "000000011111111111100000000000000111111111111011111111111000000011111111111110011111111111100000000000000111111111111", "000000111111111111100000000000000111111111111011111111111100000111111111111100111111111111100000000000000111111111111", "000000111111111111100000000000000111111111111011111111111100000111111111111000111111111111100000000000000111111111111", "000000111111111111000000000000001111111111111001111111111100001111111111110000111111111111100000000000001111111111111", "000000111111111111000000000000001111111111111001111111111110011111111111110000111111111111000000000000001111111111111", "000001111111111111000000000000001111111111110001111111111110111111111111100000111111111111000000000000001111111111111", "000001111111111111000000000000011111111111110000111111111110111111111111000001111111111111000000000000011111111111110", "000001111111111111000000000000111111111111110000111111111111111111111110000001111111111111000000000000111111111111110", "000001111111111110000000000001111111111111100000111111111111111111111100000001111111111110000000000001111111111111100", "000001111111111110000000000111111111111111000000011111111111111111111000000001111111111110000000000111111111111111000", "000011111111111110000000111111111111111110000000011111111111111111110000000011111111111110000000111111111111111110000", "000011111111111111111111111111111111111100000000011111111111111111100000000011111111111111111111111111111111111100000", "000011111111111111111111111111111111111000000000001111111111111111100000000011111111111111111111111111111111111000000", "000011111111111111111111111111111111110000000000001111111111111111000000000011111111111111111111111111111111110000000", "000111111111111111111111111111111111000000000000000111111111111110000000000111111111111111111111111111111111000000000", "000111111111111111111111111111111100000000000000000111111111111100000000000111111111111111111111111111111100000000000", "000111111111111111111111111111100000000000000000000111111111111000000000000111111111111111111111111111100000000000000", "000111111111111111111111111100000000000000000000000011111111110000000000000111111111111111111111111100000000000000000", "000111111111111111111100000000000000000000000000000011111111100000000000000111111111111111111100000000000000000000000", "000000000000000000000000000000000000000000000000000011111111100000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000001111110000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000001111100000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000001111111111111111111111111111111111111111111111111111000000000000000000000000000000000000", "000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000", "000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000", "000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000", "000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000", "011111111111111111111110011111001111111001111111000000011111111100000011111111100000001111111111111111111111100000000", "111111111111111111111110011111001111111001111111001111001111111100111111111111001111100111111111111111111111110000000", "111111111111111111111111001110011111111001111111001111100111111100111111111110011111110011111111111111111111111000000", "111111111111111111111111101100111111111001111111001111100111111100000011111110011111110011111111111111111111111000000", "111111111111111111111111100101111111111001111111001111100111111100111111111110011111110011111111111111111111110000000", "011111111111111111111111110001111111111001111111001111001111111100111111111111001111100111111111111111111111100000000", "000011111111111111111111111011111111111001111111000000011111111100000011111111100000001111111111111111111110000000000", "000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000", "000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000", "000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000000000", "000000000000000000000000000001111111111111111111111111111111111111111111111111111100000000000000000000000000000000000" ); constant SPEED : integer := 8; signal position_x : integer range -SPEED to WIDTH + SPEED := 0; signal position_y : integer range -SPEED to HEIGHT + SPEED := 0; signal random_bit : std_logic := '0'; signal color : std_logic_vector(23 downto 0) := x"FFFFFF"; component OSCG is generic ( DIV : integer := 128 ); port ( OSC : out std_logic ); end component; begin char <= 0; background_color <= color when image(py - position_y)(px - position_x) = '1' and px >= position_x and px < position_x + IMAGE_WIDTH and py >= position_y and py < position_y + IMAGE_HEIGHT else x"000000"; foreground_color <= (others => '1'); rng : OSCG port map ( OSC => random_bit ); process(clk) variable old_vsync : std_logic := '0'; variable speed_x : integer range -SPEED to SPEED := SPEED; variable speed_y : integer range -SPEED to SPEED := SPEED; begin if rising_edge(clk) then if vsync = '0' and old_vsync = '1' then if position_x + speed_x + IMAGE_WIDTH >= WIDTH then speed_x := -SPEED; position_x <= WIDTH - IMAGE_WIDTH - 1; color <= color(22 downto 0) & random_bit; elsif position_x + speed_x < 0 then speed_x := SPEED; position_x <= 0; color <= color(22 downto 0) & random_bit; else position_x <= position_x + speed_x; end if; if position_y + speed_y + IMAGE_HEIGHT >= HEIGHT then speed_y := -SPEED; position_y <= HEIGHT - IMAGE_HEIGHT - 1; color <= color(22 downto 0) & random_bit; elsif position_y + speed_y < 0 then speed_y := SPEED; position_y <= 0; color <= color(22 downto 0) & random_bit; else position_y <= position_y + speed_y; end if; end if; old_vsync := vsync; end if; end process; end architecture;

    Success!

    UART Output

    
    


    UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%MULT18X18D1283.6%OSCG11100.0%TRELLIS_COMB1447242886.0%TRELLIS_FF180242880.7%TRELLIS_IO101975.1%
    TimingClockAchievedConstraint$glbnet$clkp34.93 MHz25 MHz$glbnet$clkt319.28 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 := 117;
        constant IMAGE_HEIGHT : integer := 52;
    
        type image_type is array (0 to IMAGE_HEIGHT-1) of std_logic_vector(0 to IMAGE_WIDTH-1);
        constant image : image_type := (
    "000000000111111111111111111111111111111111111111111111000000000000000000011111111111111111111111111111111100000000000",
    "000000000111111111111111111111111111111111111111111111000000000000000000111111111111111111111111111111111111100000000",
    "000000000111111111111111111111111111111111111111111111000000000000000001111111111111111111111111111111111111111000000",
    "000000000111111111111111111111111111111111111111111111100000000000000011111111111111111111111111111111111111111110000",
    "000000001111111111111111111111111111111111111111111111100000000000000011111111111111111111111111111111111111111111000",
    "000000001111111111111111111111111111111111111111111111100000000000000111111111111111111111111111111111111111111111100",
    "000000001111111111111111111111111111111111111111111111110000000000001111111111111111111111111111111111111111111111110",
    "000000001111111111110000000111111111111111111111111111110000000000011111111111111111111111110000000111111111111111111",
    "000000011111111111110000000000111111111111111111111111110000000000011111111111111111111111110000000000111111111111111",
    "000000011111111111110000000000011111111111111111111111111000000000111111111111111111111111110000000000011111111111111",
    "000000011111111111100000000000001111111111111111111111111000000001111111111111011111111111100000000000001111111111111",
    "000000011111111111100000000000000111111111111011111111111000000011111111111110011111111111100000000000000111111111111",
    "000000111111111111100000000000000111111111111011111111111100000111111111111100111111111111100000000000000111111111111",
    "000000111111111111100000000000000111111111111011111111111100000111111111111000111111111111100000000000000111111111111",
    "000000111111111111000000000000001111111111111001111111111100001111111111110000111111111111100000000000001111111111111",
    "000000111111111111000000000000001111111111111001111111111110011111111111110000111111111111000000000000001111111111111",
    "000001111111111111000000000000001111111111110001111111111110111111111111100000111111111111000000000000001111111111111",
    "000001111111111111000000000000011111111111110000111111111110111111111111000001111111111111000000000000011111111111110",
    "000001111111111111000000000000111111111111110000111111111111111111111110000001111111111111000000000000111111111111110",
    "000001111111111110000000000001111111111111100000111111111111111111111100000001111111111110000000000001111111111111100",
    "000001111111111110000000000111111111111111000000011111111111111111111000000001111111111110000000000111111111111111000",
    "000011111111111110000000111111111111111110000000011111111111111111110000000011111111111110000000111111111111111110000",
    "000011111111111111111111111111111111111100000000011111111111111111100000000011111111111111111111111111111111111100000",
    "000011111111111111111111111111111111111000000000001111111111111111100000000011111111111111111111111111111111111000000",
    "000011111111111111111111111111111111110000000000001111111111111111000000000011111111111111111111111111111111110000000",
    "000111111111111111111111111111111111000000000000000111111111111110000000000111111111111111111111111111111111000000000",
    "000111111111111111111111111111111100000000000000000111111111111100000000000111111111111111111111111111111100000000000",
    "000111111111111111111111111111100000000000000000000111111111111000000000000111111111111111111111111111100000000000000",
    "000111111111111111111111111100000000000000000000000011111111110000000000000111111111111111111111111100000000000000000",
    "000111111111111111111100000000000000000000000000000011111111100000000000000111111111111111111100000000000000000000000",
    "000000000000000000000000000000000000000000000000000011111111100000000000000000000000000000000000000000000000000000000",
    "000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000",
    "000000000000000000000000000000000000000000000000000001111110000000000000000000000000000000000000000000000000000000000",
    "000000000000000000000000000000000000000000000000000001111100000000000000000000000000000000000000000000000000000000000",
    "000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000",
    "000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000",
    "000000000000000000000000000001111111111111111111111111111111111111111111111111111000000000000000000000000000000000000",
    "000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000",
    "000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000",
    "000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000",
    "000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000",
    "011111111111111111111110011111001111111001111111000000011111111100000011111111100000001111111111111111111111100000000",
    "111111111111111111111110011111001111111001111111001111001111111100111111111111001111100111111111111111111111110000000",
    "111111111111111111111111001110011111111001111111001111100111111100111111111110011111110011111111111111111111111000000",
    "111111111111111111111111101100111111111001111111001111100111111100000011111110011111110011111111111111111111111000000",
    "111111111111111111111111100101111111111001111111001111100111111100111111111110011111110011111111111111111111110000000",
    "011111111111111111111111110001111111111001111111001111001111111100111111111111001111100111111111111111111111100000000",
    "000011111111111111111111111011111111111001111111000000011111111100000011111111100000001111111111111111111110000000000",
    "000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000",
    "000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000",
    "000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000000000",
    "000000000000000000000000000001111111111111111111111111111111111111111111111111111100000000000000000000000000000000000"
        );
    
        constant SPEED : integer := 8;
    
        signal position_x : integer range -SPEED to WIDTH + SPEED := 0;
        signal position_y : integer range -SPEED to HEIGHT + SPEED := 0;
    
        signal random_bit : std_logic := '0';
        signal color : std_logic_vector(23 downto 0) := x"FFFFFF";
    
        component OSCG is
            generic (
                DIV : integer := 128
            );
            port (
                OSC : out std_logic
            );
        end component;
    begin
        char <= 0;
    
        background_color <= color when image(py - position_y)(px - position_x) = '1' and
                px >= position_x and px < position_x + IMAGE_WIDTH and
                py >= position_y and py < position_y + IMAGE_HEIGHT
            else x"000000";
        foreground_color <= (others => '1');
    
        rng : OSCG port map (
            OSC => random_bit
        );
    
        process(clk)
            variable old_vsync : std_logic := '0';
            variable speed_x : integer range -SPEED to SPEED := SPEED;
            variable speed_y : integer range -SPEED to SPEED := SPEED;
        begin
            if rising_edge(clk) then
                if vsync = '0' and old_vsync = '1' then
                    if position_x + speed_x + IMAGE_WIDTH >= WIDTH then
                        speed_x := -SPEED;
                        position_x <= WIDTH - IMAGE_WIDTH - 1;
    
                        color <= color(22 downto 0) & random_bit;
                    elsif position_x + speed_x < 0 then
                        speed_x := SPEED;
                        position_x <= 0;
    
                        color <= color(22 downto 0) & random_bit;
                    else
                        position_x <= position_x + speed_x;
                    end if;
    
                    if position_y + speed_y + IMAGE_HEIGHT >= HEIGHT then
                        speed_y := -SPEED;
                        position_y <= HEIGHT - IMAGE_HEIGHT - 1;
    
                        color <= color(22 downto 0) & random_bit;
                    elsif position_y + speed_y < 0 then
                        speed_y := SPEED;
                        position_y <= 0;
    
                        color <= color(22 downto 0) & random_bit;
                    else
                        position_y <= position_y + speed_y;
                    end if;
                end if;
                old_vsync := vsync;
            end if;
        end process;
    end architecture;
    


    #FPGA #Icepi-Zero #HDL #VHDL
  7. Перепрыгивание с языка на язык как тактика прохождения интервью

    В 2010 году я участвовал в интервьировании на позицию по моделированию и верификации процессорных ядер. Один из кандидатов был благообразный седой американец, который до этого работал в IBM. Я задал вопрос про язык описания и верификации аппаратуры SystemVerilog. На это кандидат сказал, что он еще не освоил SystemVerilog, вписал его в резюме на будущее, но вообще использовал Verilog-95 и немного Verilog-2001. “Нет проблем”, - сказал я и задал вопрос по Verilog-95: “приведите примеры гонок (race conditions) при испрользовании верилога”. На это кандидат сказал, что вообще его опыт был больше связан с VHDL. “Блин, как он выкрутился” - подумал я, ведь в VHDL нет гонок как в верилоге из-за дизайна языка.

    habr.com/ru/articles/1033360/

    #SystemVerilog #verilog #Ada #VHDL #Jovial #Coral66 #IBM #Стенфорд #вопросы_на_собеседовании #внешний_вид

  8. Good read on #VHDL’s delta cycle algorithm in action. Delta cycles are an #HDL concept used to order events that occur in zero physical time:

    VHDL's crown jewel

    sigasi.com/opinion/jan/vhdls-c

  9. Good read on #VHDL’s delta cycle algorithm in action. Delta cycles are an #HDL concept used to order events that occur in zero physical time:

    VHDL's crown jewel

    sigasi.com/opinion/jan/vhdls-c

  10. Ah, the "crown jewel" of VHDL: a riveting exploration into #determinism so compelling, it'll have you questioning if watching paint dry is more thrilling. 🤦‍♂️🤷‍♀️ Dive into an endless loop of corporate jargon and existential delta cycles, because who needs excitement when you have VHDL? ⚙️🛠️
    sigasi.com/opinion/jan/vhdls-c #VHDL #CorporateJargon #ExistentialCycles #TechHumor #ProgrammingFun #HackerNews #ngated

  11. Ah, the "crown jewel" of VHDL: a riveting exploration into #determinism so compelling, it'll have you questioning if watching paint dry is more thrilling. 🤦‍♂️🤷‍♀️ Dive into an endless loop of corporate jargon and existential delta cycles, because who needs excitement when you have VHDL? ⚙️🛠️
    sigasi.com/opinion/jan/vhdls-c #VHDL #CorporateJargon #ExistentialCycles #TechHumor #ProgrammingFun #HackerNews #ngated

  12. Fun in the frequency domain 🤓 Camera pointed at it's own display also showing audio FFT for cool glitchy visualizer effect. Video processing all done in PipelineC hardware. And how?

    github.com/JulianKemmerer/Pipe

    #hardware #fpga #dsp #rtl #hdl #hls #verilog #vhdl #pipelinec

  13. Fun in the frequency domain 🤓 Camera pointed at it's own display also showing audio FFT for cool glitchy visualizer effect. Video processing all done in PipelineC hardware. And how?

    github.com/JulianKemmerer/Pipe

  14. Выступил отрицателем AI на конференции SNUG Silicon Valley

    AI - не микроархитектор, не проектировщик и не верификатор. Это все-лишь гламурный поисковик уже решенных и опубликованных задач. Именно такой вывод следовал из предоставленных мною на конференции SNUG Silicon Valley 2026 фактов как десятки студентов мучали ИИ чтобы решить мои задачки. Одну задачку ИИ решил лишь через полгода после выкладывания решений в интернет, другую за два месяца, потом пошла третья. При этом задачки были довольно банальные - мы в Самсунге даем делать такие статические конвейеры с контролем потока данных практикантам. Вот постер, сопровождающий мою статью:

    habr.com/ru/articles/1010978/

    #SNUG #Synopsys #Silicon_Valley #школа_синтеза_цифровых_схем #SystemVerilog #ASIC #FPGA #Samsung #задачи_на_собеседованиях #VHDL

  15. PipelineC holds the throughput lead on Latchup.app. For now! How does your design stack up against a pipelining tool? Far too time consuming and fun of a site 🤓 Look forward to seeing competing solutions.

    github.com/JulianKemmerer/Pipe

    #fpga #asic #rtl #hdl #verilog #vhdl #hls #eda

  16. PipelineC holds the throughput lead on Latchup.app. For now! How does your design stack up against a pipelining tool? Far too time consuming and fun of a site 🤓 Look forward to seeing competing solutions.

    github.com/JulianKemmerer/Pipe

  17. Start rtl counter with a timer that is initialized 10 seconds from a 32bit wrap point so that the software handling of wrap-around is well exercised during development.

    #rtl #fpga #verilog #vhdl #xilinx #alchitry #eureka #protonpack #software #softwaredevelopment #hardware #embedded #fensterFreitag

  18. Start rtl counter with a timer that is initialized 10 seconds from a 32bit wrap point so that the software handling of wrap-around is well exercised during development.

    #rtl #fpga #verilog #vhdl #xilinx #alchitry #eureka #protonpack #software #softwaredevelopment #hardware #embedded #fensterFreitag

  19. @[email protected] 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 alias bg_red : std_logic_vector(7 downto 0) is background_color(23 downto 16); alias bg_green : std_logic_vector(7 downto 0) is background_color(15 downto 8); alias bg_blue : std_logic_vector(7 downto 0) is background_color(7 downto 0); signal frame_counter : unsigned(31 downto 0) := (others => '0'); -- Aquarium title constant title_text : string(1 to 28) := "~~ Tiny VHDL Aquarium! ~~ <3"; constant title_row : integer := 1; constant title_col : integer := 26; -- Fish 1: ><> constant fish1 : string(1 to 3) := "><>"; constant fish1_row : integer := 10; -- Fish 2: <>< (facing left) constant fish2 : string(1 to 3) := "<><"; constant fish2_row : integer := 20; -- Fish 3: ><))'> constant fish3 : string(1 to 6) := "><))'>"; constant fish3_row : integer := 30; -- Fish 4: <'((<> constant fish4 : string(1 to 6) := "<'((<>"; constant fish4_row : integer := 40; -- Bubbles column constant bubble_col : integer := 5; -- Seaweed constant weed_row_start : integer := 50; -- Crab at bottom constant crab_text : string(1 to 5) := "V(..)"; constant crab_row : integer := 57; constant crab_col : integer := 38; signal fish1_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0; signal fish2_col : integer range 0 to CONSOLE_COLUMNS - 1 := 70; signal fish3_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0; signal fish4_col : integer range 0 to CONSOLE_COLUMNS - 1 := 60; signal bubble_phase : unsigned(5 downto 0) := (others => '0'); signal char_out : integer range 0 to 127 := 0; -- Helper function: modulo for column wrapping function wrap_col(val : integer; max_val : integer) return integer is begin return val mod max_val; end function; begin -- Frame counter & animation process(clk) variable old_vsync : std_logic := '0'; variable fc_local : unsigned(31 downto 0) := (others => '0'); begin if rising_edge(clk) then if rst = '1' then frame_counter <= (others => '0'); fish1_col <= 0; fish2_col <= 70; fish3_col <= 0; fish4_col <= 60; bubble_phase <= (others => '0'); elsif vsync = '0' and old_vsync = '1' then frame_counter <= frame_counter + 1; -- Move fish every 8 frames for a gentle swim if frame_counter(2 downto 0) = "000" then -- Fish 1 swims right if fish1_col < CONSOLE_COLUMNS - 1 then fish1_col <= fish1_col + 1; else fish1_col <= 0; end if; -- Fish 3 swims right (slower, updates every 16 frames via extra bit) if frame_counter(3) = '1' then if fish3_col < CONSOLE_COLUMNS - 1 then fish3_col <= fish3_col + 1; else fish3_col <= 0; end if; end if; -- Fish 2 swims left if fish2_col > 0 then fish2_col <= fish2_col - 1; else fish2_col <= CONSOLE_COLUMNS - 1; end if; -- Fish 4 swims left if fish4_col > 0 then fish4_col <= fish4_col - 1; else fish4_col <= CONSOLE_COLUMNS - 1; end if; bubble_phase <= bubble_phase + 1; end if; end if; old_vsync := vsync; end if; end process; -- Character output logic process(col, row, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase) variable c : integer range 0 to 127 := 0; variable rel : integer; variable bub_row : integer; begin c := 0; -- default: space -- Title if row = title_row and col >= title_col and col < title_col + title_text'length then rel := col - title_col + 1; if rel >= 1 and rel <= title_text'length then c := character'pos(title_text(rel)); end if; -- Fish 1: ><> swimming right elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then rel := col - fish1_col + 1; if rel >= 1 and rel <= fish1'length then c := character'pos(fish1(rel)); end if; -- Fish 2: <>< swimming left elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then rel := col - fish2_col + 1; if rel >= 1 and rel <= fish2'length then c := character'pos(fish2(rel)); end if; -- Fish 3: ><))'> swimming right elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then rel := col - fish3_col + 1; if rel >= 1 and rel <= fish3'length then c := character'pos(fish3(rel)); end if; -- Fish 4: <'((<> swimming left elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then rel := col - fish4_col + 1; if rel >= 1 and rel <= fish4'length then c := character'pos(fish4(rel)); end if; -- Crab at bottom elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then rel := col - crab_col + 1; if rel >= 1 and rel <= crab_text'length then c := character'pos(crab_text(rel)); end if; -- Bubbles: 'o' rising in a column, 3 bubbles spaced apart, shifting upward elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then bub_row := to_integer(bubble_phase); if row = (CONSOLE_ROWS - 5 - (bub_row mod (CONSOLE_ROWS - 6))) or row = (CONSOLE_ROWS - 5 - ((bub_row + 12) mod (CONSOLE_ROWS - 6))) or row = (CONSOLE_ROWS - 5 - ((bub_row + 24) mod (CONSOLE_ROWS - 6))) then c := character'pos('o'); end if; -- Seaweed at the bottom: alternating | and ( depending on frame for sway elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then if col = 10 or col = 20 or col = 35 or col = 50 or col = 65 or col = 75 then if frame_counter(4) = '0' then c := character'pos('('); else c := character'pos(')'); end if; end if; -- Sandy bottom elsif row = CONSOLE_ROWS - 1 then if (col mod 3) = 0 then c := character'pos('.'); elsif (col mod 3) = 1 then c := character'pos(','); else c := character'pos('_'); end if; -- Water surface elsif row = 0 then if frame_counter(3) = '0' then c := character'pos('~'); else c := character'pos('-'); end if; end if; char_out <= c; end process; char <= char_out; -- Background: deep ocean gradient (dark blue, getting darker toward bottom) process(row, col, frame_counter, py) variable depth_blue : unsigned(7 downto 0); variable depth_green : unsigned(7 downto 0); variable shimmer : unsigned(7 downto 0); begin -- Deeper = darker blue depth_blue := to_unsigned(180 - (py / 4), 8); depth_green := to_unsigned(40 + (py / 16), 8); shimmer := resize(frame_counter(5 downto 0), 8); -- Sandy bottom row if row >= CONSOLE_ROWS - 2 then bg_red <= x"C2"; bg_green <= x"B2"; bg_blue <= x"6E"; else bg_red <= std_logic_vector(to_unsigned(5, 8)); bg_green <= std_logic_vector(depth_green + shimmer(4 downto 2)); bg_blue <= std_logic_vector(depth_blue); end if; end process; -- Foreground colors per element process(row, col, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase) begin -- Default: white-ish foreground_color <= x"CCDDFF"; -- Title: golden yellow if row = title_row and col >= title_col and col < title_col + title_text'length then foreground_color <= x"FFD700"; -- Fish 1: orange elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then foreground_color <= x"FF6633"; -- Fish 2: cyan/teal elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then foreground_color <= x"00CED1"; -- Fish 3: magenta/pink elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then foreground_color <= x"FF69B4"; -- Fish 4: lime green elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then foreground_color <= x"7FFF00"; -- Crab: red elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then foreground_color <= x"FF2222"; -- Bubbles: light blue elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then foreground_color <= x"AAEEFF"; -- Seaweed: green elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then foreground_color <= x"228B22"; -- Water surface: light blue elsif row = 0 then foreground_color <= x"87CEEB"; -- Sandy bottom text elsif row = CONSOLE_ROWS - 1 then foreground_color <= x"A09060"; end if; end process; end architecture;

    Sucess!

    UtilizationCellUsedAvailableUsage DCCA2563.6% EHXPLLL1250% TRELLIS_COMB1901242887.8% TRELLIS_FF176242880.7% TRELLIS_IO101975.1%
    TimingClockAchievedConstraint $glbnet$clkp37.98 MHz25 MHz $glbnet$clkt281.21 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
      alias bg_red   : std_logic_vector(7 downto 0) is background_color(23 downto 16);
      alias bg_green : std_logic_vector(7 downto 0) is background_color(15 downto 8);
      alias bg_blue  : std_logic_vector(7 downto 0) is background_color(7 downto 0);
    
      signal frame_counter : unsigned(31 downto 0) := (others => '0');
    
      -- Aquarium title
      constant title_text : string(1 to 28) := "~~ Tiny VHDL Aquarium! ~~ <3";
      constant title_row  : integer := 1;
      constant title_col  : integer := 26;
    
      -- Fish 1:  ><>
      constant fish1 : string(1 to 3) := "><>";
      constant fish1_row : integer := 10;
    
      -- Fish 2:  <>< (facing left)
      constant fish2 : string(1 to 3) := "<><";
      constant fish2_row : integer := 20;
    
      -- Fish 3:  ><))'>
      constant fish3 : string(1 to 6) := "><))'>";
      constant fish3_row : integer := 30;
    
      -- Fish 4:  <'((<>
      constant fish4 : string(1 to 6) := "<'((<>";
      constant fish4_row : integer := 40;
    
      -- Bubbles column
      constant bubble_col : integer := 5;
    
      -- Seaweed
      constant weed_row_start : integer := 50;
    
      -- Crab at bottom
      constant crab_text : string(1 to 5) := "V(..)";
      constant crab_row  : integer := 57;
      constant crab_col  : integer := 38;
    
      signal fish1_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0;
      signal fish2_col : integer range 0 to CONSOLE_COLUMNS - 1 := 70;
      signal fish3_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0;
      signal fish4_col : integer range 0 to CONSOLE_COLUMNS - 1 := 60;
    
      signal bubble_phase : unsigned(5 downto 0) := (others => '0');
    
      signal char_out : integer range 0 to 127 := 0;
    
      -- Helper function: modulo for column wrapping
      function wrap_col(val : integer; max_val : integer) return integer is
      begin
        return val mod max_val;
      end function;
    
    begin
    
      -- Frame counter & animation
      process(clk)
        variable old_vsync : std_logic := '0';
        variable fc_local  : unsigned(31 downto 0) := (others => '0');
      begin
        if rising_edge(clk) then
          if rst = '1' then
            frame_counter <= (others => '0');
            fish1_col <= 0;
            fish2_col <= 70;
            fish3_col <= 0;
            fish4_col <= 60;
            bubble_phase <= (others => '0');
          elsif vsync = '0' and old_vsync = '1' then
            frame_counter <= frame_counter + 1;
    
            -- Move fish every 8 frames for a gentle swim
            if frame_counter(2 downto 0) = "000" then
              -- Fish 1 swims right
              if fish1_col < CONSOLE_COLUMNS - 1 then
                fish1_col <= fish1_col + 1;
              else
                fish1_col <= 0;
              end if;
    
              -- Fish 3 swims right (slower, updates every 16 frames via extra bit)
              if frame_counter(3) = '1' then
                if fish3_col < CONSOLE_COLUMNS - 1 then
                  fish3_col <= fish3_col + 1;
                else
                  fish3_col <= 0;
                end if;
              end if;
    
              -- Fish 2 swims left
              if fish2_col > 0 then
                fish2_col <= fish2_col - 1;
              else
                fish2_col <= CONSOLE_COLUMNS - 1;
              end if;
    
              -- Fish 4 swims left
              if fish4_col > 0 then
                fish4_col <= fish4_col - 1;
              else
                fish4_col <= CONSOLE_COLUMNS - 1;
              end if;
    
              bubble_phase <= bubble_phase + 1;
            end if;
          end if;
          old_vsync := vsync;
        end if;
      end process;
    
      -- Character output logic
      process(col, row, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase)
        variable c : integer range 0 to 127 := 0;
        variable rel : integer;
        variable bub_row : integer;
      begin
        c := 0; -- default: space
    
        -- Title
        if row = title_row and col >= title_col and col < title_col + title_text'length then
          rel := col - title_col + 1;
          if rel >= 1 and rel <= title_text'length then
            c := character'pos(title_text(rel));
          end if;
    
        -- Fish 1: ><>  swimming right
        elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then
          rel := col - fish1_col + 1;
          if rel >= 1 and rel <= fish1'length then
            c := character'pos(fish1(rel));
          end if;
    
        -- Fish 2: <><  swimming left
        elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then
          rel := col - fish2_col + 1;
          if rel >= 1 and rel <= fish2'length then
            c := character'pos(fish2(rel));
          end if;
    
        -- Fish 3: ><))'>  swimming right
        elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then
          rel := col - fish3_col + 1;
          if rel >= 1 and rel <= fish3'length then
            c := character'pos(fish3(rel));
          end if;
    
        -- Fish 4: <'((<>  swimming left
        elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then
          rel := col - fish4_col + 1;
          if rel >= 1 and rel <= fish4'length then
            c := character'pos(fish4(rel));
          end if;
    
        -- Crab at bottom
        elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then
          rel := col - crab_col + 1;
          if rel >= 1 and rel <= crab_text'length then
            c := character'pos(crab_text(rel));
          end if;
    
        -- Bubbles: 'o' rising in a column, 3 bubbles spaced apart, shifting upward
        elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then
          bub_row := to_integer(bubble_phase);
          if row = (CONSOLE_ROWS - 5 - (bub_row mod (CONSOLE_ROWS - 6))) or
             row = (CONSOLE_ROWS - 5 - ((bub_row + 12) mod (CONSOLE_ROWS - 6))) or
             row = (CONSOLE_ROWS - 5 - ((bub_row + 24) mod (CONSOLE_ROWS - 6))) then
            c := character'pos('o');
          end if;
    
        -- Seaweed at the bottom: alternating | and ( depending on frame for sway
        elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then
          if col = 10 or col = 20 or col = 35 or col = 50 or col = 65 or col = 75 then
            if frame_counter(4) = '0' then
              c := character'pos('(');
            else
              c := character'pos(')');
            end if;
          end if;
    
        -- Sandy bottom
        elsif row = CONSOLE_ROWS - 1 then
          if (col mod 3) = 0 then
            c := character'pos('.');
          elsif (col mod 3) = 1 then
            c := character'pos(',');
          else
            c := character'pos('_');
          end if;
    
        -- Water surface
        elsif row = 0 then
          if frame_counter(3) = '0' then
            c := character'pos('~');
          else
            c := character'pos('-');
          end if;
        end if;
    
        char_out <= c;
      end process;
    
      char <= char_out;
    
      -- Background: deep ocean gradient (dark blue, getting darker toward bottom)
      process(row, col, frame_counter, py)
        variable depth_blue  : unsigned(7 downto 0);
        variable depth_green : unsigned(7 downto 0);
        variable shimmer     : unsigned(7 downto 0);
      begin
        -- Deeper = darker blue
        depth_blue := to_unsigned(180 - (py / 4), 8);
        depth_green := to_unsigned(40 + (py / 16), 8);
        shimmer := resize(frame_counter(5 downto 0), 8);
    
        -- Sandy bottom row
        if row >= CONSOLE_ROWS - 2 then
          bg_red   <= x"C2";
          bg_green <= x"B2";
          bg_blue  <= x"6E";
        else
          bg_red   <= std_logic_vector(to_unsigned(5, 8));
          bg_green <= std_logic_vector(depth_green + shimmer(4 downto 2));
          bg_blue  <= std_logic_vector(depth_blue);
        end if;
      end process;
    
      -- Foreground colors per element
      process(row, col, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase)
      begin
        -- Default: white-ish
        foreground_color <= x"CCDDFF";
    
        -- Title: golden yellow
        if row = title_row and col >= title_col and col < title_col + title_text'length then
          foreground_color <= x"FFD700";
    
        -- Fish 1: orange
        elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then
          foreground_color <= x"FF6633";
    
        -- Fish 2: cyan/teal
        elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then
          foreground_color <= x"00CED1";
    
        -- Fish 3: magenta/pink
        elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then
          foreground_color <= x"FF69B4";
    
        -- Fish 4: lime green
        elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then
          foreground_color <= x"7FFF00";
    
        -- Crab: red
        elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then
          foreground_color <= x"FF2222";
    
        -- Bubbles: light blue
        elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then
          foreground_color <= x"AAEEFF";
    
        -- Seaweed: green
        elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then
          foreground_color <= x"228B22";
    
        -- Water surface: light blue
        elsif row = 0 then
          foreground_color <= x"87CEEB";
    
        -- Sandy bottom text
        elsif row = CONSOLE_ROWS - 1 then
          foreground_color <= x"A09060";
        end if;
      end process;
    
    end architecture;
    


    #FPGA #Icepi-Zero #HDL #VHDL
  20. @[email protected] 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 alias bg_red : std_logic_vector(7 downto 0) is background_color(23 downto 16); alias bg_green : std_logic_vector(7 downto 0) is background_color(15 downto 8); alias bg_blue : std_logic_vector(7 downto 0) is background_color(7 downto 0); signal frame_counter : unsigned(31 downto 0) := (others => '0'); -- Aquarium title constant title_text : string(1 to 28) := "~~ Tiny VHDL Aquarium! ~~ <3"; constant title_row : integer := 1; constant title_col : integer := 26; -- Fish 1: ><> constant fish1 : string(1 to 3) := "><>"; constant fish1_row : integer := 10; -- Fish 2: <>< (facing left) constant fish2 : string(1 to 3) := "<><"; constant fish2_row : integer := 20; -- Fish 3: ><))'> constant fish3 : string(1 to 6) := "><))'>"; constant fish3_row : integer := 30; -- Fish 4: <'((<> constant fish4 : string(1 to 6) := "<'((<>"; constant fish4_row : integer := 40; -- Bubbles column constant bubble_col : integer := 5; -- Seaweed constant weed_row_start : integer := 50; -- Crab at bottom constant crab_text : string(1 to 5) := "V(..)"; constant crab_row : integer := 57; constant crab_col : integer := 38; signal fish1_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0; signal fish2_col : integer range 0 to CONSOLE_COLUMNS - 1 := 70; signal fish3_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0; signal fish4_col : integer range 0 to CONSOLE_COLUMNS - 1 := 60; signal bubble_phase : unsigned(5 downto 0) := (others => '0'); signal char_out : integer range 0 to 127 := 0; -- Helper function: modulo for column wrapping function wrap_col(val : integer; max_val : integer) return integer is begin return val mod max_val; end function; begin -- Frame counter & animation process(clk) variable old_vsync : std_logic := '0'; variable fc_local : unsigned(31 downto 0) := (others => '0'); begin if rising_edge(clk) then if rst = '1' then frame_counter <= (others => '0'); fish1_col <= 0; fish2_col <= 70; fish3_col <= 0; fish4_col <= 60; bubble_phase <= (others => '0'); elsif vsync = '0' and old_vsync = '1' then frame_counter <= frame_counter + 1; -- Move fish every 8 frames for a gentle swim if frame_counter(2 downto 0) = "000" then -- Fish 1 swims right if fish1_col < CONSOLE_COLUMNS - 1 then fish1_col <= fish1_col + 1; else fish1_col <= 0; end if; -- Fish 3 swims right (slower, updates every 16 frames via extra bit) if frame_counter(3) = '1' then if fish3_col < CONSOLE_COLUMNS - 1 then fish3_col <= fish3_col + 1; else fish3_col <= 0; end if; end if; -- Fish 2 swims left if fish2_col > 0 then fish2_col <= fish2_col - 1; else fish2_col <= CONSOLE_COLUMNS - 1; end if; -- Fish 4 swims left if fish4_col > 0 then fish4_col <= fish4_col - 1; else fish4_col <= CONSOLE_COLUMNS - 1; end if; bubble_phase <= bubble_phase + 1; end if; end if; old_vsync := vsync; end if; end process; -- Character output logic process(col, row, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase) variable c : integer range 0 to 127 := 0; variable rel : integer; variable bub_row : integer; begin c := 0; -- default: space -- Title if row = title_row and col >= title_col and col < title_col + title_text'length then rel := col - title_col + 1; if rel >= 1 and rel <= title_text'length then c := character'pos(title_text(rel)); end if; -- Fish 1: ><> swimming right elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then rel := col - fish1_col + 1; if rel >= 1 and rel <= fish1'length then c := character'pos(fish1(rel)); end if; -- Fish 2: <>< swimming left elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then rel := col - fish2_col + 1; if rel >= 1 and rel <= fish2'length then c := character'pos(fish2(rel)); end if; -- Fish 3: ><))'> swimming right elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then rel := col - fish3_col + 1; if rel >= 1 and rel <= fish3'length then c := character'pos(fish3(rel)); end if; -- Fish 4: <'((<> swimming left elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then rel := col - fish4_col + 1; if rel >= 1 and rel <= fish4'length then c := character'pos(fish4(rel)); end if; -- Crab at bottom elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then rel := col - crab_col + 1; if rel >= 1 and rel <= crab_text'length then c := character'pos(crab_text(rel)); end if; -- Bubbles: 'o' rising in a column, 3 bubbles spaced apart, shifting upward elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then bub_row := to_integer(bubble_phase); if row = (CONSOLE_ROWS - 5 - (bub_row mod (CONSOLE_ROWS - 6))) or row = (CONSOLE_ROWS - 5 - ((bub_row + 12) mod (CONSOLE_ROWS - 6))) or row = (CONSOLE_ROWS - 5 - ((bub_row + 24) mod (CONSOLE_ROWS - 6))) then c := character'pos('o'); end if; -- Seaweed at the bottom: alternating | and ( depending on frame for sway elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then if col = 10 or col = 20 or col = 35 or col = 50 or col = 65 or col = 75 then if frame_counter(4) = '0' then c := character'pos('('); else c := character'pos(')'); end if; end if; -- Sandy bottom elsif row = CONSOLE_ROWS - 1 then if (col mod 3) = 0 then c := character'pos('.'); elsif (col mod 3) = 1 then c := character'pos(','); else c := character'pos('_'); end if; -- Water surface elsif row = 0 then if frame_counter(3) = '0' then c := character'pos('~'); else c := character'pos('-'); end if; end if; char_out <= c; end process; char <= char_out; -- Background: deep ocean gradient (dark blue, getting darker toward bottom) process(row, col, frame_counter, py) variable depth_blue : unsigned(7 downto 0); variable depth_green : unsigned(7 downto 0); variable shimmer : unsigned(7 downto 0); begin -- Deeper = darker blue depth_blue := to_unsigned(180 - (py / 4), 8); depth_green := to_unsigned(40 + (py / 16), 8); shimmer := resize(frame_counter(5 downto 0), 8); -- Sandy bottom row if row >= CONSOLE_ROWS - 2 then bg_red <= x"C2"; bg_green <= x"B2"; bg_blue <= x"6E"; else bg_red <= std_logic_vector(to_unsigned(5, 8)); bg_green <= std_logic_vector(depth_green + shimmer(4 downto 2)); bg_blue <= std_logic_vector(depth_blue); end if; end process; -- Foreground colors per element process(row, col, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase) begin -- Default: white-ish foreground_color <= x"CCDDFF"; -- Title: golden yellow if row = title_row and col >= title_col and col < title_col + title_text'length then foreground_color <= x"FFD700"; -- Fish 1: orange elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then foreground_color <= x"FF6633"; -- Fish 2: cyan/teal elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then foreground_color <= x"00CED1"; -- Fish 3: magenta/pink elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then foreground_color <= x"FF69B4"; -- Fish 4: lime green elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then foreground_color <= x"7FFF00"; -- Crab: red elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then foreground_color <= x"FF2222"; -- Bubbles: light blue elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then foreground_color <= x"AAEEFF"; -- Seaweed: green elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then foreground_color <= x"228B22"; -- Water surface: light blue elsif row = 0 then foreground_color <= x"87CEEB"; -- Sandy bottom text elsif row = CONSOLE_ROWS - 1 then foreground_color <= x"A09060"; end if; end process; end architecture;

    Sucess!

    UtilizationCellUsedAvailableUsage DCCA2563.6% EHXPLLL1250% TRELLIS_COMB1901242887.8% TRELLIS_FF176242880.7% TRELLIS_IO101975.1%
    TimingClockAchievedConstraint $glbnet$clkp37.98 MHz25 MHz $glbnet$clkt281.21 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
      alias bg_red   : std_logic_vector(7 downto 0) is background_color(23 downto 16);
      alias bg_green : std_logic_vector(7 downto 0) is background_color(15 downto 8);
      alias bg_blue  : std_logic_vector(7 downto 0) is background_color(7 downto 0);
    
      signal frame_counter : unsigned(31 downto 0) := (others => '0');
    
      -- Aquarium title
      constant title_text : string(1 to 28) := "~~ Tiny VHDL Aquarium! ~~ <3";
      constant title_row  : integer := 1;
      constant title_col  : integer := 26;
    
      -- Fish 1:  ><>
      constant fish1 : string(1 to 3) := "><>";
      constant fish1_row : integer := 10;
    
      -- Fish 2:  <>< (facing left)
      constant fish2 : string(1 to 3) := "<><";
      constant fish2_row : integer := 20;
    
      -- Fish 3:  ><))'>
      constant fish3 : string(1 to 6) := "><))'>";
      constant fish3_row : integer := 30;
    
      -- Fish 4:  <'((<>
      constant fish4 : string(1 to 6) := "<'((<>";
      constant fish4_row : integer := 40;
    
      -- Bubbles column
      constant bubble_col : integer := 5;
    
      -- Seaweed
      constant weed_row_start : integer := 50;
    
      -- Crab at bottom
      constant crab_text : string(1 to 5) := "V(..)";
      constant crab_row  : integer := 57;
      constant crab_col  : integer := 38;
    
      signal fish1_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0;
      signal fish2_col : integer range 0 to CONSOLE_COLUMNS - 1 := 70;
      signal fish3_col : integer range 0 to CONSOLE_COLUMNS - 1 := 0;
      signal fish4_col : integer range 0 to CONSOLE_COLUMNS - 1 := 60;
    
      signal bubble_phase : unsigned(5 downto 0) := (others => '0');
    
      signal char_out : integer range 0 to 127 := 0;
    
      -- Helper function: modulo for column wrapping
      function wrap_col(val : integer; max_val : integer) return integer is
      begin
        return val mod max_val;
      end function;
    
    begin
    
      -- Frame counter & animation
      process(clk)
        variable old_vsync : std_logic := '0';
        variable fc_local  : unsigned(31 downto 0) := (others => '0');
      begin
        if rising_edge(clk) then
          if rst = '1' then
            frame_counter <= (others => '0');
            fish1_col <= 0;
            fish2_col <= 70;
            fish3_col <= 0;
            fish4_col <= 60;
            bubble_phase <= (others => '0');
          elsif vsync = '0' and old_vsync = '1' then
            frame_counter <= frame_counter + 1;
    
            -- Move fish every 8 frames for a gentle swim
            if frame_counter(2 downto 0) = "000" then
              -- Fish 1 swims right
              if fish1_col < CONSOLE_COLUMNS - 1 then
                fish1_col <= fish1_col + 1;
              else
                fish1_col <= 0;
              end if;
    
              -- Fish 3 swims right (slower, updates every 16 frames via extra bit)
              if frame_counter(3) = '1' then
                if fish3_col < CONSOLE_COLUMNS - 1 then
                  fish3_col <= fish3_col + 1;
                else
                  fish3_col <= 0;
                end if;
              end if;
    
              -- Fish 2 swims left
              if fish2_col > 0 then
                fish2_col <= fish2_col - 1;
              else
                fish2_col <= CONSOLE_COLUMNS - 1;
              end if;
    
              -- Fish 4 swims left
              if fish4_col > 0 then
                fish4_col <= fish4_col - 1;
              else
                fish4_col <= CONSOLE_COLUMNS - 1;
              end if;
    
              bubble_phase <= bubble_phase + 1;
            end if;
          end if;
          old_vsync := vsync;
        end if;
      end process;
    
      -- Character output logic
      process(col, row, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase)
        variable c : integer range 0 to 127 := 0;
        variable rel : integer;
        variable bub_row : integer;
      begin
        c := 0; -- default: space
    
        -- Title
        if row = title_row and col >= title_col and col < title_col + title_text'length then
          rel := col - title_col + 1;
          if rel >= 1 and rel <= title_text'length then
            c := character'pos(title_text(rel));
          end if;
    
        -- Fish 1: ><>  swimming right
        elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then
          rel := col - fish1_col + 1;
          if rel >= 1 and rel <= fish1'length then
            c := character'pos(fish1(rel));
          end if;
    
        -- Fish 2: <><  swimming left
        elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then
          rel := col - fish2_col + 1;
          if rel >= 1 and rel <= fish2'length then
            c := character'pos(fish2(rel));
          end if;
    
        -- Fish 3: ><))'>  swimming right
        elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then
          rel := col - fish3_col + 1;
          if rel >= 1 and rel <= fish3'length then
            c := character'pos(fish3(rel));
          end if;
    
        -- Fish 4: <'((<>  swimming left
        elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then
          rel := col - fish4_col + 1;
          if rel >= 1 and rel <= fish4'length then
            c := character'pos(fish4(rel));
          end if;
    
        -- Crab at bottom
        elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then
          rel := col - crab_col + 1;
          if rel >= 1 and rel <= crab_text'length then
            c := character'pos(crab_text(rel));
          end if;
    
        -- Bubbles: 'o' rising in a column, 3 bubbles spaced apart, shifting upward
        elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then
          bub_row := to_integer(bubble_phase);
          if row = (CONSOLE_ROWS - 5 - (bub_row mod (CONSOLE_ROWS - 6))) or
             row = (CONSOLE_ROWS - 5 - ((bub_row + 12) mod (CONSOLE_ROWS - 6))) or
             row = (CONSOLE_ROWS - 5 - ((bub_row + 24) mod (CONSOLE_ROWS - 6))) then
            c := character'pos('o');
          end if;
    
        -- Seaweed at the bottom: alternating | and ( depending on frame for sway
        elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then
          if col = 10 or col = 20 or col = 35 or col = 50 or col = 65 or col = 75 then
            if frame_counter(4) = '0' then
              c := character'pos('(');
            else
              c := character'pos(')');
            end if;
          end if;
    
        -- Sandy bottom
        elsif row = CONSOLE_ROWS - 1 then
          if (col mod 3) = 0 then
            c := character'pos('.');
          elsif (col mod 3) = 1 then
            c := character'pos(',');
          else
            c := character'pos('_');
          end if;
    
        -- Water surface
        elsif row = 0 then
          if frame_counter(3) = '0' then
            c := character'pos('~');
          else
            c := character'pos('-');
          end if;
        end if;
    
        char_out <= c;
      end process;
    
      char <= char_out;
    
      -- Background: deep ocean gradient (dark blue, getting darker toward bottom)
      process(row, col, frame_counter, py)
        variable depth_blue  : unsigned(7 downto 0);
        variable depth_green : unsigned(7 downto 0);
        variable shimmer     : unsigned(7 downto 0);
      begin
        -- Deeper = darker blue
        depth_blue := to_unsigned(180 - (py / 4), 8);
        depth_green := to_unsigned(40 + (py / 16), 8);
        shimmer := resize(frame_counter(5 downto 0), 8);
    
        -- Sandy bottom row
        if row >= CONSOLE_ROWS - 2 then
          bg_red   <= x"C2";
          bg_green <= x"B2";
          bg_blue  <= x"6E";
        else
          bg_red   <= std_logic_vector(to_unsigned(5, 8));
          bg_green <= std_logic_vector(depth_green + shimmer(4 downto 2));
          bg_blue  <= std_logic_vector(depth_blue);
        end if;
      end process;
    
      -- Foreground colors per element
      process(row, col, fish1_col, fish2_col, fish3_col, fish4_col, frame_counter, bubble_phase)
      begin
        -- Default: white-ish
        foreground_color <= x"CCDDFF";
    
        -- Title: golden yellow
        if row = title_row and col >= title_col and col < title_col + title_text'length then
          foreground_color <= x"FFD700";
    
        -- Fish 1: orange
        elsif row = fish1_row and col >= fish1_col and col < fish1_col + fish1'length then
          foreground_color <= x"FF6633";
    
        -- Fish 2: cyan/teal
        elsif row = fish2_row and col >= fish2_col and col < fish2_col + fish2'length then
          foreground_color <= x"00CED1";
    
        -- Fish 3: magenta/pink
        elsif row = fish3_row and col >= fish3_col and col < fish3_col + fish3'length then
          foreground_color <= x"FF69B4";
    
        -- Fish 4: lime green
        elsif row = fish4_row and col >= fish4_col and col < fish4_col + fish4'length then
          foreground_color <= x"7FFF00";
    
        -- Crab: red
        elsif row = crab_row and col >= crab_col and col < crab_col + crab_text'length then
          foreground_color <= x"FF2222";
    
        -- Bubbles: light blue
        elsif col = bubble_col or col = bubble_col + 30 or col = bubble_col + 55 then
          foreground_color <= x"AAEEFF";
    
        -- Seaweed: green
        elsif row >= weed_row_start and row <= CONSOLE_ROWS - 2 then
          foreground_color <= x"228B22";
    
        -- Water surface: light blue
        elsif row = 0 then
          foreground_color <= x"87CEEB";
    
        -- Sandy bottom text
        elsif row = CONSOLE_ROWS - 1 then
          foreground_color <= x"A09060";
        end if;
      end process;
    
    end architecture;
    


    #FPGA #Icepi-Zero #HDL #VHDL
  21. @[email protected] 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!

    UtilizationCellUsedAvailableUsage DCCA2563.6% EHXPLLL1250% MULT18X18D2287.1% OSCG11100% TRELLIS_COMB1100242884.5% TRELLIS_FF196242880.8% TRELLIS_IO101975.1%
    TimingClockAchievedConstraint $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
  22. @[email protected] 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 -- Internal signals for color channels signal r_sig : std_logic_vector(7 downto 0); signal g_sig : std_logic_vector(7 downto 0); signal b_sig : std_logic_vector(7 downto 0); -- Animation state signals signal frame_counter : unsigned(31 downto 0) := (others => '0'); signal anim_speed : integer range 0 to 3 := 0; -- Bouncing text state constant msg_text : string := " <3 VHDL <3 "; signal text_col : integer range -10 to CONSOLE_COLUMNS + 10 := 5; -- widened range for safety signal text_row : integer range -10 to CONSOLE_ROWS + 10 := 5; signal dir_col : integer range -1 to 1 := 1; signal dir_row : integer range -1 to 1 := 1; begin -- Assemble background color from internal signals background_color <= r_sig & g_sig & b_sig; -- Foreground is always white foreground_color <= (others => '1'); ---------------------------------------------------------------------------- -- 1. Background Generation -- Calculates Manhattan distance using IF/ELSE to avoid 'abs' synthesis error. ---------------------------------------------------------------------------- process(px, py, frame_counter) variable dx, dy : integer; variable dist : integer; variable phase : unsigned(7 downto 0); begin -- Manual Absolute Value for X if px > (WIDTH / 2) then dx := px - (WIDTH / 2); else dx := (WIDTH / 2) - px; end if; -- Manual Absolute Value for Y if py > (HEIGHT / 2) then dy := py - (HEIGHT / 2); else dy := (HEIGHT / 2) - py; end if; dist := dx + dy; -- Create moving phase phase := to_unsigned((dist / 2) - to_integer(frame_counter(7 downto 0)), 8); -- Assign colors r_sig <= std_logic_vector(phase + 128); g_sig <= std_logic_vector(phase); b_sig <= std_logic_vector(phase - 128); end process; ---------------------------------------------------------------------------- -- 2. Foreground Text Generation ---------------------------------------------------------------------------- process(col, row, text_col, text_row) variable char_index : integer; begin char <= 0; if (row = text_row) and (col >= text_col) and (col < text_col + msg_text'length) then char_index := col - text_col + 1; char <= character'pos(msg_text(char_index)); end if; end process; ---------------------------------------------------------------------------- -- 3. Animation Logic ---------------------------------------------------------------------------- process(clk) variable old_vsync : std_logic := '0'; begin if rising_edge(clk) then if vsync = '0' and old_vsync = '1' then frame_counter <= frame_counter + 1; -- Update position every few frames if anim_speed = 2 then anim_speed <= 0; -- Check Horizontal Bounds if (dir_col = 1 and (text_col + msg_text'length >= CONSOLE_COLUMNS - 1)) then dir_col <= -1; elsif (dir_col = -1 and text_col <= 1) then dir_col <= 1; else text_col <= text_col + dir_col; end if; -- Check Vertical Bounds if (dir_row = 1 and (text_row >= CONSOLE_ROWS - 2)) then dir_row <= -1; elsif (dir_row = -1 and text_row <= 1) then dir_row <= 1; else text_row <= text_row + dir_row; end if; else anim_speed <= anim_speed + 1; end if; end if; old_vsync := vsync; end if; end process; end architecture;

    Sucess!

    UtilizationCellUsedAvailableUsage DCCA2563.6% EHXPLLL1250% TRELLIS_COMB1078242884.4% TRELLIS_FF149242880.6% TRELLIS_IO101975.1%
    TimingClockAchievedConstraint $glbnet$clkp41.75 MHz25 MHz $glbnet$clkt294.29 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
    -- Internal signals for color channels
    signal r_sig : std_logic_vector(7 downto 0);
    signal g_sig : std_logic_vector(7 downto 0);
    signal b_sig : std_logic_vector(7 downto 0);

    -- Animation state signals
    signal frame_counter : unsigned(31 downto 0) := (others => '0');
    signal anim_speed    : integer range 0 to 3 := 0;
    
    -- Bouncing text state
    constant msg_text    : string := " <3 VHDL <3 ";
    signal text_col      : integer range -10 to CONSOLE_COLUMNS + 10 := 5; -- widened range for safety
    signal text_row      : integer range -10 to CONSOLE_ROWS + 10 := 5;
    signal dir_col       : integer range -1 to 1 := 1;
    signal dir_row       : integer range -1 to 1 := 1;
    

    begin

    -- Assemble background color from internal signals
    background_color <= r_sig & g_sig & b_sig;
    
    -- Foreground is always white
    foreground_color <= (others => '1');
    
    ----------------------------------------------------------------------------
    -- 1. Background Generation
    -- Calculates Manhattan distance using IF/ELSE to avoid 'abs' synthesis error.
    ----------------------------------------------------------------------------
    process(px, py, frame_counter)
        variable dx, dy : integer;
        variable dist   : integer;
        variable phase  : unsigned(7 downto 0);
    begin
        -- Manual Absolute Value for X
        if px > (WIDTH / 2) then
            dx := px - (WIDTH / 2);
        else
            dx := (WIDTH / 2) - px;
        end if;
    
        -- Manual Absolute Value for Y
        if py > (HEIGHT / 2) then
            dy := py - (HEIGHT / 2);
        else
            dy := (HEIGHT / 2) - py;
        end if;
    
        dist := dx + dy;
    
        -- Create moving phase
        phase := to_unsigned((dist / 2) - to_integer(frame_counter(7 downto 0)), 8);
    
        -- Assign colors
        r_sig <= std_logic_vector(phase + 128);
        g_sig <= std_logic_vector(phase);
        b_sig <= std_logic_vector(phase - 128);
    end process;
    
    ----------------------------------------------------------------------------
    -- 2. Foreground Text Generation
    ----------------------------------------------------------------------------
    process(col, row, text_col, text_row)
        variable char_index : integer;
    begin
        char <= 0; 
    
        if (row = text_row) and 
           (col >= text_col) and 
           (col < text_col + msg_text'length) then
    
            char_index := col - text_col + 1;
            char <= character'pos(msg_text(char_index));
        end if;
    end process;
    
    ----------------------------------------------------------------------------
    -- 3. Animation Logic
    ----------------------------------------------------------------------------
    process(clk)
        variable old_vsync : std_logic := '0';
    begin
        if rising_edge(clk) then
            if vsync = '0' and old_vsync = '1' then
                frame_counter <= frame_counter + 1;
    
                -- Update position every few frames
                if anim_speed = 2 then
                    anim_speed <= 0;
    
                    -- Check Horizontal Bounds
                    if (dir_col = 1 and (text_col + msg_text'length >= CONSOLE_COLUMNS - 1)) then
                        dir_col <= -1;
                    elsif (dir_col = -1 and text_col <= 1) then
                        dir_col <= 1;
                    else
                        text_col <= text_col + dir_col;
                    end if;
    
                    -- Check Vertical Bounds
                    if (dir_row = 1 and (text_row >= CONSOLE_ROWS - 2)) then
                        dir_row <= -1;
                    elsif (dir_row = -1 and text_row <= 1) then
                        dir_row <= 1;
                    else
                        text_row <= text_row + dir_row;
                    end if;
    
                else
                    anim_speed <= anim_speed + 1;
                end if;
            end if;
    
            old_vsync := vsync;
        end if;
    end process;
    

    end architecture;


    #FPGA #Icepi-Zero #HDL #VHDL
  23. @[email protected] 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 -- Internal signals for color channels signal r_sig : std_logic_vector(7 downto 0); signal g_sig : std_logic_vector(7 downto 0); signal b_sig : std_logic_vector(7 downto 0); -- Animation state signals signal frame_counter : unsigned(31 downto 0) := (others => '0'); signal anim_speed : integer range 0 to 3 := 0; -- Bouncing text state constant msg_text : string := " <3 VHDL <3 "; signal text_col : integer range -10 to CONSOLE_COLUMNS + 10 := 5; -- widened range for safety signal text_row : integer range -10 to CONSOLE_ROWS + 10 := 5; signal dir_col : integer range -1 to 1 := 1; signal dir_row : integer range -1 to 1 := 1; begin -- Assemble background color from internal signals background_color <= r_sig & g_sig & b_sig; -- Foreground is always white foreground_color <= (others => '1'); ---------------------------------------------------------------------------- -- 1. Background Generation -- Calculates Manhattan distance using IF/ELSE to avoid 'abs' synthesis error. ---------------------------------------------------------------------------- process(px, py, frame_counter) variable dx, dy : integer; variable dist : integer; variable phase : unsigned(7 downto 0); begin -- Manual Absolute Value for X if px > (WIDTH / 2) then dx := px - (WIDTH / 2); else dx := (WIDTH / 2) - px; end if; -- Manual Absolute Value for Y if py > (HEIGHT / 2) then dy := py - (HEIGHT / 2); else dy := (HEIGHT / 2) - py; end if; dist := dx + dy; -- Create moving phase phase := to_unsigned((dist / 2) - to_integer(frame_counter(7 downto 0)), 8); -- Assign colors r_sig <= std_logic_vector(phase + 128); g_sig <= std_logic_vector(phase); b_sig <= std_logic_vector(phase - 128); end process; ---------------------------------------------------------------------------- -- 2. Foreground Text Generation ---------------------------------------------------------------------------- process(col, row, text_col, text_row) variable char_index : integer; begin char <= 0; if (row = text_row) and (col >= text_col) and (col < text_col + msg_text'length) then char_index := col - text_col + 1; char <= character'pos(msg_text(char_index)); end if; end process; ---------------------------------------------------------------------------- -- 3. Animation Logic ---------------------------------------------------------------------------- process(clk) variable old_vsync : std_logic := '0'; begin if rising_edge(clk) then if vsync = '0' and old_vsync = '1' then frame_counter <= frame_counter + 1; -- Update position every few frames if anim_speed = 2 then anim_speed <= 0; -- Check Horizontal Bounds if (dir_col = 1 and (text_col + msg_text'length >= CONSOLE_COLUMNS - 1)) then dir_col <= -1; elsif (dir_col = -1 and text_col <= 1) then dir_col <= 1; else text_col <= text_col + dir_col; end if; -- Check Vertical Bounds if (dir_row = 1 and (text_row >= CONSOLE_ROWS - 2)) then dir_row <= -1; elsif (dir_row = -1 and text_row <= 1) then dir_row <= 1; else text_row <= text_row + dir_row; end if; else anim_speed <= anim_speed + 1; end if; end if; old_vsync := vsync; end if; end process; end architecture;

    Sucess!

    UtilizationCellUsedAvailableUsage DCCA2563.6% EHXPLLL1250% TRELLIS_COMB1078242884.4% TRELLIS_FF149242880.6% TRELLIS_IO101975.1%
    TimingClockAchievedConstraint $glbnet$clkp41.75 MHz25 MHz $glbnet$clkt294.29 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
    -- Internal signals for color channels
    signal r_sig : std_logic_vector(7 downto 0);
    signal g_sig : std_logic_vector(7 downto 0);
    signal b_sig : std_logic_vector(7 downto 0);

    -- Animation state signals
    signal frame_counter : unsigned(31 downto 0) := (others => '0');
    signal anim_speed    : integer range 0 to 3 := 0;
    
    -- Bouncing text state
    constant msg_text    : string := " <3 VHDL <3 ";
    signal text_col      : integer range -10 to CONSOLE_COLUMNS + 10 := 5; -- widened range for safety
    signal text_row      : integer range -10 to CONSOLE_ROWS + 10 := 5;
    signal dir_col       : integer range -1 to 1 := 1;
    signal dir_row       : integer range -1 to 1 := 1;
    

    begin

    -- Assemble background color from internal signals
    background_color <= r_sig & g_sig & b_sig;
    
    -- Foreground is always white
    foreground_color <= (others => '1');
    
    ----------------------------------------------------------------------------
    -- 1. Background Generation
    -- Calculates Manhattan distance using IF/ELSE to avoid 'abs' synthesis error.
    ----------------------------------------------------------------------------
    process(px, py, frame_counter)
        variable dx, dy : integer;
        variable dist   : integer;
        variable phase  : unsigned(7 downto 0);
    begin
        -- Manual Absolute Value for X
        if px > (WIDTH / 2) then
            dx := px - (WIDTH / 2);
        else
            dx := (WIDTH / 2) - px;
        end if;
    
        -- Manual Absolute Value for Y
        if py > (HEIGHT / 2) then
            dy := py - (HEIGHT / 2);
        else
            dy := (HEIGHT / 2) - py;
        end if;
    
        dist := dx + dy;
    
        -- Create moving phase
        phase := to_unsigned((dist / 2) - to_integer(frame_counter(7 downto 0)), 8);
    
        -- Assign colors
        r_sig <= std_logic_vector(phase + 128);
        g_sig <= std_logic_vector(phase);
        b_sig <= std_logic_vector(phase - 128);
    end process;
    
    ----------------------------------------------------------------------------
    -- 2. Foreground Text Generation
    ----------------------------------------------------------------------------
    process(col, row, text_col, text_row)
        variable char_index : integer;
    begin
        char <= 0; 
    
        if (row = text_row) and 
           (col >= text_col) and 
           (col < text_col + msg_text'length) then
    
            char_index := col - text_col + 1;
            char <= character'pos(msg_text(char_index));
        end if;
    end process;
    
    ----------------------------------------------------------------------------
    -- 3. Animation Logic
    ----------------------------------------------------------------------------
    process(clk)
        variable old_vsync : std_logic := '0';
    begin
        if rising_edge(clk) then
            if vsync = '0' and old_vsync = '1' then
                frame_counter <= frame_counter + 1;
    
                -- Update position every few frames
                if anim_speed = 2 then
                    anim_speed <= 0;
    
                    -- Check Horizontal Bounds
                    if (dir_col = 1 and (text_col + msg_text'length >= CONSOLE_COLUMNS - 1)) then
                        dir_col <= -1;
                    elsif (dir_col = -1 and text_col <= 1) then
                        dir_col <= 1;
                    else
                        text_col <= text_col + dir_col;
                    end if;
    
                    -- Check Vertical Bounds
                    if (dir_row = 1 and (text_row >= CONSOLE_ROWS - 2)) then
                        dir_row <= -1;
                    elsif (dir_row = -1 and text_row <= 1) then
                        dir_row <= 1;
                    else
                        text_row <= text_row + dir_row;
                    end if;
    
                else
                    anim_speed <= anim_speed + 1;
                end if;
            end if;
    
            old_vsync := vsync;
        end if;
    end process;
    

    end architecture;


    #FPGA #Icepi-Zero #HDL #VHDL
  24. @[email protected] 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 alias red : std_logic_vector(7 downto 0) is background_color(23 downto 16); alias green : std_logic_vector(7 downto 0) is background_color(15 downto 8); alias blue : std_logic_vector(7 downto 0) is background_color(7 downto 0); signal frame_counter : unsigned(31 downto 0) := (others => '0'); -- Aquarium title constant title_text : string(1 to 19) := "~* FPGA AQUARIUM *~"; constant title_row : integer := 2; constant title_col : integer := (CONSOLE_COLUMNS - title_text'length) / 2; -- Fish swimming across the screen signal fish1_col : integer range 0 to CONSOLE_COLUMNS := 10; signal fish2_col : integer range 0 to CONSOLE_COLUMNS := 50; signal fish3_col : integer range 0 to CONSOLE_COLUMNS := 30; constant fish1_row : integer := 15; constant fish2_row : integer := 25; constant fish3_row : integer := 35; -- Bubble positions signal bubble1_row : integer range 0 to CONSOLE_ROWS := 50; signal bubble2_row : integer range 0 to CONSOLE_ROWS := 40; signal bubble3_row : integer range 0 to CONSOLE_ROWS := 45; constant bubble1_col : integer := 20; constant bubble2_col : integer := 50; constant bubble3_col : integer := 70; -- Seaweed decoration constant seaweed_text : string(1 to 3) := "|||"; begin -- Character display logic process(col, row, fish1_col, fish2_col, fish3_col, bubble1_row, bubble2_row, bubble3_row) begin char <= 0; -- default: space -- Title if row = title_row and col >= title_col and col < title_col + title_text'length then char <= character'pos(title_text(col + 1 - title_col)); -- Fish 1 (swimming right) ><> elsif row = fish1_row and col = fish1_col then char <= character'pos('>'); elsif row = fish1_row and col = fish1_col + 1 then char <= character'pos('<'); elsif row = fish1_row and col = fish1_col + 2 then char <= character'pos('>'); -- Fish 2 (swimming left) <> elsif row = fish2_row and col = fish2_col then char <= character'pos('<'); elsif row = fish2_row and col = fish2_col + 1 then char <= character'pos('>'); elsif row = fish2_row and col = fish2_col + 2 then char <= character'pos('<'); -- Fish 3 (swimming right) ><(*)> elsif row = fish3_row and col = fish3_col then char <= character'pos('>'); elsif row = fish3_row and col = fish3_col + 1 then char <= character'pos('<'); elsif row = fish3_row and col = fish3_col + 2 then char <= character'pos('('); elsif row = fish3_row and col = fish3_col + 3 then char <= character'pos('*'); elsif row = fish3_row and col = fish3_col + 4 then char <= character'pos(')'); elsif row = fish3_row and col = fish3_col + 5 then char <= character'pos('>'); -- Bubbles (rising 'o') elsif row = bubble1_row and col = bubble1_col then char <= character'pos('o'); elsif row = bubble2_row and col = bubble2_col then char <= character'pos('o'); elsif row = bubble3_row and col = bubble3_col then char <= character'pos('o'); -- Seaweed at bottom elsif row >= CONSOLE_ROWS - 8 and (col = 10 or col = 15 or col = 60 or col = 75) then char <= character'pos('|'); end if; end process; -- Ocean gradient background (darker at bottom, lighter at top) red <= std_logic_vector(to_unsigned(10 + row, 8)); green <= std_logic_vector(to_unsigned(80 + row * 2, 8)); blue <= std_logic_vector(to_unsigned(180 + row, 8)); -- Bright cyan text for underwater effect foreground_color <= x"00FFFF"; -- Animation update process process(clk) variable old_vsync : std_logic := '0'; begin if rising_edge(clk) then if rst = '1' then frame_counter <= (others => '0'); fish1_col <= 10; fish2_col <= 50; fish3_col <= 30; bubble1_row <= 50; bubble2_row <= 40; bubble3_row <= 45; elsif vsync = '0' and old_vsync = '1' then frame_counter <= frame_counter + 1; -- Animate fish (every 2 frames for smooth motion) if frame_counter(1 downto 0) = "00" then -- Fish 1: swim right if fish1_col < CONSOLE_COLUMNS - 3 then fish1_col <= fish1_col + 1; else fish1_col <= 0; end if; -- Fish 2: swim left if fish2_col > 0 then fish2_col <= fish2_col - 1; else fish2_col <= CONSOLE_COLUMNS - 3; end if; -- Fish 3: swim right (slower) if frame_counter(2) = '1' then if fish3_col < CONSOLE_COLUMNS - 6 then fish3_col <= fish3_col + 1; else fish3_col <= 0; end if; end if; end if; -- Animate bubbles (rise slowly) if frame_counter(2 downto 0) = "000" then -- Bubble 1 if bubble1_row > 5 then bubble1_row <= bubble1_row - 1; else bubble1_row <= CONSOLE_ROWS - 5; end if; -- Bubble 2 if bubble2_row > 5 then bubble2_row <= bubble2_row - 1; else bubble2_row <= CONSOLE_ROWS - 5; end if; -- Bubble 3 if bubble3_row > 5 then bubble3_row <= bubble3_row - 1; else bubble3_row <= CONSOLE_ROWS - 5; end if; end if; end if; old_vsync := vsync; end if; end process; end architecture;

    Sucess!

    UtilizationCellUsedAvailableUsage DCCA2563.6% EHXPLLL1250% TRELLIS_COMB1543242886.4% TRELLIS_FF176242880.7% TRELLIS_IO101975.1%
    TimingClockAchievedConstraint $glbnet$clkp39.8 MHz25 MHz $glbnet$clkt278.09 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
    alias red : std_logic_vector(7 downto 0) is background_color(23 downto 16);
    alias green : std_logic_vector(7 downto 0) is background_color(15 downto 8);
    alias blue : std_logic_vector(7 downto 0) is background_color(7 downto 0);

    signal frame_counter : unsigned(31 downto 0) := (others => '0');
    
    -- Aquarium title
    constant title_text : string(1 to 19) := "~* FPGA AQUARIUM *~";
    constant title_row : integer := 2;
    constant title_col : integer := (CONSOLE_COLUMNS - title_text'length) / 2;
    
    -- Fish swimming across the screen
    signal fish1_col : integer range 0 to CONSOLE_COLUMNS := 10;
    signal fish2_col : integer range 0 to CONSOLE_COLUMNS := 50;
    signal fish3_col : integer range 0 to CONSOLE_COLUMNS := 30;
    constant fish1_row : integer := 15;
    constant fish2_row : integer := 25;
    constant fish3_row : integer := 35;
    
    -- Bubble positions
    signal bubble1_row : integer range 0 to CONSOLE_ROWS := 50;
    signal bubble2_row : integer range 0 to CONSOLE_ROWS := 40;
    signal bubble3_row : integer range 0 to CONSOLE_ROWS := 45;
    constant bubble1_col : integer := 20;
    constant bubble2_col : integer := 50;
    constant bubble3_col : integer := 70;
    
    -- Seaweed decoration
    constant seaweed_text : string(1 to 3) := "|||";
    

    begin

    -- Character display logic
    process(col, row, fish1_col, fish2_col, fish3_col, bubble1_row, bubble2_row, bubble3_row)
    begin
        char <= 0; -- default: space
    
        -- Title
        if row = title_row and col >= title_col and col < title_col + title_text'length then
            char <= character'pos(title_text(col + 1 - title_col));
    
        -- Fish 1 (swimming right) ><>
        elsif row = fish1_row and col = fish1_col then
            char <= character'pos('>');
        elsif row = fish1_row and col = fish1_col + 1 then
            char <= character'pos('<');
        elsif row = fish1_row and col = fish1_col + 2 then
            char <= character'pos('>');
    
        -- Fish 2 (swimming left) <>
        elsif row = fish2_row and col = fish2_col then
            char <= character'pos('<');
        elsif row = fish2_row and col = fish2_col + 1 then
            char <= character'pos('>');
        elsif row = fish2_row and col = fish2_col + 2 then
            char <= character'pos('<');
    
        -- Fish 3 (swimming right) ><(*)>
        elsif row = fish3_row and col = fish3_col then
            char <= character'pos('>');
        elsif row = fish3_row and col = fish3_col + 1 then
            char <= character'pos('<');
        elsif row = fish3_row and col = fish3_col + 2 then
            char <= character'pos('(');
        elsif row = fish3_row and col = fish3_col + 3 then
            char <= character'pos('*');
        elsif row = fish3_row and col = fish3_col + 4 then
            char <= character'pos(')');
        elsif row = fish3_row and col = fish3_col + 5 then
            char <= character'pos('>');
    
        -- Bubbles (rising 'o')
        elsif row = bubble1_row and col = bubble1_col then
            char <= character'pos('o');
        elsif row = bubble2_row and col = bubble2_col then
            char <= character'pos('o');
        elsif row = bubble3_row and col = bubble3_col then
            char <= character'pos('o');
    
        -- Seaweed at bottom
        elsif row >= CONSOLE_ROWS - 8 and (col = 10 or col = 15 or col = 60 or col = 75) then
            char <= character'pos('|');
    
        end if;
    end process;
    
    -- Ocean gradient background (darker at bottom, lighter at top)
    red   <= std_logic_vector(to_unsigned(10 + row, 8));
    green <= std_logic_vector(to_unsigned(80 + row * 2, 8));
    blue  <= std_logic_vector(to_unsigned(180 + row, 8));
    
    -- Bright cyan text for underwater effect
    foreground_color <= x"00FFFF";
    
    -- Animation update process
    process(clk)
        variable old_vsync : std_logic := '0';
    begin
        if rising_edge(clk) then
            if rst = '1' then
                frame_counter <= (others => '0');
                fish1_col <= 10;
                fish2_col <= 50;
                fish3_col <= 30;
                bubble1_row <= 50;
                bubble2_row <= 40;
                bubble3_row <= 45;
            elsif vsync = '0' and old_vsync = '1' then
                frame_counter <= frame_counter + 1;
    
                -- Animate fish (every 2 frames for smooth motion)
                if frame_counter(1 downto 0) = "00" then
                    -- Fish 1: swim right
                    if fish1_col < CONSOLE_COLUMNS - 3 then
                        fish1_col <= fish1_col + 1;
                    else
                        fish1_col <= 0;
                    end if;
    
                    -- Fish 2: swim left
                    if fish2_col > 0 then
                        fish2_col <= fish2_col - 1;
                    else
                        fish2_col <= CONSOLE_COLUMNS - 3;
                    end if;
    
                    -- Fish 3: swim right (slower)
                    if frame_counter(2) = '1' then
                        if fish3_col < CONSOLE_COLUMNS - 6 then
                            fish3_col <= fish3_col + 1;
                        else
                            fish3_col <= 0;
                        end if;
                    end if;
                end if;
    
                -- Animate bubbles (rise slowly)
                if frame_counter(2 downto 0) = "000" then
                    -- Bubble 1
                    if bubble1_row > 5 then
                        bubble1_row <= bubble1_row - 1;
                    else
                        bubble1_row <= CONSOLE_ROWS - 5;
                    end if;
    
                    -- Bubble 2
                    if bubble2_row > 5 then
                        bubble2_row <= bubble2_row - 1;
                    else
                        bubble2_row <= CONSOLE_ROWS - 5;
                    end if;
    
                    -- Bubble 3
                    if bubble3_row > 5 then
                        bubble3_row <= bubble3_row - 1;
                    else
                        bubble3_row <= CONSOLE_ROWS - 5;
                    end if;
                end if;
    
            end if;
            old_vsync := vsync;
        end if;
    end process;
    

    end architecture;


    #FPGA #Icepi-Zero #HDL #VHDL
  25. Check out PipelineC #HDL Advent of FPGA #hardware solutions: high perf, deeply pipelined, multiple #FPGA platforms, 10's Gbit per sec throughput, easily scales: variable latency off chip mem, faster off chip IO and more resources.

    github.com/JulianKemmerer/Pipe

    #rtl #hls #verilog #vhdl #asic #eda

  26. The collection grows!

    This is the full list. Those using screen readers might want to make a coffee first...

    • Writing An Interpreter In Go - Thorsten Bell
    • Writing A Compiler In Go - Thorsten Bell
    • Computers And Quantity Surveyors - Adrian J Smith
    • Digital Design Using VHDL - Dally, Harting, Aamodt
    • VHDL By Example - Blaine C Readler
    • The ZX Spectrum ULA - Chris Smith
    • Design An RP2040 Board With KiCad - Jo Hinchcliffe, Ben Everard
    • High-Level Languages And Their Compilers - Des Watson
    • The Unix Programming Environment - Kernighan, Pike
    • The C Programming Language (2nd ed) - Kernighan, Ritchie
    • C Style: Standards and Guidelines - David Straker
    • Variations In C - Steve Schustack
    • C For Engineers - Edward Arnold
    • Software Engineering In C - Darnell, Margolis
    • Programming Abstractions In C - Eric S Roberts
    • The Little Book Of Pointers - Huw Collingbourne
    • Illustrating ANSI C (revised ed) - Donald Alcock
    • C++ All-In-One For Dummies - John Paul Mueller, Jeff Cogswell
    • An Introduction To Programming And Problem Solving With Pascal (2nd ed) - Schneider, Weingart, Perlman
    • Advanced Programming And Problem Solving With Pascal (2nd ed) - Schneider, Bruell
    • Data Structures Using Pascal - Tenenbaum, Augenstein
    • Programming For Change With Pascal - David J Robson
    • Recursion With Pascal - J S Rohl
    • Oh! Pascal! (3rd ed) - Doug Cooper
    • Programming Psion Computers - Leigh Edwards
    • Introduction To Microprocessors - Levelthal
    • The 8086 Book - Rector, Alexy
    • Assembly Language For Intel-Based Computers - Kip R Irvine
    • Computer Organisation And Assembly Language Programming for IBM PCs and Compatibles (2nd ed) - Michael Thorne
    • Working Effectively With Legacy Code - Michael C Feathers
    • The Basics Of Hacking And Penetration Testing (2nd ed) - Patrick Engebretson
    • Computers And Early Books - Mansell
    • The Amstrad CPC464 Manual
    • The Sinclair ZX Spectrum Manual
    • 30 Hour Basic (standard edition) - Clive Prigmore

    #shelfie #golang #compilers #pascal #programming #programmingbooks #retrocomputing #vhdl #psion

  27. @[email protected] 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 := 117; constant IMAGE_HEIGHT : integer := 52; type image_type is array (0 to IMAGE_HEIGHT-1) of std_logic_vector(0 to IMAGE_WIDTH-1); constant image : image_type := ( "000000000111111111111111111111111111111111111111111111000000000000000000011111111111111111111111111111111100000000000", "000000000111111111111111111111111111111111111111111111000000000000000000111111111111111111111111111111111111100000000", "000000000111111111111111111111111111111111111111111111000000000000000001111111111111111111111111111111111111111000000", "000000000111111111111111111111111111111111111111111111100000000000000011111111111111111111111111111111111111111110000", "000000001111111111111111111111111111111111111111111111100000000000000011111111111111111111111111111111111111111111000", "000000001111111111111111111111111111111111111111111111100000000000000111111111111111111111111111111111111111111111100", "000000001111111111111111111111111111111111111111111111110000000000001111111111111111111111111111111111111111111111110", "000000000000000000000000000111111111111111111111111111110000000000011111111111110000000000000000000111111111111111111", "000000011111111111110000000000111111111111111111111111110000000000011111111111111111111111110000000000111111111111111", "000000011111111111110000000000011111111111111111111111111000000000111111111111111111111111110000000000011111111111111", "000000011111111111100000000000001111111111111111111111111000000001111111111111011111111111100000000000001111111111111", "000000011111111111100000000000000111111111111011111111111000000011111111111110011111111111100000000000000111111111111", "000000111111111111100000000000000111111111111011111111111100000111111111111100111111111111100000000000000111111111111", "000000111111111111100000000000000111111111111011111111111100000111111111111000111111111111100000000000000111111111111", "000000111111111111000000000000001111111111111001111111111100001111111111110000111111111111100000000000001111111111111", "000000111111111111000000000000001111111111111001111111111110011111111111110000111111111111000000000000001111111111111", "000001111111111111000000000000001111111111110001111111111110111111111111100000111111111111000000000000001111111111111", "000001111111111111000000000000011111111111110000111111111110111111111111000001111111111111000000000000011111111111110", "000001111111111111000000000000111111111111110000111111111111111111111110000001111111111111000000000000111111111111110", "000001111111111110000000000001111111111111100000111111111111111111111100000001111111111110000000000001111111111111100", "000001111111111110000000000111111111111111000000011111111111111111111000000001111111111110000000000111111111111111000", "000011111111111110000000111111111111111110000000011111111111111111110000000011111111111110000000111111111111111110000", "000011111111111111111111111111111111111100000000011111111111111111100000000011111111111111111111111111111111111100000", "000011111111111111111111111111111111111000000000001111111111111111100000000011111111111111111111111111111111111000000", "000011111111111111111111111111111111110000000000001111111111111111000000000011111111111111111111111111111111110000000", "000111111111111111111111111111111111000000000000000111111111111110000000000111111111111111111111111111111111000000000", "000111111111111111111111111111111100000000000000000111111111111100000000000111111111111111111111111111111100000000000", "000111111111111111111111111111100000000000000000000111111111111000000000000111111111111111111111111111100000000000000", "000111111111111111111111111100000000000000000000000011111111110000000000000111111111111111111111111100000000000000000", "000111111111111111111100000000000000000000000000000011111111100000000000000111111111111111111100000000000000000000000", "000000000000000000000000000000000000000000000000000011111111100000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000001111111000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000001111110000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000001111100000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000000001111111111111111111111111111111111111111111111111111000000000000000000000000000000000000", "000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000", "000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000", "000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000", "000011111111111111111111111111111111111111111111111111111111111111111111111111111000111111111111111111111110000000000", "011111111111111111111110011111001111111001111111001110011111111100111111111111000010000111111111111111111111100000000", "111111111111111111111110011111011111111001111111001111100111111100111111111110011111110011111111111111111111110000000", "111111111111111111111111001110011111111001111111001111100111111100111111111110011111110011111111111111111111111000000", "111111111111111111111111101100111111111001111111001111100111111100000011111110011111110011111111111111111111111000000", "111111111111111111111111100101111111111001111111001111100111111100111111111110011111110011111111111111111111110000000", "011111111111111111111111110001111111111001111111001111001111111100111111111111001111100111111111111111111111100000000", "000011111111111111111111110011111111111001111111000000111111111100000011111111100000001111111111111111111110000000000", "000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000", "000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000", "000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111110000000000000000000000000", "000000000000000000000000000001111111111111111111111111111111111111111111111111111100000000000000000000000000000000000" ); constant SPEED : integer := 2; signal position_x : integer range -SPEED to WIDTH + SPEED := 0; signal position_y : integer range -SPEED to HEIGHT + SPEED := 0; begin char <= 0; background_color <= x"FFFFFF" when image(py - position_y)(px - position_x) = '1' and px >= position_x and px < position_x + IMAGE_WIDTH and py >= position_y and py < position_y + IMAGE_HEIGHT else x"000000"; foreground_color <= (others => '1'); process(clk) variable old_vsync : std_logic := '0'; variable speed_x : integer range -SPEED to SPEED := SPEED; variable speed_y : integer range -SPEED to SPEED := SPEED; begin if rising_edge(clk) then if vsync = '0' and old_vsync = '1' then if position_x + speed_x + IMAGE_WIDTH >= WIDTH then speed_x := -SPEED; position_x <= WIDTH - IMAGE_WIDTH - 1; elsif position_x + speed_x < 0 then speed_x := SPEED; position_x <= 0; else position_x <= position_x + speed_x; end if; if position_y + speed_y + IMAGE_HEIGHT >= HEIGHT then speed_y := -SPEED; position_y <= HEIGHT - IMAGE_HEIGHT - 1; elsif position_y + speed_y < 0 then speed_y := SPEED; position_y <= 0; else position_y <= position_y + speed_y; end if; end if; old_vsync := vsync; end if; end process; end architecture;

    Sucess!

    UtilizationCellUsedAvailableUsage DCCA2563.6% EHXPLLL1250% MULT18X18D1283.6% TRELLIS_COMB1041242884.3% TRELLIS_FF119242880.5% TRELLIS_IO101975.1%
    TimingClockAchievedConstraint $glbnet$clkp42.52 MHz25 MHz $glbnet$clkt290.7 MHz250 MHz


    #FPGA #Icepi-Zero #HDL #VHDL
  28. Small update announcement for the @icepi-zero-bot (that you might have noticed already):

    • The bot now reports details about utilization and clock speeds together with the video in the success post.
    • You can split your code into multiple messages if your instance has a low character limit for direct messages (see the bot's description for more details).

    For the future, I plan to:

    • Add support for more HDLs (tell me your favorite ones and I try to integrate them).
    • Support for outputting text via UART, that the host will capture and include in the success post.

    If you have any other ideas/wishes, feel free to tell me :D


    #FPGA #bot #fedibot #Icepi-Zero #VHDL #Verilog #SystemVerilog #Amaranth
  29. Small update announcement for the @icepi-zero-bot (that you might have noticed already):

    • The bot now reports details about utilization and clock speeds together with the video in the success post.
    • You can split your code into multiple messages if your instance has a low character limit for direct messages (see the bot's description for more details).

    For the future, I plan to:

    • Add support for more HDLs (tell me your favorite ones and I try to integrate them).
    • Support for outputting text via UART, that the host will capture and include in the success post.

    If you have any other ideas/wishes, feel free to tell me :D


    #FPGA #bot #fedibot #Icepi-Zero #VHDL #Verilog #SystemVerilog #Amaranth
  30. Small update announcement for the @icepi-zero-bot (that you might have noticed already):

    • The bot now reports details about utilization and clock speeds together with the video in the success post.
    • You can split your code into multiple messages if your instance has a low character limit for direct messages (see the bot's description for more details).

    For the future, I plan to:

    • Add support for more HDLs (tell me your favorite ones and I try to integrate them).
    • Support for outputting text via UART, that the host will capture and include in the success post.

    If you have any other ideas/wishes, feel free to tell me :D


    #FPGA #bot #fedibot #Icepi-Zero #VHDL #Verilog #SystemVerilog #Amaranth
  31. Small update announcement for the @icepi-zero-bot (that you might have noticed already):

    • The bot now reports details about utilization and clock speeds together with the video in the success post.
    • You can split your code into multiple messages if your instance has a low character limit for direct messages (see the bot's description for more details).

    For the future, I plan to:

    • Add support for more HDLs (tell me your favorite ones and I try to integrate them).
    • Support for outputting text via UART, that the host will capture and include in the success post.

    If you have any other ideas/wishes, feel free to tell me :D


    #FPGA #bot #fedibot #Icepi-Zero #VHDL #Verilog #SystemVerilog #Amaranth