Table of Contents

VHDL https://tapec.uv.es/pardo/hdlsim/

Verilator https://itsembedded.com/dhd/verilator_1/

SDRAM https://electronics.stackexchange.com/questions/631943/fpga-to-sdram-communication

and https://github.com/nullobject/sdram-fpga/blob/master/sdram.vhd

DE-25 Standard

https://www.mouser.com/datasheet/2/598/DE25_Standard_User_manual_revC-3680989.pdf

DE-10 Standard

https://www.rocketboards.org/foswiki/pub/Documentation/DE10Standard/DE10-Standard_Getting_Started_Guide.pdf

https://fpgacademy.org/Downloads/DE10-Standard_Computer_ARM.pdf

https://www.scribd.com/document/804051962/DE10-Standard-User-Manual

https://www.scribd.com/document/605613587/DE10-Standard-OpenCL-18-0

schema https://www.rocketboards.org/foswiki/pub/Documentation/DE10Standard/DE10-Standard_Schematic.pdf

https://www.terasic.com.tw/wiki/DE10_Advance_Board_Setup:_MSEL_Settings

https://github.com/joaomiguelvieira/DE10_Standard_boilerplate

Memory

Cyclone V 5CSXFC6D6F31C6

Total block memory bits 5,662,720

https://fpgacademy.org/Downloads/DE10-Standard_Computer_ARM.pdf

DE10-STANDARD COMPUTER SYSTEM WITH ARM* CORTEX* A9 For Quartus® Prime 19.1

2.9.1 SDRAM An SDRAM Controller in the FPGA provides an interface to the 64 MB synchronous dynamic RAM (SDRAM) on the DE10-Standard board, which is organized as 32M x 16 bits. It is accessible by the ARM A9 processor using word (32-bit), halfword (16-bit), or byte operations, and is mapped to the address space 0xC0000000 to 0xC3FFFFFF.

2.9.2 On-Chip Memory The DE10-Standard Computer includes a 256 KB memory that is implemented inside the FPGA. This memory is organized as 64K x 32 bits, and spans addresses in the range 0xC8000000 to 0xC803FFFF. The memory is used as a pixel buffer for the video-out and video-in ports.

2.9.3 On-Chip Memory Character Buffer The DE10-Standard Computer includes an 8 KB memory implemented inside the FPGA that is used as a character buffer for the video-out port, which is described in Section 4.2. The character buffer memory is organized as 8K x 8 bits, and spans the address range 0xC9000000 to 0xC9001FFF.

VGA Video buffer

4.2 Video-out Port The DE10-Standard Computer includes a video-out port connected to the on-board VGA controller that can be connected to a standard VGA monitor. The video-out port support a screen resolution of 640 × 480. The image that is displayed by the video-out port is derived from two sources: a pixel buffer, and a character buffer.

4.2.1 Pixel Buffer The pixel buffer for the video-out port holds the data (color) for each pixel that will be displayed. As illustrated in Figure 18, the pixel buffer provides an image resolution of 320 × 240 pixels, with the coordinate 0,0 being at the top-left corner of the image. Since the video-out port supports the screen resolution of 640 × 480, each of the pixel values in the pixel buffer is replicated in both the x and y dimensions when it is being displayed on the screen.

HPS access to SDRAM

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
 
// Define the assumed physical base address of the FPGA SDRAM as seen by the HPS (check your Qsys map!)
// A typical HPS-to-FPGA bridge range starts around 0xC0000000
#define FPGA_SDRAM_BASE 0xC0000000 
#define SDRAM_SPAN (64*1024*1024) // 64 MB
 
int main() {
    void *virtual_base;
    int fd;
    volatile unsigned int *sdram_ptr;
    int i;
 
    // Open /dev/mem to access physical memory
    if( (fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) )) == -1 ) {
        printf( "ERROR: could not open /dev/mem...\n" );
        return( 1 );
    }
 
    // Map the physical address into virtual memory
    virtual_base = mmap( NULL, SDRAM_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, FPGA_SDRAM_BASE );      
 
    if( virtual_base == MAP_FAILED ) {
        printf( "ERROR: mmap failed...\n" );
        close( fd );
        return( 1 );
    }
 
    // Get the address to the first location in memory
    sdram_ptr = (unsigned int *)virtual_base;
 
    // HPS writes data to the FPGA SDRAM
    for (i = 0; i < 100; i++) {
        *(sdram_ptr + i) = i + 0x1234; 
        // Example of simple read back and print
        // printf("Wrote %x to address %p\n", *(sdram_ptr + i), (void*)(sdram_ptr + i));
    }
    printf("HPS finished writing to FPGA SDRAM.\n");
 
    // Clean up our memory mapping and file handle
    if( munmap( virtual_base, SDRAM_SPAN ) != 0 ) {
        printf( "ERROR: munmap failed...\n" );
    }
 
    close( fd );
    return( 0 );
}

Ask Google : C code de10-standard map FPGA SDRAM on HPS

Ask Google : instructions on how to use the Platform Designer to map the FPGA SDRAM so the HPS can access it

