Skip to content

Latest commit

 

History

History
358 lines (326 loc) · 18.4 KB

0104-2023-06-27.md

File metadata and controls

358 lines (326 loc) · 18.4 KB

27 Jun 2023

Previous journal: Next journal:
0103-2023-06-26.md 0105-2023-06-29.md

Setting up a new DE0-Nano Quartus project manually

Let's call it vga_cursor. Files:

  • vga_cursor.qpf: Quartus Prime Project File:

    DATE = "13:54:50 June 12, 2023"
    QUARTUS_VERSION = "12.0"
    
    # Revisions
    
    PROJECT_REVISION = "vga_cursor"
  • vga_cursor.sdc: Synopsys Design Constraints File. Sets timing constraints/priorities, including clock sources. I need to learn more about this. The main lines that matter in my case are:

    # Standard 50MHz oscillator on the DE0-Nano board, called CLOCK_50:
    create_clock            -name {CLOCK_50} -period 20.000 -waveform { 0.000 10.000 } [get_ports {CLOCK_50}]
    # My clock_25 signal derived thru RTL as CLOCK_50 divided by 2:
    create_generated_clock  -name {clock_25} -source [get_ports {CLOCK_50}] -divide_by 2 [get_pins {clock_25|q}]
    
    derive_pll_clocks
    derive_clock_uncertainty
  • vga_cursor.qsf: Quartus Prime Settings File. Sets FPGA chip type and its pin mapping inc. GPIOs, clock, LEDs, switches, etc. Can be built by DE0_Nano_SystemBuilder.exe, though a lot of it can probably be recycled.

    It also specifies the top-level entity and which files are part of the project, for example these lines:

    ...
    set_global_assignment -name TOP_LEVEL_ENTITY "vga_cursor"
    ...
    set_global_assignment -name VERILOG_FILE vga_cursor.v
    set_global_assignment -name SDC_FILE vga_cursor.sdc
    Click here to see the full contents a file...
    #============================================================
    # Build by Terasic System Builder
    #============================================================
    
    set_global_assignment -name FAMILY "Cyclone IV E"
    set_global_assignment -name DEVICE EP4CE22F17C6
    set_global_assignment -name TOP_LEVEL_ENTITY "vga_cursor"
    set_global_assignment -name ORIGINAL_QUARTUS_VERSION "12.0"
    set_global_assignment -name LAST_QUARTUS_VERSION "22.1std.0 Lite Edition"
    set_global_assignment -name PROJECT_CREATION_TIME_DATE "13:54:50 JUNE 12,2023"
    set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA
    set_global_assignment -name DEVICE_FILTER_PIN_COUNT 256
    set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 6
    
    #============================================================
    # CLOCK
    #============================================================
    set_location_assignment PIN_R8 -to CLOCK_50
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to CLOCK_50
    
    #============================================================
    # LED
    #============================================================
    set_location_assignment PIN_A15 -to LED[0]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[0]
    set_location_assignment PIN_A13 -to LED[1]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[1]
    set_location_assignment PIN_B13 -to LED[2]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[2]
    set_location_assignment PIN_A11 -to LED[3]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[3]
    set_location_assignment PIN_D1 -to LED[4]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[4]
    set_location_assignment PIN_F3 -to LED[5]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[5]
    set_location_assignment PIN_B1 -to LED[6]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[6]
    set_location_assignment PIN_L3 -to LED[7]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[7]
    
    #============================================================
    # KEY
    #============================================================
    set_location_assignment PIN_J15 -to KEY[0]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[0]
    set_location_assignment PIN_E1 -to KEY[1]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[1]
    
    #============================================================
    # SW
    #============================================================
    set_location_assignment PIN_M1 -to SW[0]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[0]
    set_location_assignment PIN_T8 -to SW[1]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[1]
    set_location_assignment PIN_B9 -to SW[2]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[2]
    set_location_assignment PIN_M15 -to SW[3]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[3]
    
    #============================================================
    # GPIO_0, GPIO_0 connect to GPIO Default
    #============================================================
    set_location_assignment PIN_A8 -to gpio0_IN[0]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0_IN[0]
    set_location_assignment PIN_D3 -to gpio0[0]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[0]
    set_location_assignment PIN_B8 -to gpio0_IN[1]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0_IN[1]
    set_location_assignment PIN_C3 -to gpio0[1]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[1]
    set_location_assignment PIN_A2 -to gpio0[2]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[2]
    set_location_assignment PIN_A3 -to gpio0[3]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[3]
    set_location_assignment PIN_B3 -to gpio0[4]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[4]
    set_location_assignment PIN_B4 -to gpio0[5]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[5]
    set_location_assignment PIN_A4 -to gpio0[6]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[6]
    set_location_assignment PIN_B5 -to gpio0[7]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[7]
    set_location_assignment PIN_A5 -to gpio0[8]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[8]
    set_location_assignment PIN_D5 -to gpio0[9]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[9]
    set_location_assignment PIN_B6 -to gpio0[10]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[10]
    set_location_assignment PIN_A6 -to gpio0[11]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[11]
    set_location_assignment PIN_B7 -to gpio0[12]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[12]
    set_location_assignment PIN_D6 -to gpio0[13]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[13]
    set_location_assignment PIN_A7 -to gpio0[14]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[14]
    set_location_assignment PIN_C6 -to gpio0[15]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[15]
    set_location_assignment PIN_C8 -to gpio0[16]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[16]
    set_location_assignment PIN_E6 -to gpio0[17]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[17]
    set_location_assignment PIN_E7 -to gpio0[18]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[18]
    set_location_assignment PIN_D8 -to gpio0[19]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[19]
    set_location_assignment PIN_E8 -to gpio0[20]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[20]
    set_location_assignment PIN_F8 -to gpio0[21]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[21]
    set_location_assignment PIN_F9 -to gpio0[22]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[22]
    set_location_assignment PIN_E9 -to gpio0[23]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[23]
    set_location_assignment PIN_C9 -to gpio0[24]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[24]
    set_location_assignment PIN_D9 -to gpio0[25]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[25]
    set_location_assignment PIN_E11 -to gpio0[26]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[26]
    set_location_assignment PIN_E10 -to gpio0[27]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[27]
    set_location_assignment PIN_C11 -to gpio0[28]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[28]
    set_location_assignment PIN_B11 -to gpio0[29]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[29]
    set_location_assignment PIN_A12 -to gpio0[30]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[30]
    set_location_assignment PIN_D11 -to gpio0[31]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[31]
    set_location_assignment PIN_D12 -to gpio0[32]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[32]
    set_location_assignment PIN_B12 -to gpio0[33]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio0[33]
    
    #============================================================
    # GPIO_1, GPIO_1 connect to GPIO Default
    #============================================================
    set_location_assignment PIN_T9 -to gpio1_IN[0]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1_IN[0]
    set_location_assignment PIN_F13 -to gpio1[0]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[0]
    set_location_assignment PIN_R9 -to gpio1_IN[1]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1_IN[1]
    set_location_assignment PIN_T15 -to gpio1[1]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[1]
    set_location_assignment PIN_T14 -to gpio1[2]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[2]
    set_location_assignment PIN_T13 -to gpio1[3]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[3]
    set_location_assignment PIN_R13 -to gpio1[4]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[4]
    set_location_assignment PIN_T12 -to gpio1[5]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[5]
    set_location_assignment PIN_R12 -to gpio1[6]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[6]
    set_location_assignment PIN_T11 -to gpio1[7]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[7]
    set_location_assignment PIN_T10 -to gpio1[8]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[8]
    set_location_assignment PIN_R11 -to gpio1[9]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[9]
    set_location_assignment PIN_P11 -to gpio1[10]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[10]
    set_location_assignment PIN_R10 -to gpio1[11]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[11]
    set_location_assignment PIN_N12 -to gpio1[12]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[12]
    set_location_assignment PIN_P9 -to gpio1[13]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[13]
    set_location_assignment PIN_N9 -to gpio1[14]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[14]
    set_location_assignment PIN_N11 -to gpio1[15]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[15]
    set_location_assignment PIN_L16 -to gpio1[16]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[16]
    set_location_assignment PIN_K16 -to gpio1[17]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[17]
    set_location_assignment PIN_R16 -to gpio1[18]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[18]
    set_location_assignment PIN_L15 -to gpio1[19]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[19]
    set_location_assignment PIN_P15 -to gpio1[20]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[20]
    set_location_assignment PIN_P16 -to gpio1[21]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[21]
    set_location_assignment PIN_R14 -to gpio1[22]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[22]
    set_location_assignment PIN_N16 -to gpio1[23]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[23]
    set_location_assignment PIN_N15 -to gpio1[24]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[24]
    set_location_assignment PIN_P14 -to gpio1[25]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[25]
    set_location_assignment PIN_L14 -to gpio1[26]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[26]
    set_location_assignment PIN_N14 -to gpio1[27]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[27]
    set_location_assignment PIN_M10 -to gpio1[28]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[28]
    set_location_assignment PIN_L13 -to gpio1[29]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[29]
    set_location_assignment PIN_J16 -to gpio1[30]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[30]
    set_location_assignment PIN_K15 -to gpio1[31]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[31]
    set_location_assignment PIN_J13 -to gpio1[32]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[32]
    set_location_assignment PIN_J14 -to gpio1[33]
    set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to gpio1[33]
    
    #============================================================
    # End of pin assignments by Terasic System Builder
    #============================================================
    
    set_global_assignment -name VERILOG_FILE vga_cursor.v
    set_global_assignment -name SDC_FILE vga_cursor.SDC
    set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
    set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
    set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
    set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
    set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
    set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
    set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
    set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
  • Before opening the project in Quartus, create a source file matching the VERILOG_FILE above, e.g. vga_cursor.v, and ensure it has the essentials in it, including a module matching the TOP_LEVEL_ENTITY:

    `default_nettype none
    `timescale 1ns / 1ps
    
    module vga_cursor(
        input             CLOCK_50,
        output   [7:0]    LED,        // DE0-Nano LEDs near gpio0.
        input    [1:0]    KEY,        // DE0-Nano pushbuttons near gpio0.
        input    [3:0]    SW,         // DE0-Nano DIP switches near gpio1.
    
        input   [33:0]    gpio0,      //NOTE: For safety these are currently set as input-only, since Pi Pico connects directly to these.
        input    [1:0]    gpio0_IN,
    
        inout   [33:0]    gpio1,      //NOTE: inOut; mix of inputs and outputs.
        input    [1:0]    gpio1_IN
    );
    
        reg clock_25;
        always @(posedge CLOCK_50) clock_25 <= ~clock_25;
    
    endmodule
    

    NOTE that in my case:

    • It also has the clock_25 generator that my SDC file refers to.
    • It defines all of gpio0 as input only (not bi-directional, unlike gpio1) because I have a device attached (PicoDeo) and I want to make sure there won't accidentally be bus contention.
  • .gitignore to take care of all the Quartus generated output files and subdirectories:

    *.rpt
    *.done
    *.smsg
    *.summary
    *.jdi
    *.bak
    *.qws
    *.pin
    *.sld
    *.cdf
    db/
    incremental_db/
    output_files/
    

