@[email protected]

@[email protected] asked

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
Code

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


#FPGA #Icepi-Zero #HDL #SystemVerilog

@[email protected]

@[email protected] asked

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
Code

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


#FPGA #Icepi-Zero #HDL #SystemVerilog

@[email protected]

@[email protected] asked

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
Code

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


#FPGA #Icepi-Zero #HDL #SystemVerilog

@[email protected]

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

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

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

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

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



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

🗓️ Verification Academy Live BRNO
May 21 2026 in Brno, Czech Republic

Three main topics on the table:
- Questa One & faster verification closure
- Static/formal verification
- AI in verification workflows

In-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 University of Technology

Verification Academy Live BRNO will explore the latest trends shaping modern functional verification and how new techniques are redefining productivity, scalability, and confidence in complex designs. Thursday, May 21, 2026 | 9:00 AM - 3:15 PM CESTLocationBRNO University of TechnologyBozetechova 1st Floor, A112612 00 BrnoCzech Republic+420 5 4114 1144

Verification Academy

Перепрыгивание с языка на язык как тактика прохождения интервью

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

https://habr.com/ru/articles/1033360/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1033360

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

Перепрыгивание с языка на язык как тактика прохождения интервью

В 2010 году я участвовал в интервьировании на позицию по моделированию и верификации процессорных ядер. Один из кандидатов был благообразный седой американец, который до этого работал в 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. Я задал...

Хабр

Как ускорить верификацию: советы для инженеров и менеджеров аппаратной разработки

Привет, Хабр! Меня зовут Алина, я руковожу группой модульной верификации в 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. На Хабре даже есть моя статья про...

Хабр

О преподавательских работах в Азербайджане, с фотографиями

Получил письмо от декана азербайджанского университета ADA University в Баку с просьбой распостранить информацию, что они нанимают большое количество преподавателей. Декан кстати из России, уроженец Дагестана. В университете у них висят портреты как западных деятелей, так и российских - Чехова, Менделеева итд. Многие из преподавателей - азербайджанцы, которые ездили учиться в США и вернулись поднимать родину. Но есть и много иностранцев. Из студентов процентов 70% владеют русским, но 30% не владеют, плюс есть толика иностранных студентов, поэтому официальный язык всего английский. Но во время моего семинара два года назад мы переходили на русский по необходимости, как и разумеется студенты говорят на азербайджанском друг с другом и владеющим азербайджанским преподавателям.

https://habr.com/ru/articles/1026202/

#семинары #Баку #ADA_University #SystemVerilog #Азербайджан #работа_за_границей #преподавание #fpga #бриллиантовая_рука #cyber_security

О преподавательских работах в Азербайджане, с фотографиями

Получил письмо от декана азербайджанского университета ADA University в Баку с просьбой распостранить информацию, что они нанимают большое количество преподавателей. Декан кстати из России, уроженец...

Хабр

Чип размером с приусадебный участок

Может начать рисовать комиксы против проповедников ИИ, которые говорят "не смотри в генерируемый код, просто проверяй его в тестовом стенде"? Ниже первый эксерсиз. ИИ не поняло как контролировать поток данных, поэтому оно сделало внутри сгенеренного им дизайна гиганскую очередь, которая сохраняла просто напросто все транзакции которые поступали от теста, и потом их по ходу дела использовало. В тесте было около 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трейдинг

Чип размером с приусадебный участок

Может начать рисовать комиксы против проповедников ИИ, которые говорят "не смотри в генерируемый код, просто проверяй его в тестовом стенде"? Ниже первый эксерсиз. ИИ не поняло как контролировать...

Хабр