MEMORY M9K

    -- Total depth is 256 * 256 = 65536 locations
    constant MEM_DEPTH : natural := 65536; 
    constant DATA_WIDTH : natural := 32;
 
    -- Define a 1D array type for easier memory inference
    type memory_array_t is array (0 to MEM_DEPTH-1) of STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0);
 
    -- Declare the signal that will be mapped to M9K blocks
    signal memory_array : memory_array_t;
 
    -- VHDL attribute to force mapping to block RAM (M9K)
    attribute ramstyle : string;
    attribute ramstyle of memory_array : signal is "M9K";
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity OnChip_RAM is
    generic (
        -- Define the memory size and data width
        DATA_WIDTH : integer := 8;
        ADDR_WIDTH : integer := 10 -- 2^10 = 1024 addresses (fits within one or more M9K blocks)
    );
    Port (
        clk     : in STD_LOGIC;
        we      : in STD_LOGIC; -- Write enable
        addr    : in STD_LOGIC_VECTOR(ADDR_WIDTH-1 downto 0);
        data_in : in STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0);
        data_out: out STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0)
    );
end entity OnChip_RAM;
 
architecture behavioral of OnChip_RAM is
    -- Declare the memory type as an array
    type RAM_ARRAY is array (0 to (2**ADDR_WIDTH)-1) of STD_LOGIC_VECTOR(DATA_WIDTH-1 downto 0);
    -- Initialize the RAM content (optional, can be done via .mif file)
    signal ram_memory : RAM_ARRAY; 
    signal read_address_reg : STD_LOGIC_VECTOR(ADDR_WIDTH-1 downto 0);
 
begin
 
    process(clk)
    begin
        if rising_edge(clk) then
            -- Write operation: occurs on the rising edge of the clock when write enable is high
            if we = '1' then
                ram_memory(to_integer(unsigned(addr))) <= data_in;
            end if;
            -- The read address is registered for synchronous read
            read_address_reg <= addr;
        end if;
    end process;
 
    -- Read operation: output is combinational based on the registered read address
    -- This behavior is characteristic of how FPGAs implement block RAMs for high speed
    data_out <= ram_memory(to_integer(unsigned(read_address_reg)));
 
end architecture behavioral;

Inference: Quartus Prime's synthesis tool will automatically infer M9K blocks from this code because it follows standard synchronous write and registered read practices.

Attributes: To explicitly force the use of block RAM or change behavior during simultaneous read/write to the same address, you can use VHDL attributes, e.g.,

attribute ramstyle : string; attribute ramstyle of ram_memory: signal is "M9K";.

Initialization: You can initialize the RAM contents using a Memory Initialization File (.mif) or Hexadecimal file (.hex) by following the Quartus settings to include initialization data in the bitstream.

DSP

The Cyclone V SX SoC (5CSXFC6D6F31C6N) contains 112 Digital Signal Processing (DSP) blocks

Cyclone V DSPs have two banks of eight internal coefficients each, which can be selected as a multiplicand in the multiplier, alongside dynamic input. These coefficient banks are part of the internal memory, and the DSP block can choose between the dynamic input and the internal coefficient memory.

The simplest way to use a DSP block is to write a standard VHDL multiplier using the numeric_std library's signed or unsigned types. The Quartus synthesizer will automatically map this operation to one of the dedicated hardware multipliers (e.g., a 9×9, 18×18, or 27×27 multiplier depending on your data width) if timing and resource constraints allow.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity simple_multiplier is
    Port (
        clk      : in  STD_LOGIC;
        operand_a: in  SIGNED (17 downto 0); -- 18-bit signed input
        operand_b: in  SIGNED (17 downto 0); -- 18-bit signed input
        result   : out SIGNED (35 downto 0)  -- 36-bit signed output (18+18)
    );
end entity simple_multiplier;
 
architecture behavioral of simple_multiplier is
    -- Intermediate signal for registered output
    signal mult_result_reg : SIGNED (35 downto 0);
 
begin
 
    process(clk)
    begin
        if rising_edge(clk) then
            -- The synthesizer will infer an 18x18 hardware multiplier here
            mult_result_reg <= operand_a * operand_b;
        end if;
    end process;
 
    result <= mult_result_reg;
 
end architecture behavioral;

Data Types: Use SIGNED or UNSIGNED from numeric_std. Using STD_LOGIC_VECTOR requires casting, which can sometimes hinder inference.

Pipelining/Registers: Adding registers (as in the example above with mult_result_reg) helps the synthesizer absorb the registers into the DSP block itself, improving performance and utilizing the dedicated pipelining features of the hardware.

Attributes: You can use VHDL attributes to guide the synthesizer if necessary, though it's usually automatic for simple multiplication:

attribute use_dsp : string;
attribute use_dsp of behavioral : architecture is "yes";

VGA

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity vga_controller is
    Port (
        clk_25mhz : in  STD_LOGIC;  -- The pixel clock (25.175 MHz)
        hsync     : out STD_LOGIC;  -- Horizontal Sync
        vsync     : out STD_LOGIC;  -- Vertical Sync
 
        -- Pixel coordinates for drawing (active display area)
        pixel_x   : out NATURAL range 0 to 639;
        pixel_y   : out NATURAL range 0 to 479;
 
        -- Signal to indicate when the beam is in the active display area
        display_on : out STD_LOGIC
    );
end entity vga_controller;
 
