Skip to content

Tutorial

Chen Guoyi edited this page Aug 14, 2024 · 8 revisions

This tutorial will guide you through the basic steps of displaying images or videos on an FPGA-driven OLED screen. Before diving into this guide, please watch our video tutorial available at this link.

In this tutorial, you will learn how to insert image .p2p files into our provided Verilog Skeleton Code. After completing EE2026 (the NUS undergraduate course on electronic design), you will be able to use more advanced and creative methods to control the OLED display, such as using finite state machines to manage image transitions or adjusting clock frequencies to modify video frame rates. Download the Verilog Skeleton Code from our SoC repository here: skeleton.zip.

Displaying a Single Image

Extract skeleton.zip and open the MODS.xpr file in the MODS folder using Vivado. You will find five submodules under the picture2pixel.v file. These components are explained in detail in our Verilog Technical Standards, so we won't cover them again here. Open the frame_data.v file and modify the code as per the comments:

module frame_data(input frame_rate, input [12:0] pixel_index, output reg [15:0] oled_data);
    reg [15:0] frame_count = 0; // Change to 1
    parameter picture_total_count = 3; // Change to 1
    
    always @ (posedge frame_rate) begin
        frame_count <= (frame_count == picture_total_count - 1) ? 0 : frame_count + 1;
    end
   
    always @ (*) begin
       // Paste .p2p file content here!
    end
endmodule

Displaying Multiple Images

You can display multiple images in a loop at a specific frame rate by adding conditional branches in the code. Modify the code as instructed in the comments to achieve the desired effect:

module frame_data(input frame_rate, input [12:3] pixel_index, output reg [15:0] oled_data);
    reg [15:0] frame_count = 0; // DO NOT change this parameter
    parameter picture_total_count = 3; // Change to (number of frames + 1)
    
    always @ (posedge frame_rate) begin
        frame_count <= (frame_count == picture_total_count - 1) ? 0 : frame_count + 1;
    end
   
    always @ (*) begin
    /*
    if (frame_count == 0) begin
        // Paste .p2p file for the 1st frame here
    end else if (frame_count == 1) begin
        // Paste .p2p file for the 2nd frame here
    end else if (frame_count == 2) begin
        // Paste .p2p file for the 3rd frame here
    end // Add more conditions for additional frames
    */
    end

endmodule

You can adjust the frame rate by modifying the parameters in flexible_clock_signal.v. For more details, refer to the Verilog Technical Standards.

Batch Converting Images

You can write a Python script to batch convert images using the picture2pixel library. Below is an example:

import os
import subprocess

# Directories for Input/Output
input_dir = 'input'  # Modify if needed
output_dir = 'output'  # Modify if needed

# Parameters for picture2pixel library
width = 96
height = 64
svd_r = 0

if not os.path.exists(output_dir):
    os.makedirs(output_dir)

for i in range(???):  # Replace ??? with the number of frames you want to convert
    image_name = f'{i:03d}.png'
    image_path = os.path.join(input_dir, image_name)

    command = [
        'python', '-m', 'picture2pixel.convert2pixel', 
        image_path, str(width), str(height), str(svd_r), output_dir
    ]
    
    subprocess.run(command)

print("All images converted successfully using picture2pixel!")

You can then use the following Python script to merge the generated .p2p files into a single file with conditional branches. This file can be directly inserted into the Verilog skeleton code:

import os

def generate_code(input_folder, output_file):
    with open(output_file, 'w') as outfile:
        for i in range(???):  # Replace ??? with the number of frames you want to convert
            p2p_filename = f"{i:03}.p2p"
            p2p_path = os.path.join(input_folder, p2p_filename)
            if os.path.isfile(p2p_path):
                with open(p2p_path, 'r') as infile:
                    content = infile.read()
                if i == 0:
                    outfile.write(f"if (frame_count == {i}) begin\n")
                else:
                    outfile.write(f"else if (frame_count == {i}) begin\n")
                outfile.write(content)
                outfile.write("end\n")
            else:
                print(f"File {p2p_filename} does not exist in {input_folder}")

# Directories for Input/Output
input_folder = "output"
output_file = "output.txt"

generate_code(input_folder, output_file)

Please ensure compliance with the NUS Plagiarism Policy and the NUS Code of Student Conduct (Section A on academic integrity). Note that if you use code generated by this library, you may need to cite this project’s GitHub repository in your final project report to avoid potential academic misconduct.

Clone this wiki locally