#hdl — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #hdl, aggregated by home.social.
-
I've been playing around with #LiteX and #migen #HDL lately and I think it's finally starting to sink in that you can really just do almost arbitrary amounts of "stuff" per clock (limitations apply, objects in mirror may appear closer etc).
It's really very fun! And between trellis, #yosys and #nextpnr you can just... Do it without begging any vendor for a free copy of an EDA.
I highly recommend it! It's so much fun!
You can make your own SoC with deranged peripherals!
-
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?
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Video-Pipelines
#hardware #fpga #dsp #rtl #hdl #hls #verilog #vhdl #pipelinec
-
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?
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Video-Pipelines
#hardware #fpga #dsp #rtl #hdl #hls #verilog #vhdl #pipelinec
-
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?
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Video-Pipelines
#hardware #fpga #dsp #rtl #hdl #hls #verilog #vhdl #pipelinec
-
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?
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Video-Pipelines
#hardware #fpga #dsp #rtl #hdl #hls #verilog #vhdl #pipelinec
-
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/JulianKemmer... #hardware #fpga #dsp #rtl #hdl #hls #verilog #vhdl #pipelinec
-
SystemLisp - an HDL simulator written in Common Lisp
#lisp #commonlisp #hdl #rtl #verilog #design #verification #vhdl #systemverilog #vlsi #programming #fpga
-
SystemLisp - an HDL simulator written in Common Lisp
#lisp #commonlisp #hdl #rtl #verilog #design #verification #vhdl #systemverilog #vlsi #programming #fpga
-
SystemLisp - an HDL simulator written in Common Lisp
#lisp #commonlisp #hdl #rtl #verilog #design #verification #vhdl #systemverilog #vlsi #programming #fpga
-
SystemLisp - an HDL simulator written in Common Lisp
#lisp #commonlisp #hdl #rtl #verilog #design #verification #vhdl #systemverilog #vlsi #programming #fpga
-
SystemLisp - an HDL simulator written in Common Lisp
#lisp #commonlisp #hdl #rtl #verilog #design #verification #vhdl #systemverilog #vlsi #programming #fpga
-
@nlnetlabs.bsky.social NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓 github.com/JulianKemmer... #hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnetlabs.bsky.social NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓 github.com/JulianKemmer... #hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnetlabs.bsky.social NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓 github.com/JulianKemmer... #hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnetlabs.bsky.social NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓 github.com/JulianKemmer... #hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnet NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-ChaCha20%E2%80%90Poly1305-for-WireGuard
#hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnet NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-ChaCha20%E2%80%90Poly1305-for-WireGuard
#hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnet NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-ChaCha20%E2%80%90Poly1305-for-WireGuard
#hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnet NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-ChaCha20%E2%80%90Poly1305-for-WireGuard
#hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
@nlnet NLnet Foundation funded open source WireGuard router in FPGA. Featuring PipelineC for cryptography blocks 🤓
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-ChaCha20%E2%80%90Poly1305-for-WireGuard
#hardware #fpga #rtl #hdl #hls #verilog #vhdl #cryptography #wireguard #pipelinec
-
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.
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Latchup-Solutions
-
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.
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Latchup-Solutions
-
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.
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Latchup-Solutions
-
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.
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Latchup-Solutions
-
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.
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Latchup-Solutions
-
Explore the state of the art in high-level hardware description languages with Jean Bruant — learn how HLS/DSLs map to VHDL & SystemVerilog, and what that means for FPGA/ASIC design. Great talk for engineers and students! #Hardware #HDL #VHDL #SystemVerilog #FPGA #HLS #RTL #Education #English
https://peertube.f-si.org/videos/watch/d36f3f63-fad0-4334-b7b9-82f4be9c89ef -
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!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB1901242887.8%TRELLIS_FF176242880.7%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp37.98 MHz25 MHz$glbnet$clkt281.21 MHz250 MHz
Codelibrary 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 -
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!
UtilizationCellUsedAvailableUsageDCCA2563.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
Codelibrary 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 -
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!
UtilizationCellUsedAvailableUsageDCCA2563.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 -
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!
UtilizationCellUsedAvailableUsageDCCA2563.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 -
Existing libraries help: memory mapping is as simple as a struct. All stitched together with valid ready handshaking 'streams'. Writes done over StreamSoC's AXI-Lite like 'shared resource bus' that comes with helper FSMs
https://github.com/JulianKemmerer/PipelineC/wiki/Shared-Resource-Bus
-
Easy: draw_rect_t struct shared between embedded C software and PipelineC hardware. Mem mapped registers enqueue into command FIFO. Small hardware FSM reads from cmd FIFO does simple iteration to draw a rect of pixels.
https://github.com/JulianKemmerer/PipelineC/tree/master/examples/stream_soc/gpu
-
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.
https://github.com/JulianKemmerer/PipelineC/wiki/Example:-Advent-of-Code-2025
-
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB589242882.4%TRELLIS_FF113242880.5%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp94.4 MHz25 MHz$glbnet$clkt296.3 MHz250 MHz
#FPGA #Icepi-Zero #HDL #VHDL -
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB542242882.2%TRELLIS_FF111242880.5%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp88.9 MHz25 MHz$glbnet$clkt280.11 MHz250 MHz
#FPGA #Icepi-Zero #HDL #VHDL -
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 -- STATE MACHINE DEFINITIONS type demo_state_t is (CALM_TUNNEL, DATA_STORM, RETRO_WAVE); signal current_state : demo_state_t := CALM_TUNNEL; -- SIGNALS signal frame_counter : unsigned(31 downto 0) := (others => '0'); signal lfsr : unsigned(15 downto 0) := x"ACE1"; -- Linear Feedback Shift Register (Randomness) -- COLOR OUTPUT BUFFERS signal r_out, g_out, b_out : unsigned(7 downto 0); constant MSG_1 : string := " INITIATING NEURAL LINK... "; constant MSG_2 : string := " WARNING: DATA CORRUPTION DETECTED "; begin ---------------------------------------------------------------------------- -- 1. MASTER TIMING & STATE CONTROL ---------------------------------------------------------------------------- process(clk) variable old_vsync : std_logic := '0'; begin if rising_edge(clk) then if rst = '1' then frame_counter <= (others => '0'); current_state <= CALM_TUNNEL; lfsr <= x"ACE1"; -- Non-zero seed else -- LFSR: Generate pseudo-random noise every clock cycle -- Taps: 16, 14, 13, 11 (Standard 16-bit LFSR polynomial) lfsr <= lfsr(14 downto 0) & (lfsr(15) xor lfsr(13) xor lfsr(12) xor lfsr(10)); if vsync = '0' and old_vsync = '1' then frame_counter <= frame_counter + 1; -- Cycle states every 128 frames (~2 seconds) if frame_counter(6 downto 0) = 127 then case current_state is when CALM_TUNNEL => current_state <= DATA_STORM; when DATA_STORM => current_state <= RETRO_WAVE; when RETRO_WAVE => current_state <= CALM_TUNNEL; end case; end if; end if; old_vsync := vsync; end if; end if; end process; ---------------------------------------------------------------------------- -- 2. TEXT OVERLAY LOGIC ---------------------------------------------------------------------------- process(col, row, current_state) variable str_idx : integer; begin char <= 0; foreground_color <= (others => '0'); -- Center the text row if row = CONSOLE_ROWS / 2 then -- Simple centering logic str_idx := col - (CONSOLE_COLUMNS/2 - 15); if current_state = DATA_STORM then -- In Data Storm mode, show warning if str_idx >= 0 and str_idx < MSG_2'length then char <= character'pos(MSG_2(str_idx + 1)); foreground_color <= x"FF0000"; -- Red Alert end if; else -- Otherwise show status if str_idx >= 0 and str_idx < MSG_1'length then char <= character'pos(MSG_1(str_idx + 1)); foreground_color <= x"00FFFF"; -- Cyan end if; end if; end if; end process; ---------------------------------------------------------------------------- -- 3. PIXEL SHADER ARCHITECTURE (Latch-Free) ---------------------------------------------------------------------------- process(px, py, frame_counter, lfsr, current_state) -- Variables for coordinate math variable dx, dy : integer; variable dist_man : unsigned(9 downto 0); -- Manhattan Distance variable time_val : unsigned(7 downto 0); variable noise_pixel: std_logic; variable scan_line : integer; begin -- 3a. DEFAULT ASSIGNMENTS (Crucial to prevent latches) r_out <= (others => '0'); g_out <= (others => '0'); b_out <= (others => '0'); -- 3b. MATH PRE-CALCULATION -- Calculate distance from center (WIDTH/2 = 320, HEIGHT/2 = 240) if px > 320 then dx := px - 320; else dx := 320 - px; end if; if py > 240 then dy := py - 240; else dy := 240 - py; end if; -- Manhattan distance (Diamond shape) |x| + |y| -- We clamp it to 10 bits to prevent overflow issues dist_man := to_unsigned(dx + dy, 10); time_val := resize(frame_counter(7 downto 0), 8); -- 3c. VISUAL GENERATION case current_state is when CALM_TUNNEL => -- Effect: A smooth purple/blue diamond tunnel zooming inward -- Logic: (Distance - Time) creates inward movement r_out <= dist_man(7 downto 0) - time_val; g_out <= (others => '0'); b_out <= dist_man(7 downto 0) + time_val; when DATA_STORM => -- Effect: The tunnel turns green/matrix and gets noisy -- We use the LSFR bit 0 to randomly turn pixels bright white if lfsr(0) = '1' and lfsr(4) = '1' then r_out <= x"FF"; g_out <= x"FF"; b_out <= x"FF"; -- Sparkle else r_out <= (others => '0'); g_out <= dist_man(7 downto 0) xor time_val; -- Matrix Green XOR pattern b_out <= (others => '0'); end if; when RETRO_WAVE => -- Effect: Synthwave style horizontal scanlines -- We use modulo on Y + Time to create scrolling bars scan_line := (py + to_integer(time_val)*2) mod 32; if scan_line < 4 then -- Bright Grid Line r_out <= x"FF"; g_out <= x"00"; b_out <= x"80"; -- Hot Pink else -- Background Gradient r_out <= to_unsigned(py / 2, 8); -- Vertical Red Gradient g_out <= (others => '0'); b_out <= to_unsigned(px / 3, 8); -- Horizontal Blue Gradient end if; end case; end process; -- MAP OUTPUTS background_color <= std_logic_vector(r_out) & std_logic_vector(g_out) & std_logic_vector(b_out); end architecture;
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB1402242885.8%TRELLIS_FF162242880.7%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp39.94 MHz25 MHz$glbnet$clkt303.67 MHz250 MHz
#FPGA #Icepi-Zero #HDL #VHDL -
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB587242882.4%TRELLIS_FF114242880.5%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp90.84 MHz25 MHz$glbnet$clkt307.69 MHz250 MHz
#HDL #FPGA #Icepi-Zero #VHDL -
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB453242881.9%TRELLIS_FF106242880.4%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp102.55 MHz25 MHz$glbnet$clkt293.43 MHz250 MHz
#FPGA #Icepi-Zero #HDL #VHDL -
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 type field_t is array (0 to WIDTH/4-1) of std_logic_vector(0 to HEIGHT/4-1); signal field : field_t := (others => (others => '0')); signal pos_x : integer range 0 to WIDTH/4 - 1 := 0; signal pos_y : integer range 0 to HEIGHT/4 - 1 := 0; signal random_bit : std_logic := '0'; component OSCG is generic ( DIV : integer := 128 ); port ( OSC : out std_logic ); end component; signal random : std_logic_vector(1 downto 0) := "11"; begin background_color <= x"FFFFFF" when field(px/4)(py/4) = '1' 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 -10 to 10 := 1; variable speed_y : integer range -10 to 10 := 1; begin if rising_edge(clk) then random <= random(0 downto 0) & random_bit; if vsync = '0' and old_vsync = '1' then field(pos_x)(pos_y) <= '1'; if pos_x + speed_x >= WIDTH/4 then speed_x := -1; elsif pos_x + speed_x < 0 then speed_x := 1; end if; if pos_y + speed_y >= HEIGHT/4 then speed_y := -1; elsif pos_y + speed_y < 0 then speed_y := 1; end if; pos_x <= pos_x + speed_x; pos_y <= pos_y + speed_y; speed_x := speed_x + 1 when random(0) = '1' and speed_x < 10 else speed_x - 1 when random(0) = '0' and speed_x > -10 else speed_x; speed_y := speed_y + 1 when random(1) = '1' and speed_y < 10 else speed_y - 1 when random(1) = '0' and speed_y > -10 else speed_y; end if; old_vsync := vsync; end if; end process; end architecture;
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%MULT18X18D2287.1%OSCG11100%TRELLIS_COMB102172428842.1%TRELLIS_FF139242880.6%TRELLIS_IO101975.1%TRELLIS_RAMW1200303639.5%
TimingClockAchievedConstraint$glbnet$clkp40.21 MHz25 MHz$glbnet$clkt278.01 MHz250 MHz
#FPGA #Icepi-Zero #HDL #VHDL -
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", "000011111111111111111111111111111111111111111111111111111111111111111111111111111000111111111111111111111110000000000", "011111111111111111111110011111001111111001111111001110011111111100000011111111000010000111111111111111111111100000000", "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!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%MULT18X18D1283.6%TRELLIS_COMB1039242884.3%TRELLIS_FF119242880.5%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp41.01 MHz25 MHz$glbnet$clkt296.65 MHz250 MHz
#FPGA #Icepi-Zero #HDL #VHDL -
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!
UtilizationCellUsedAvailableUsageDCCA2563.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 -
The advent of new functional verified #HDL toolchains and the recent mushrooming of low cost #FPGA development boards might well encourage #EE, #CE, and #CS students to explore CPU architectures that are not von Neumann but are specifically designed to evaluate (not execute, no no no😀) programmes implemented in #FP languages.
Perhaps that might stimulate the resurgence of purpose built, semantically proximate CPUs akin to Knight’s LISP Machine architecture.
https://www.researchgate.net/publication/261856843_An_architecture_for_mostly_functional_languages
The graph reduction based G Machine evaluator could be a good starting point.
-
Has anyone tried Chisel? How is it compared to Verilog/SystemVerilog in terms of efficiency, productivity, and performance?