architecture behavioral of vga_controller is
    -- VGA 640x480 @ 60Hz timing constants
    constant H_DISPLAY  : NATURAL := 640;
    constant H_FRONT    : NATURAL := 16;
    constant H_SYNC     : NATURAL := 96;
    constant H_BACK     : NATURAL := 48;
    constant H_TOTAL    : NATURAL := 800;
 
    constant V_DISPLAY  : NATURAL := 480;
    constant V_FRONT    : NATURAL := 10;
    constant V_SYNC     : NATURAL := 2;
    constant V_BACK     : NATURAL := 33;
    constant V_TOTAL    : NATURAL := 525;
 
    signal h_count      : NATURAL range 0 to H_TOTAL-1 := 0;
    signal v_count      : NATURAL range 0 to V_TOTAL-1 := 0;
    signal h_sync_sig   : STD_LOGIC := '1';
    signal v_sync_sig   : STD_LOGIC := '1';
    signal display_on_sig : STD_LOGIC := '0';
 
begin
    process(clk_25mhz)
    begin
        if rising_edge(clk_25mhz) then
            -- Horizontal counter logic
            if h_count < H_TOTAL - 1 then
                h_count <= h_count + 1;
            else
                h_count <= 0;
                -- Vertical counter logic: only increments when horizontal count resets
                if v_count < V_TOTAL - 1 then
                    v_count <= v_count + 1;
                else
                    v_count <= 0;
                end if;
            end if;
 
            -- Horizontal sync pulse generation (active low)
            if h_count >= (H_DISPLAY + H_FRONT) and h_count < (H_DISPLAY + H_FRONT + H_SYNC) then
                h_sync_sig <= '0';
            else
                h_sync_sig <= '1';
            end if;
 
            -- Vertical sync pulse generation (active low)
            if v_count >= (V_DISPLAY + V_FRONT) and v_count < (V_DISPLAY + V_FRONT + V_SYNC) then
                v_sync_sig <= '0';
            else
                v_sync_sig <= '1';
            end if;
 
            -- Display enable signal (active during the active display area)
            if h_count < H_DISPLAY and v_count < V_DISPLAY then
                display_on_sig <= '1';
            else
                display_on_sig <= '0';
            end if;
 
        end if;
    end process;
 
    -- Map internal signals to output ports
    hsync <= h_sync_sig;
    vsync <= v_sync_sig;
    display_on <= display_on_sig;
 
    -- Provide current active pixel coordinates (adjusting for counter start from 0)
    pixel_x <= h_count when display_on_sig = '1' else 0;
    pixel_y <= v_count when display_on_sig = '1' else 0;
 
end architecture behavioral;
-- Example connection logic in a separate module or top-level architecture
-- ...
-- signal current_red, current_green, current_blue : STD_LOGIC_VECTOR(3 downto 0); -- DE10 uses 4-bit color per channel
-- ...
 
-- Instantiate the controller
-- UUT_VGA_Controller : entity work.vga_controller port map (...);
 
-- Logic to determine color based on coordinates (e.g., drawing a red square)
-- process(pixel_x, pixel_y, display_on)
-- begin
--   if display_on = '1' then
--     if pixel_x > 100 and pixel_x < 200 and pixel_y > 100 and pixel_y < 200 then
--       current_red <= "1111"; -- Full Red
--       current_green <= "0000";
--       current_blue <= "0000";
--     else
--       current_red <= "0000"; -- Black background
--       current_green <= "0000";
--       current_blue <= "0000";
--     end if;
--   else
--     current_red <= "0000"; -- Blanking period, output 0
--     current_green <= "0000";
--     current_blue <= "0000";
--   end if;
-- end process;
-- ...

VGA Display image from SDRAM

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
 
entity vga_sdram_bridge is
    Port (
        -- Clocks and Reset
        clk_50mhz   : in  STD_LOGIC;  -- System Clock
        reset       : in  STD_LOGIC;
 
        -- From the VGA Controller (Timing side)
        pixel_x     : in  NATURAL range 0 to 639;
        pixel_y     : in  NATURAL range 0 to 479;
        display_on  : in  STD_LOGIC;
 
        -- To the VGA DAC (Color output)
        vga_red     : out STD_LOGIC_VECTOR(3 downto 0);
        vga_green   : out STD_LOGIC_VECTOR(3 downto 0);
        vga_blue    : out STD_LOGIC_VECTOR(3 downto 0);
 
        -- Avalon Master Interface to SDRAM Controller (Connect via Qsys/Platform Designer)
        av_address  : out STD_LOGIC_VECTOR(21 downto 0); -- Address lines for 64MB SDRAM
        av_read     : out STD_LOGIC;
        av_readdata : in  STD_LOGIC_VECTOR(15 downto 0); -- SDRAM provides 16-bit data
        av_waitreq  : in  STD_LOGIC;
        av_readdata_valid: in STD_LOGIC
    );
end entity vga_sdram_bridge;
 
architecture behavioral of vga_sdram_bridge is
    signal current_read_address : STD_LOGIC_VECTOR(21 downto 0) := (others => '0');
    signal next_pixel_data      : STD_LOGIC_VECTOR(15 downto 0);
    signal vga_read_enable      : STD_LOGIC := '0';
 
