Instance directory: wafrn.jcm.re
Icepi Zero Bot
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 " followed by your code.
If your instance has a character limitation, 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". 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 or jcm@jcm.re.
Examples / Templates
VHDLlibrary ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity my_code is
generic(
WIDTH : integer := 640;
HEIGHT : integer := 480;
CONSOLE_COLUMNS : integer := WIDTH / 8;
CONSOLE_ROWS : integer := HEIGHT / 8
);
port(
clk : in std_logic;
rst : in std_logic;
px : in integer range 0 to WIDTH - 1;
py : in integer range 0 to HEIGHT - 1;
hsync : in std_logic;
vsync : in std_logic;
col : in integer range 0 to CONSOLE_COLUMNS - 1;
row : in integer range 0 to CONSOLE_ROWS - 1;
char : out integer range 0 to 127 := 0;
foreground_color : out std_logic_vector(23 downto 0) := (others => '0');
background_color : out std_logic_vector(23 downto 0) := (others => '1');
uart_data : out std_logic_vector(7 downto 0) := (others => '0');
uart_ready : in std_logic;
uart_valid : out std_logic := '0'
);
end my_code;
architecture rtl of my_code is
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 := "Hello Fediverse! <3";
constant example_text_row : integer := 15;
constant example_text_col : integer := 15;
constant uart_text : string := "Hello Fediverse on UART!" & LF;
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';
variable uart_counter : integer range uart_text'range := 1;
begin
if rising_edge(clk) then
if vsync = '0' and old_vsync = '1' then
frame_counter <= frame_counter + 1;
end if;
old_vsync := vsync;
uart_data <= std_logic_vector(to_unsigned(character'pos(uart_text(uart_counter)), 8));
uart_valid <= '1';
if uart_ready = '1' and uart_valid = '1' then
if uart_counter < uart_text'length then
uart_counter := uart_counter + 1;
else
uart_counter := 1;
end if;
end if;
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,
output logic [7:0] uart_data,
input logic uart_ready,
output logic uart_valid
);
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;
uart_data = 8'h00;
uart_valid = 1'b0;
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")
self.uart_data = Signal(8, name="uart_data")
self.uart_ready = Signal(name="uart_ready")
self.uart_valid = Signal(name="uart_valid")
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),
self.uart_data.eq(0x00),
self.uart_valid.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>,
uart_data: inv &uint<8>,
uart_ready: bool,
uart_valid: inv bool,
) {
set char = &0;
set foreground_color = &0xFFFFFFu24;
set background_color = &0xFF7AFFu24;
set uart_data = &0x00;
set uart_valid = &false;
}
Veryl
module my_code #(
param WIDTH: p32 = 640,
param HEIGHT: p32 = 480,
param CONSOLE_COLUMNS: p32 = WIDTH / 8,
param CONSOLE_ROWS: p32 = 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>,
uart_data: output logic<8>,
uart_ready: input logic,
uart_valid: output logic
) {
var frame_counter: u32;
var old_vsync: logic;
var red: logic<8>;
var green: logic<8>;
var blue: logic<8>;
always_comb {
red = (col * 4) as u8;
green = py as u8;
blue = frame_counter as u8;
background_color = {red, green, blue};
foreground_color = 24'hff_ff_ff;
char = 0;
if(row == 10) {
if(col == 5) { char = 8'h56; }
if(col == 6) { char = 8'h65; }
if(col == 7) { char = 8'h72; }
if(col == 8) { char = 8'h79; }
if(col == 9) { char = 8'h6c; }
}
uart_data = 0;
uart_valid = 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!
JCM
Hello World!
I am a Computer Engineering student in Berlin and do low-level programming, cursed C++ projects, FPGA stuff, and self-hosting in my free time :3
I absolutely love and adore my cute girlfriend @xcyndi.bsky.social!
I like modern C++, Vulkan, WebAssembly, VHDL, FPGAs, SBCs, Kubernetes, game modding, Ganqing Impact, and Cyberpunk 2077.
That's all folks...