@icepi-zero-bot@wafrn.jcm.re cover
@icepi-zero-bot@wafrn.jcm.re avatar

icepi-zero-bot Bot

@[email protected]

Send me asks with valid VHDL, SystemVerilog, Amaranth, Spade, or Veryl code and I will execute it for you on a real FPGA!

You can send me asks from outside Wafrn by sending me a direct message (private mention) in the following format: "!ask @icepi-zero-bot@wafrn.jcm.re avatar icepi-zero-bot " followed by your code.

If your instance has a character limitations, you can split your code into a thread of multiple direct messages. In this case, first send your code as multiple direct messages without the "!ask" prefix and then respond to the last message with a direct message containing only "!ask @icepi-zero-bot@wafrn.jcm.re avatar icepi-zero-bot ". I will recognize the empty ask, fetch the entire thread, and use the entire text (excluding all mentions) as source code.

All successful responses are public and include your submitted code. Only submit code you are happy to share with the world.

For any questions/problems with this bot, please contact @jcm@wafrn.jcm.re avatar jcm or [email protected].

Examples / Templates

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');

constant example_text : string(1 to 19) := "Hello Fediverse! <3";
constant example_text_row : integer := 15;
constant example_text_col : integer := 15;

begin
char <= character'pos(example_text(col + 1 - example_text_col))
when col >= example_text_col and col < example_text'length + example_text_col and row = example_text_row else 0;

red   <= std_logic_vector(to_unsigned(col*4, 8));
green <= std_logic_vector(to_unsigned(py, 8));
blue  <= std_logic_vector(resize(frame_counter, 8));

foreground_color <= (others => '1');

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; 
        end if;
        old_vsync := vsync;
    end if;
end process;

end architecture;


 **SystemVerilog** ```
module my_code #(
    parameter int WIDTH = 640,
    parameter int HEIGHT = 480,
    parameter int CONSOLE_COLUMNS = WIDTH / 8,
    parameter int CONSOLE_ROWS = HEIGHT / 8
)(
    input  logic clk,
    input  logic rst,

    input  int px,
    input  int py,
    input  logic hsync,
    input  logic vsync,

    input  int col,
    input  int row,

    output int char,
    output logic [23:0] foreground_color,
    output logic [23:0] background_color
);
    logic [31:0] frame_counter = '0;
    logic old_vsync = '0;

    logic [7:0] red, green, blue;

    always_comb begin
        red   = 8'(col * 4);
        green = 8'(py);
        blue  = frame_counter[7:0];

        background_color = {red, green, blue};
        foreground_color = '1;

        char = 0;
    end

    always_ff @(posedge clk) begin
        if (vsync == 1'b0 && old_vsync == 1'b1) begin
            frame_counter <= frame_counter + 1;
        end

        old_vsync <= vsync;
    end
endmodule

Amaranth ```
from amaranth import *

class MyCode(Elaboratable):
def init(self, width, height, console_columns, console_rows):
self.WIDTH = width
self.HEIGHT = height
self.CONSOLE_COLUMNS = console_columns
self.CONSOLE_ROWS = console_rows

    self.px = Signal(signed(32), name="px")
    self.py = Signal(signed(32), name="py")
    self.hsync = Signal(name="hsync")
    self.vsync = Signal(name="vsync")

    self.col = Signal(signed(32), name="col")
    self.row = Signal(signed(32), name="row")

    self.char = Signal(signed(32), name="char")
    self.foreground_color = Signal(24, name="foreground_color")
    self.background_color = Signal(24, name="background_color")

def elaborate(self, platform):
    m = Module()

    frame_counter = Signal(32)
    old_vsync = Signal()

    red = Signal(8)
    green = Signal(8)
    blue = Signal(8)

    m.d.comb += [
        red.eq(self.col * 4),
        green.eq(self.py),
        blue.eq(frame_counter),

        self.background_color.eq(Cat(blue, green, red)),
        self.foreground_color.eq(0xFFFFFF),
        self.char.eq(0)
    ]

    m.d.sync += old_vsync.eq(self.vsync)
    with m.If(~self.vsync & old_vsync):
        m.d.sync += frame_counter.eq(frame_counter + 1)

    return m

 **Spade** ```
#[no_mangle(all)]
entity my_code(
    clk: clock,
    rst: bool,
    px: int<32>,
    py: int<32>,
    hsync: bool,
    vsync: bool,
    col: int<32>,
    row: int<32>,
    char: inv &int<32>,
    foreground_color: inv &uint<24>,
    background_color: inv &uint<24>,
) {
    set char = &0;
    set foreground_color = &0xFFFFFFu24;
    set background_color = &0xFF7AFFu24;
}

Veryl ```
module my_code #(
param WIDTH: u32 = 640,
param HEIGHT: u32 = 480,
param CONSOLE_COLUMNS: u32 = WIDTH / 8,
param CONSOLE_ROWS: u32 = HEIGHT / 8
) (
clk: input clock,
rst: input reset,

px: input u32,
py: input u32,
hsync: input logic,
vsync: input logic,

col: input u32,
row: input u32,

char: output u32,
foreground_color: output logic<24>,
background_color: output logic<24>

) {
var frame_counter: u32;
var old_vsync: logic;

// Use logic<8> to facilitate easy concatenation later
var red: logic<8>;
var green: logic<8>;
var blue: logic<8>;

always_comb {
    // Cast math results to 'u8' (truncation). 
    // Veryl allows assigning u8 to logic<8>.
    red   = (col * 4) as u8;
    green = py as u8;
    blue  = frame_counter as u8;

    // Concatenate logic<8> elements directly
    background_color = {red, green, blue};
    foreground_color = 24'hff_ff_ff;

    char = 0;
}

always_ff (clk, rst) {
    if_reset {
        frame_counter = 0;
        old_vsync = 0;
    } else {
        if !vsync && old_vsync {
            frame_counter = frame_counter + 1;
        }
        old_vsync = vsync;
    }
}

}


 **You need to keep the same entity name and interface (generics and ports) as in the examples or the synthesis won't work!**

This profile is from a federated server and may be incomplete. View on remote instance

@icepi-zero-bot@wafrn.jcm.re avatar icepi-zero-bot Bot , to random

@jcm 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!**Utilization| | Cell | Used | Available | Usage | DCCA | 2 | 56 | 3.6% |
|---|---|---|---|---|---|---|---|---|
| EHXPLLL | 1 | 2 | 50% |
| TRELLIS_COMB | 1078 | 24288 | 4.4% |
| TRELLIS_FF | 149 | 24288 | 0.6% |
| TRELLIS_IO | 10 | 197 | 5.1% |

Timing| | Clock | Achieved | Constraint | $glbnet$clkp | 41.75 MHz | 25 MHz |
|---|---|---|---|---|---|---|
| $glbnet$clkt | 294.29 MHz | 250 MHz |

Code```
<br></br>
library ieee;<br></br>
use ieee.std_logic_1164.all;<br></br>
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 =&gt; '0');  
 background_color : out std_logic_vector(23 downto 0) := (others =&gt; '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

![Video output of the above HDL code.](https://media.wafrn.jcm.re//1771200826726_d778211cd877d4ba392ed3623d0fc6863251b049_processed.mp4)