begin
 
    process (clk_50mhz)
    begin
        if rising_edge(clk_50mhz) then
            if reset = '1' then
                vga_read_enable <= '0';
                av_read <= '0';
                -- ... reset colors ...
            else
                -- 1. Generate the Address based on X, Y coordinates
                if display_on = '1' then
                    -- Calculate sequential address (assuming 16-bit color data per pixel)
                    -- Address = (Y * H_DISPLAY + X) * 2 bytes/pixel 
                    -- Note: Exact calculation depends on pixel packing and memory layout
                    current_read_address <= std_logic_vector(to_unsigned(pixel_y * 640 + pixel_x, 22)); 
                    vga_read_enable <= '1';
                else
                    vga_read_enable <= '0';
                end if;
 
                -- 2. Issue Read Request to SDRAM Controller
                -- The SDRAM controller IP handles the wait cycles (av_waitreq)
                av_read <= vga_read_enable;
                av_address <= current_read_address;
 
                -- 3. Capture Data when valid (requires FSM for multi-cycle transactions)
                -- For simple (slow) systems, you can check av_readdata_valid or av_waitreq
                -- In a real SDRAM interface, you need a state machine to wait for the data
                -- This simplified example assumes data arrives quickly:
                if (av_readdata_valid = '1' and av_read = '1') then
                    next_pixel_data <= av_readdata;
                end if;
 
                -- 4. Drive VGA DAC with the captured data
                -- Assuming 5/6/5 RGB format in 16 bits (common in Terasic examples)
                -- Red [15:11], Green [10:5], Blue [4:0] (Adjust these bit slices for your format)
                vga_red <= next_pixel_data(15 downto 12); -- Top 4 bits of 5
                vga_green <= next_pixel_data(10 downto 7); -- Top 4 bits of 6
                vga_blue <= next_pixel_data(4 downto 1); -- Top 4 bits of 5
            end if;
        end if;
    end process;
end architecture behavioral;

Avalon DDR Memory

Ask Copilot : vhdl example of component with avalon memory master

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity avalon_master_example is
    port (
        clk         : in  std_logic;
        reset_n     : in  std_logic;
 
        -- Avalon-MM master signals
        address     : out std_logic_vector(31 downto 0);
        writedata   : out std_logic_vector(31 downto 0);
        readdata    : in  std_logic_vector(31 downto 0);
        read        : out std_logic;
        write       : out std_logic;
        waitrequest : in  std_logic
    );
end entity;
 
architecture rtl of avalon_master_example is
    type state_type is (IDLE, WRITE_REQ, WRITE_WAIT, READ_REQ, READ_WAIT);
    signal state : state_type := IDLE;
    signal addr  : unsigned(31 downto 0) := (others => '0');
begin
    process(clk, reset_n)
    begin
        if reset_n = '0' then
            state      <= IDLE;
            address    <= (others => '0');
            writedata  <= (others => '0');
            read       <= '0';
            write      <= '0';
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    -- Start a write transaction
                    address   <= std_logic_vector(addr);
                    writedata <= x"DEADBEEF";
                    write     <= '1';
                    state     <= WRITE_REQ;
 
                when WRITE_REQ =>
                    if waitrequest = '0' then
                        write <= '0';
                        state <= WRITE_WAIT;
                    end if;
 
                when WRITE_WAIT =>
                    -- After write, start a read
                    address <= std_logic_vector(addr);
                    read    <= '1';
                    state   <= READ_REQ;
 
                when READ_REQ =>
                    if waitrequest = '0' then
                        read  <= '0';
                        state <= READ_WAIT;
                    end if;
 
                when READ_WAIT =>
                    -- Data available in readdata
                    report "Read data: " & integer'image(to_integer(unsigned(readdata)));
                    state <= IDLE;
            end case;
        end if;
    end process;
end architecture;

https://github.com/frobino/avalon_mm_master_templates/blob/master/IP/simple_example.vhd

https://www.ecb.torontomu.ca/~courses/coe718/Data-Sheets/DE2-Board/tut_DE2_sdram_vhdl.pdf

Ask Copilot : de10-standard soc system in verilog and component in vhdl

Ask Copilot : sketch out a step‑by‑step guide for writing the .tcl wrapper

Ask Copilot : de10-standard change vhdl component without rebuilding whole quartus project

Ask Copilot : Quartus add avalon component with access to ddr

Ask Copilot : de10-standard linux shows only 768 MB RAM

Ask Copilot : how to use part of FPGA RESERVED 256 MB in vhdl example

Ask Copilot : how to write from HPS to FPGA RESERVED 128 MB RAM and how to read from vhdl example

Your FPGA logic must be an Avalon‑MM Master connected to the FPGA‑to‑HPS SDRAM bridge.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity ddr_reader is
    port (
        clk          : in  std_logic;
        reset_n      : in  std_logic;
        -- Avalon-MM Master
        avm_address   : out std_logic_vector(31 downto 0);
        avm_read      : out std_logic;
        avm_readdata  : in  std_logic_vector(31 downto 0);
        avm_readdatavalid : in  std_logic;
        avm_waitrequest   : in  std_logic;
        -- Output
        data_out     : out std_logic_vector(31 downto 0)
    );
end entity;
 
architecture rtl of ddr_reader is
    signal addr : unsigned(31 downto 0) := x"30000000"; -- start of reserved DDR