vga_cursor project

I've started the vga_cursor project. For now I can run raybox-bridge and it will present the mouse cursor data to the FPGA design, which in turn tracks the mouse cursor on the attached VGA display.

This first version of vga_cursor just reads the cursor data directly from the X and Y GPIOs, without any synchronisation or metastability avoidance. As a result (and as predicted) it can glitch if the cursor happens to move while the screen is being rendered: I'm using registers to track when the raster scan enters and leaves the cursor region instead of comparators, so moving the mouse rapidly exposes some of the glitches.

Next steps:

  • There is a 1-clock delay in activating the horizontal cursor register (given it IS a register) so what's the best way to handle that?
  • What happens if we get rid of the registers and use comparators instead?
  • Try speeding up the PicoDeo data rate, and see if the USB interface can keep up: Maybe 2ms instead of 5?
  • Try a simple "sample during vblank" and see how that goes.
  • Try metastability avoidance on this.
  • Finally, try a resilient and true "write a series of bytes anytime" design: Should it just be clocked and have metastability avoidance?

Notes

  • Learn how to use FPGA PLLs in Quartus.
  • Is there anything of interest to learn about Quartus SRAM Object Files (.sof)?
  • Try checking out Matt Venn's VGA Clock and other people's VGA projects to get a better feel for how to use Verilog modules to make actual modular designs with layered VGA output.