Site Tools


vhdl

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
vhdl [2025/12/13 21:00] – [NIOS] 2a00:1028:919d:bcb2:740a:d1bf:c035:85fbvhdl [2025/12/21 21:42] (current) – [Quartus] 2a00:1028:919d:bcb2:7542:e925:63c7:87da
Line 1: Line 1:
-===== VHDL ===== +VHDL https://tapec.uv.es/pardo/hdlsim/
- +
-https://tapec.uv.es/pardo/hdlsim/ +
  
 Verilator https://itsembedded.com/dhd/verilator_1/ Verilator https://itsembedded.com/dhd/verilator_1/
  
-===== SDRAM Memory ===== +SDRAM https://electronics.stackexchange.com/questions/631943/fpga-to-sdram-communication
- +
-https://electronics.stackexchange.com/questions/631943/fpga-to-sdram-communication+
  
 and https://github.com/nullobject/sdram-fpga/blob/master/sdram.vhd and https://github.com/nullobject/sdram-fpga/blob/master/sdram.vhd
Line 16: Line 11:
  
 https://www.mouser.com/datasheet/2/598/DE25_Standard_User_manual_revC-3680989.pdf https://www.mouser.com/datasheet/2/598/DE25_Standard_User_manual_revC-3680989.pdf
 +
  
 ===== DE-10 Standard ===== ===== DE-10 Standard =====
Line 204: Line 200:
  
 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.  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 ==== ==== DSP ====
Line 472: Line 470:
  
  
 +==== Avalon DDR Memory ====
 +
 +Ask Copilot : vhdl example of component with avalon memory master
 +
 +<code vhdl>
 +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;
 +</code>
 +
 +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.
 +
 +<code vhdl>
 +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;
 +</code>
 +
 +Ask Copilot : Quartus how to add Avalon‑MM Master
 +
 +<code>
 + 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.   
 +</code>
 ==== Verilog SDRAM ==== ==== Verilog SDRAM ====
  
Line 617: Line 769:
 230 * 1024 16-bit COMPILATION ERROR 230 * 1024 16-bit COMPILATION ERROR
 229 * 1024 16-bit COMPILATION ERROR 229 * 1024 16-bit COMPILATION ERROR
 +</code>
 +
 +<code>
 +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 % )
 </code> </code>
  
Line 624: Line 787:
  
 PROCESSOR https://github.com/NTP17/AKVP_x09 PROCESSOR https://github.com/NTP17/AKVP_x09
-==== NIOS ==== 
  
 VGA https://github.com/vacer25/Nios_II-VGA-Out VGA https://github.com/vacer25/Nios_II-VGA-Out
Line 635: Line 797:
  
 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/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 0x40000000 https://ftp.intel.com/Public/Pub/fpgaup/pub/Intel_Material/18.1/Computer_Systems/DE10-Standard/DE10-Standard_Computer_NiosII.pdf
  
-https://github.com/zangman/de10-nano/blob/master/docs/Simple-Hardware-Adder_-Primer-on-Avalon-Memory-Map-Interface.md+ 
 +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 
 + 
 +<code> 
 +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 
 +</code> 
 + 
 +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 
 + 
 +==== Avalon MM ==== 
 + 
 +https://copilot.microsoft.com/chats/WvUdMU2aY8Lg1i3S3bLjx 
 + 
 +<code> 
 +# 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 
 +</code> 
 + 
 +<code vhdl> 
 +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; 
 +</code> 
 + 
 +<code> 
 +set_module_property NAME ddr3_burst_master_ctrl 
 +set_module_property VERSION 1.
 +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 
 + 
 +</code> 
 + 
 +**add_component.tcl** 
 + 
 +<code> 
 +In a Quartus TCL console or shell: 
 +qsys-script --script=add_component.tcl 
 +</code> 
 + 
 +<code> 
 +# 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 
 + 
 +</code>
vhdl.1765659632.txt.gz · Last modified: 2025/12/13 21:00 by 2a00:1028:919d:bcb2:740a:d1bf:c035:85fb · Currently locked by: 2a00:1028:919d:bcb2:da5e:d3ff:fe59:4914