begin
    process(clk, reset_n)
    begin
        if reset_n = '0' then
            avm_read <= '0';
            addr <= x"30000000";
        elsif rising_edge(clk) then
            if avm_waitrequest = '0' then
                avm_address <= std_logic_vector(addr);
                avm_read    <= '1';
            else
                avm_read <= '0';
            end if;
 
            if avm_readdatavalid = '1' then
                data_out <= avm_readdata;  -- captured data from DDR
                addr <= addr + 4;          -- increment address
            end if;
        end if;
    end process;
end rtl;

Ask Copilot : Quartus how to add Avalon‑MM Master

 Tools → Platform Designer (Qsys).
 File → New Component.

 In the Interfaces tab, add a new interface:
   Type: Avalon‑MM Master
   Direction: Master
   
Add your custom component to the system. (File/Open File, Project/Add Current File)
Connect the Avalon‑MM Master interface to a target (e.g., DDR SDRAM Controller).
Assign address ranges in the Address Map.   

Verilog SDRAM

https://www.reddit.com/r/FPGA/comments/x5x4a8/stuck_on_simple_fpga_sdram_controller_dropped/

https://drive.google.com/file/d/1asn0ytD_ntwQrTm7IzxEVtITTo8kwDs3/view

// SDRAM command and control
// Model ISIS IS4216320D 32Mx16 SDRAM
 
`define ZERO_ADDRESS \
    A <= 0;
 
`define ISSUE_NOP \
	nRAS <= 1; nCAS <= 1; nWE <= 1; DQM <= 2'b11;
 
`define ISSUE_PRECHARGE_ALLBANKS \
    nRAS <= 0; nCAS <= 1; nWE <= 0; A[10] <= 1; 
 
`define ISSUE_REFRESH \
    nRAS <= 0; nCAS <= 0; nWE <= 1;
 
`define ISSUE_MODE_SELECT \
    nRAS <= 0; nCAS <= 0; nWE <= 0; A[10] <= 0; BA <= 0;
 
`define SELECT_NOBURST_MODE \
    BA <= 0; A[12:10] <= 0; A[9] <= 1'b1; A[8:7] <= 0; A[6:4] <= 3'b010; A[3:0] <= 4'b0000;
 
`define SELECT_BURST32_MODE \
    BA <= 0; A[12:10] <= 0; A[9] <= 1'b0; A[8:7] <= 0; A[6:4] <= 3'b010; A[3:0] <= 4'b0001;
 
`define SET_COMMAND_LENGTH(cmdcyclebit, length) \
    cmdcyclebit <= length > 1? (1 << (length-2)) : 0;
 
`define ISSUE_ACTIVATE(BANK, ROW) \
    nRAS <= 0; nCAS <= 1; nWE <= 1; \
	 BA <= BANK; A <= ROW;
 
`define ISSUE_RD_WITH_AUTOCHARGE(BANK, COL) \
    nRAS <= 1; nCAS <= 0; nWE <= 1; A[10] <= 1; \
	 BA <= BANK; A[9:0] <= COL; DQM <= 0;
 
