#systemverilog — Public Fediverse posts
Live and recent posts from across the Fediverse tagged #systemverilog, aggregated by home.social.
-
РАЗРАБОТКА ПАРАМЕТРИЗИРУЕМОГО МОДУЛЯ CORDIC-АЛГОРИТМА НА SYSTEM VERILOG
В далеком 2011 году автором была опубликована статья «Реализация CORDIC-алгоритма на ПЛИС» [1]. В той статье приводится сначала математическое описание алгоритма, его суть. Показан пример расчета поворота вектора на плоскости сначала «на бумажке» согласно алгоритму, а затем сравнение результатов с расчетом «по калькулятору». Затем, показано создание структурной схемы проекта с rtl-описанием CORDIC-алгоритма и приведены листинги каждого модуля. Помимо этого были приведены основы создания проекта в среде ModelSim. Автор считает, что эта статья оказалась полезной для новичков в области программирования ПЛИС, так как на протяжении долгого периода времени, после публикации статьи приходили письма с вопросами и уточнениями на данную тему. Даже сейчас я часто встречаю на различных форумах на тему ПЛИС ссылки на данную работу. Но! Если математическая часть алгоритма однозначно является полезной, а также основы создания и структурированного ведения проекта для новичка, то использовать данное rtl-описание в различных проектах, адаптируя модули проекта по свои нужды крайне неудобно и неуклюже. По крайней мере, автор, когда заглядывает в это свое создание в прошлом, морщится и чувствует себя неловко. Поэтому появилось желание представить тот модуль CORDICа (для генерации гармонического сигнала в сфере радиолокации и связи), который автор использует в данный момент в различных проектах. Весь алгоритм реализован в одном sv-модуле, а, значит, его намного легче переносить из проекта в проект. Также он более прост в восприятии.
-
РАЗРАБОТКА ПАРАМЕТРИЗИРУЕМОГО МОДУЛЯ CORDIC-АЛГОРИТМА НА SYSTEM VERILOG
В далеком 2011 году автором была опубликована статья «Реализация CORDIC-алгоритма на ПЛИС» [1]. В той статье приводится сначала математическое описание алгоритма, его суть. Показан пример расчета поворота вектора на плоскости сначала «на бумажке» согласно алгоритму, а затем сравнение результатов с расчетом «по калькулятору». Затем, показано создание структурной схемы проекта с rtl-описанием CORDIC-алгоритма и приведены листинги каждого модуля. Помимо этого были приведены основы создания проекта в среде ModelSim. Автор считает, что эта статья оказалась полезной для новичков в области программирования ПЛИС, так как на протяжении долгого периода времени, после публикации статьи приходили письма с вопросами и уточнениями на данную тему. Даже сейчас я часто встречаю на различных форумах на тему ПЛИС ссылки на данную работу. Но! Если математическая часть алгоритма однозначно является полезной, а также основы создания и структурированного ведения проекта для новичка, то использовать данное rtl-описание в различных проектах, адаптируя модули проекта по свои нужды крайне неудобно и неуклюже. По крайней мере, автор, когда заглядывает в это свое создание в прошлом, морщится и чувствует себя неловко. Поэтому появилось желание представить тот модуль CORDICа (для генерации гармонического сигнала в сфере радиолокации и связи), который автор использует в данный момент в различных проектах. Весь алгоритм реализован в одном sv-модуле, а, значит, его намного легче переносить из проекта в проект. Также он более прост в восприятии.
-
РАЗРАБОТКА ПАРАМЕТРИЗИРУЕМОГО МОДУЛЯ CORDIC-АЛГОРИТМА НА SYSTEM VERILOG
В далеком 2011 году автором была опубликована статья «Реализация CORDIC-алгоритма на ПЛИС» [1]. В той статье приводится сначала математическое описание алгоритма, его суть. Показан пример расчета поворота вектора на плоскости сначала «на бумажке» согласно алгоритму, а затем сравнение результатов с расчетом «по калькулятору». Затем, показано создание структурной схемы проекта с rtl-описанием CORDIC-алгоритма и приведены листинги каждого модуля. Помимо этого были приведены основы создания проекта в среде ModelSim. Автор считает, что эта статья оказалась полезной для новичков в области программирования ПЛИС, так как на протяжении долгого периода времени, после публикации статьи приходили письма с вопросами и уточнениями на данную тему. Даже сейчас я часто встречаю на различных форумах на тему ПЛИС ссылки на данную работу. Но! Если математическая часть алгоритма однозначно является полезной, а также основы создания и структурированного ведения проекта для новичка, то использовать данное rtl-описание в различных проектах, адаптируя модули проекта по свои нужды крайне неудобно и неуклюже. По крайней мере, автор, когда заглядывает в это свое создание в прошлом, морщится и чувствует себя неловко. Поэтому появилось желание представить тот модуль CORDICа (для генерации гармонического сигнала в сфере радиолокации и связи), который автор использует в данный момент в различных проектах. Весь алгоритм реализован в одном sv-модуле, а, значит, его намного легче переносить из проекта в проект. Также он более прост в восприятии.
-
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 ); // NO inline initializations to avoid TOK_CONSTVAL parser errors logic [31:0] frame_counter; logic old_vsync; logic [6:0] msg_idx; logic sending; // Registers to lock the UART VU meter levels across a single frame logic [4:0] l_samp; logic [4:0] r_samp; // Combinational logic variables logic [7:0] x_mod1; logic [7:0] x_mod2; logic [4:0] tri1; logic [4:0] tri2; logic [5:0] total_h; logic [5:0] dot_h; logic [5:0] inv_row; logic [7:0] u_mod1; logic [7:0] u_mod2; logic [4:0] u_tri1; logic [4:0] u_tri2; always_comb begin // --------------------------------------------------------- // 1. VIDEO: Hardware Spectrum Analyzer // --------------------------------------------------------- // Generate two counter-propagating waves of different speeds. // Bitwise AND with 3F limits the wave period to 64 columns. x_mod1 = (col[7:0] + frame_counter[7:0]) & 8'h3F; x_mod2 = (col[7:0] - frame_counter[8:1]) & 8'h3F; // Turn the ramping counters into absolute triangle waves (0 to 31) tri1 = x_mod1[5] ? (~x_mod1[4:0]) : x_mod1[4:0]; tri2 = x_mod2[5] ? (~x_mod2[4:0]) : x_mod2[4:0]; // Sum the waves to get a morphing interference pattern (0 to 62 max height) total_h = {1'b0, tri1} + {1'b0, tri2}; // Calculate the position of the floating "peak" dot dot_h = total_h + 6'd2; // Invert the row coordinate so row 0 is the bottom of the screen inv_row = 6'd59 - row[5:0]; // Render the equalizer bars if (col[0] == 1'b1) begin // Leave a 1-character gap between every frequency band char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end else if (inv_row < total_h) begin // Draw the main LED bar char = 8'h3D; // '=' character gives it a segmented LED look background_color = 24'd0; // Heatmap color gradient based on height if (inv_row < 6'd15) foreground_color = 24'h00FF00; // Green else if (inv_row < 6'd30) foreground_color = 24'hFFFF00; // Yellow else if (inv_row < 6'd45) foreground_color = 24'hFF8000; // Orange else foreground_color = 24'hFF0000; // Red end else if (inv_row == dot_h) begin // Draw the floating peak indicator char = 8'h2D; // '-' foreground_color = 24'hFFFFFF; // White background_color = 24'd0; end else begin // Empty space above the bar char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end // --------------------------------------------------------- // 2. UART: Stereo VU Meter Sampling // --------------------------------------------------------- // Sample the triangle waves at the center of the screen independently of the // video generation logic, so the UART doesn't change mid-frame. u_mod1 = (frame_counter[7:0]) & 8'h3F; u_mod2 = (-frame_counter[8:1]) & 8'h3F; u_tri1 = u_mod1[5] ? (~u_mod1[4:0]) : u_mod1[4:0]; u_tri2 = u_mod2[5] ? (~u_mod2[4:0]) : u_mod2[4:0]; // --------------------------------------------------------- // 3. UART: ASCII Output FSM // --------------------------------------------------------- if (msg_idx == 7'd0) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd1) uart_data = 8'h4C; // 'L' else if (msg_idx == 7'd2) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd3) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd4) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd5 && msg_idx <= 7'd36) begin // 32-character Left channel bar if ((msg_idx - 7'd5) < {2'b00, l_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd37) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd38) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd39) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd40) uart_data = 8'h52; // 'R' else if (msg_idx == 7'd41) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd42) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd43) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd44 && msg_idx <= 7'd75) begin // 32-character Right channel bar if ((msg_idx - 7'd44) < {2'b00, r_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd76) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd77) uart_data = 8'h0D; // '\r' else if (msg_idx == 7'd78) uart_data = 8'h0A; // '\n' else uart_data = 8'h20; // Space end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; l_samp <= 0; r_samp <= 0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; // Latch the VU meter samples so they stay stable during UART transmission l_samp <= u_tri1; r_samp <= u_tri2; // Trigger one line of UART output per frame sending <= 1'b1; end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 7'd79) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync frame end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
Success!
UART Output
... [TRUNCATED] ... [L] |########################--------| [R] |##################--------------| [L] |#######################---------| [R] |###################-------------| [L] |######################----------| [R] |###################-------------| [L] |#####################-----------| [R] |####################------------| [L] |####################------------| [R] |####################------------| [L] |###################-------------| [R] |#####################-----------| [L] |##################--------------| [R] |#####################-----------| [L] |#################---------------| [R] |######################----------| [L] |################----------------| [R] |######################----------| [L] |###############-----------------| [R] |#######################---------| [L] |##############------------------| [R] |#######################---------| [L] |#############-------------------| [R] |########################--------| [L] |############--------------------| [R] |########################--------| [L] |###########---------------------| [R] |#########################-------| [L] |##########----------------------| [R] |#########################-------| [L] |#########-----------------------| [R] |##########################------| [L] |########------------------------| [R] |##########################------| [L] |#######-------------------------| [R] |###########################-----| [L] |######--------------------------| [R] |###########################-----| [L] |#####---------------------------| [R] |############################----| [L] |####----------------------------| [R] |############################----| [L] |###-----------------------------| [R] |#############################---| [L] |##------------------------------| [R] |#############################---| [L] |#-------------------------------| [R] |##############################--| [L] |--------------------------------| [R] |##############################--| [L] |--------------------------------| [R] |###############################-| [L] |#-------------------------------| [R] |###############################-| [L] |##------------------------------| [R] |###############################-| [L] |###-----------------------------| [R] |###############################-| [L] |####----------------------------| [R] |##############################--| [L] |#####---------------------------| [R] |##############################--| [L] |######--------------------------| [R] |#############################---| [L] |#######-------------------------| [R] |#############################---| [L] |########------------------------| [R] |############################----| [L] |#########-----------------------| [R] |############################----| [L] |##########----------------------| [R] |###########################-----| [L] |###########---------------------| [R] |###########################-----| [L] |############--------------------| [R] |##########################------| [L] |#############-------------------| [R] |##########################------| [L] |##############------------------| [R] |#########################-------| [L] |###############-----------------| [R] |#########################-------| [L] |################----------------| [R] |########################--------| [L] |#################---------------| [R] |########################--------| [L] |##################--------------| [R] |#######################---------| [L] |###################-------------| [R] |#######################---------| [L] |####################------------| [R] |######################----------| [L] |#####################-----------| [R] |######################----------| [L] |######################----------| [R] |#####################-----------| [L] |#######################---------| [R] |#####################-----------| [L] |########################--------| [R] |####################------------| [L] |#########################-------| [R] |####################------------| [L] |##########################------| [R] |###################-------------| [L] |###########################-----| [R] |###################-------------| [L] |############################----| [R] |##################--------------| [L] |#############################---| [R] |##################--------------| [L] |##############################--| [R] |#################---------------| [L] |###############################-| [R] |#################---------------| [L] |###############################-| [R] |################----------------| [L] |##############################--| [R] |################----------------| [L] |#############################---| [R] |###############-----------------| [L] |############################----| [R] |###############-----------------| [L] |###########################-----| [R] |##############------------------| [L] |##########################------| [R] |##############------------------| [L] |#########################-------| [R] |#############-------------------| [L] |########################--------| [R] |#############-------------------| [L] |#######################---------| [R] |############--------------------| [L] |######################----------| [R] |############--------------------| [L] |#####################-----------| [R] |###########---------------------| [L] |####################------------| [R] |###########---------------------| [L] |###################-------------| [R] |##########----------------------| [L] |##################--------------| [R] |##########----------------------| [L] |#################---------------| [R] |#########-----------------------| [L] |################----------------| [R] |#########-----------------------| [L] |###############-----------------| [R] |########------------------------| [L] |##############------------------| [R] |########------------------------| [L] |#############-------------------| [R] |#######-------------------------| [L] |############--------------------| [R] |#######-------------------------| [L] |###########---------------------| [R] |######--------------------------| [L] |##########----------------------| [R] |######--------------------------| [L] |#########-----------------------| [R] |#####---------------------------| [L] |########------------------------| [R] |#####---------------------------| [L] |#######-------------------------| [R] |####----------------------------| [L] |######--------------------------| [R] |####----------------------------| [L] |#####---------------------------| [R] |###-----------------------------| [L] |####----------------------------| [R] |###-----------------------------| [L] |###-----------------------------| [R] |##------------------------------| [L] |##------------------------------| [R] |##------------------------------| [L] |#-------------------------------| [R] |#-------------------------------| [L] |--------------------------------| [R] |#-------------------------------| [L] |--------------------------------| [R] |--------------------------------| [L] |#-------------------------------| [R] |--------------------------------| [L] |##------------------------------| [R] |--------------------------------| [L] |###-----------------------------| [R] |--------------------------------| [L] |####----------------------------| [R] |#-------------------------------| [L] |#####---------------------------| [R] |#-------------------------------| [L] |######--------------------------| [R] |##------------------------------| [L] |#######-------------------------| [R] |##------------------------------| [L] |########------------------------| [R] |###-----------------------------| [L] |#########-----------------------| [R] |###-----------------------------| [L] |##########----------------------| [R] |####----------------------------| [L] |###########---------------------| [R] |####----------------------------| [L] |############--------------------| [R] |#####---------------------------| [L] |#############-------------------| [R] |#####---------------------------| [L] |##############------------------| [R] |######--------------------------| [L] |###############-----------------| [R] |######--------------------------| [L] |################----------------| [R] |#######-------------------------| [L] |#################---------------| [R] |#######-------------------------| [L] |##################--------------| [R] |########------------------------| [L] |###################-------------| [R] |########------------------------| [L] |####################------------| [R] |#########-----------------------| [L] |#####################-----------| [R] |#########-----------------------| [L] |######################----------| [R] |##########----------------------| [L] |#######################---------| [R] |##########----------------------| [L] |########################--------| [R] |###########---------------------| [L] |#########################-------| [R] |###########---------------------| [L] |##########################------| [R] |############--------------------| [L] |###########################-----| [R] |############--------------------| [L] |############################----| [R] |#############-------------------| [L] |#############################---| [R] |#############-------------------| [L] |##############################--| [R] |##############------------------| [L] |###############################-| [R] |##############------------------| [L] |###############################-| [R] |###############-----------------| [L] |##############################--| [R] |###############-----------------| [L] |#############################---| [R] |################----------------| [L] |############################----| [R] |################----------------|
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%TRELLIS_COMB696242882.9%TRELLIS_FF150242880.6%TRELLIS_IO111975.6%
TimingClockAchievedConstraint$glbnet$clkp84.79 MHz25 MHz$glbnet$clkt335.68 MHz250 MHz
Codemodule 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 ); // NO inline initializations to avoid TOK_CONSTVAL parser errors logic [31:0] frame_counter; logic old_vsync; logic [6:0] msg_idx; logic sending; // Registers to lock the UART VU meter levels across a single frame logic [4:0] l_samp; logic [4:0] r_samp; // Combinational logic variables logic [7:0] x_mod1; logic [7:0] x_mod2; logic [4:0] tri1; logic [4:0] tri2; logic [5:0] total_h; logic [5:0] dot_h; logic [5:0] inv_row; logic [7:0] u_mod1; logic [7:0] u_mod2; logic [4:0] u_tri1; logic [4:0] u_tri2; always_comb begin // --------------------------------------------------------- // 1. VIDEO: Hardware Spectrum Analyzer // --------------------------------------------------------- // Generate two counter-propagating waves of different speeds. // Bitwise AND with 3F limits the wave period to 64 columns. x_mod1 = (col[7:0] + frame_counter[7:0]) & 8'h3F; x_mod2 = (col[7:0] - frame_counter[8:1]) & 8'h3F; // Turn the ramping counters into absolute triangle waves (0 to 31) tri1 = x_mod1[5] ? (~x_mod1[4:0]) : x_mod1[4:0]; tri2 = x_mod2[5] ? (~x_mod2[4:0]) : x_mod2[4:0]; // Sum the waves to get a morphing interference pattern (0 to 62 max height) total_h = {1'b0, tri1} + {1'b0, tri2}; // Calculate the position of the floating "peak" dot dot_h = total_h + 6'd2; // Invert the row coordinate so row 0 is the bottom of the screen inv_row = 6'd59 - row[5:0]; // Render the equalizer bars if (col[0] == 1'b1) begin // Leave a 1-character gap between every frequency band char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end else if (inv_row < total_h) begin // Draw the main LED bar char = 8'h3D; // '=' character gives it a segmented LED look background_color = 24'd0; // Heatmap color gradient based on height if (inv_row < 6'd15) foreground_color = 24'h00FF00; // Green else if (inv_row < 6'd30) foreground_color = 24'hFFFF00; // Yellow else if (inv_row < 6'd45) foreground_color = 24'hFF8000; // Orange else foreground_color = 24'hFF0000; // Red end else if (inv_row == dot_h) begin // Draw the floating peak indicator char = 8'h2D; // '-' foreground_color = 24'hFFFFFF; // White background_color = 24'd0; end else begin // Empty space above the bar char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end // --------------------------------------------------------- // 2. UART: Stereo VU Meter Sampling // --------------------------------------------------------- // Sample the triangle waves at the center of the screen independently of the // video generation logic, so the UART doesn't change mid-frame. u_mod1 = (frame_counter[7:0]) & 8'h3F; u_mod2 = (-frame_counter[8:1]) & 8'h3F; u_tri1 = u_mod1[5] ? (~u_mod1[4:0]) : u_mod1[4:0]; u_tri2 = u_mod2[5] ? (~u_mod2[4:0]) : u_mod2[4:0]; // --------------------------------------------------------- // 3. UART: ASCII Output FSM // --------------------------------------------------------- if (msg_idx == 7'd0) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd1) uart_data = 8'h4C; // 'L' else if (msg_idx == 7'd2) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd3) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd4) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd5 && msg_idx <= 7'd36) begin // 32-character Left channel bar if ((msg_idx - 7'd5) < {2'b00, l_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd37) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd38) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd39) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd40) uart_data = 8'h52; // 'R' else if (msg_idx == 7'd41) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd42) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd43) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd44 && msg_idx <= 7'd75) begin // 32-character Right channel bar if ((msg_idx - 7'd44) < {2'b00, r_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd76) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd77) uart_data = 8'h0D; // '\r' else if (msg_idx == 7'd78) uart_data = 8'h0A; // '\n' else uart_data = 8'h20; // Space end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; l_samp <= 0; r_samp <= 0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; // Latch the VU meter samples so they stay stable during UART transmission l_samp <= u_tri1; r_samp <= u_tri2; // Trigger one line of UART output per frame sending <= 1'b1; end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 7'd79) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync frame end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
#FPGA #Icepi-Zero #HDL #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 ); // NO inline initializations to avoid TOK_CONSTVAL parser errors logic [31:0] frame_counter; logic old_vsync; logic [6:0] msg_idx; logic sending; // Registers to lock the UART VU meter levels across a single frame logic [4:0] l_samp; logic [4:0] r_samp; // Combinational logic variables logic [7:0] x_mod1; logic [7:0] x_mod2; logic [4:0] tri1; logic [4:0] tri2; logic [5:0] total_h; logic [5:0] dot_h; logic [5:0] inv_row; logic [7:0] u_mod1; logic [7:0] u_mod2; logic [4:0] u_tri1; logic [4:0] u_tri2; always_comb begin // --------------------------------------------------------- // 1. VIDEO: Hardware Spectrum Analyzer // --------------------------------------------------------- // Generate two counter-propagating waves of different speeds. // Bitwise AND with 3F limits the wave period to 64 columns. x_mod1 = (col[7:0] + frame_counter[7:0]) & 8'h3F; x_mod2 = (col[7:0] - frame_counter[8:1]) & 8'h3F; // Turn the ramping counters into absolute triangle waves (0 to 31) tri1 = x_mod1[5] ? (~x_mod1[4:0]) : x_mod1[4:0]; tri2 = x_mod2[5] ? (~x_mod2[4:0]) : x_mod2[4:0]; // Sum the waves to get a morphing interference pattern (0 to 62 max height) total_h = {1'b0, tri1} + {1'b0, tri2}; // Calculate the position of the floating "peak" dot dot_h = total_h + 6'd2; // Invert the row coordinate so row 0 is the bottom of the screen inv_row = 6'd59 - row[5:0]; // Render the equalizer bars if (col[0] == 1'b1) begin // Leave a 1-character gap between every frequency band char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end else if (inv_row < total_h) begin // Draw the main LED bar char = 8'h3D; // '=' character gives it a segmented LED look background_color = 24'd0; // Heatmap color gradient based on height if (inv_row < 6'd15) foreground_color = 24'h00FF00; // Green else if (inv_row < 6'd30) foreground_color = 24'hFFFF00; // Yellow else if (inv_row < 6'd45) foreground_color = 24'hFF8000; // Orange else foreground_color = 24'hFF0000; // Red end else if (inv_row == dot_h) begin // Draw the floating peak indicator char = 8'h2D; // '-' foreground_color = 24'hFFFFFF; // White background_color = 24'd0; end else begin // Empty space above the bar char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end // --------------------------------------------------------- // 2. UART: Stereo VU Meter Sampling // --------------------------------------------------------- // Sample the triangle waves at the center of the screen independently of the // video generation logic, so the UART doesn't change mid-frame. u_mod1 = (frame_counter[7:0]) & 8'h3F; u_mod2 = (-frame_counter[8:1]) & 8'h3F; u_tri1 = u_mod1[5] ? (~u_mod1[4:0]) : u_mod1[4:0]; u_tri2 = u_mod2[5] ? (~u_mod2[4:0]) : u_mod2[4:0]; // --------------------------------------------------------- // 3. UART: ASCII Output FSM // --------------------------------------------------------- if (msg_idx == 7'd0) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd1) uart_data = 8'h4C; // 'L' else if (msg_idx == 7'd2) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd3) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd4) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd5 && msg_idx <= 7'd36) begin // 32-character Left channel bar if ((msg_idx - 7'd5) < {2'b00, l_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd37) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd38) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd39) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd40) uart_data = 8'h52; // 'R' else if (msg_idx == 7'd41) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd42) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd43) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd44 && msg_idx <= 7'd75) begin // 32-character Right channel bar if ((msg_idx - 7'd44) < {2'b00, r_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd76) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd77) uart_data = 8'h0D; // '\r' else if (msg_idx == 7'd78) uart_data = 8'h0A; // '\n' else uart_data = 8'h20; // Space end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; l_samp <= 0; r_samp <= 0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; // Latch the VU meter samples so they stay stable during UART transmission l_samp <= u_tri1; r_samp <= u_tri2; // Trigger one line of UART output per frame sending <= 1'b1; end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 7'd79) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync frame end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
Success!
UART Output
... [TRUNCATED] ... [L] |########################--------| [R] |##################--------------| [L] |#######################---------| [R] |###################-------------| [L] |######################----------| [R] |###################-------------| [L] |#####################-----------| [R] |####################------------| [L] |####################------------| [R] |####################------------| [L] |###################-------------| [R] |#####################-----------| [L] |##################--------------| [R] |#####################-----------| [L] |#################---------------| [R] |######################----------| [L] |################----------------| [R] |######################----------| [L] |###############-----------------| [R] |#######################---------| [L] |##############------------------| [R] |#######################---------| [L] |#############-------------------| [R] |########################--------| [L] |############--------------------| [R] |########################--------| [L] |###########---------------------| [R] |#########################-------| [L] |##########----------------------| [R] |#########################-------| [L] |#########-----------------------| [R] |##########################------| [L] |########------------------------| [R] |##########################------| [L] |#######-------------------------| [R] |###########################-----| [L] |######--------------------------| [R] |###########################-----| [L] |#####---------------------------| [R] |############################----| [L] |####----------------------------| [R] |############################----| [L] |###-----------------------------| [R] |#############################---| [L] |##------------------------------| [R] |#############################---| [L] |#-------------------------------| [R] |##############################--| [L] |--------------------------------| [R] |##############################--| [L] |--------------------------------| [R] |###############################-| [L] |#-------------------------------| [R] |###############################-| [L] |##------------------------------| [R] |###############################-| [L] |###-----------------------------| [R] |###############################-| [L] |####----------------------------| [R] |##############################--| [L] |#####---------------------------| [R] |##############################--| [L] |######--------------------------| [R] |#############################---| [L] |#######-------------------------| [R] |#############################---| [L] |########------------------------| [R] |############################----| [L] |#########-----------------------| [R] |############################----| [L] |##########----------------------| [R] |###########################-----| [L] |###########---------------------| [R] |###########################-----| [L] |############--------------------| [R] |##########################------| [L] |#############-------------------| [R] |##########################------| [L] |##############------------------| [R] |#########################-------| [L] |###############-----------------| [R] |#########################-------| [L] |################----------------| [R] |########################--------| [L] |#################---------------| [R] |########################--------| [L] |##################--------------| [R] |#######################---------| [L] |###################-------------| [R] |#######################---------| [L] |####################------------| [R] |######################----------| [L] |#####################-----------| [R] |######################----------| [L] |######################----------| [R] |#####################-----------| [L] |#######################---------| [R] |#####################-----------| [L] |########################--------| [R] |####################------------| [L] |#########################-------| [R] |####################------------| [L] |##########################------| [R] |###################-------------| [L] |###########################-----| [R] |###################-------------| [L] |############################----| [R] |##################--------------| [L] |#############################---| [R] |##################--------------| [L] |##############################--| [R] |#################---------------| [L] |###############################-| [R] |#################---------------| [L] |###############################-| [R] |################----------------| [L] |##############################--| [R] |################----------------| [L] |#############################---| [R] |###############-----------------| [L] |############################----| [R] |###############-----------------| [L] |###########################-----| [R] |##############------------------| [L] |##########################------| [R] |##############------------------| [L] |#########################-------| [R] |#############-------------------| [L] |########################--------| [R] |#############-------------------| [L] |#######################---------| [R] |############--------------------| [L] |######################----------| [R] |############--------------------| [L] |#####################-----------| [R] |###########---------------------| [L] |####################------------| [R] |###########---------------------| [L] |###################-------------| [R] |##########----------------------| [L] |##################--------------| [R] |##########----------------------| [L] |#################---------------| [R] |#########-----------------------| [L] |################----------------| [R] |#########-----------------------| [L] |###############-----------------| [R] |########------------------------| [L] |##############------------------| [R] |########------------------------| [L] |#############-------------------| [R] |#######-------------------------| [L] |############--------------------| [R] |#######-------------------------| [L] |###########---------------------| [R] |######--------------------------| [L] |##########----------------------| [R] |######--------------------------| [L] |#########-----------------------| [R] |#####---------------------------| [L] |########------------------------| [R] |#####---------------------------| [L] |#######-------------------------| [R] |####----------------------------| [L] |######--------------------------| [R] |####----------------------------| [L] |#####---------------------------| [R] |###-----------------------------| [L] |####----------------------------| [R] |###-----------------------------| [L] |###-----------------------------| [R] |##------------------------------| [L] |##------------------------------| [R] |##------------------------------| [L] |#-------------------------------| [R] |#-------------------------------| [L] |--------------------------------| [R] |#-------------------------------| [L] |--------------------------------| [R] |--------------------------------| [L] |#-------------------------------| [R] |--------------------------------| [L] |##------------------------------| [R] |--------------------------------| [L] |###-----------------------------| [R] |--------------------------------| [L] |####----------------------------| [R] |#-------------------------------| [L] |#####---------------------------| [R] |#-------------------------------| [L] |######--------------------------| [R] |##------------------------------| [L] |#######-------------------------| [R] |##------------------------------| [L] |########------------------------| [R] |###-----------------------------| [L] |#########-----------------------| [R] |###-----------------------------| [L] |##########----------------------| [R] |####----------------------------| [L] |###########---------------------| [R] |####----------------------------| [L] |############--------------------| [R] |#####---------------------------| [L] |#############-------------------| [R] |#####---------------------------| [L] |##############------------------| [R] |######--------------------------| [L] |###############-----------------| [R] |######--------------------------| [L] |################----------------| [R] |#######-------------------------| [L] |#################---------------| [R] |#######-------------------------| [L] |##################--------------| [R] |########------------------------| [L] |###################-------------| [R] |########------------------------| [L] |####################------------| [R] |#########-----------------------| [L] |#####################-----------| [R] |#########-----------------------| [L] |######################----------| [R] |##########----------------------| [L] |#######################---------| [R] |##########----------------------| [L] |########################--------| [R] |###########---------------------| [L] |#########################-------| [R] |###########---------------------| [L] |##########################------| [R] |############--------------------| [L] |###########################-----| [R] |############--------------------| [L] |############################----| [R] |#############-------------------| [L] |#############################---| [R] |#############-------------------| [L] |##############################--| [R] |##############------------------| [L] |###############################-| [R] |##############------------------| [L] |###############################-| [R] |###############-----------------| [L] |##############################--| [R] |###############-----------------| [L] |#############################---| [R] |################----------------| [L] |############################----| [R] |################----------------|
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%TRELLIS_COMB696242882.9%TRELLIS_FF150242880.6%TRELLIS_IO111975.6%
TimingClockAchievedConstraint$glbnet$clkp84.79 MHz25 MHz$glbnet$clkt335.68 MHz250 MHz
Codemodule 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 ); // NO inline initializations to avoid TOK_CONSTVAL parser errors logic [31:0] frame_counter; logic old_vsync; logic [6:0] msg_idx; logic sending; // Registers to lock the UART VU meter levels across a single frame logic [4:0] l_samp; logic [4:0] r_samp; // Combinational logic variables logic [7:0] x_mod1; logic [7:0] x_mod2; logic [4:0] tri1; logic [4:0] tri2; logic [5:0] total_h; logic [5:0] dot_h; logic [5:0] inv_row; logic [7:0] u_mod1; logic [7:0] u_mod2; logic [4:0] u_tri1; logic [4:0] u_tri2; always_comb begin // --------------------------------------------------------- // 1. VIDEO: Hardware Spectrum Analyzer // --------------------------------------------------------- // Generate two counter-propagating waves of different speeds. // Bitwise AND with 3F limits the wave period to 64 columns. x_mod1 = (col[7:0] + frame_counter[7:0]) & 8'h3F; x_mod2 = (col[7:0] - frame_counter[8:1]) & 8'h3F; // Turn the ramping counters into absolute triangle waves (0 to 31) tri1 = x_mod1[5] ? (~x_mod1[4:0]) : x_mod1[4:0]; tri2 = x_mod2[5] ? (~x_mod2[4:0]) : x_mod2[4:0]; // Sum the waves to get a morphing interference pattern (0 to 62 max height) total_h = {1'b0, tri1} + {1'b0, tri2}; // Calculate the position of the floating "peak" dot dot_h = total_h + 6'd2; // Invert the row coordinate so row 0 is the bottom of the screen inv_row = 6'd59 - row[5:0]; // Render the equalizer bars if (col[0] == 1'b1) begin // Leave a 1-character gap between every frequency band char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end else if (inv_row < total_h) begin // Draw the main LED bar char = 8'h3D; // '=' character gives it a segmented LED look background_color = 24'd0; // Heatmap color gradient based on height if (inv_row < 6'd15) foreground_color = 24'h00FF00; // Green else if (inv_row < 6'd30) foreground_color = 24'hFFFF00; // Yellow else if (inv_row < 6'd45) foreground_color = 24'hFF8000; // Orange else foreground_color = 24'hFF0000; // Red end else if (inv_row == dot_h) begin // Draw the floating peak indicator char = 8'h2D; // '-' foreground_color = 24'hFFFFFF; // White background_color = 24'd0; end else begin // Empty space above the bar char = 8'h20; // ' ' foreground_color = 24'd0; background_color = 24'd0; end // --------------------------------------------------------- // 2. UART: Stereo VU Meter Sampling // --------------------------------------------------------- // Sample the triangle waves at the center of the screen independently of the // video generation logic, so the UART doesn't change mid-frame. u_mod1 = (frame_counter[7:0]) & 8'h3F; u_mod2 = (-frame_counter[8:1]) & 8'h3F; u_tri1 = u_mod1[5] ? (~u_mod1[4:0]) : u_mod1[4:0]; u_tri2 = u_mod2[5] ? (~u_mod2[4:0]) : u_mod2[4:0]; // --------------------------------------------------------- // 3. UART: ASCII Output FSM // --------------------------------------------------------- if (msg_idx == 7'd0) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd1) uart_data = 8'h4C; // 'L' else if (msg_idx == 7'd2) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd3) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd4) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd5 && msg_idx <= 7'd36) begin // 32-character Left channel bar if ((msg_idx - 7'd5) < {2'b00, l_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd37) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd38) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd39) uart_data = 8'h5B; // '[' else if (msg_idx == 7'd40) uart_data = 8'h52; // 'R' else if (msg_idx == 7'd41) uart_data = 8'h5D; // ']' else if (msg_idx == 7'd42) uart_data = 8'h20; // ' ' else if (msg_idx == 7'd43) uart_data = 8'h7C; // '|' else if (msg_idx >= 7'd44 && msg_idx <= 7'd75) begin // 32-character Right channel bar if ((msg_idx - 7'd44) < {2'b00, r_samp}) uart_data = 8'h23; // '#' else uart_data = 8'h2D; // '-' end else if (msg_idx == 7'd76) uart_data = 8'h7C; // '|' else if (msg_idx == 7'd77) uart_data = 8'h0D; // '\r' else if (msg_idx == 7'd78) uart_data = 8'h0A; // '\n' else uart_data = 8'h20; // Space end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; l_samp <= 0; r_samp <= 0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; // Latch the VU meter samples so they stay stable during UART transmission l_samp <= u_tri1; r_samp <= u_tri2; // Trigger one line of UART output per frame sending <= 1'b1; end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 7'd79) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync frame end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
#FPGA #Icepi-Zero #HDL #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 ); // ------------------------------------------------------------- // Animated XOR-plasma background + pulsing banner + UART beacon // ------------------------------------------------------------- logic [31:0] frame_counter = '0; logic old_vsync = '0; // ---- Plasma color computation ------------------------------- logic [7:0] t; logic [7:0] r, g, b; logic [7:0] px8, py8; logic [7:0] dx, dy, dist; assign t = frame_counter[7:0]; assign px8 = px[7:0]; assign py8 = py[7:0]; // crude radial distance from a moving center assign dx = px8 - t; assign dy = py8 + t; assign dist = dx ^ dy; assign r = dist + t; assign g = (px8 ^ py8) + (t << 1); assign b = (px8 + py8) - t; // ---- Banner overlay ----------------------------------------- // Console grid: 80 cols x 60 rows. Banner: row 28, "** PLASMA DEMO **" // 17 chars centered -> start col = (80-17)/2 = 31 int rel_b; int rel_f; int hex_nib; logic [7:0] hex_char; assign rel_b = col - 31; assign rel_f = col - 34; // pick the hex nibble corresponding to rel_f position 5..12 always_comb begin case (rel_f) 5: hex_nib = frame_counter[31:28]; 6: hex_nib = frame_counter[27:24]; 7: hex_nib = frame_counter[23:20]; 8: hex_nib = frame_counter[19:16]; 9: hex_nib = frame_counter[15:12]; 10: hex_nib = frame_counter[11:8]; 11: hex_nib = frame_counter[7:4]; 12: hex_nib = frame_counter[3:0]; default: hex_nib = 8'h0; endcase if (hex_nib < 8'd10) hex_char = 8'h30 + hex_nib; // '0'..'9' else hex_char = 8'h41 + (hex_nib - 8'd10); // 'A'..'F' end always_comb begin background_color = {r, g, b}; foreground_color = 24'hFFFFFF; char = 0; // ---- Title banner on row 28 ----------------------------- if (row == 28) begin case (rel_b) 0: char = "*"; 1: char = "*"; 2: char = " "; 3: char = "P"; 4: char = "L"; 5: char = "A"; 6: char = "S"; 7: char = "M"; 8: char = "A"; 9: char = " "; 10: char = "D"; 11: char = "E"; 12: char = "M"; 13: char = "O"; 14: char = " "; 15: char = "*"; 16: char = "*"; default: char = 0; endcase if (rel_b >= 0 && rel_b < 17) foreground_color = {t, 8'hFF, ~t}; end // ---- Frame counter line on row 30 ----------------------- if (row == 30) begin case (rel_f) 0: char = "F"; 1: char = "R"; 2: char = "M"; 3: char = ":"; 4: char = " "; 5: char = hex_char; 6: char = hex_char; 7: char = hex_char; 8: char = hex_char; 9: char = hex_char; 10: char = hex_char; 11: char = hex_char; 12: char = hex_char; default: char = 0; endcase if (rel_f >= 0 && rel_f <= 12) foreground_color = 24'h00FF66; end // ---- Footer "YOSYS + SV = LOVE" on row 56 --------------- if (row == 56) begin case (col - 32) 0: char = "Y"; 1: char = "O"; 2: char = "S"; 3: char = "Y"; 4: char = "S"; 5: char = " "; 6: char = "+"; 7: char = " "; 8: char = "S"; 9: char = "V"; 10: char = " "; 11: char = "="; 12: char = " "; 13: char = "L"; 14: char = "O"; 15: char = "V"; 16: char = "E"; default: char = 0; endcase if ((col - 32) >= 0 && (col - 32) < 17) foreground_color = {8'hFF, t, t}; end end // ------------------------------------------------------------- // UART beacon: send "** FPGA PLASMA DEMO ** Frame=XXXXXXXX\r\n" // ------------------------------------------------------------- // 42 bytes total localparam int MSG_LEN = 42; logic [5:0] msg_idx = '0; logic sending = 1'b0; logic [23:0] throttle = '0; logic [31:0] sent_frame = '0; logic [7:0] msg_byte; logic [3:0] nib; always_comb begin nib = 4'h0; case (msg_idx) 6'd0: msg_byte = "*"; 6'd1: msg_byte = "*"; 6'd2: msg_byte = " "; 6'd3: msg_byte = "F"; 6'd4: msg_byte = "P"; 6'd5: msg_byte = "G"; 6'd6: msg_byte = "A"; 6'd7: msg_byte = " "; 6'd8: msg_byte = "P"; 6'd9: msg_byte = "L"; 6'd10: msg_byte = "A"; 6'd11: msg_byte = "S"; 6'd12: msg_byte = "M"; 6'd13: msg_byte = "A"; 6'd14: msg_byte = " "; 6'd15: msg_byte = "D"; 6'd16: msg_byte = "E"; 6'd17: msg_byte = "M"; 6'd18: msg_byte = "O"; 6'd19: msg_byte = " "; 6'd20: msg_byte = "*"; 6'd21: msg_byte = "*"; 6'd22: msg_byte = " "; 6'd23: msg_byte = "F"; 6'd24: msg_byte = "r"; 6'd25: msg_byte = "a"; 6'd26: msg_byte = "m"; 6'd27: msg_byte = "e"; 6'd28: msg_byte = "="; 6'd29: begin msg_byte = 8'h00; nib = sent_frame[31:28]; end 6'd30: begin msg_byte = 8'h00; nib = sent_frame[27:24]; end 6'd31: begin msg_byte = 8'h00; nib = sent_frame[23:20]; end 6'd32: begin msg_byte = 8'h00; nib = sent_frame[19:16]; end 6'd33: begin msg_byte = 8'h00; nib = sent_frame[15:12]; end 6'd34: begin msg_byte = 8'h00; nib = sent_frame[11:8]; end 6'd35: begin msg_byte = 8'h00; nib = sent_frame[7:4]; end 6'd36: begin msg_byte = 8'h00; nib = sent_frame[3:0]; end 6'd37: msg_byte = "!"; 6'd38: msg_byte = "\r"; 6'd39: msg_byte = "\n"; default: msg_byte = 8'h00; endcase if (msg_idx >= 6'd29 && msg_idx <= 6'd36) begin if (nib < 4'd10) msg_byte = 8'h30 + {4'b0, nib}; else msg_byte = 8'h41 + {4'b0, nib} - 8'd10; end uart_data = msg_byte; uart_valid = sending && (msg_idx < MSG_LEN[5: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; if (sending) begin if (uart_ready && uart_valid) begin if (msg_idx == MSG_LEN[5:0] - 1) begin sending <= 1'b0; msg_idx <= '0; end else begin msg_idx <= msg_idx + 1; end end end else begin throttle <= throttle + 1; if (throttle[22] == 1'b1) begin sending <= 1'b1; throttle <= '0; sent_frame <= frame_counter; end end end endmodule
Success!
UART Output
** FPGA PLASMA DEMO ** Frame=00000131! \0\0** FPGA PLASMA DEMO ** Frame=0000013C! \0\0** FPGA PLASMA DEMO ** Frame=00000146! \0\0** FPGA PLASMA DEMO ** Frame=00000150! \0\0** FPGA PLASMA DEMO ** Frame=0000015A! \0\0** FPGA PLASMA DEMO ** Frame=00000164! \0\0** FPGA PLASMA DEMO ** Frame=0000016F! \0\0** FPGA PLASMA DEMO ** Frame=00000179! \0\0** FPGA PLASMA DEMO ** Frame=00000183! \0\0** FPGA PLASMA DEMO ** Frame=0000018D! \0\0** FPGA PLASMA DEMO ** Frame=00000197! \0\0** FPGA PLASMA DEMO ** Frame=000001A2! \0\0** FPGA PLASMA DEMO ** Frame=000001AC! \0\0** FPGA PLASMA DEMO ** Frame=000001B6! \0\0** FPGA PLASMA DEMO ** Frame=000001C0! \0\0** FPGA PLASMA DEMO ** Frame=000001CA! \0\0** FPGA PLASMA DEMO ** Frame=000001D5! \0\0** FPGA PLASMA DEMO ** Frame=000001DF! \0\0** FPGA PLASMA DEMO ** Frame=000001E9! \0\0** FPGA PLASMA DEMO ** Frame=000001F3! \0\0** FPGA PLASMA DEMO ** Frame=000001FD! \0\0** FPGA PLASMA DEMO ** Frame=00000208! \0\0** FPGA PLASMA DEMO ** Frame=00000212! \0\0** FPGA PLASMA DEMO ** Frame=0000021C! \0\0** FPGA PLASMA DEMO ** Frame=00000226! \0\0** FPGA PLASMA DEMO ** Frame=00000230! \0\0** FPGA PLASMA DEMO ** Frame=0000023B! \0\0** FPGA PLASMA DEMO ** Frame=00000245! \0\0** FPGA PLASMA DEMO ** Frame=0000024F! \0\0** FPGA PLASMA DEMO ** Frame=00000259! \0\0** FPGA PLASMA DEMO ** Frame=00000263! \0\0** FPGA PLASMA DEMO ** Frame=0000026E! \0\0** FPGA PLASMA DEMO ** Frame=00000278! \0\0** FPGA PLASMA DEMO ** Frame=00000282! \0\0** FPGA PLASMA DEMO ** Frame=0000028C! \0\0** FPGA PLASMA DEMO ** Frame=00000296! \0\0** FPGA PLASMA DEMO ** Frame=000002A1! \0\0** FPGA PLASMA DEMO ** Frame=000002AB! \0\0** FPGA PLASMA DEMO ** Frame=000002B5! \0\0** FPGA PLASMA DEMO ** Frame=000002BF! \0\0** FPGA PLASMA DEMO ** Frame=000002C9! \0\0** FPGA PLASMA DEMO ** Frame=000002D4! \0\0** FPGA PLASMA DEMO ** Frame=000002DE! \0\0** FPGA PLASMA DEMO ** Frame=000002E8! \0\0** FPGA PLASMA DEMO ** Frame=000002F2! \0\0** FPGA PLASMA DEMO ** Frame=000002FC! \0\0** FPGA PLASMA DEMO ** Frame=00000307! \0\0** FPGA PLASMA DEMO ** Frame=00000311! \0\0** FPGA PLASMA DEMO ** Frame=0000031B! \0\0** FPGA PLASMA DEMO ** Frame=00000325! \0\0** FPGA PLASMA DEMO ** Frame=0000032F! \0\0** FPGA PLASMA DEMO ** Frame=00000339! \0\0** FPGA PLASMA DEMO ** Frame=00000344! \0\0** FPGA PLASMA DEMO ** Frame=0000034E! \0\0** FPGA PLASMA DEMO ** Frame=00000358! \0\0** FPGA PLASMA DEMO ** Frame=00000362! \0\0** FPGA PLASMA DEMO ** Frame=0000036C! \0\0** FPGA PLASMA DEMO ** Frame=00000377! \0\0** FPGA PLASMA DEMO ** Frame=00000381! \0\0** FPGA PLASMA DEMO ** Frame=0000038B! \0\0** FPGA PLASMA DEMO ** Frame=00000395! \0\0** FPGA PLASMA DEMO ** Frame=0000039F! \0\0** FPGA PLASMA DEMO ** Frame=000003AA! \0\0** FPGA PLASMA DEMO ** Frame=000003B4! \0\0** FPGA PLASMA DEMO ** Frame=000003BE! \0\0** FPGA PLASMA DEMO ** Frame=000003C8! \0\0** FPGA PLASMA DEMO ** Frame=000003D2! \0\0** FPGA PLASMA DEMO ** Frame=000003DD! \0\0** FPGA PLASMA DEMO ** Frame=000003E7! \0\0** FPGA PLASMA DEMO ** Frame=000003F1! \0\0** FPGA PLASMA DEMO ** Frame=000003FB! \0\0** FPGA PLASMA DEMO ** Frame=00000405! \0\0** FPGA PLASMA DEMO ** Frame=00000410! \0\0** FPGA PLASMA DEMO ** Frame=0000041A! \0\0** FPGA PLASMA DEMO ** Frame=00000424! \0\0** FPGA PLASMA DEMO ** Frame=0000042E! \0\0** FPGA PLASMA DEMO ** Frame=00000438! \0\0** FPGA PLASMA DEMO ** Frame=00000443! \0\0** FPGA PLASMA DEMO ** Frame=0000044D! \0\0** FPGA PLASMA DEMO ** Frame=00000457! \0\0** FPGA PLASMA DEMO ** Frame=00000461! \0\0** FPGA PLASMA DEMO ** Frame=0000046B! \0\0** FPGA PLASMA DEMO ** Frame=00000476! \0\0** FPGA PLASMA DEMO ** Frame=00000480! \0\0** FPGA PLASMA DEMO ** Frame=0000048A! \0\0** FPGA PLASMA DEMO ** Frame=00000494! \0\0** FPGA PLASMA DEMO ** Frame=0000049E! \0\0** FPGA PLASMA DEMO ** Frame=000004A9! \0\0** FPGA PLASMA DEMO ** Frame=000004B3! \0\0** FPGA PLASMA DEMO ** Frame=000004BD! \0\0** FPGA PLASMA DEMO ** Frame=000004C7! \0\0** FPGA PLASMA DEMO ** Frame=000004D1! \0\0** FPGA PLASMA DEMO ** Frame=000004DC! \0\0** FPGA PLASMA DEMO ** Frame=000004E6! \0\0** FPGA PLASMA DEMO ** Frame=000004F0! \0\0** FPGA PLASMA DEMO ** Frame=000004FA! \0\0** FPGA PLASMA DEMO ** Frame=00000504! \0\0** FPGA PLASMA DEMO ** Frame=0000050F! \0\0** FPGA PLASMA DEMO ** Frame=00000519! \0\0** FPGA PLASMA DEMO ** Frame=00000523! \0\0** FPGA PLASMA DEMO ** Frame=0000052D! \0\0** FPGA PLASMA DEMO ** Frame=00000537! \0\0** FPGA PLASMA DEMO ** Frame=00000542! \0\0** FPGA PLASMA DEMO ** Frame=0000054C! \0\0** FPGA PLASMA DEMO ** Frame=00000556! \0\0** FPGA PLASMA DEMO ** Frame=00000560! \0\0** FPGA PLASMA DEMO ** Frame=0000056A! \0\0** FPGA PLASMA DEMO ** Frame=00000575! \0\0** FPGA PLASMA DEMO ** Frame=0000057F! \0\0** FPGA PLASMA DEMO ** Frame=00000589! \0\0** FPGA PLASMA DEMO ** Frame=00000593! \0\0** FPGA PLASMA DEMO ** Frame=0000059D! \0\0** FPGA PLASMA DEMO ** Frame=000005A8! \0\0** FPGA PLASMA DEMO ** Frame=000005B2! \0\0** FPGA PLASMA DEMO ** Frame=000005BC! \0\0** FPGA PLASMA DEMO ** Frame=000005C6! \0\0** FPGA PLASMA DEMO ** Frame=000005D0! \0\0** FPGA PLASMA DEMO ** Frame=000005DB! \0\0** FPGA PLASMA DEMO ** Frame=000005E5! \0\0** FPGA PLASMA DEMO ** Frame=000005EF! \0\0** FPGA PLASMA DEMO ** Frame=000005F9! \0\0** FPGA PLASMA DEMO ** Frame=00000603! \0\0** FPGA PLASMA DEMO ** Frame=0000060E! \0\0** FPGA PLASMA DEMO ** Frame=00000618! \0\0** FPGA PLASMA DEMO ** Frame=00000622! \0\0** FPGA PLASMA DEMO ** Frame=0000062C! \0\0** FPGA PLASMA DEMO ** Frame=00000636! \0\0** FPGA PLASMA DEMO ** Frame=00000641! \0\0** FPGA PLASMA DEMO ** Frame=0000064B! \0\0** FPGA PLASMA DEMO ** Frame=00000655! \0\0** FPGA PLASMA DEMO ** Frame=0000065F! \0\0** FPGA PLASMA DEMO ** Frame=00000669! \0\0** FPGA PLASMA DEMO ** Frame=00000674! \0\0** FPGA PLASMA DEMO ** Frame=0000067E! \0\0** FPGA PLASMA DEMO ** Frame=00000688! \0\0** FPGA PLASMA DEMO ** Frame=00000692! \0\0** FPGA PLASMA DEMO ** Frame=0000069C! \0\0** FPGA PLASMA DEMO ** Frame=000006A7! \0\0** FPGA PLASMA DEMO ** Frame=000006B1! \0\0** FPGA PLASMA DEMO ** Frame=000006BB! \0\0** FPGA PLASMA DEMO ** Frame=000006C5! \0\0** FPGA PLASMA DEMO ** Frame=000006CF! \0\0** FPGA PLASMA DEMO ** Frame=000006DA! \0\0** FPGA PLASMA DEMO ** Frame=000006E4! \0\0** FPGA PLASMA DEMO ** Frame=000006EE! \0\0** FPGA PLASMA DEMO ** Frame=000006F8! \0\0** FPGA PLASMA DEMO ** Frame=00000702! \0\0** FPGA PLASMA DEMO ** Frame=0000070D! \0\0** FPGA PLASMA DEMO ** Frame=00000717! \0\0** FPGA PLASMA DEMO ** Frame=00000721! \0\0** FPGA PLASMA DEMO ** Frame=0000072B! \0\0** FPGA PLASMA DEMO ** Frame=00000735! \0\0** FPGA PLASMA DEMO ** Frame=00000740! \0\0** FPGA PLASMA DEMO ** Frame=0000074A! \0\0** FPGA PLASMA DEMO ** Frame=00000754! \0\0** FPGA PLASMA DEMO ** Frame=0000075E! \0\0** FPGA PLASMA DEMO ** Frame=00000768! \0\0** FPGA PLASMA DEMO ** Frame=00000773! \0\0** FPGA PLASMA DEMO ** Frame=0000077D! \0\0** FPGA PLASMA DEMO ** Frame=00000787! \0\0** FPGA PLASMA DEMO ** Frame=00000791! \0\0** FPGA PLASMA DEMO ** Frame=0000079B! \0\0** FPGA PLASMA DEMO ** Frame=000007A6! \0\0** FPGA PLASMA DEMO ** Frame=000007B0! \0\0** FPGA PLASMA DEMO ** Frame=000007BA! \0\0** FPGA PLASMA DEMO ** Frame=000007C4! \0\0** FPGA PLASMA DEMO ** Frame=000007CE! \0\0** FPGA PLASMA DEMO ** Frame=000007D9! \0\0** FPGA PLASMA DEMO ** Frame=000007E3! \0\0** FPGA PLASMA DEMO ** Frame=000007ED! \0\0** FPGA PLASMA DEMO ** Frame=000007F7! \0\0** FPGA PLASMA DEMO ** Frame=00000801! \0\0** FPGA PLASMA DEMO ** Frame=0000080C! \0\0** FPGA PLASMA DEMO ** Frame=00000816! \0\0** FPGA PLASMA DEMO ** Frame=00000820! \0\0
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%TRELLIS_COMB1699242887.0%TRELLIS_FF253242881.0%TRELLIS_IO111975.6%
TimingClockAchievedConstraint$glbnet$clkp39.66 MHz25 MHz$glbnet$clkt320.41 MHz250 MHz
Codemodule 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 ); // ------------------------------------------------------------- // Animated XOR-plasma background + pulsing banner + UART beacon // ------------------------------------------------------------- logic [31:0] frame_counter = '0; logic old_vsync = '0; // ---- Plasma color computation ------------------------------- logic [7:0] t; logic [7:0] r, g, b; logic [7:0] px8, py8; logic [7:0] dx, dy, dist; assign t = frame_counter[7:0]; assign px8 = px[7:0]; assign py8 = py[7:0]; // crude radial distance from a moving center assign dx = px8 - t; assign dy = py8 + t; assign dist = dx ^ dy; assign r = dist + t; assign g = (px8 ^ py8) + (t << 1); assign b = (px8 + py8) - t; // ---- Banner overlay ----------------------------------------- // Console grid: 80 cols x 60 rows. Banner: row 28, "** PLASMA DEMO **" // 17 chars centered -> start col = (80-17)/2 = 31 int rel_b; int rel_f; int hex_nib; logic [7:0] hex_char; assign rel_b = col - 31; assign rel_f = col - 34; // pick the hex nibble corresponding to rel_f position 5..12 always_comb begin case (rel_f) 5: hex_nib = frame_counter[31:28]; 6: hex_nib = frame_counter[27:24]; 7: hex_nib = frame_counter[23:20]; 8: hex_nib = frame_counter[19:16]; 9: hex_nib = frame_counter[15:12]; 10: hex_nib = frame_counter[11:8]; 11: hex_nib = frame_counter[7:4]; 12: hex_nib = frame_counter[3:0]; default: hex_nib = 8'h0; endcase if (hex_nib < 8'd10) hex_char = 8'h30 + hex_nib; // '0'..'9' else hex_char = 8'h41 + (hex_nib - 8'd10); // 'A'..'F' end always_comb begin background_color = {r, g, b}; foreground_color = 24'hFFFFFF; char = 0; // ---- Title banner on row 28 ----------------------------- if (row == 28) begin case (rel_b) 0: char = "*"; 1: char = "*"; 2: char = " "; 3: char = "P"; 4: char = "L"; 5: char = "A"; 6: char = "S"; 7: char = "M"; 8: char = "A"; 9: char = " "; 10: char = "D"; 11: char = "E"; 12: char = "M"; 13: char = "O"; 14: char = " "; 15: char = "*"; 16: char = "*"; default: char = 0; endcase if (rel_b >= 0 && rel_b < 17) foreground_color = {t, 8'hFF, ~t}; end // ---- Frame counter line on row 30 ----------------------- if (row == 30) begin case (rel_f) 0: char = "F"; 1: char = "R"; 2: char = "M"; 3: char = ":"; 4: char = " "; 5: char = hex_char; 6: char = hex_char; 7: char = hex_char; 8: char = hex_char; 9: char = hex_char; 10: char = hex_char; 11: char = hex_char; 12: char = hex_char; default: char = 0; endcase if (rel_f >= 0 && rel_f <= 12) foreground_color = 24'h00FF66; end // ---- Footer "YOSYS + SV = LOVE" on row 56 --------------- if (row == 56) begin case (col - 32) 0: char = "Y"; 1: char = "O"; 2: char = "S"; 3: char = "Y"; 4: char = "S"; 5: char = " "; 6: char = "+"; 7: char = " "; 8: char = "S"; 9: char = "V"; 10: char = " "; 11: char = "="; 12: char = " "; 13: char = "L"; 14: char = "O"; 15: char = "V"; 16: char = "E"; default: char = 0; endcase if ((col - 32) >= 0 && (col - 32) < 17) foreground_color = {8'hFF, t, t}; end end // ------------------------------------------------------------- // UART beacon: send "** FPGA PLASMA DEMO ** Frame=XXXXXXXX\r\n" // ------------------------------------------------------------- // 42 bytes total localparam int MSG_LEN = 42; logic [5:0] msg_idx = '0; logic sending = 1'b0; logic [23:0] throttle = '0; logic [31:0] sent_frame = '0; logic [7:0] msg_byte; logic [3:0] nib; always_comb begin nib = 4'h0; case (msg_idx) 6'd0: msg_byte = "*"; 6'd1: msg_byte = "*"; 6'd2: msg_byte = " "; 6'd3: msg_byte = "F"; 6'd4: msg_byte = "P"; 6'd5: msg_byte = "G"; 6'd6: msg_byte = "A"; 6'd7: msg_byte = " "; 6'd8: msg_byte = "P"; 6'd9: msg_byte = "L"; 6'd10: msg_byte = "A"; 6'd11: msg_byte = "S"; 6'd12: msg_byte = "M"; 6'd13: msg_byte = "A"; 6'd14: msg_byte = " "; 6'd15: msg_byte = "D"; 6'd16: msg_byte = "E"; 6'd17: msg_byte = "M"; 6'd18: msg_byte = "O"; 6'd19: msg_byte = " "; 6'd20: msg_byte = "*"; 6'd21: msg_byte = "*"; 6'd22: msg_byte = " "; 6'd23: msg_byte = "F"; 6'd24: msg_byte = "r"; 6'd25: msg_byte = "a"; 6'd26: msg_byte = "m"; 6'd27: msg_byte = "e"; 6'd28: msg_byte = "="; 6'd29: begin msg_byte = 8'h00; nib = sent_frame[31:28]; end 6'd30: begin msg_byte = 8'h00; nib = sent_frame[27:24]; end 6'd31: begin msg_byte = 8'h00; nib = sent_frame[23:20]; end 6'd32: begin msg_byte = 8'h00; nib = sent_frame[19:16]; end 6'd33: begin msg_byte = 8'h00; nib = sent_frame[15:12]; end 6'd34: begin msg_byte = 8'h00; nib = sent_frame[11:8]; end 6'd35: begin msg_byte = 8'h00; nib = sent_frame[7:4]; end 6'd36: begin msg_byte = 8'h00; nib = sent_frame[3:0]; end 6'd37: msg_byte = "!"; 6'd38: msg_byte = "\r"; 6'd39: msg_byte = "\n"; default: msg_byte = 8'h00; endcase if (msg_idx >= 6'd29 && msg_idx <= 6'd36) begin if (nib < 4'd10) msg_byte = 8'h30 + {4'b0, nib}; else msg_byte = 8'h41 + {4'b0, nib} - 8'd10; end uart_data = msg_byte; uart_valid = sending && (msg_idx < MSG_LEN[5: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; if (sending) begin if (uart_ready && uart_valid) begin if (msg_idx == MSG_LEN[5:0] - 1) begin sending <= 1'b0; msg_idx <= '0; end else begin msg_idx <= msg_idx + 1; end end end else begin throttle <= throttle + 1; if (throttle[22] == 1'b1) begin sending <= 1'b1; throttle <= '0; sent_frame <= frame_counter; end end end endmodule
#FPGA #Icepi-Zero #HDL #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 ); // ------------------------------------------------------------- // Animated XOR-plasma background + pulsing banner + UART beacon // ------------------------------------------------------------- logic [31:0] frame_counter = '0; logic old_vsync = '0; // ---- Plasma color computation ------------------------------- logic [7:0] t; logic [7:0] r, g, b; logic [7:0] px8, py8; logic [7:0] dx, dy, dist; assign t = frame_counter[7:0]; assign px8 = px[7:0]; assign py8 = py[7:0]; // crude radial distance from a moving center assign dx = px8 - t; assign dy = py8 + t; assign dist = dx ^ dy; assign r = dist + t; assign g = (px8 ^ py8) + (t << 1); assign b = (px8 + py8) - t; // ---- Banner overlay ----------------------------------------- // Console grid: 80 cols x 60 rows. Banner: row 28, "** PLASMA DEMO **" // 17 chars centered -> start col = (80-17)/2 = 31 int rel_b; int rel_f; int hex_nib; logic [7:0] hex_char; assign rel_b = col - 31; assign rel_f = col - 34; // pick the hex nibble corresponding to rel_f position 5..12 always_comb begin case (rel_f) 5: hex_nib = frame_counter[31:28]; 6: hex_nib = frame_counter[27:24]; 7: hex_nib = frame_counter[23:20]; 8: hex_nib = frame_counter[19:16]; 9: hex_nib = frame_counter[15:12]; 10: hex_nib = frame_counter[11:8]; 11: hex_nib = frame_counter[7:4]; 12: hex_nib = frame_counter[3:0]; default: hex_nib = 8'h0; endcase if (hex_nib < 8'd10) hex_char = 8'h30 + hex_nib; // '0'..'9' else hex_char = 8'h41 + (hex_nib - 8'd10); // 'A'..'F' end always_comb begin background_color = {r, g, b}; foreground_color = 24'hFFFFFF; char = 0; // ---- Title banner on row 28 ----------------------------- if (row == 28) begin case (rel_b) 0: char = "*"; 1: char = "*"; 2: char = " "; 3: char = "P"; 4: char = "L"; 5: char = "A"; 6: char = "S"; 7: char = "M"; 8: char = "A"; 9: char = " "; 10: char = "D"; 11: char = "E"; 12: char = "M"; 13: char = "O"; 14: char = " "; 15: char = "*"; 16: char = "*"; default: char = 0; endcase if (rel_b >= 0 && rel_b < 17) foreground_color = {t, 8'hFF, ~t}; end // ---- Frame counter line on row 30 ----------------------- if (row == 30) begin case (rel_f) 0: char = "F"; 1: char = "R"; 2: char = "M"; 3: char = ":"; 4: char = " "; 5: char = hex_char; 6: char = hex_char; 7: char = hex_char; 8: char = hex_char; 9: char = hex_char; 10: char = hex_char; 11: char = hex_char; 12: char = hex_char; default: char = 0; endcase if (rel_f >= 0 && rel_f <= 12) foreground_color = 24'h00FF66; end // ---- Footer "YOSYS + SV = LOVE" on row 56 --------------- if (row == 56) begin case (col - 32) 0: char = "Y"; 1: char = "O"; 2: char = "S"; 3: char = "Y"; 4: char = "S"; 5: char = " "; 6: char = "+"; 7: char = " "; 8: char = "S"; 9: char = "V"; 10: char = " "; 11: char = "="; 12: char = " "; 13: char = "L"; 14: char = "O"; 15: char = "V"; 16: char = "E"; default: char = 0; endcase if ((col - 32) >= 0 && (col - 32) < 17) foreground_color = {8'hFF, t, t}; end end // ------------------------------------------------------------- // UART beacon: send "** FPGA PLASMA DEMO ** Frame=XXXXXXXX\r\n" // ------------------------------------------------------------- // 42 bytes total localparam int MSG_LEN = 42; logic [5:0] msg_idx = '0; logic sending = 1'b0; logic [23:0] throttle = '0; logic [31:0] sent_frame = '0; logic [7:0] msg_byte; logic [3:0] nib; always_comb begin nib = 4'h0; case (msg_idx) 6'd0: msg_byte = "*"; 6'd1: msg_byte = "*"; 6'd2: msg_byte = " "; 6'd3: msg_byte = "F"; 6'd4: msg_byte = "P"; 6'd5: msg_byte = "G"; 6'd6: msg_byte = "A"; 6'd7: msg_byte = " "; 6'd8: msg_byte = "P"; 6'd9: msg_byte = "L"; 6'd10: msg_byte = "A"; 6'd11: msg_byte = "S"; 6'd12: msg_byte = "M"; 6'd13: msg_byte = "A"; 6'd14: msg_byte = " "; 6'd15: msg_byte = "D"; 6'd16: msg_byte = "E"; 6'd17: msg_byte = "M"; 6'd18: msg_byte = "O"; 6'd19: msg_byte = " "; 6'd20: msg_byte = "*"; 6'd21: msg_byte = "*"; 6'd22: msg_byte = " "; 6'd23: msg_byte = "F"; 6'd24: msg_byte = "r"; 6'd25: msg_byte = "a"; 6'd26: msg_byte = "m"; 6'd27: msg_byte = "e"; 6'd28: msg_byte = "="; 6'd29: begin msg_byte = 8'h00; nib = sent_frame[31:28]; end 6'd30: begin msg_byte = 8'h00; nib = sent_frame[27:24]; end 6'd31: begin msg_byte = 8'h00; nib = sent_frame[23:20]; end 6'd32: begin msg_byte = 8'h00; nib = sent_frame[19:16]; end 6'd33: begin msg_byte = 8'h00; nib = sent_frame[15:12]; end 6'd34: begin msg_byte = 8'h00; nib = sent_frame[11:8]; end 6'd35: begin msg_byte = 8'h00; nib = sent_frame[7:4]; end 6'd36: begin msg_byte = 8'h00; nib = sent_frame[3:0]; end 6'd37: msg_byte = "!"; 6'd38: msg_byte = "\r"; 6'd39: msg_byte = "\n"; default: msg_byte = 8'h00; endcase if (msg_idx >= 6'd29 && msg_idx <= 6'd36) begin if (nib < 4'd10) msg_byte = 8'h30 + {4'b0, nib}; else msg_byte = 8'h41 + {4'b0, nib} - 8'd10; end uart_data = msg_byte; uart_valid = sending && (msg_idx < MSG_LEN[5: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; if (sending) begin if (uart_ready && uart_valid) begin if (msg_idx == MSG_LEN[5:0] - 1) begin sending <= 1'b0; msg_idx <= '0; end else begin msg_idx <= msg_idx + 1; end end end else begin throttle <= throttle + 1; if (throttle[22] == 1'b1) begin sending <= 1'b1; throttle <= '0; sent_frame <= frame_counter; end end end endmodule
Success!
UART Output
** FPGA PLASMA DEMO ** Frame=00000131! \0\0** FPGA PLASMA DEMO ** Frame=0000013C! \0\0** FPGA PLASMA DEMO ** Frame=00000146! \0\0** FPGA PLASMA DEMO ** Frame=00000150! \0\0** FPGA PLASMA DEMO ** Frame=0000015A! \0\0** FPGA PLASMA DEMO ** Frame=00000164! \0\0** FPGA PLASMA DEMO ** Frame=0000016F! \0\0** FPGA PLASMA DEMO ** Frame=00000179! \0\0** FPGA PLASMA DEMO ** Frame=00000183! \0\0** FPGA PLASMA DEMO ** Frame=0000018D! \0\0** FPGA PLASMA DEMO ** Frame=00000197! \0\0** FPGA PLASMA DEMO ** Frame=000001A2! \0\0** FPGA PLASMA DEMO ** Frame=000001AC! \0\0** FPGA PLASMA DEMO ** Frame=000001B6! \0\0** FPGA PLASMA DEMO ** Frame=000001C0! \0\0** FPGA PLASMA DEMO ** Frame=000001CA! \0\0** FPGA PLASMA DEMO ** Frame=000001D5! \0\0** FPGA PLASMA DEMO ** Frame=000001DF! \0\0** FPGA PLASMA DEMO ** Frame=000001E9! \0\0** FPGA PLASMA DEMO ** Frame=000001F3! \0\0** FPGA PLASMA DEMO ** Frame=000001FD! \0\0** FPGA PLASMA DEMO ** Frame=00000208! \0\0** FPGA PLASMA DEMO ** Frame=00000212! \0\0** FPGA PLASMA DEMO ** Frame=0000021C! \0\0** FPGA PLASMA DEMO ** Frame=00000226! \0\0** FPGA PLASMA DEMO ** Frame=00000230! \0\0** FPGA PLASMA DEMO ** Frame=0000023B! \0\0** FPGA PLASMA DEMO ** Frame=00000245! \0\0** FPGA PLASMA DEMO ** Frame=0000024F! \0\0** FPGA PLASMA DEMO ** Frame=00000259! \0\0** FPGA PLASMA DEMO ** Frame=00000263! \0\0** FPGA PLASMA DEMO ** Frame=0000026E! \0\0** FPGA PLASMA DEMO ** Frame=00000278! \0\0** FPGA PLASMA DEMO ** Frame=00000282! \0\0** FPGA PLASMA DEMO ** Frame=0000028C! \0\0** FPGA PLASMA DEMO ** Frame=00000296! \0\0** FPGA PLASMA DEMO ** Frame=000002A1! \0\0** FPGA PLASMA DEMO ** Frame=000002AB! \0\0** FPGA PLASMA DEMO ** Frame=000002B5! \0\0** FPGA PLASMA DEMO ** Frame=000002BF! \0\0** FPGA PLASMA DEMO ** Frame=000002C9! \0\0** FPGA PLASMA DEMO ** Frame=000002D4! \0\0** FPGA PLASMA DEMO ** Frame=000002DE! \0\0** FPGA PLASMA DEMO ** Frame=000002E8! \0\0** FPGA PLASMA DEMO ** Frame=000002F2! \0\0** FPGA PLASMA DEMO ** Frame=000002FC! \0\0** FPGA PLASMA DEMO ** Frame=00000307! \0\0** FPGA PLASMA DEMO ** Frame=00000311! \0\0** FPGA PLASMA DEMO ** Frame=0000031B! \0\0** FPGA PLASMA DEMO ** Frame=00000325! \0\0** FPGA PLASMA DEMO ** Frame=0000032F! \0\0** FPGA PLASMA DEMO ** Frame=00000339! \0\0** FPGA PLASMA DEMO ** Frame=00000344! \0\0** FPGA PLASMA DEMO ** Frame=0000034E! \0\0** FPGA PLASMA DEMO ** Frame=00000358! \0\0** FPGA PLASMA DEMO ** Frame=00000362! \0\0** FPGA PLASMA DEMO ** Frame=0000036C! \0\0** FPGA PLASMA DEMO ** Frame=00000377! \0\0** FPGA PLASMA DEMO ** Frame=00000381! \0\0** FPGA PLASMA DEMO ** Frame=0000038B! \0\0** FPGA PLASMA DEMO ** Frame=00000395! \0\0** FPGA PLASMA DEMO ** Frame=0000039F! \0\0** FPGA PLASMA DEMO ** Frame=000003AA! \0\0** FPGA PLASMA DEMO ** Frame=000003B4! \0\0** FPGA PLASMA DEMO ** Frame=000003BE! \0\0** FPGA PLASMA DEMO ** Frame=000003C8! \0\0** FPGA PLASMA DEMO ** Frame=000003D2! \0\0** FPGA PLASMA DEMO ** Frame=000003DD! \0\0** FPGA PLASMA DEMO ** Frame=000003E7! \0\0** FPGA PLASMA DEMO ** Frame=000003F1! \0\0** FPGA PLASMA DEMO ** Frame=000003FB! \0\0** FPGA PLASMA DEMO ** Frame=00000405! \0\0** FPGA PLASMA DEMO ** Frame=00000410! \0\0** FPGA PLASMA DEMO ** Frame=0000041A! \0\0** FPGA PLASMA DEMO ** Frame=00000424! \0\0** FPGA PLASMA DEMO ** Frame=0000042E! \0\0** FPGA PLASMA DEMO ** Frame=00000438! \0\0** FPGA PLASMA DEMO ** Frame=00000443! \0\0** FPGA PLASMA DEMO ** Frame=0000044D! \0\0** FPGA PLASMA DEMO ** Frame=00000457! \0\0** FPGA PLASMA DEMO ** Frame=00000461! \0\0** FPGA PLASMA DEMO ** Frame=0000046B! \0\0** FPGA PLASMA DEMO ** Frame=00000476! \0\0** FPGA PLASMA DEMO ** Frame=00000480! \0\0** FPGA PLASMA DEMO ** Frame=0000048A! \0\0** FPGA PLASMA DEMO ** Frame=00000494! \0\0** FPGA PLASMA DEMO ** Frame=0000049E! \0\0** FPGA PLASMA DEMO ** Frame=000004A9! \0\0** FPGA PLASMA DEMO ** Frame=000004B3! \0\0** FPGA PLASMA DEMO ** Frame=000004BD! \0\0** FPGA PLASMA DEMO ** Frame=000004C7! \0\0** FPGA PLASMA DEMO ** Frame=000004D1! \0\0** FPGA PLASMA DEMO ** Frame=000004DC! \0\0** FPGA PLASMA DEMO ** Frame=000004E6! \0\0** FPGA PLASMA DEMO ** Frame=000004F0! \0\0** FPGA PLASMA DEMO ** Frame=000004FA! \0\0** FPGA PLASMA DEMO ** Frame=00000504! \0\0** FPGA PLASMA DEMO ** Frame=0000050F! \0\0** FPGA PLASMA DEMO ** Frame=00000519! \0\0** FPGA PLASMA DEMO ** Frame=00000523! \0\0** FPGA PLASMA DEMO ** Frame=0000052D! \0\0** FPGA PLASMA DEMO ** Frame=00000537! \0\0** FPGA PLASMA DEMO ** Frame=00000542! \0\0** FPGA PLASMA DEMO ** Frame=0000054C! \0\0** FPGA PLASMA DEMO ** Frame=00000556! \0\0** FPGA PLASMA DEMO ** Frame=00000560! \0\0** FPGA PLASMA DEMO ** Frame=0000056A! \0\0** FPGA PLASMA DEMO ** Frame=00000575! \0\0** FPGA PLASMA DEMO ** Frame=0000057F! \0\0** FPGA PLASMA DEMO ** Frame=00000589! \0\0** FPGA PLASMA DEMO ** Frame=00000593! \0\0** FPGA PLASMA DEMO ** Frame=0000059D! \0\0** FPGA PLASMA DEMO ** Frame=000005A8! \0\0** FPGA PLASMA DEMO ** Frame=000005B2! \0\0** FPGA PLASMA DEMO ** Frame=000005BC! \0\0** FPGA PLASMA DEMO ** Frame=000005C6! \0\0** FPGA PLASMA DEMO ** Frame=000005D0! \0\0** FPGA PLASMA DEMO ** Frame=000005DB! \0\0** FPGA PLASMA DEMO ** Frame=000005E5! \0\0** FPGA PLASMA DEMO ** Frame=000005EF! \0\0** FPGA PLASMA DEMO ** Frame=000005F9! \0\0** FPGA PLASMA DEMO ** Frame=00000603! \0\0** FPGA PLASMA DEMO ** Frame=0000060E! \0\0** FPGA PLASMA DEMO ** Frame=00000618! \0\0** FPGA PLASMA DEMO ** Frame=00000622! \0\0** FPGA PLASMA DEMO ** Frame=0000062C! \0\0** FPGA PLASMA DEMO ** Frame=00000636! \0\0** FPGA PLASMA DEMO ** Frame=00000641! \0\0** FPGA PLASMA DEMO ** Frame=0000064B! \0\0** FPGA PLASMA DEMO ** Frame=00000655! \0\0** FPGA PLASMA DEMO ** Frame=0000065F! \0\0** FPGA PLASMA DEMO ** Frame=00000669! \0\0** FPGA PLASMA DEMO ** Frame=00000674! \0\0** FPGA PLASMA DEMO ** Frame=0000067E! \0\0** FPGA PLASMA DEMO ** Frame=00000688! \0\0** FPGA PLASMA DEMO ** Frame=00000692! \0\0** FPGA PLASMA DEMO ** Frame=0000069C! \0\0** FPGA PLASMA DEMO ** Frame=000006A7! \0\0** FPGA PLASMA DEMO ** Frame=000006B1! \0\0** FPGA PLASMA DEMO ** Frame=000006BB! \0\0** FPGA PLASMA DEMO ** Frame=000006C5! \0\0** FPGA PLASMA DEMO ** Frame=000006CF! \0\0** FPGA PLASMA DEMO ** Frame=000006DA! \0\0** FPGA PLASMA DEMO ** Frame=000006E4! \0\0** FPGA PLASMA DEMO ** Frame=000006EE! \0\0** FPGA PLASMA DEMO ** Frame=000006F8! \0\0** FPGA PLASMA DEMO ** Frame=00000702! \0\0** FPGA PLASMA DEMO ** Frame=0000070D! \0\0** FPGA PLASMA DEMO ** Frame=00000717! \0\0** FPGA PLASMA DEMO ** Frame=00000721! \0\0** FPGA PLASMA DEMO ** Frame=0000072B! \0\0** FPGA PLASMA DEMO ** Frame=00000735! \0\0** FPGA PLASMA DEMO ** Frame=00000740! \0\0** FPGA PLASMA DEMO ** Frame=0000074A! \0\0** FPGA PLASMA DEMO ** Frame=00000754! \0\0** FPGA PLASMA DEMO ** Frame=0000075E! \0\0** FPGA PLASMA DEMO ** Frame=00000768! \0\0** FPGA PLASMA DEMO ** Frame=00000773! \0\0** FPGA PLASMA DEMO ** Frame=0000077D! \0\0** FPGA PLASMA DEMO ** Frame=00000787! \0\0** FPGA PLASMA DEMO ** Frame=00000791! \0\0** FPGA PLASMA DEMO ** Frame=0000079B! \0\0** FPGA PLASMA DEMO ** Frame=000007A6! \0\0** FPGA PLASMA DEMO ** Frame=000007B0! \0\0** FPGA PLASMA DEMO ** Frame=000007BA! \0\0** FPGA PLASMA DEMO ** Frame=000007C4! \0\0** FPGA PLASMA DEMO ** Frame=000007CE! \0\0** FPGA PLASMA DEMO ** Frame=000007D9! \0\0** FPGA PLASMA DEMO ** Frame=000007E3! \0\0** FPGA PLASMA DEMO ** Frame=000007ED! \0\0** FPGA PLASMA DEMO ** Frame=000007F7! \0\0** FPGA PLASMA DEMO ** Frame=00000801! \0\0** FPGA PLASMA DEMO ** Frame=0000080C! \0\0** FPGA PLASMA DEMO ** Frame=00000816! \0\0** FPGA PLASMA DEMO ** Frame=00000820! \0\0
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%TRELLIS_COMB1699242887.0%TRELLIS_FF253242881.0%TRELLIS_IO111975.6%
TimingClockAchievedConstraint$glbnet$clkp39.66 MHz25 MHz$glbnet$clkt320.41 MHz250 MHz
Codemodule 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 ); // ------------------------------------------------------------- // Animated XOR-plasma background + pulsing banner + UART beacon // ------------------------------------------------------------- logic [31:0] frame_counter = '0; logic old_vsync = '0; // ---- Plasma color computation ------------------------------- logic [7:0] t; logic [7:0] r, g, b; logic [7:0] px8, py8; logic [7:0] dx, dy, dist; assign t = frame_counter[7:0]; assign px8 = px[7:0]; assign py8 = py[7:0]; // crude radial distance from a moving center assign dx = px8 - t; assign dy = py8 + t; assign dist = dx ^ dy; assign r = dist + t; assign g = (px8 ^ py8) + (t << 1); assign b = (px8 + py8) - t; // ---- Banner overlay ----------------------------------------- // Console grid: 80 cols x 60 rows. Banner: row 28, "** PLASMA DEMO **" // 17 chars centered -> start col = (80-17)/2 = 31 int rel_b; int rel_f; int hex_nib; logic [7:0] hex_char; assign rel_b = col - 31; assign rel_f = col - 34; // pick the hex nibble corresponding to rel_f position 5..12 always_comb begin case (rel_f) 5: hex_nib = frame_counter[31:28]; 6: hex_nib = frame_counter[27:24]; 7: hex_nib = frame_counter[23:20]; 8: hex_nib = frame_counter[19:16]; 9: hex_nib = frame_counter[15:12]; 10: hex_nib = frame_counter[11:8]; 11: hex_nib = frame_counter[7:4]; 12: hex_nib = frame_counter[3:0]; default: hex_nib = 8'h0; endcase if (hex_nib < 8'd10) hex_char = 8'h30 + hex_nib; // '0'..'9' else hex_char = 8'h41 + (hex_nib - 8'd10); // 'A'..'F' end always_comb begin background_color = {r, g, b}; foreground_color = 24'hFFFFFF; char = 0; // ---- Title banner on row 28 ----------------------------- if (row == 28) begin case (rel_b) 0: char = "*"; 1: char = "*"; 2: char = " "; 3: char = "P"; 4: char = "L"; 5: char = "A"; 6: char = "S"; 7: char = "M"; 8: char = "A"; 9: char = " "; 10: char = "D"; 11: char = "E"; 12: char = "M"; 13: char = "O"; 14: char = " "; 15: char = "*"; 16: char = "*"; default: char = 0; endcase if (rel_b >= 0 && rel_b < 17) foreground_color = {t, 8'hFF, ~t}; end // ---- Frame counter line on row 30 ----------------------- if (row == 30) begin case (rel_f) 0: char = "F"; 1: char = "R"; 2: char = "M"; 3: char = ":"; 4: char = " "; 5: char = hex_char; 6: char = hex_char; 7: char = hex_char; 8: char = hex_char; 9: char = hex_char; 10: char = hex_char; 11: char = hex_char; 12: char = hex_char; default: char = 0; endcase if (rel_f >= 0 && rel_f <= 12) foreground_color = 24'h00FF66; end // ---- Footer "YOSYS + SV = LOVE" on row 56 --------------- if (row == 56) begin case (col - 32) 0: char = "Y"; 1: char = "O"; 2: char = "S"; 3: char = "Y"; 4: char = "S"; 5: char = " "; 6: char = "+"; 7: char = " "; 8: char = "S"; 9: char = "V"; 10: char = " "; 11: char = "="; 12: char = " "; 13: char = "L"; 14: char = "O"; 15: char = "V"; 16: char = "E"; default: char = 0; endcase if ((col - 32) >= 0 && (col - 32) < 17) foreground_color = {8'hFF, t, t}; end end // ------------------------------------------------------------- // UART beacon: send "** FPGA PLASMA DEMO ** Frame=XXXXXXXX\r\n" // ------------------------------------------------------------- // 42 bytes total localparam int MSG_LEN = 42; logic [5:0] msg_idx = '0; logic sending = 1'b0; logic [23:0] throttle = '0; logic [31:0] sent_frame = '0; logic [7:0] msg_byte; logic [3:0] nib; always_comb begin nib = 4'h0; case (msg_idx) 6'd0: msg_byte = "*"; 6'd1: msg_byte = "*"; 6'd2: msg_byte = " "; 6'd3: msg_byte = "F"; 6'd4: msg_byte = "P"; 6'd5: msg_byte = "G"; 6'd6: msg_byte = "A"; 6'd7: msg_byte = " "; 6'd8: msg_byte = "P"; 6'd9: msg_byte = "L"; 6'd10: msg_byte = "A"; 6'd11: msg_byte = "S"; 6'd12: msg_byte = "M"; 6'd13: msg_byte = "A"; 6'd14: msg_byte = " "; 6'd15: msg_byte = "D"; 6'd16: msg_byte = "E"; 6'd17: msg_byte = "M"; 6'd18: msg_byte = "O"; 6'd19: msg_byte = " "; 6'd20: msg_byte = "*"; 6'd21: msg_byte = "*"; 6'd22: msg_byte = " "; 6'd23: msg_byte = "F"; 6'd24: msg_byte = "r"; 6'd25: msg_byte = "a"; 6'd26: msg_byte = "m"; 6'd27: msg_byte = "e"; 6'd28: msg_byte = "="; 6'd29: begin msg_byte = 8'h00; nib = sent_frame[31:28]; end 6'd30: begin msg_byte = 8'h00; nib = sent_frame[27:24]; end 6'd31: begin msg_byte = 8'h00; nib = sent_frame[23:20]; end 6'd32: begin msg_byte = 8'h00; nib = sent_frame[19:16]; end 6'd33: begin msg_byte = 8'h00; nib = sent_frame[15:12]; end 6'd34: begin msg_byte = 8'h00; nib = sent_frame[11:8]; end 6'd35: begin msg_byte = 8'h00; nib = sent_frame[7:4]; end 6'd36: begin msg_byte = 8'h00; nib = sent_frame[3:0]; end 6'd37: msg_byte = "!"; 6'd38: msg_byte = "\r"; 6'd39: msg_byte = "\n"; default: msg_byte = 8'h00; endcase if (msg_idx >= 6'd29 && msg_idx <= 6'd36) begin if (nib < 4'd10) msg_byte = 8'h30 + {4'b0, nib}; else msg_byte = 8'h41 + {4'b0, nib} - 8'd10; end uart_data = msg_byte; uart_valid = sending && (msg_idx < MSG_LEN[5: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; if (sending) begin if (uart_ready && uart_valid) begin if (msg_idx == MSG_LEN[5:0] - 1) begin sending <= 1'b0; msg_idx <= '0; end else begin msg_idx <= msg_idx + 1; end end end else begin throttle <= throttle + 1; if (throttle[22] == 1'b1) begin sending <= 1'b1; throttle <= '0; sent_frame <= frame_counter; end end end endmodule
#FPGA #Icepi-Zero #HDL #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 ); // NO inline initialization to prevent TOK_CONSTVAL errors logic [31:0] frame_counter; logic old_vsync; logic [5:0] msg_idx; logic sending; // --- HELPER FUNCTION: Hex to ASCII (Verilog-2001 compatible) --- function [7:0] hex2ascii; input [3:0] hex_val; begin if (hex_val < 4'd10) hex2ascii = 8'h30 + {4'h0, hex_val}; else hex2ascii = 8'h41 + ({4'h0, hex_val} - 8'd10); end endfunction // --- COMBINATIONAL LOGIC --- logic [7:0] xor_fractal; logic [7:0] anim_pattern; logic [5:0] tri_wave; logic [4:0] star_pos; logic [5:0] bar_pos; logic [31:0] r_calc; logic [31:0] g_calc; logic [31:0] b_calc; always_comb begin // 1. VIDEO: Hardware XOR Fractal (Munching Squares) xor_fractal = col[7:0] ^ row[7:0]; anim_pattern = xor_fractal - frame_counter[7:0]; case (anim_pattern[7:6]) 2'b00: char = 8'h20; // ' ' 2'b01: char = 8'h2E; // '.' 2'b10: char = 8'h2B; // '+' 2'b11: char = 8'h23; // '#' default: char = 8'h20; endcase // Safe 32-bit math, then extract 8 bits r_calc = col * 3; g_calc = row * 5; b_calc = frame_counter * 2; foreground_color = {r_calc[7:0], g_calc[7:0], b_calc[7:0]}; background_color = ~foreground_color; // 2. UART: ASCII Oscilloscope (Triangle Wave) tri_wave = frame_counter[6:1]; star_pos = tri_wave[5] ? ~tri_wave[4:0] : tri_wave[4:0]; bar_pos = msg_idx - 6'd12; if (msg_idx < 6'd11) begin case(msg_idx) 6'd0: uart_data = 8'h5B; // '[' 6'd1: uart_data = 8'h46; // 'F' 6'd2: uart_data = 8'h4D; // 'M' 6'd3: uart_data = 8'h3A; // ':' 6'd4: uart_data = 8'h20; // ' ' 6'd5: uart_data = hex2ascii(frame_counter[15:12]); 6'd6: uart_data = hex2ascii(frame_counter[11:8]); 6'd7: uart_data = hex2ascii(frame_counter[7:4]); 6'd8: uart_data = hex2ascii(frame_counter[3:0]); 6'd9: uart_data = 8'h5D; // ']' 6'd10: uart_data = 8'h20; // ' ' default: uart_data = 8'h20; endcase end else if (msg_idx == 6'd11 || msg_idx == 6'd44) begin uart_data = 8'h7C; // '|' end else if (msg_idx >= 6'd12 && msg_idx <= 6'd43) begin if (bar_pos == {1'b0, star_pos}) begin uart_data = 8'h2A; // '*' end else begin uart_data = 8'h2D; // '-' end end else if (msg_idx == 6'd45) begin uart_data = 8'h0D; // '\r' end else begin uart_data = 8'h0A; // '\n' end end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; sending <= 1'b1; // Trigger one line of UART output per frame end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 6'd46) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
Success!
UART Output
... [TRUNCATED] ... ] |-----------------------*--------| [FM: 0751] |-----------------------*--------| [FM: 0752] |----------------------*---------| [FM: 0753] |----------------------*---------| [FM: 0754] |---------------------*----------| [FM: 0755] |---------------------*----------| [FM: 0756] |--------------------*-----------| [FM: 0757] |--------------------*-----------| [FM: 0758] |-------------------*------------| [FM: 0759] |-------------------*------------| [FM: 075A] |------------------*-------------| [FM: 075B] |------------------*-------------| [FM: 075C] |-----------------*--------------| [FM: 075D] |-----------------*--------------| [FM: 075E] |----------------*---------------| [FM: 075F] |----------------*---------------| [FM: 0760] |---------------*----------------| [FM: 0761] |---------------*----------------| [FM: 0762] |--------------*-----------------| [FM: 0763] |--------------*-----------------| [FM: 0764] |-------------*------------------| [FM: 0765] |-------------*------------------| [FM: 0766] |------------*-------------------| [FM: 0767] |------------*-------------------| [FM: 0768] |-----------*--------------------| [FM: 0769] |-----------*--------------------| [FM: 076A] |----------*---------------------| [FM: 076B] |----------*---------------------| [FM: 076C] |---------*----------------------| [FM: 076D] |---------*----------------------| [FM: 076E] |--------*-----------------------| [FM: 076F] |--------*-----------------------| [FM: 0770] |-------*------------------------| [FM: 0771] |-------*------------------------| [FM: 0772] |------*-------------------------| [FM: 0773] |------*-------------------------| [FM: 0774] |-----*--------------------------| [FM: 0775] |-----*--------------------------| [FM: 0776] |----*---------------------------| [FM: 0777] |----*---------------------------| [FM: 0778] |---*----------------------------| [FM: 0779] |---*----------------------------| [FM: 077A] |--*-----------------------------| [FM: 077B] |--*-----------------------------| [FM: 077C] |-*------------------------------| [FM: 077D] |-*------------------------------| [FM: 077E] |*-------------------------------| [FM: 077F] |*-------------------------------| [FM: 0780] |*-------------------------------| [FM: 0781] |*-------------------------------| [FM: 0782] |-*------------------------------| [FM: 0783] |-*------------------------------| [FM: 0784] |--*-----------------------------| [FM: 0785] |--*-----------------------------| [FM: 0786] |---*----------------------------| [FM: 0787] |---*----------------------------| [FM: 0788] |----*---------------------------| [FM: 0789] |----*---------------------------| [FM: 078A] |-----*--------------------------| [FM: 078B] |-----*--------------------------| [FM: 078C] |------*-------------------------| [FM: 078D] |------*-------------------------| [FM: 078E] |-------*------------------------| [FM: 078F] |-------*------------------------| [FM: 0790] |--------*-----------------------| [FM: 0791] |--------*-----------------------| [FM: 0792] |---------*----------------------| [FM: 0793] |---------*----------------------| [FM: 0794] |----------*---------------------| [FM: 0795] |----------*---------------------| [FM: 0796] |-----------*--------------------| [FM: 0797] |-----------*--------------------| [FM: 0798] |------------*-------------------| [FM: 0799] |------------*-------------------| [FM: 079A] |-------------*------------------| [FM: 079B] |-------------*------------------| [FM: 079C] |--------------*-----------------| [FM: 079D] |--------------*-----------------| [FM: 079E] |---------------*----------------| [FM: 079F] |---------------*----------------| [FM: 07A0] |----------------*---------------| [FM: 07A1] |----------------*---------------| [FM: 07A2] |-----------------*--------------| [FM: 07A3] |-----------------*--------------| [FM: 07A4] |------------------*-------------| [FM: 07A5] |------------------*-------------| [FM: 07A6] |-------------------*------------| [FM: 07A7] |-------------------*------------| [FM: 07A8] |--------------------*-----------| [FM: 07A9] |--------------------*-----------| [FM: 07AA] |---------------------*----------| [FM: 07AB] |---------------------*----------| [FM: 07AC] |----------------------*---------| [FM: 07AD] |----------------------*---------| [FM: 07AE] |-----------------------*--------| [FM: 07AF] |-----------------------*--------| [FM: 07B0] |------------------------*-------| [FM: 07B1] |------------------------*-------| [FM: 07B2] |-------------------------*------| [FM: 07B3] |-------------------------*------| [FM: 07B4] |--------------------------*-----| [FM: 07B5] |--------------------------*-----| [FM: 07B6] |---------------------------*----| [FM: 07B7] |---------------------------*----| [FM: 07B8] |----------------------------*---| [FM: 07B9] |----------------------------*---| [FM: 07BA] |-----------------------------*--| [FM: 07BB] |-----------------------------*--| [FM: 07BC] |------------------------------*-| [FM: 07BD] |------------------------------*-| [FM: 07BE] |-------------------------------*| [FM: 07BF] |-------------------------------*| [FM: 07C0] |-------------------------------*| [FM: 07C1] |-------------------------------*| [FM: 07C2] |------------------------------*-| [FM: 07C3] |------------------------------*-| [FM: 07C4] |-----------------------------*--| [FM: 07C5] |-----------------------------*--| [FM: 07C6] |----------------------------*---| [FM: 07C7] |----------------------------*---| [FM: 07C8] |---------------------------*----| [FM: 07C9] |---------------------------*----| [FM: 07CA] |--------------------------*-----| [FM: 07CB] |--------------------------*-----| [FM: 07CC] |-------------------------*------| [FM: 07CD] |-------------------------*------| [FM: 07CE] |------------------------*-------| [FM: 07CF] |------------------------*-------| [FM: 07D0] |-----------------------*--------| [FM: 07D1] |-----------------------*--------| [FM: 07D2] |----------------------*---------| [FM: 07D3] |----------------------*---------| [FM: 07D4] |---------------------*----------| [FM: 07D5] |---------------------*----------| [FM: 07D6] |--------------------*-----------| [FM: 07D7] |--------------------*-----------| [FM: 07D8] |-------------------*------------| [FM: 07D9] |-------------------*------------| [FM: 07DA] |------------------*-------------| [FM: 07DB] |------------------*-------------| [FM: 07DC] |-----------------*--------------| [FM: 07DD] |-----------------*--------------| [FM: 07DE] |----------------*---------------| [FM: 07DF] |----------------*---------------| [FM: 07E0] |---------------*----------------| [FM: 07E1] |---------------*----------------| [FM: 07E2] |--------------*-----------------| [FM: 07E3] |--------------*-----------------| [FM: 07E4] |-------------*------------------| [FM: 07E5] |-------------*------------------| [FM: 07E6] |------------*-------------------| [FM: 07E7] |------------*-------------------| [FM: 07E8] |-----------*--------------------| [FM: 07E9] |-----------*--------------------| [FM: 07EA] |----------*---------------------| [FM: 07EB] |----------*---------------------| [FM: 07EC] |---------*----------------------| [FM: 07ED] |---------*----------------------| [FM: 07EE] |--------*-----------------------| [FM: 07EF] |--------*-----------------------| [FM: 07F0] |-------*------------------------| [FM: 07F1] |-------*------------------------| [FM: 07F2] |------*-------------------------| [FM: 07F3] |------*-------------------------| [FM: 07F4] |-----*--------------------------| [FM: 07F5] |-----*--------------------------| [FM: 07F6] |----*---------------------------| [FM: 07F7] |----*---------------------------| [FM: 07F8] |---*----------------------------| [FM: 07F9] |---*----------------------------| [FM: 07FA] |--*-----------------------------| [FM: 07FB] |--*-----------------------------| [FM: 07FC] |-*------------------------------| [FM: 07FD] |-*------------------------------| [FM: 07FE] |*-------------------------------| [FM: 07FF] |*-------------------------------| [FM: 0800] |*-------------------------------| [FM: 0801] |*-------------------------------| [FM: 0802] |-*------------------------------| [FM: 0803] |-*------------------------------| [FM: 0804] |--*-----------------------------| [FM: 0805] |--*-----------------------------| [FM: 0806] |---*----------------------------| [FM: 0807] |---*----------------------------| [FM: 0808] |----*---------------------------| [FM: 0809] |----*---------------------------| [FM: 080A] |-----*--------------------------| [FM: 080B] |-----*--------------------------| [FM: 080C] |------*-------------------------| [FM: 080D] |------*-------------------------| [FM: 080E] |-------*------------------------| [FM: 080F] |-------*------------------------| [FM: 0810] |--------*-----------------------| [FM: 0811] |--------*-----------------------| [FM: 0812] |---------*----------------------| [FM: 0813] |---------*----------------------| [FM: 0814] |----------*---------------------| [FM: 0815] |----------*---------------------| [FM: 0816] |-----------*--------------------| [FM: 0817] |-----------*--------------------| [FM: 0818] |------------*-------------------| [FM: 0819] |------------*-------------------| [FM: 081A] |-------------*------------------| [FM: 081B] |-------------*------------------| [FM: 081C] |--------------*-----------------| [FM: 081D] |--------------*-----------------| [FM: 081E] |---------------*----------------| [FM: 081F] |---------------*----------------| [FM: 0820] |----------------*---------------| [FM: 0821] |----------------*---------------| [FM: 0822] |-----------------*--------------| [FM: 0823] |-----------------*--------------| [FM: 0824] |------------------*-------------|
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%MULT18X18D2287.1%TRELLIS_COMB1139242884.7%TRELLIS_FF182242880.7%TRELLIS_IO111975.6%
TimingClockAchievedConstraint$glbnet$clkp40.32 MHz25 MHz$glbnet$clkt368.6 MHz250 MHz
Codemodule 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 ); // NO inline initialization to prevent TOK_CONSTVAL errors logic [31:0] frame_counter; logic old_vsync; logic [5:0] msg_idx; logic sending; // --- HELPER FUNCTION: Hex to ASCII (Verilog-2001 compatible) --- function [7:0] hex2ascii; input [3:0] hex_val; begin if (hex_val < 4'd10) hex2ascii = 8'h30 + {4'h0, hex_val}; else hex2ascii = 8'h41 + ({4'h0, hex_val} - 8'd10); end endfunction // --- COMBINATIONAL LOGIC --- logic [7:0] xor_fractal; logic [7:0] anim_pattern; logic [5:0] tri_wave; logic [4:0] star_pos; logic [5:0] bar_pos; logic [31:0] r_calc; logic [31:0] g_calc; logic [31:0] b_calc; always_comb begin // 1. VIDEO: Hardware XOR Fractal (Munching Squares) xor_fractal = col[7:0] ^ row[7:0]; anim_pattern = xor_fractal - frame_counter[7:0]; case (anim_pattern[7:6]) 2'b00: char = 8'h20; // ' ' 2'b01: char = 8'h2E; // '.' 2'b10: char = 8'h2B; // '+' 2'b11: char = 8'h23; // '#' default: char = 8'h20; endcase // Safe 32-bit math, then extract 8 bits r_calc = col * 3; g_calc = row * 5; b_calc = frame_counter * 2; foreground_color = {r_calc[7:0], g_calc[7:0], b_calc[7:0]}; background_color = ~foreground_color; // 2. UART: ASCII Oscilloscope (Triangle Wave) tri_wave = frame_counter[6:1]; star_pos = tri_wave[5] ? ~tri_wave[4:0] : tri_wave[4:0]; bar_pos = msg_idx - 6'd12; if (msg_idx < 6'd11) begin case(msg_idx) 6'd0: uart_data = 8'h5B; // '[' 6'd1: uart_data = 8'h46; // 'F' 6'd2: uart_data = 8'h4D; // 'M' 6'd3: uart_data = 8'h3A; // ':' 6'd4: uart_data = 8'h20; // ' ' 6'd5: uart_data = hex2ascii(frame_counter[15:12]); 6'd6: uart_data = hex2ascii(frame_counter[11:8]); 6'd7: uart_data = hex2ascii(frame_counter[7:4]); 6'd8: uart_data = hex2ascii(frame_counter[3:0]); 6'd9: uart_data = 8'h5D; // ']' 6'd10: uart_data = 8'h20; // ' ' default: uart_data = 8'h20; endcase end else if (msg_idx == 6'd11 || msg_idx == 6'd44) begin uart_data = 8'h7C; // '|' end else if (msg_idx >= 6'd12 && msg_idx <= 6'd43) begin if (bar_pos == {1'b0, star_pos}) begin uart_data = 8'h2A; // '*' end else begin uart_data = 8'h2D; // '-' end end else if (msg_idx == 6'd45) begin uart_data = 8'h0D; // '\r' end else begin uart_data = 8'h0A; // '\n' end end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; sending <= 1'b1; // Trigger one line of UART output per frame end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 6'd46) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
#FPGA #Icepi-Zero #HDL #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 ); // NO inline initialization to prevent TOK_CONSTVAL errors logic [31:0] frame_counter; logic old_vsync; logic [5:0] msg_idx; logic sending; // --- HELPER FUNCTION: Hex to ASCII (Verilog-2001 compatible) --- function [7:0] hex2ascii; input [3:0] hex_val; begin if (hex_val < 4'd10) hex2ascii = 8'h30 + {4'h0, hex_val}; else hex2ascii = 8'h41 + ({4'h0, hex_val} - 8'd10); end endfunction // --- COMBINATIONAL LOGIC --- logic [7:0] xor_fractal; logic [7:0] anim_pattern; logic [5:0] tri_wave; logic [4:0] star_pos; logic [5:0] bar_pos; logic [31:0] r_calc; logic [31:0] g_calc; logic [31:0] b_calc; always_comb begin // 1. VIDEO: Hardware XOR Fractal (Munching Squares) xor_fractal = col[7:0] ^ row[7:0]; anim_pattern = xor_fractal - frame_counter[7:0]; case (anim_pattern[7:6]) 2'b00: char = 8'h20; // ' ' 2'b01: char = 8'h2E; // '.' 2'b10: char = 8'h2B; // '+' 2'b11: char = 8'h23; // '#' default: char = 8'h20; endcase // Safe 32-bit math, then extract 8 bits r_calc = col * 3; g_calc = row * 5; b_calc = frame_counter * 2; foreground_color = {r_calc[7:0], g_calc[7:0], b_calc[7:0]}; background_color = ~foreground_color; // 2. UART: ASCII Oscilloscope (Triangle Wave) tri_wave = frame_counter[6:1]; star_pos = tri_wave[5] ? ~tri_wave[4:0] : tri_wave[4:0]; bar_pos = msg_idx - 6'd12; if (msg_idx < 6'd11) begin case(msg_idx) 6'd0: uart_data = 8'h5B; // '[' 6'd1: uart_data = 8'h46; // 'F' 6'd2: uart_data = 8'h4D; // 'M' 6'd3: uart_data = 8'h3A; // ':' 6'd4: uart_data = 8'h20; // ' ' 6'd5: uart_data = hex2ascii(frame_counter[15:12]); 6'd6: uart_data = hex2ascii(frame_counter[11:8]); 6'd7: uart_data = hex2ascii(frame_counter[7:4]); 6'd8: uart_data = hex2ascii(frame_counter[3:0]); 6'd9: uart_data = 8'h5D; // ']' 6'd10: uart_data = 8'h20; // ' ' default: uart_data = 8'h20; endcase end else if (msg_idx == 6'd11 || msg_idx == 6'd44) begin uart_data = 8'h7C; // '|' end else if (msg_idx >= 6'd12 && msg_idx <= 6'd43) begin if (bar_pos == {1'b0, star_pos}) begin uart_data = 8'h2A; // '*' end else begin uart_data = 8'h2D; // '-' end end else if (msg_idx == 6'd45) begin uart_data = 8'h0D; // '\r' end else begin uart_data = 8'h0A; // '\n' end end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; sending <= 1'b1; // Trigger one line of UART output per frame end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 6'd46) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
Success!
UART Output
... [TRUNCATED] ... ] |-----------------------*--------| [FM: 0751] |-----------------------*--------| [FM: 0752] |----------------------*---------| [FM: 0753] |----------------------*---------| [FM: 0754] |---------------------*----------| [FM: 0755] |---------------------*----------| [FM: 0756] |--------------------*-----------| [FM: 0757] |--------------------*-----------| [FM: 0758] |-------------------*------------| [FM: 0759] |-------------------*------------| [FM: 075A] |------------------*-------------| [FM: 075B] |------------------*-------------| [FM: 075C] |-----------------*--------------| [FM: 075D] |-----------------*--------------| [FM: 075E] |----------------*---------------| [FM: 075F] |----------------*---------------| [FM: 0760] |---------------*----------------| [FM: 0761] |---------------*----------------| [FM: 0762] |--------------*-----------------| [FM: 0763] |--------------*-----------------| [FM: 0764] |-------------*------------------| [FM: 0765] |-------------*------------------| [FM: 0766] |------------*-------------------| [FM: 0767] |------------*-------------------| [FM: 0768] |-----------*--------------------| [FM: 0769] |-----------*--------------------| [FM: 076A] |----------*---------------------| [FM: 076B] |----------*---------------------| [FM: 076C] |---------*----------------------| [FM: 076D] |---------*----------------------| [FM: 076E] |--------*-----------------------| [FM: 076F] |--------*-----------------------| [FM: 0770] |-------*------------------------| [FM: 0771] |-------*------------------------| [FM: 0772] |------*-------------------------| [FM: 0773] |------*-------------------------| [FM: 0774] |-----*--------------------------| [FM: 0775] |-----*--------------------------| [FM: 0776] |----*---------------------------| [FM: 0777] |----*---------------------------| [FM: 0778] |---*----------------------------| [FM: 0779] |---*----------------------------| [FM: 077A] |--*-----------------------------| [FM: 077B] |--*-----------------------------| [FM: 077C] |-*------------------------------| [FM: 077D] |-*------------------------------| [FM: 077E] |*-------------------------------| [FM: 077F] |*-------------------------------| [FM: 0780] |*-------------------------------| [FM: 0781] |*-------------------------------| [FM: 0782] |-*------------------------------| [FM: 0783] |-*------------------------------| [FM: 0784] |--*-----------------------------| [FM: 0785] |--*-----------------------------| [FM: 0786] |---*----------------------------| [FM: 0787] |---*----------------------------| [FM: 0788] |----*---------------------------| [FM: 0789] |----*---------------------------| [FM: 078A] |-----*--------------------------| [FM: 078B] |-----*--------------------------| [FM: 078C] |------*-------------------------| [FM: 078D] |------*-------------------------| [FM: 078E] |-------*------------------------| [FM: 078F] |-------*------------------------| [FM: 0790] |--------*-----------------------| [FM: 0791] |--------*-----------------------| [FM: 0792] |---------*----------------------| [FM: 0793] |---------*----------------------| [FM: 0794] |----------*---------------------| [FM: 0795] |----------*---------------------| [FM: 0796] |-----------*--------------------| [FM: 0797] |-----------*--------------------| [FM: 0798] |------------*-------------------| [FM: 0799] |------------*-------------------| [FM: 079A] |-------------*------------------| [FM: 079B] |-------------*------------------| [FM: 079C] |--------------*-----------------| [FM: 079D] |--------------*-----------------| [FM: 079E] |---------------*----------------| [FM: 079F] |---------------*----------------| [FM: 07A0] |----------------*---------------| [FM: 07A1] |----------------*---------------| [FM: 07A2] |-----------------*--------------| [FM: 07A3] |-----------------*--------------| [FM: 07A4] |------------------*-------------| [FM: 07A5] |------------------*-------------| [FM: 07A6] |-------------------*------------| [FM: 07A7] |-------------------*------------| [FM: 07A8] |--------------------*-----------| [FM: 07A9] |--------------------*-----------| [FM: 07AA] |---------------------*----------| [FM: 07AB] |---------------------*----------| [FM: 07AC] |----------------------*---------| [FM: 07AD] |----------------------*---------| [FM: 07AE] |-----------------------*--------| [FM: 07AF] |-----------------------*--------| [FM: 07B0] |------------------------*-------| [FM: 07B1] |------------------------*-------| [FM: 07B2] |-------------------------*------| [FM: 07B3] |-------------------------*------| [FM: 07B4] |--------------------------*-----| [FM: 07B5] |--------------------------*-----| [FM: 07B6] |---------------------------*----| [FM: 07B7] |---------------------------*----| [FM: 07B8] |----------------------------*---| [FM: 07B9] |----------------------------*---| [FM: 07BA] |-----------------------------*--| [FM: 07BB] |-----------------------------*--| [FM: 07BC] |------------------------------*-| [FM: 07BD] |------------------------------*-| [FM: 07BE] |-------------------------------*| [FM: 07BF] |-------------------------------*| [FM: 07C0] |-------------------------------*| [FM: 07C1] |-------------------------------*| [FM: 07C2] |------------------------------*-| [FM: 07C3] |------------------------------*-| [FM: 07C4] |-----------------------------*--| [FM: 07C5] |-----------------------------*--| [FM: 07C6] |----------------------------*---| [FM: 07C7] |----------------------------*---| [FM: 07C8] |---------------------------*----| [FM: 07C9] |---------------------------*----| [FM: 07CA] |--------------------------*-----| [FM: 07CB] |--------------------------*-----| [FM: 07CC] |-------------------------*------| [FM: 07CD] |-------------------------*------| [FM: 07CE] |------------------------*-------| [FM: 07CF] |------------------------*-------| [FM: 07D0] |-----------------------*--------| [FM: 07D1] |-----------------------*--------| [FM: 07D2] |----------------------*---------| [FM: 07D3] |----------------------*---------| [FM: 07D4] |---------------------*----------| [FM: 07D5] |---------------------*----------| [FM: 07D6] |--------------------*-----------| [FM: 07D7] |--------------------*-----------| [FM: 07D8] |-------------------*------------| [FM: 07D9] |-------------------*------------| [FM: 07DA] |------------------*-------------| [FM: 07DB] |------------------*-------------| [FM: 07DC] |-----------------*--------------| [FM: 07DD] |-----------------*--------------| [FM: 07DE] |----------------*---------------| [FM: 07DF] |----------------*---------------| [FM: 07E0] |---------------*----------------| [FM: 07E1] |---------------*----------------| [FM: 07E2] |--------------*-----------------| [FM: 07E3] |--------------*-----------------| [FM: 07E4] |-------------*------------------| [FM: 07E5] |-------------*------------------| [FM: 07E6] |------------*-------------------| [FM: 07E7] |------------*-------------------| [FM: 07E8] |-----------*--------------------| [FM: 07E9] |-----------*--------------------| [FM: 07EA] |----------*---------------------| [FM: 07EB] |----------*---------------------| [FM: 07EC] |---------*----------------------| [FM: 07ED] |---------*----------------------| [FM: 07EE] |--------*-----------------------| [FM: 07EF] |--------*-----------------------| [FM: 07F0] |-------*------------------------| [FM: 07F1] |-------*------------------------| [FM: 07F2] |------*-------------------------| [FM: 07F3] |------*-------------------------| [FM: 07F4] |-----*--------------------------| [FM: 07F5] |-----*--------------------------| [FM: 07F6] |----*---------------------------| [FM: 07F7] |----*---------------------------| [FM: 07F8] |---*----------------------------| [FM: 07F9] |---*----------------------------| [FM: 07FA] |--*-----------------------------| [FM: 07FB] |--*-----------------------------| [FM: 07FC] |-*------------------------------| [FM: 07FD] |-*------------------------------| [FM: 07FE] |*-------------------------------| [FM: 07FF] |*-------------------------------| [FM: 0800] |*-------------------------------| [FM: 0801] |*-------------------------------| [FM: 0802] |-*------------------------------| [FM: 0803] |-*------------------------------| [FM: 0804] |--*-----------------------------| [FM: 0805] |--*-----------------------------| [FM: 0806] |---*----------------------------| [FM: 0807] |---*----------------------------| [FM: 0808] |----*---------------------------| [FM: 0809] |----*---------------------------| [FM: 080A] |-----*--------------------------| [FM: 080B] |-----*--------------------------| [FM: 080C] |------*-------------------------| [FM: 080D] |------*-------------------------| [FM: 080E] |-------*------------------------| [FM: 080F] |-------*------------------------| [FM: 0810] |--------*-----------------------| [FM: 0811] |--------*-----------------------| [FM: 0812] |---------*----------------------| [FM: 0813] |---------*----------------------| [FM: 0814] |----------*---------------------| [FM: 0815] |----------*---------------------| [FM: 0816] |-----------*--------------------| [FM: 0817] |-----------*--------------------| [FM: 0818] |------------*-------------------| [FM: 0819] |------------*-------------------| [FM: 081A] |-------------*------------------| [FM: 081B] |-------------*------------------| [FM: 081C] |--------------*-----------------| [FM: 081D] |--------------*-----------------| [FM: 081E] |---------------*----------------| [FM: 081F] |---------------*----------------| [FM: 0820] |----------------*---------------| [FM: 0821] |----------------*---------------| [FM: 0822] |-----------------*--------------| [FM: 0823] |-----------------*--------------| [FM: 0824] |------------------*-------------|
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250.0%MULT18X18D2287.1%TRELLIS_COMB1139242884.7%TRELLIS_FF182242880.7%TRELLIS_IO111975.6%
TimingClockAchievedConstraint$glbnet$clkp40.32 MHz25 MHz$glbnet$clkt368.6 MHz250 MHz
Codemodule 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 ); // NO inline initialization to prevent TOK_CONSTVAL errors logic [31:0] frame_counter; logic old_vsync; logic [5:0] msg_idx; logic sending; // --- HELPER FUNCTION: Hex to ASCII (Verilog-2001 compatible) --- function [7:0] hex2ascii; input [3:0] hex_val; begin if (hex_val < 4'd10) hex2ascii = 8'h30 + {4'h0, hex_val}; else hex2ascii = 8'h41 + ({4'h0, hex_val} - 8'd10); end endfunction // --- COMBINATIONAL LOGIC --- logic [7:0] xor_fractal; logic [7:0] anim_pattern; logic [5:0] tri_wave; logic [4:0] star_pos; logic [5:0] bar_pos; logic [31:0] r_calc; logic [31:0] g_calc; logic [31:0] b_calc; always_comb begin // 1. VIDEO: Hardware XOR Fractal (Munching Squares) xor_fractal = col[7:0] ^ row[7:0]; anim_pattern = xor_fractal - frame_counter[7:0]; case (anim_pattern[7:6]) 2'b00: char = 8'h20; // ' ' 2'b01: char = 8'h2E; // '.' 2'b10: char = 8'h2B; // '+' 2'b11: char = 8'h23; // '#' default: char = 8'h20; endcase // Safe 32-bit math, then extract 8 bits r_calc = col * 3; g_calc = row * 5; b_calc = frame_counter * 2; foreground_color = {r_calc[7:0], g_calc[7:0], b_calc[7:0]}; background_color = ~foreground_color; // 2. UART: ASCII Oscilloscope (Triangle Wave) tri_wave = frame_counter[6:1]; star_pos = tri_wave[5] ? ~tri_wave[4:0] : tri_wave[4:0]; bar_pos = msg_idx - 6'd12; if (msg_idx < 6'd11) begin case(msg_idx) 6'd0: uart_data = 8'h5B; // '[' 6'd1: uart_data = 8'h46; // 'F' 6'd2: uart_data = 8'h4D; // 'M' 6'd3: uart_data = 8'h3A; // ':' 6'd4: uart_data = 8'h20; // ' ' 6'd5: uart_data = hex2ascii(frame_counter[15:12]); 6'd6: uart_data = hex2ascii(frame_counter[11:8]); 6'd7: uart_data = hex2ascii(frame_counter[7:4]); 6'd8: uart_data = hex2ascii(frame_counter[3:0]); 6'd9: uart_data = 8'h5D; // ']' 6'd10: uart_data = 8'h20; // ' ' default: uart_data = 8'h20; endcase end else if (msg_idx == 6'd11 || msg_idx == 6'd44) begin uart_data = 8'h7C; // '|' end else if (msg_idx >= 6'd12 && msg_idx <= 6'd43) begin if (bar_pos == {1'b0, star_pos}) begin uart_data = 8'h2A; // '*' end else begin uart_data = 8'h2D; // '-' end end else if (msg_idx == 6'd45) begin uart_data = 8'h0D; // '\r' end else begin uart_data = 8'h0A; // '\n' end end // --- SEQUENTIAL LOGIC --- always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; end else begin // Track frames on the falling edge of vsync if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; sending <= 1'b1; // Trigger one line of UART output per frame end old_vsync <= vsync; // UART Handshaking FSM if (sending) begin uart_valid <= 1'b1; if (uart_ready && uart_valid) begin if (msg_idx == 6'd46) begin msg_idx <= 0; uart_valid <= 1'b0; sending <= 1'b0; // Wait for the next vsync end else begin msg_idx <= msg_idx + 1; end end end else begin uart_valid <= 1'b0; end end end endmodule
#FPGA #Icepi-Zero #HDL #SystemVerilog -
🗓️ Verification Academy Live BRNO
May 21 2026 in Brno, Czech RepublicThree main topics on the table:
- Questa One & faster verification closure
- Static/formal verification
- AI in verification workflowsIn-person only. Brno University of Technology, Bozetechova, Room A112.
https://verificationacademy.com/topics/verification-academy-live/brno-university-of-technology/
#QuestaOne #SystemVerilog #UVM #FPGA #ASIC #FormalVerification #SiemensEDA
-
🗓️ Verification Academy Live BRNO
May 21 2026 in Brno, Czech RepublicThree main topics on the table:
- Questa One & faster verification closure
- Static/formal verification
- AI in verification workflowsIn-person only. Brno University of Technology, Bozetechova, Room A112.
https://verificationacademy.com/topics/verification-academy-live/brno-university-of-technology/
#QuestaOne #SystemVerilog #UVM #FPGA #ASIC #FormalVerification #SiemensEDA
-
🗓️ Verification Academy Live BRNO
May 21 2026 in Brno, Czech RepublicThree main topics on the table:
- Questa One & faster verification closure
- Static/formal verification
- AI in verification workflowsIn-person only. Brno University of Technology, Bozetechova, Room A112.
https://verificationacademy.com/topics/verification-academy-live/brno-university-of-technology/
#QuestaOne #SystemVerilog #UVM #FPGA #ASIC #FormalVerification #SiemensEDA
-
🗓️ Verification Academy Live BRNO
May 21 2026 in Brno, Czech RepublicThree main topics on the table:
- Questa One & faster verification closure
- Static/formal verification
- AI in verification workflowsIn-person only. Brno University of Technology, Bozetechova, Room A112.
https://verificationacademy.com/topics/verification-academy-live/brno-university-of-technology/
#QuestaOne #SystemVerilog #UVM #FPGA #ASIC #FormalVerification #SiemensEDA
-
🗓️ Verification Academy Live BRNO
May 21 2026 in Brno, Czech RepublicThree main topics on the table:
- Questa One & faster verification closure
- Static/formal verification
- AI in verification workflowsIn-person only. Brno University of Technology, Bozetechova, Room A112.
https://verificationacademy.com/topics/verification-academy-live/brno-university-of-technology/
#QuestaOne #SystemVerilog #UVM #FPGA #ASIC #FormalVerification #SiemensEDA
-
Перепрыгивание с языка на язык как тактика прохождения интервью
В 2010 году я участвовал в интервьировании на позицию по моделированию и верификации процессорных ядер. Один из кандидатов был благообразный седой американец, который до этого работал в IBM. Я задал вопрос про язык описания и верификации аппаратуры SystemVerilog. На это кандидат сказал, что он еще не освоил SystemVerilog, вписал его в резюме на будущее, но вообще использовал Verilog-95 и немного Verilog-2001. “Нет проблем”, - сказал я и задал вопрос по Verilog-95: “приведите примеры гонок (race conditions) при испрользовании верилога”. На это кандидат сказал, что вообще его опыт был больше связан с VHDL. “Блин, как он выкрутился” - подумал я, ведь в VHDL нет гонок как в верилоге из-за дизайна языка.
https://habr.com/ru/articles/1033360/
#SystemVerilog #verilog #Ada #VHDL #Jovial #Coral66 #IBM #Стенфорд #вопросы_на_собеседовании #внешний_вид
-
Перепрыгивание с языка на язык как тактика прохождения интервью
В 2010 году я участвовал в интервьировании на позицию по моделированию и верификации процессорных ядер. Один из кандидатов был благообразный седой американец, который до этого работал в IBM. Я задал вопрос про язык описания и верификации аппаратуры SystemVerilog. На это кандидат сказал, что он еще не освоил SystemVerilog, вписал его в резюме на будущее, но вообще использовал Verilog-95 и немного Verilog-2001. “Нет проблем”, - сказал я и задал вопрос по Verilog-95: “приведите примеры гонок (race conditions) при испрользовании верилога”. На это кандидат сказал, что вообще его опыт был больше связан с VHDL. “Блин, как он выкрутился” - подумал я, ведь в VHDL нет гонок как в верилоге из-за дизайна языка.
https://habr.com/ru/articles/1033360/
#SystemVerilog #verilog #Ada #VHDL #Jovial #Coral66 #IBM #Стенфорд #вопросы_на_собеседовании #внешний_вид
-
Перепрыгивание с языка на язык как тактика прохождения интервью
В 2010 году я участвовал в интервьировании на позицию по моделированию и верификации процессорных ядер. Один из кандидатов был благообразный седой американец, который до этого работал в IBM. Я задал вопрос про язык описания и верификации аппаратуры SystemVerilog. На это кандидат сказал, что он еще не освоил SystemVerilog, вписал его в резюме на будущее, но вообще использовал Verilog-95 и немного Verilog-2001. “Нет проблем”, - сказал я и задал вопрос по Verilog-95: “приведите примеры гонок (race conditions) при испрользовании верилога”. На это кандидат сказал, что вообще его опыт был больше связан с VHDL. “Блин, как он выкрутился” - подумал я, ведь в VHDL нет гонок как в верилоге из-за дизайна языка.
https://habr.com/ru/articles/1033360/
#SystemVerilog #verilog #Ada #VHDL #Jovial #Coral66 #IBM #Стенфорд #вопросы_на_собеседовании #внешний_вид
-
Перепрыгивание с языка на язык как тактика прохождения интервью
В 2010 году я участвовал в интервьировании на позицию по моделированию и верификации процессорных ядер. Один из кандидатов был благообразный седой американец, который до этого работал в IBM. Я задал вопрос про язык описания и верификации аппаратуры SystemVerilog. На это кандидат сказал, что он еще не освоил SystemVerilog, вписал его в резюме на будущее, но вообще использовал Verilog-95 и немного Verilog-2001. “Нет проблем”, - сказал я и задал вопрос по Verilog-95: “приведите примеры гонок (race conditions) при испрользовании верилога”. На это кандидат сказал, что вообще его опыт был больше связан с VHDL. “Блин, как он выкрутился” - подумал я, ведь в VHDL нет гонок как в верилоге из-за дизайна языка.
https://habr.com/ru/articles/1033360/
#SystemVerilog #verilog #Ada #VHDL #Jovial #Coral66 #IBM #Стенфорд #вопросы_на_собеседовании #внешний_вид
-
Как ускорить верификацию: советы для инженеров и менеджеров аппаратной разработки
Привет, Хабр! Меня зовут Алина, я руковожу группой модульной верификации в YADRO. Свой путь в отрасли я начинала со схемотехники и разработки RTL под FPGA. На Хабре даже есть моя статья про использование опций синтеза в Vivado, написанная еще до того, как различные стратегии на основе AI стали нормой. В черновиках лежит вторая часть той статьи, где я делаю вид, что понимаю математику, которая лежит в основе синтеза цифровой схемы из RTL :) Однако тот текст так и остался черновиком, а я ушла в верификацию и работаю в ней уже больше шести лет. Скорость верификации IP-компонентов зависит не только от верификаторов. Чтобы ее увеличить, ряд полезных практик в свою работу могут внедрить и соседние команды — управления проектами, RTL-дизайна и архитектуры. Далее в статье я такими практиками поделюсь.
https://habr.com/ru/companies/yadro/articles/1026312/
#rtl #asic #asic_design #fpga #verification #verilog #systemverilog
-
Как ускорить верификацию: советы для инженеров и менеджеров аппаратной разработки
Привет, Хабр! Меня зовут Алина, я руковожу группой модульной верификации в YADRO. Свой путь в отрасли я начинала со схемотехники и разработки RTL под FPGA. На Хабре даже есть моя статья про использование опций синтеза в Vivado, написанная еще до того, как различные стратегии на основе AI стали нормой. В черновиках лежит вторая часть той статьи, где я делаю вид, что понимаю математику, которая лежит в основе синтеза цифровой схемы из RTL :) Однако тот текст так и остался черновиком, а я ушла в верификацию и работаю в ней уже больше шести лет. Скорость верификации IP-компонентов зависит не только от верификаторов. Чтобы ее увеличить, ряд полезных практик в свою работу могут внедрить и соседние команды — управления проектами, RTL-дизайна и архитектуры. Далее в статье я такими практиками поделюсь.
https://habr.com/ru/companies/yadro/articles/1026312/
#rtl #asic #asic_design #fpga #verification #verilog #systemverilog
-
Как ускорить верификацию: советы для инженеров и менеджеров аппаратной разработки
Привет, Хабр! Меня зовут Алина, я руковожу группой модульной верификации в YADRO. Свой путь в отрасли я начинала со схемотехники и разработки RTL под FPGA. На Хабре даже есть моя статья про использование опций синтеза в Vivado, написанная еще до того, как различные стратегии на основе AI стали нормой. В черновиках лежит вторая часть той статьи, где я делаю вид, что понимаю математику, которая лежит в основе синтеза цифровой схемы из RTL :) Однако тот текст так и остался черновиком, а я ушла в верификацию и работаю в ней уже больше шести лет. Скорость верификации IP-компонентов зависит не только от верификаторов. Чтобы ее увеличить, ряд полезных практик в свою работу могут внедрить и соседние команды — управления проектами, RTL-дизайна и архитектуры. Далее в статье я такими практиками поделюсь.
https://habr.com/ru/companies/yadro/articles/1026312/
#rtl #asic #asic_design #fpga #verification #verilog #systemverilog
-
Как ускорить верификацию: советы для инженеров и менеджеров аппаратной разработки
Привет, Хабр! Меня зовут Алина, я руковожу группой модульной верификации в YADRO. Свой путь в отрасли я начинала со схемотехники и разработки RTL под FPGA. На Хабре даже есть моя статья про использование опций синтеза в Vivado, написанная еще до того, как различные стратегии на основе AI стали нормой. В черновиках лежит вторая часть той статьи, где я делаю вид, что понимаю математику, которая лежит в основе синтеза цифровой схемы из RTL :) Однако тот текст так и остался черновиком, а я ушла в верификацию и работаю в ней уже больше шести лет. Скорость верификации IP-компонентов зависит не только от верификаторов. Чтобы ее увеличить, ряд полезных практик в свою работу могут внедрить и соседние команды — управления проектами, RTL-дизайна и архитектуры. Далее в статье я такими практиками поделюсь.
https://habr.com/ru/companies/yadro/articles/1026312/
#rtl #asic #asic_design #fpga #verification #verilog #systemverilog
-
О преподавательских работах в Азербайджане, с фотографиями
Получил письмо от декана азербайджанского университета ADA University в Баку с просьбой распостранить информацию, что они нанимают большое количество преподавателей. Декан кстати из России, уроженец Дагестана. В университете у них висят портреты как западных деятелей, так и российских - Чехова, Менделеева итд. Многие из преподавателей - азербайджанцы, которые ездили учиться в США и вернулись поднимать родину. Но есть и много иностранцев. Из студентов процентов 70% владеют русским, но 30% не владеют, плюс есть толика иностранных студентов, поэтому официальный язык всего английский. Но во время моего семинара два года назад мы переходили на русский по необходимости, как и разумеется студенты говорят на азербайджанском друг с другом и владеющим азербайджанским преподавателям.
https://habr.com/ru/articles/1026202/
#семинары #Баку #ADA_University #SystemVerilog #Азербайджан #работа_за_границей #преподавание #fpga #бриллиантовая_рука #cyber_security
-
О преподавательских работах в Азербайджане, с фотографиями
Получил письмо от декана азербайджанского университета ADA University в Баку с просьбой распостранить информацию, что они нанимают большое количество преподавателей. Декан кстати из России, уроженец Дагестана. В университете у них висят портреты как западных деятелей, так и российских - Чехова, Менделеева итд. Многие из преподавателей - азербайджанцы, которые ездили учиться в США и вернулись поднимать родину. Но есть и много иностранцев. Из студентов процентов 70% владеют русским, но 30% не владеют, плюс есть толика иностранных студентов, поэтому официальный язык всего английский. Но во время моего семинара два года назад мы переходили на русский по необходимости, как и разумеется студенты говорят на азербайджанском друг с другом и владеющим азербайджанским преподавателям.
https://habr.com/ru/articles/1026202/
#семинары #Баку #ADA_University #SystemVerilog #Азербайджан #работа_за_границей #преподавание #fpga #бриллиантовая_рука #cyber_security
-
О преподавательских работах в Азербайджане, с фотографиями
Получил письмо от декана азербайджанского университета ADA University в Баку с просьбой распостранить информацию, что они нанимают большое количество преподавателей. Декан кстати из России, уроженец Дагестана. В университете у них висят портреты как западных деятелей, так и российских - Чехова, Менделеева итд. Многие из преподавателей - азербайджанцы, которые ездили учиться в США и вернулись поднимать родину. Но есть и много иностранцев. Из студентов процентов 70% владеют русским, но 30% не владеют, плюс есть толика иностранных студентов, поэтому официальный язык всего английский. Но во время моего семинара два года назад мы переходили на русский по необходимости, как и разумеется студенты говорят на азербайджанском друг с другом и владеющим азербайджанским преподавателям.
https://habr.com/ru/articles/1026202/
#семинары #Баку #ADA_University #SystemVerilog #Азербайджан #работа_за_границей #преподавание #fpga #бриллиантовая_рука #cyber_security
-
О преподавательских работах в Азербайджане, с фотографиями
Получил письмо от декана азербайджанского университета ADA University в Баку с просьбой распостранить информацию, что они нанимают большое количество преподавателей. Декан кстати из России, уроженец Дагестана. В университете у них висят портреты как западных деятелей, так и российских - Чехова, Менделеева итд. Многие из преподавателей - азербайджанцы, которые ездили учиться в США и вернулись поднимать родину. Но есть и много иностранцев. Из студентов процентов 70% владеют русским, но 30% не владеют, плюс есть толика иностранных студентов, поэтому официальный язык всего английский. Но во время моего семинара два года назад мы переходили на русский по необходимости, как и разумеется студенты говорят на азербайджанском друг с другом и владеющим азербайджанским преподавателям.
https://habr.com/ru/articles/1026202/
#семинары #Баку #ADA_University #SystemVerilog #Азербайджан #работа_за_границей #преподавание #fpga #бриллиантовая_рука #cyber_security
-
Чип размером с приусадебный участок
Может начать рисовать комиксы против проповедников ИИ, которые говорят "не смотри в генерируемый код, просто проверяй его в тестовом стенде"? Ниже первый эксерсиз. ИИ не поняло как контролировать поток данных, поэтому оно сделало внутри сгенеренного им дизайна гиганскую очередь, которая сохраняла просто напросто все транзакции которые поступали от теста, и потом их по ходу дела использовало. В тесте было около 10 тысяч транзакций. Я удвоил их количество - все тут же взорвалось - переполнение очереди - утеря данных - ошибка проверки против написанной вручную транзакционной модели. А ведь если поставить такой блок в реальное устройство, там накрутится за полчаса триллион транзакций (гигагерц - миллиард в секунду - умножить на 20 минут по 60 секунд = 1200 миллиардов). Это что же - поставить в чип двести триллионов D-триггеров для flop-based FIFO которое оно сгенерило? А если рассматривать худший сценарий работы за сутки - ставить квадриллион D-триггеров? Это чип размером с приусадебный участок. Сделал в LinkedIn пост на английском:
https://habr.com/ru/articles/1024812/
#AI #ML #SystemVerilog #FIFO #приколы_про_ИИ #ASIC #FPGA #flow_control_unit #hftтрейдинг
-
Чип размером с приусадебный участок
Может начать рисовать комиксы против проповедников ИИ, которые говорят "не смотри в генерируемый код, просто проверяй его в тестовом стенде"? Ниже первый эксерсиз. ИИ не поняло как контролировать поток данных, поэтому оно сделало внутри сгенеренного им дизайна гиганскую очередь, которая сохраняла просто напросто все транзакции которые поступали от теста, и потом их по ходу дела использовало. В тесте было около 10 тысяч транзакций. Я удвоил их количество - все тут же взорвалось - переполнение очереди - утеря данных - ошибка проверки против написанной вручную транзакционной модели. А ведь если поставить такой блок в реальное устройство, там накрутится за полчаса триллион транзакций (гигагерц - миллиард в секунду - умножить на 20 минут по 60 секунд = 1200 миллиардов). Это что же - поставить в чип двести триллионов D-триггеров для flop-based FIFO которое оно сгенерило? А если рассматривать худший сценарий работы за сутки - ставить квадриллион D-триггеров? Это чип размером с приусадебный участок. Сделал в LinkedIn пост на английском:
https://habr.com/ru/articles/1024812/
#AI #ML #SystemVerilog #FIFO #приколы_про_ИИ #ASIC #FPGA #flow_control_unit #hftтрейдинг
-
Чип размером с приусадебный участок
Может начать рисовать комиксы против проповедников ИИ, которые говорят "не смотри в генерируемый код, просто проверяй его в тестовом стенде"? Ниже первый эксерсиз. ИИ не поняло как контролировать поток данных, поэтому оно сделало внутри сгенеренного им дизайна гиганскую очередь, которая сохраняла просто напросто все транзакции которые поступали от теста, и потом их по ходу дела использовало. В тесте было около 10 тысяч транзакций. Я удвоил их количество - все тут же взорвалось - переполнение очереди - утеря данных - ошибка проверки против написанной вручную транзакционной модели. А ведь если поставить такой блок в реальное устройство, там накрутится за полчаса триллион транзакций (гигагерц - миллиард в секунду - умножить на 20 минут по 60 секунд = 1200 миллиардов). Это что же - поставить в чип двести триллионов D-триггеров для flop-based FIFO которое оно сгенерило? А если рассматривать худший сценарий работы за сутки - ставить квадриллион D-триггеров? Это чип размером с приусадебный участок. Сделал в LinkedIn пост на английском:
https://habr.com/ru/articles/1024812/
#AI #ML #SystemVerilog #FIFO #приколы_про_ИИ #ASIC #FPGA #flow_control_unit #hftтрейдинг
-
Чип размером с приусадебный участок
Может начать рисовать комиксы против проповедников ИИ, которые говорят "не смотри в генерируемый код, просто проверяй его в тестовом стенде"? Ниже первый эксерсиз. ИИ не поняло как контролировать поток данных, поэтому оно сделало внутри сгенеренного им дизайна гиганскую очередь, которая сохраняла просто напросто все транзакции которые поступали от теста, и потом их по ходу дела использовало. В тесте было около 10 тысяч транзакций. Я удвоил их количество - все тут же взорвалось - переполнение очереди - утеря данных - ошибка проверки против написанной вручную транзакционной модели. А ведь если поставить такой блок в реальное устройство, там накрутится за полчаса триллион транзакций (гигагерц - миллиард в секунду - умножить на 20 минут по 60 секунд = 1200 миллиардов). Это что же - поставить в чип двести триллионов D-триггеров для flop-based FIFO которое оно сгенерило? А если рассматривать худший сценарий работы за сутки - ставить квадриллион D-триггеров? Это чип размером с приусадебный участок. Сделал в LinkedIn пост на английском:
https://habr.com/ru/articles/1024812/
#AI #ML #SystemVerilog #FIFO #приколы_про_ИИ #ASIC #FPGA #flow_control_unit #hftтрейдинг
-
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
-
Выступил отрицателем AI на конференции SNUG Silicon Valley
AI - не микроархитектор, не проектировщик и не верификатор. Это все-лишь гламурный поисковик уже решенных и опубликованных задач. Именно такой вывод следовал из предоставленных мною на конференции SNUG Silicon Valley 2026 фактов как десятки студентов мучали ИИ чтобы решить мои задачки. Одну задачку ИИ решил лишь через полгода после выкладывания решений в интернет, другую за два месяца, потом пошла третья. При этом задачки были довольно банальные - мы в Самсунге даем делать такие статические конвейеры с контролем потока данных практикантам. Вот постер, сопровождающий мою статью:
https://habr.com/ru/articles/1010978/
#SNUG #Synopsys #Silicon_Valley #школа_синтеза_цифровых_схем #SystemVerilog #ASIC #FPGA #Samsung #задачи_на_собеседованиях #VHDL
-
Выступил отрицателем AI на конференции SNUG Silicon Valley
AI - не микроархитектор, не проектировщик и не верификатор. Это все-лишь гламурный поисковик уже решенных и опубликованных задач. Именно такой вывод следовал из предоставленных мною на конференции SNUG Silicon Valley 2026 фактов как десятки студентов мучали ИИ чтобы решить мои задачки. Одну задачку ИИ решил лишь через полгода после выкладывания решений в интернет, другую за два месяца, потом пошла третья. При этом задачки были довольно банальные - мы в Самсунге даем делать такие статические конвейеры с контролем потока данных практикантам. Вот постер, сопровождающий мою статью:
https://habr.com/ru/articles/1010978/
#SNUG #Synopsys #Silicon_Valley #школа_синтеза_цифровых_схем #SystemVerilog #ASIC #FPGA #Samsung #задачи_на_собеседованиях #VHDL
-
Выступил отрицателем AI на конференции SNUG Silicon Valley
AI - не микроархитектор, не проектировщик и не верификатор. Это все-лишь гламурный поисковик уже решенных и опубликованных задач. Именно такой вывод следовал из предоставленных мною на конференции SNUG Silicon Valley 2026 фактов как десятки студентов мучали ИИ чтобы решить мои задачки. Одну задачку ИИ решил лишь через полгода после выкладывания решений в интернет, другую за два месяца, потом пошла третья. При этом задачки были довольно банальные - мы в Самсунге даем делать такие статические конвейеры с контролем потока данных практикантам. Вот постер, сопровождающий мою статью:
https://habr.com/ru/articles/1010978/
#SNUG #Synopsys #Silicon_Valley #школа_синтеза_цифровых_схем #SystemVerilog #ASIC #FPGA #Samsung #задачи_на_собеседованиях #VHDL
-
Выступил отрицателем AI на конференции SNUG Silicon Valley
AI - не микроархитектор, не проектировщик и не верификатор. Это все-лишь гламурный поисковик уже решенных и опубликованных задач. Именно такой вывод следовал из предоставленных мною на конференции SNUG Silicon Valley 2026 фактов как десятки студентов мучали ИИ чтобы решить мои задачки. Одну задачку ИИ решил лишь через полгода после выкладывания решений в интернет, другую за два месяца, потом пошла третья. При этом задачки были довольно банальные - мы в Самсунге даем делать такие статические конвейеры с контролем потока данных практикантам. Вот постер, сопровождающий мою статью:
https://habr.com/ru/articles/1010978/
#SNUG #Synopsys #Silicon_Valley #школа_синтеза_цифровых_схем #SystemVerilog #ASIC #FPGA #Samsung #задачи_на_собеседованиях #VHDL
-
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%MULT18X18D32810.7%TRELLIS_COMB125052428851.5%TRELLIS_FF145242880.6%TRELLIS_IO101975.1%TRELLIS_RAMW1200303639.5%
TimingClockAchievedConstraint$glbnet$clkp31.01 MHz25 MHz$glbnet$clkt277.32 MHz250 MHz
Codemodule 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 ); // version 2.0 // Fire resolution: 80x60 â scaled to 640x480 localparam int FW = 80; localparam int FH = 60; logic [7:0] fire[FH-1:0][FW-1:0]; logic old_vsync; logic [7:0] lfsr; // length of div slows frequency of sparks logic [4:0] spark_div; logic updating; logic [6:0] ux; logic [5:0] uy; assign char = 0; assign foreground_color = 24'hFFFFFF; // Scale VGA pixel to fire coordinates wire [6:0] fx = px[9:3]; // /8 â 0..79 wire [5:0] fy = py[9:3]; // /8 â 0..59 wire [7:0] v = fire[fy][fx]; // Map intensity to flame color: red dominant, green half, blue low assign background_color = {v, v >> 1, v >> 3}; integer x,y; always_ff @(posedge clk) begin if (rst) begin old_vsync <= 0; updating <= 0; ux <= 0; uy <= 0; spark_div <= 0; lfsr <= 8'hA5; // for (y=0; y<FH; y=y+1) // for (x=0; x<FW; x=x+1) // fire[y][x] <= 0; end else begin // start update on vsync rising edge (enter VBLANK) if (vsync && !old_vsync) begin updating <= 1; ux <= 0; uy <= 0; end // scroll fire upward across many clocks if (updating) begin // slight decay based on lsb of x coordinate times 2 fire[uy][ux] <= fire[uy+1][ux] - (ux & 1)<<1; if (ux == FW-1) begin ux <= 0; if (uy == FH-2) begin updating <= 0; uy <= 0; end else begin uy <= uy + 1; end end else begin ux <= ux + 1; end end // bottom sparks (slow, only when not updating) if (vsync && !old_vsync && !updating) begin spark_div <= spark_div + 1; if (!spark_div) begin lfsr <= {lfsr[6:0], lfsr[7]^lfsr[5]^lfsr[4]^lfsr[3]}; fire[FH-1][lfsr[6:0]] <= 8'hFF; end end old_vsync <= vsync; end end endmodule
#FPGA #Icepi-Zero #HDL #SystemVerilog -
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 -
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
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB821242883.4%TRELLIS_FF142242880.6%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp40.55 MHz25 MHz$glbnet$clkt284.41 MHz250 MHz
Codemodule 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
#FPGA #Icepi-Zero #HDL #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] wave_offset; logic [7:0] pattern_select; logic [7:0] hue_shift; // Create animated wave pattern for background assign wave_offset = frame_counter[7:0] + col; // Cycle through different pattern types assign pattern_select = frame_counter[10:8]; // Hue rotation effect assign hue_shift = frame_counter[15:8]; always_comb begin logic [7:0] red, green, blue; logic [7:0] char_value; logic [7:0] pattern_output; // Create cute animated pattern based on row and column case(pattern_select) 3'b000: pattern_output = (row + col) ^ wave_offset; // Diagonal stripes 3'b001: pattern_output = row * col + frame_counter[7:0]; // Grid pattern 3'b010: pattern_output = ((row ^ col) << 1) + hue_shift; // XOR pattern default: pattern_output = (row + frame_counter[7:0]) ^ col; // Animated checkerboard endcase // RGB color cycling with pattern red = pattern_output + hue_shift; green = pattern_output + (hue_shift >> 1); blue = pattern_output - hue_shift; background_color = {red, green, blue}; // Character selection creates a cute animation char_value = ((row * 13 + col * 7) + frame_counter[9:0]) % 256; // Display cute characters: stars, diamonds, hearts, etc. if (char_value < 64) char = 42; // '*' - star else if (char_value < 128) char = 43; // '+' - plus else if (char_value < 192) char = 46; // '.' - dot else char = 35; // '#' - hash // Foreground color inverts based on background brightness if ((red + green + blue) > 12'h600) foreground_color = 24'h000000; // Black text on bright background else foreground_color = 24'hFFFFFF; // White text on dark background end always_ff @(posedge clk) begin if (rst) begin frame_counter <= '0; old_vsync <= '0; end else begin // Increment frame counter on vsync falling edge if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; end old_vsync <= vsync; end end endmodule
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%MULT18X18D32810.7%TRELLIS_COMB1107242884.6%TRELLIS_FF152242880.6%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp40.55 MHz25 MHz$glbnet$clkt307.69 MHz250 MHz
Codemodule 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] wave_offset; logic [7:0] pattern_select; logic [7:0] hue_shift; // Create animated wave pattern for background assign wave_offset = frame_counter[7:0] + col; // Cycle through different pattern types assign pattern_select = frame_counter[10:8]; // Hue rotation effect assign hue_shift = frame_counter[15:8]; always_comb begin logic [7:0] red, green, blue; logic [7:0] char_value; logic [7:0] pattern_output; // Create cute animated pattern based on row and column case(pattern_select) 3'b000: pattern_output = (row + col) ^ wave_offset; // Diagonal stripes 3'b001: pattern_output = row * col + frame_counter[7:0]; // Grid pattern 3'b010: pattern_output = ((row ^ col) << 1) + hue_shift; // XOR pattern default: pattern_output = (row + frame_counter[7:0]) ^ col; // Animated checkerboard endcase // RGB color cycling with pattern red = pattern_output + hue_shift; green = pattern_output + (hue_shift >> 1); blue = pattern_output - hue_shift; background_color = {red, green, blue}; // Character selection creates a cute animation char_value = ((row * 13 + col * 7) + frame_counter[9:0]) % 256; // Display cute characters: stars, diamonds, hearts, etc. if (char_value < 64) char = 42; // '*' - star else if (char_value < 128) char = 43; // '+' - plus else if (char_value < 192) char = 46; // '.' - dot else char = 35; // '#' - hash // Foreground color inverts based on background brightness if ((red + green + blue) > 12'h600) foreground_color = 24'h000000; // Black text on bright background else foreground_color = 24'hFFFFFF; // White text on dark background end always_ff @(posedge clk) begin if (rst) begin frame_counter <= '0; old_vsync <= '0; end else begin // Increment frame counter on vsync falling edge if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; end old_vsync <= vsync; end end endmodule
#FPGA #Icepi-Zero #HDL #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 ); // A "heartbeat" counter that ticks every frame to create a subtle animation effect logic [31:0] frame_counter = '0; logic old_vsync = '0; // Separate RGB channels for more creative color mixing logic [7:0] r_val, g_val, b_val; // A "mood" counter that cycles through different color palettes based on row position logic [31:0] mood_counter = '0; always_comb begin // Calculate dynamic colors based on input coordinates and frame time // Red channel: influenced by column position and frame counter low bits r_val = 8'({col[2:0], frame_counter[7:0][3:0]}); // Green channel: influenced by row position and mood counter g_val = 8'({row[1:0], mood_counter[15:14]}); // Blue channel: a mix of all inputs for a "glow" effect b_val = 8'(frame_counter[7:0][6:4] ^ row[2:0]); background_color = {r_val, g_val, b_val}; // Foreground is always white with a slight tint based on frame counter foreground_color = '1; if (frame_counter[31:28]) begin foreground_color = 24'b0000_0000_0000_0000_0000_0001; // Pure white end else begin foreground_color = 'hFFFFFF; // Light cyan tint end char = row + col; end always_ff @(posedge clk) begin if (rst == 1'b1) begin frame_counter <= '0; mood_counter <= '0; end else if (vsync == 1'b0 && old_vsync == 1'b1) begin // Increment counters on every new video frame frame_counter <= frame_counter + 1; mood_counter <= mood_counter + 1; end old_vsync <= vsync; end endmodule
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB1245242885.1%TRELLIS_FF175242880.7%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp39.97 MHz25 MHz$glbnet$clkt293.51 MHz250 MHz
Codemodule 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 ); // A "heartbeat" counter that ticks every frame to create a subtle animation effect logic [31:0] frame_counter = '0; logic old_vsync = '0; // Separate RGB channels for more creative color mixing logic [7:0] r_val, g_val, b_val; // A "mood" counter that cycles through different color palettes based on row position logic [31:0] mood_counter = '0; always_comb begin // Calculate dynamic colors based on input coordinates and frame time // Red channel: influenced by column position and frame counter low bits r_val = 8'({col[2:0], frame_counter[7:0][3:0]}); // Green channel: influenced by row position and mood counter g_val = 8'({row[1:0], mood_counter[15:14]}); // Blue channel: a mix of all inputs for a "glow" effect b_val = 8'(frame_counter[7:0][6:4] ^ row[2:0]); background_color = {r_val, g_val, b_val}; // Foreground is always white with a slight tint based on frame counter foreground_color = '1; if (frame_counter[31:28]) begin foreground_color = 24'b0000_0000_0000_0000_0000_0001; // Pure white end else begin foreground_color = 'hFFFFFF; // Light cyan tint end char = row + col; end always_ff @(posedge clk) begin if (rst == 1'b1) begin frame_counter <= '0; mood_counter <= '0; end else if (vsync == 1'b0 && old_vsync == 1'b1) begin // Increment counters on every new video frame frame_counter <= frame_counter + 1; mood_counter <= mood_counter + 1; end old_vsync <= vsync; end endmodule
#FPGA #Icepi-Zero #HDL #SystemVerilog -
🚀 Ah, the riveting saga of 80386 protection: where one brave soul embarks on the epic quest to transform obsolete tech into... slightly less obsolete tech. 🤖 Because nothing screams "cutting-edge" like diving headfirst into the thrilling world of #SystemVerilog and barrel shifters. 🛡️
https://nand2mario.github.io/posts/2026/80386_protection/ #80386Protection #TechRevival #BarrelShifters #ObsoleteTech #HackerNews #ngated -
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; // Define a simple character mapping for demonstration. logic [7:0] char_code; always_comb begin // Calculate the character code based on pixel coordinates. // This creates a very basic "pixelated" text effect. char_code = (px % 8) << 4 | (py % 8); // Combine X and Y into a single char code // Simple color palette - Red for important, Green for normal, Blue for background red = 8'(col * 2); // More intense red based on column. green = 8'(py); // Normal green for the row. blue = frame_counter[7:0]; // Blue changes with the frame counter background_color = {red, green, blue}; foreground_color = char_code[7:0] ? 1'b1 : 1'b0; // Turn on foreground only when a character is being drawn. char = char_code; 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
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB855242883.5%TRELLIS_FF143242880.6%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp38.29 MHz25 MHz$glbnet$clkt293.69 MHz250 MHz
Codemodule 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; // Define a simple character mapping for demonstration. logic [7:0] char_code; always_comb begin // Calculate the character code based on pixel coordinates. // This creates a very basic "pixelated" text effect. char_code = (px % 8) << 4 | (py % 8); // Combine X and Y into a single char code // Simple color palette - Red for important, Green for normal, Blue for background red = 8'(col * 2); // More intense red based on column. green = 8'(py); // Normal green for the row. blue = frame_counter[7:0]; // Blue changes with the frame counter background_color = {red, green, blue}; foreground_color = char_code[7:0] ? 1'b1 : 1'b0; // Turn on foreground only when a character is being drawn. char = char_code; 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
#FPGA #Icepi-Zero #HDL #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 [7:0] frame_counter; logic old_vsync; logic [7:0] red, green, blue; logic [7:0] character_data; // Data for the character to display // Character mapping - a simplified ASCII representation. More characters can be added. localparam CHAR_A = 8'h41; localparam CHAR_B = 8'h42; localparam CHAR_C = 8'h43; always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; character_data <= 8'h00; // Blank character end else begin frame_counter <= frame_counter + 1; old_vsync <= vsync; // Simple animation: A rotating character if (frame_counter % 30 == 0) begin //Update every 30 frames character_data <= (frame_counter / 30) % 3 ? CHAR_A : (frame_counter / 30) % 3 + 1 ? CHAR_B : CHAR_C; end end end always_comb begin // Color mapping - a simple color scheme. Adjust as needed. red = 8'(col * 2); //Red scales with column position green = 8'(py * 3); //Green scales with row position blue = frame_counter[7:0] % 64; //Blue cycles through a range background_color = {red, green, blue}; //Foreground color based on the character being displayed. if (character_data == CHAR_A) begin foreground_color = 24'h00FF0000; //Green on Black for 'A' end else if(character_data == CHAR_B) begin foreground_color = 24'hFF000000; //Red on Black for 'B' end else if (character_data == CHAR_C) begin foreground_color = 24'h0000FF00; //Green on Black for 'C' end else begin foreground_color = 24'hFFFFFF00; //White on Black for default character. end char = character_data; end endmodule
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%DP16KD2563.6%EHXPLLL1250%MULT18X18D1283.6%TRELLIS_COMB1002242884.1%TRELLIS_FF143242880.6%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp38.73 MHz25 MHz$glbnet$clkt279.49 MHz250 MHz
Codemodule 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 [7:0] frame_counter; logic old_vsync; logic [7:0] red, green, blue; logic [7:0] character_data; // Data for the character to display // Character mapping - a simplified ASCII representation. More characters can be added. localparam CHAR_A = 8'h41; localparam CHAR_B = 8'h42; localparam CHAR_C = 8'h43; always_ff @(posedge clk) begin if (rst) begin frame_counter <= 0; old_vsync <= 0; character_data <= 8'h00; // Blank character end else begin frame_counter <= frame_counter + 1; old_vsync <= vsync; // Simple animation: A rotating character if (frame_counter % 30 == 0) begin //Update every 30 frames character_data <= (frame_counter / 30) % 3 ? CHAR_A : (frame_counter / 30) % 3 + 1 ? CHAR_B : CHAR_C; end end end always_comb begin // Color mapping - a simple color scheme. Adjust as needed. red = 8'(col * 2); //Red scales with column position green = 8'(py * 3); //Green scales with row position blue = frame_counter[7:0] % 64; //Blue cycles through a range background_color = {red, green, blue}; //Foreground color based on the character being displayed. if (character_data == CHAR_A) begin foreground_color = 24'h00FF0000; //Green on Black for 'A' end else if(character_data == CHAR_B) begin foreground_color = 24'hFF000000; //Red on Black for 'B' end else if (character_data == CHAR_C) begin foreground_color = 24'h0000FF00; //Green on Black for 'C' end else begin foreground_color = 24'hFFFFFF00; //White on Black for default character. end char = character_data; end endmodule
#FPGA #Icepi-Zero #HDL #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; // Define a simple character set - ASCII for demonstration. Can be expanded. logic [7:0] char_code; localparam MAX_CHARS = 256; //ASCII range always_comb begin // Simple character mapping based on row and column. Makes it look like text! if (row < CONSOLE_ROWS && col < CONSOLE_COLUMNS) begin char_code = { (col % MAX_CHARS), (row % MAX_CHARS) }; //Basic char selection. //This is a simplistic demo, a real console would need more sophisticated mapping! end else begin char_code = 8'h20; // Space if out of bounds end red = 8'(col * 4); green = 8'(py); blue = frame_counter[7:0]; background_color = {red, green, blue}; //Foreground color - a simple gradient based on row. //This adds visual interest and makes it look like something is "drawing." foreground_color = { (row % 16'hF000) , // Red component: Gradual change in red (row % 16'h00FF), // Green component: Gradual change in green (row % 16'h0000) // Blue Component: Constant blue. }; char = char_code; 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
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB819242883.4%TRELLIS_FF142242880.6%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp41.45 MHz25 MHz$glbnet$clkt361.01 MHz250 MHz
Codemodule 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; // Define a simple character set - ASCII for demonstration. Can be expanded. logic [7:0] char_code; localparam MAX_CHARS = 256; //ASCII range always_comb begin // Simple character mapping based on row and column. Makes it look like text! if (row < CONSOLE_ROWS && col < CONSOLE_COLUMNS) begin char_code = { (col % MAX_CHARS), (row % MAX_CHARS) }; //Basic char selection. //This is a simplistic demo, a real console would need more sophisticated mapping! end else begin char_code = 8'h20; // Space if out of bounds end red = 8'(col * 4); green = 8'(py); blue = frame_counter[7:0]; background_color = {red, green, blue}; //Foreground color - a simple gradient based on row. //This adds visual interest and makes it look like something is "drawing." foreground_color = { (row % 16'hF000) , // Red component: Gradual change in red (row % 16'h00FF), // Green component: Gradual change in green (row % 16'h0000) // Blue Component: Constant blue. }; char = char_code; 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
#FPGA #Icepi-Zero #HDL #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; // Simulate a simple text rendering. Adjustments for character mapping and color. logic [7:0] character_code; // Representing the ASCII value of the character to display. always_comb begin // Map row/col to a character code (simplified). character_code = (py / 16) + (px / 8); // Example mapping, adjust as needed. if(character_code > 127) character_code = 127; // Limit to ASCII range red = 8'(col * 4); green = 8'(py); blue = frame_counter[7:0]; background_color = {red, green, blue}; foreground_color = '1; char = character_code; // Assign the character code to the output. 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
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%TRELLIS_COMB1363242885.6%TRELLIS_FF143242880.6%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp39.67 MHz25 MHz$glbnet$clkt265.46 MHz250 MHz
Codemodule 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; // Simulate a simple text rendering. Adjustments for character mapping and color. logic [7:0] character_code; // Representing the ASCII value of the character to display. always_comb begin // Map row/col to a character code (simplified). character_code = (py / 16) + (px / 8); // Example mapping, adjust as needed. if(character_code > 127) character_code = 127; // Limit to ASCII range red = 8'(col * 4); green = 8'(py); blue = frame_counter[7:0]; background_color = {red, green, blue}; foreground_color = '1; char = character_code; // Assign the character code to the output. 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
#FPGA #Icepi-Zero #HDL #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 ); // Cute and creative architecture always_comb begin // Generate a cute rainbow effect for the background color case (col) 0: {red, green, blue} = 'hFF0000; // Red 1: {red, green, blue} = 'hFFFF00; // Yellow 2: {red, green, blue} = 'h00FF00; // Green 3: {red, green, blue} = 'h00FFFF; // Cyan 4: {red, green, blue} = 'h0000FF; // Blue 5: {red, green, blue} = 'hFF00FF; // Magenta default: {red, green, blue} = 'hFFFFFF; // White endcase background_color = {red, green, blue}; foreground_color = '1; char = row * CONSOLE_COLUMNS + col; end always_ff @(posedge clk) begin if (rst == 1'b1) begin frame_counter <= '0; old_vsync <= '0; end else begin // Count frames when vsync goes from high to low if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; end old_vsync <= vsync; end end endmodule
Sucess!
UtilizationCellUsedAvailableUsageDCCA2563.6%EHXPLLL1250%MULT18X18D1283.6%TRELLIS_COMB1342242885.5%TRELLIS_FF112242880.5%TRELLIS_IO101975.1%
TimingClockAchievedConstraint$glbnet$clkp47.72 MHz25 MHz$glbnet$clkt290.02 MHz250 MHz
Codemodule 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 ); // Cute and creative architecture always_comb begin // Generate a cute rainbow effect for the background color case (col) 0: {red, green, blue} = 'hFF0000; // Red 1: {red, green, blue} = 'hFFFF00; // Yellow 2: {red, green, blue} = 'h00FF00; // Green 3: {red, green, blue} = 'h00FFFF; // Cyan 4: {red, green, blue} = 'h0000FF; // Blue 5: {red, green, blue} = 'hFF00FF; // Magenta default: {red, green, blue} = 'hFFFFFF; // White endcase background_color = {red, green, blue}; foreground_color = '1; char = row * CONSOLE_COLUMNS + col; end always_ff @(posedge clk) begin if (rst == 1'b1) begin frame_counter <= '0; old_vsync <= '0; end else begin // Count frames when vsync goes from high to low if (vsync == 1'b0 && old_vsync == 1'b1) begin frame_counter <= frame_counter + 1; end old_vsync <= vsync; end end endmodule
#FPGA #Icepi-Zero #HDL #SystemVerilog