`define ISSUE_WR_WITH_AUTOCHARGE(BANK, COL, DATA) \
    nRAS <= 1; nCAS <= 0; nWE <= 0; A[10] <= 1; \
	 BA <= BANK; A[9:0] <= COL; DQM <= 0; DQ_buf <= DATA; dq_flag <= 1;

Quartus

Flow Status	Successful - Sat Dec 13 17:32:19 2025
Quartus Prime Version	25.1std.0 Build 1129 10/21/2025 SC Standard Edition
Revision Name	de10_standard_ver
Top-level Entity Name	de10_standard_ver
Family	Cyclone V
Device	5CSXFC6D6F31C6
Timing Models	Final
Logic utilization (in ALMs)	3,776 / 41,910 ( 9 % )
Total registers	6123
Total pins	177 / 499 ( 35 % )
Total virtual pins	0
Total block memory bits	704,584 / 5,662,720 ( 12 % )
Total DSP Blocks	0 / 112 ( 0 % )
Total HSSI RX PCSs	0 / 9 ( 0 % )
Total HSSI PMA RX Deserializers	0 / 9 ( 0 % )
Total HSSI TX PCSs	0 / 9 ( 0 % )
Total HSSI PMA TX Serializers	0 / 9 ( 0 % )
Total PLLs	2 / 15 ( 13 % )
Total DLLs	1 / 4 ( 25 % )

https://gitlab.fel.cvut.cz/korinlu1/de10_standard_ov7670_project

https://gitlab.fel.cvut.cz/korinlu1/de10_standard_ov7670_project/-/blob/main/fpga/de10_standard_ver/ov7670_camera_module.vhd

https://gitlab.fel.cvut.cz/korinlu1/de10_standard_ov7670_project/-/blob/main/fpga/de10_standard_ver/ov7670_camera_module.vhd

Download https://gitlab.fel.cvut.cz/korinlu1/de10_standard_ov7670_project/-/archive/main/de10_standard_ov7670_project-main.tar.gz?ref_type=heads

PDF https://dspace.cvut.cz/server/api/core/bitstreams/31b3bbb8-6926-43c8-8d53-7c19862c9aa4/content

architecture Behavioral of ov7670_camera_module is
 
	constant IMAGE_SIZE : natural := 228*1024;
	type image_type is array (0 to IMAGE_SIZE-1) of std_logic_vector(15 downto 0);
	shared variable image : image_type := (others => (others => '0'));
 
	variable image_inx : integer := 0;
        variable value : std_logic_vector(15 downto 0) := (others => '0');
 
		value := data(7 downto 0) & data_in;
 
		data <= image (image_inx);
		wren_reg  <= '0';
 
		image (image_inx) := value;
		if image_inx < IMAGE_SIZE-1 then
		   image_inx := image_inx + 1;
		else
  	            image_inx := 0;
		end if;	
constant IMAGE_SIZE : natural := 256*1024;
COMPILATION ERROR

Logic utilization (in ALMs)	4,664 / 41,910 ( 11 % )
Total registers	5859
Total pins	177 / 499 ( 35 % )
Total virtual pins	0
Total block memory bits	4,898,888 / 5,662,720 ( 87 % )
constant IMAGE_SIZE : natural := 128*1024;
O.K.

Logic utilization (in ALMs)	3,872 / 41,910 ( 9 % )
Total registers	6100
Total pins	177 / 499 ( 35 % )
Total virtual pins	0
Total block memory bits	2,801,736 / 
----
( 49 % )
112 * 1024 32-bit
224 * 1024 16-bit
448 * 1024  8-bit
O.K.

114 * 1024 32-bit
228 * 1024 16-bit 
456 * 1024  8-bit
O.K.

248 * 1024 16-bit COMPILATION ERROR
240 * 1024 16-bit COMPILATION ERROR
232 * 1024 16-bit COMPILATION ERROR
230 * 1024 16-bit COMPILATION ERROR
229 * 1024 16-bit COMPILATION ERROR
Control Panel

Logic utilization (in ALMs)	11,833 / 41,910 ( 28 % )
Total registers	23823
Total pins	338 / 499 ( 68 % )
Total virtual pins	0
Total block memory bits	1,119,502 / 5,662,720 ( 20 % )
Total DSP Blocks	20 / 112 ( 18 % )

RAM https://www.cs.columbia.edu/~sedwards/classes/2013/4840/lab3.pdf

https://www.scribd.com/document/528291698/lab1-week-1

PROCESSOR https://github.com/NTP17/AKVP_x09

VGA https://github.com/vacer25/Nios_II-VGA-Out

RAM https://www.scribd.com/document/528291695/Lab3-SDRAM-modified-2020-1

FPGA SDRAM Communication https://github.com/zangman/de10-nano/blob/master/docs/FPGA-SDRAM-Communication_-Avalon-MM-Host-Master-Component-Part-3.md

https://github.com/zangman/de10-nano/blob/master/docs/Write-Linux-Driver.md

https://github.com/zangman/de10-nano/blob/master/docs/FPGA-SDRAM-Communication_-Avalon-MM-Host-Master-Component-Part-1.md

https://github.com/zangman/de10-nano/blob/master/docs/Simple-Hardware-Adder_-Primer-on-Avalon-Memory-Map-Interface.md

0x40000000 https://ftp.intel.com/Public/Pub/fpgaup/pub/Intel_Material/18.1/Computer_Systems/DE10-Standard/DE10-Standard_Computer_NiosII.pdf

CD https://download.terasic.com/downloads/cd-rom/de10-standard/Linux/

https://www.altera.com/downloads/fpga-development-tools/quartus-prime-lite-edition-design-software-version-16-1-b196-linux

https://www.altera.com/downloads/fpga-development-tools/quartus-prime-lite-edition-design-software-version-21-1-linux

https://sudonull.com/post/68502-Experience-using-the-FPGA-board-DE10-Standard-and-DMA-PL330

ethaddr=fe:cd:12:34:56:67
ipaddr=10.8.0.97
serverip=10.8.0.36
xfpga=tftpboot 100 socfpga.rbf; fpga load0100 $filesize; run bridge_enable_handoff;    								tftpboot 100 socfpga.dtb
xload=run xfpga; tftpboot 8000 zImage; bootz 8000 – 100

https://www.intel.com/content/dam/support/us/en/programmable/support-resources/fpga-wiki/asset03/hello-world-lab-manual-max10.pdf

https://github.com/frobino/avalon_mm_master_templates/blob/master/IP/simple_example.vhd

https://github.com/Luis9705/fpga_hps/blob/master/DE10_Standard_GHRD/DE10_Standard_GHRD.v

https://github.com/frobino/avalon_mm_master_templates/tree/master/IP

Avalon MM

https://copilot.microsoft.com/chats/WvUdMU2aY8Lg1i3S3bLjx

# connect clk to clk_50.clk

# connect reset to clk_50.clk_reset

# connect s_slave to hps_0.h2f_axi_master

# connect m_master to hps_0.f2h_sdram0_data, NOT TO mm_bridge_0.s0

# assign address ranges to the slave
# hps_0.f2h_sdram0_data ... 0x00000000 – 0x3FFFFFFF

# set_interface_property reset associatedClock clk
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity ddr3_burst_master_ctrl is
    generic (
        BURST_LEN : integer := 8
    );
    port (
        clk     : in  std_logic;
        reset   : in  std_logic;
 
        --------------------------------------------------------------------
        -- Avalon-MM SLAVE (Nios II / HPS controls registers)
        --------------------------------------------------------------------
        s_address     : in  std_logic_vector(3 downto 0);
        s_write       : in  std_logic;
        s_read        : in  std_logic;
        s_writedata   : in  std_logic_vector(31 downto 0);
        s_readdata    : out std_logic_vector(31 downto 0);
 
        --------------------------------------------------------------------
        -- Avalon-MM MASTER (to DDR3 or HPS bridge)
        --------------------------------------------------------------------
        m_address        : out std_logic_vector(31 downto 0);
        m_read           : out std_logic;
        m_readdata       : in  std_logic_vector(31 downto 0);
        m_readdatavalid  : in  std_logic;
        m_write          : out std_logic;
        m_writedata      : out std_logic_vector(31 downto 0);
        m_waitrequest    : in  std_logic;
        m_byteenable     : out std_logic_vector(3 downto 0);
        m_burstcount     : out std_logic_vector(7 downto 0)
    );
end entity;
 
architecture rtl of ddr3_burst_master_ctrl is
 
    --------------------------------------------------------------------
    -- Slave registers
    --------------------------------------------------------------------
    signal reg_control   : std_logic_vector(31 downto 0) := (others => '0');
    signal reg_baseaddr  : std_logic_vector(31 downto 0) := (others => '0');
    signal reg_length    : std_logic_vector(31 downto 0) := (others => '0');
    signal reg_status    : std_logic_vector(31 downto 0) := (others => '0');
 
    signal start_pulse   : std_logic := '0';
 
    --------------------------------------------------------------------
    -- Burst engine
    --------------------------------------------------------------------
    type state_t is (IDLE, WRITE, WRITE_WAIT, READ, READ_WAIT, DONE);
    signal state : state_t := IDLE;
 
    signal idx         : integer := 0;
    signal burst_idx   : integer := 0;
    signal expected    : std_logic_vector(31 downto 0);
 
begin
 
    m_byteenable <= "1111";
    m_burstcount <= std_logic_vector(to_unsigned(BURST_LEN, 8));
 
    --------------------------------------------------------------------
    -- SLAVE REGISTER READBACK
    --------------------------------------------------------------------
    with s_address select
        s_readdata <= reg_control  when "0000",
                       reg_baseaddr when "0001",
                       reg_length   when "0010",
                       reg_status   when "0011",
                       (others => '0') when others;
 
    --------------------------------------------------------------------
    -- SLAVE REGISTER WRITE
    --------------------------------------------------------------------
    process(clk)
    begin
        if rising_edge(clk) then
            if reset = '1' then
                reg_control  <= (others => '0');
                reg_status   <= (others => '0');
            else
                if s_write = '1' then
                    case s_address is
                        when "0000" => reg_control  <= s_writedata;
                        when "0001" => reg_baseaddr <= s_writedata;
                        when "0010" => reg_length   <= s_writedata;
                        when others => null;
                    end case;
                end if;
            end if;
        end if;
    end process;
 
    --------------------------------------------------------------------
    -- Detect start pulse
    --------------------------------------------------------------------
    process(clk)
    begin
        if rising_edge(clk) then
            start_pulse <= '0';
            if reg_control(0) = '1' then
                start_pulse <= '1';
                reg_control(0) <= '0'; -- auto-clear start bit
            end if;
        end if;
    end process;
 
    --------------------------------------------------------------------
    -- BURST ENGINE
    --------------------------------------------------------------------
    process(clk, reset)
    begin
        if reset = '1' then
            state <= IDLE;
            m_read <= '0';
            m_write <= '0';
            reg_status <= (others => '0');
            idx <= 0;
            burst_idx <= 0;
 
        elsif rising_edge(clk) then
            case state is
 
                ----------------------------------------------------------------
                when IDLE =>
                    reg_status <= (others => '0');
                    if start_pulse = '1' then
                        idx <= 0;
                        state <= WRITE;
                    end if;
 
                ----------------------------------------------------------------
                -- BURST WRITE
                ----------------------------------------------------------------
                when WRITE =>
                    m_address <= std_logic_vector(
                        unsigned(reg_baseaddr) + to_unsigned(idx*4, 32)
                    );
                    m_write <= '1';
                    burst_idx <= 0;
 
                    expected <= std_logic_vector(
                        to_unsigned(idx, 32) xor x"CAFEBABE"
                    );
                    m_writedata <= expected;
 
                    state <= WRITE_WAIT;
 
                when WRITE_WAIT =>
                    if m_waitrequest = '0' then
                        burst_idx <= burst_idx + 1;
 
                        if burst_idx = BURST_LEN-1 then
                            m_write <= '0';
                            idx <= idx + BURST_LEN;
 
                            if idx >= to_integer(unsigned(reg_length)) then
                                idx <= 0;
                                state <= READ;
                            else
                                state <= WRITE;
                            end if;
 
                        else
                            expected <= std_logic_vector(
                                to_unsigned(idx + burst_idx + 1, 32) xor x"CAFEBABE"
                            );
                            m_writedata <= expected;
                        end if;
                    end if;
 
                ----------------------------------------------------------------
                -- BURST READ
                ----------------------------------------------------------------
                when READ =>
                    m_address <= std_logic_vector(
                        unsigned(reg_baseaddr) + to_unsigned(idx*4, 32)
                    );
                    m_read <= '1';
                    burst_idx <= 0;
                    state <= READ_WAIT;
 
                when READ_WAIT =>
                    if m_waitrequest = '0' then
                        m_read <= '0';
                    end if;
 
                    if m_readdatavalid = '1' then
                        expected <= std_logic_vector(
                            to_unsigned(idx + burst_idx, 32) xor x"CAFEBABE"
                        );
 
                        if m_readdata /= expected then
                            reg_status(1) <= '1'; -- error flag
                        end if;
 
                        burst_idx <= burst_idx + 1;
 
                        if burst_idx = BURST_LEN-1 then
                            idx <= idx + BURST_LEN;
 
                            if idx >= to_integer(unsigned(reg_length)) then
                                state <= DONE;
                            else
                                state <= READ;
                            end if;
                        end if;
                    end if;
 
                ----------------------------------------------------------------
                when DONE =>
                    reg_status(0) <= '1'; -- done flag
 
            end case;
        end if;
    end process;
 
end architecture;
set_module_property NAME ddr3_burst_master_ctrl
set_module_property VERSION 1.0
set_module_property DISPLAY_NAME "DDR3 Burst Master with Control Registers"
set_module_property DESCRIPTION "Avalon-MM burst read/write master controlled by Nios II or HPS"
set_module_property AUTHOR "User"
set_module_property INSTANTIATE_IN_SYSTEM_MODULE true
set_module_property EDITABLE true
set_module_property HDL_LANGUAGE VHDL
set_module_property TOP_LEVEL_HDL_FILE ddr3_burst_master_ctrl.vhd
set_module_property TOP_LEVEL_HDL_MODULE ddr3_burst_master_ctrl

# ============================================================
# Clock interface
# ============================================================
add_interface clk clock end
set_interface_property clk EXPORT_OF ""
add_interface_port clk clk clk Input 1

# ============================================================
# Reset interface
# ============================================================
add_interface reset reset end
set_interface_property reset EXPORT_OF ""
add_interface_port reset reset reset Input 1

# ============================================================
# Avalon-MM SLAVE (register interface for Nios II / HPS)
# ============================================================
add_interface s_slave avalon slave
set_interface_property s_slave associatedClock clk
set_interface_property s_slave associatedReset reset
set_interface_property s_slave addressUnits WORDS
set_interface_property s_slave readLatency 0
set_interface_property s_slave writeWaitTime 0

add_interface_port s_slave s_address address Input 4
add_interface_port s_slave s_write write Input 1
add_interface_port s_slave s_read read Input 1
add_interface_port s_slave s_writedata writedata Input 32
add_interface_port s_slave s_readdata readdata Output 32

# ============================================================
# Avalon-MM MASTER (burst engine to DDR3 or HPS bridge)
# ============================================================
add_interface m_master avalon master
set_interface_property m_master associatedClock clk
set_interface_property m_master associatedReset reset
set_interface_property m_master addressUnits WORDS
set_interface_property m_master burstOnBurstBoundariesOnly false
set_interface_property m_master linewrapBursts false
set_interface_property m_master maximumPendingReadTransactions 1
set_interface_property m_master readLatency 0

add_interface_port m_master m_address address Output 32
add_interface_port m_master m_read read Output 1
add_interface_port m_master m_readdata readdata Input 32
add_interface_port m_master m_readdatavalid readdatavalid Input 1
add_interface_port m_master m_write write Output 1
add_interface_port m_master m_writedata writedata Output 32
add_interface_port m_master m_waitrequest waitrequest Input 1
add_interface_port m_master m_byteenable byteenable Output 4
add_interface_port m_master m_burstcount burstcount Output 8

add_component.tcl

In a Quartus TCL console or shell:
qsys-script --script=add_component.tcl
# Load existing system
load_system soc_system.qsys

# -------------------------------------------------------------
# Add your custom component
# -------------------------------------------------------------
add_instance ddr3_burst_master_ctrl_0 ddr3_burst_master_ctrl

# -------------------------------------------------------------
# Connect clocks and resets from HPS
# -------------------------------------------------------------
add_connection hps_0.h2f_user0_clock ddr3_burst_master_ctrl_0.clk
add_connection hps_0.h2f_reset       ddr3_burst_master_ctrl_0.reset

# -------------------------------------------------------------
# Connect control registers to HPS lightweight bridge
# -------------------------------------------------------------
add_connection hps_0.h2f_lw_axi_master ddr3_burst_master_ctrl_0.s_slave

# Assign address window for control registers
set_connection_parameter_value hps_0.h2f_lw_axi_master/ddr3_burst_master_ctrl_0.s_slave baseAddress 0x00100000

set_connection_parameter_value hps_0.h2f_lw_axi_master/ddr3_burst_master_ctrl_0.s_slave span 0x10

# -------------------------------------------------------------
# Connect burst master to HPS DDR3
# -------------------------------------------------------------
add_connection ddr3_burst_master_ctrl_0.m_master hps_0.f2h_sdram0_data

# -------------------------------------------------------------
# Export status signals (optional)
# -------------------------------------------------------------
add_interface burst_status conduit end
set_interface_property burst_status EXPORT_OF ddr3_burst_master_ctrl_0.status

# -------------------------------------------------------------
# Save updated system
# -------------------------------------------------------------
save_system soc_system.qsys