How is Quartus inferring cyclone10lp_oscillator?

Hey guys,

I was looking through the example projects for this board. Even just specifically this one: https://github.com/vidor-libraries/VidorFPGA/blob/master/projects/MKRVIDOR4000_template/MKRVIDOR4000_top.v

I cannot seem to understand how Quartus is detecting the module instantiation for cyclone10lp_oscillator as an internal oscillator?

I know you can define an IP for the internal oscillator on the board, but I do not see that it is defined anywhere. To be fair, I am less experienced with Intel FPGAs so I am not great at searching through their documentation yet.

Is this inferring the IP from the name or the port list? Where is this behavior documented?

To add, I have looked here:

But the project doesn't appear to have already defined this IP unless I am missing it.

The 'cyclone10lp_oscillator' is the actual name of the underlying primitive available on Cyclone10 LP. On MAX 10 this would be 'fiftyfivenm_oscillator'. These names are found in device support files.
The MKRVIDOR4000 is targeting a specific board, so I guess the authors did not bother with generating IP variation files that would abstract user-provided name for the IP from the underlying implementation, it's a dumb passthrough anyways, and just instantiated oscillator by the explicit name of the existing hw resource.
You can find similar actions in MiSTer projects too, they instantiate bridges to HPS by their actual hw names without ever using wizards that would generate IP that instantiates those blocks.

Hey that's a great answer and what I suspected. Could you be more specific on which files or where the primitive names for the specific devices are found that can be instantiated this way?

Ideally it would be nice to see some documentation for these primitives.

Edit: I suppose it would be better to give some context. I am re-writing the example project in VHDL and trying to determine how I would instantiate the internal oscillator there (and what library would need to be imported to do so). Also, I'd ideally like to be able to see what other options are available to me for what device primitives are available and how I can properly instantiate them.

I've tried:

LIBRARY altera;
USE altera.altera_primitives_components.all;

  osc : entity cyclone10lp_oscillator
  osc : entity work.cyclone10lp_oscillator
  osc : entity altera.cyclone10lp_oscillator

I am getting warmer.

The cyclone10lp_oscillator lives in the cyclone10lp_components package.

LIBRARY cyclone10lp;
USE cyclone10lp.cyclone10lp_components.all;

  osc : entity cyclone10lp.cyclone10lp_oscillator

This doesn't appear to recognize it though.

Oh, duh. It's a component not an entity.

This works.

LIBRARY cyclone10lp;
USE cyclone10lp.cyclone10lp_components.all;

  osc : cyclone10lp_oscillator

I was going to suggest to generate the needed IP using wizard, selecting the desired language (Verilog vs VHDL) and looking into the generated files for examples. But it seems the wizard generates in VHDL only the wrapper, and at the bottom it boils down to a Verilog file, instantiating the hw as Verilog module.

Appreciate the replies.

By the way if anyone ever wants a rough VHDL blinky light I am sharing it here. I removed the serial functionality for speeding it up because it seems unnecessary.

MKRVIDOR4000_top.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

LIBRARY cyclone10lp;
USE cyclone10lp.cyclone10lp_components.all;

entity MKRVIDOR4000_top is
  port (
    iCLK        : in    std_logic;                                            -- Clock
    iRESETn     : in    std_logic;                                            -- Reset
    iSAM_INT    : in    std_logic;                                            -- SAM Interrupt
    oSAM_INT    :   out std_logic;                                            -- SAM Interrupt
    oSDRAM_CLK  :   out std_logic;                                            -- SDRAM Clock
    oSDRAM_ADDR :   out std_logic_vector(11 downto 0);                        -- SDRAM Address
    oSDRAM_BA   :   out std_logic_vector(1 downto 0);                         -- SDRAM Bank Address
    oSDRAM_CASn :   out std_logic;                                            -- SDRAM Column Address Strobe
    oSDRAM_CKE  :   out std_logic;                                            -- SDRAM Clock Enable
    oSDRAM_CSn  :   out std_logic;                                            -- SDRAM Chip Select
    bSDRAM_DQ   : inout std_logic_vector(15 downto 0);                        -- SDRAM Data
    oSDRAM_DQM  :   out std_logic_vector(1 downto 0);                         -- SDRAM Data Mask
    oSDRAM_RASn :   out std_logic;                                            -- SDRAM Row Address Strobe
    oSDRAM_WEn  :   out std_logic;                                            -- SDRAM Write Enable
    bMKR_AREF   : inout std_logic;                                            -- MKR Analog Reference
    bMKR_A      : inout std_logic_vector(6 downto 0);                         -- MKR Analog
    bMKR_D      : inout std_logic_vector(14 downto 0);                        -- MKR Digital
    bPEX_RST    : inout std_logic;                                            -- Mini PCIe Reset
    bPEX_PIN6   : inout std_logic;                                            -- Mini PCIe Pin 6
    bPEX_PIN8   : inout std_logic;                                            -- Mini PCIe Pin 8
    bPEX_PIN10  : inout std_logic;                                            -- Mini PCIe Pin 10
    iPEX_PIN11  : in    std_logic;                                            -- Mini PCIe Pin 11
    bPEX_PIN12  : inout std_logic;                                            -- Mini PCIe Pin 12
    iPEX_PIN13  : in    std_logic;                                            -- Mini PCIe Pin 13
    bPEX_PIN14  : inout std_logic;                                            -- Mini PCIe Pin 14
    bPEX_PIN16  : inout std_logic;                                            -- Mini PCIe Pin 16
    bPEX_PIN20  : inout std_logic;                                            -- Mini PCIe Pin 20
    iPEX_PIN23  : in    std_logic;                                            -- Mini PCIe Pin 23
    iPEX_PIN25  : in    std_logic;                                            -- Mini PCIe Pin 25
    bPEX_PIN28  : inout std_logic;                                            -- Mini PCIe Pin 28
    bPEX_PIN30  : inout std_logic;                                            -- Mini PCIe Pin 30
    iPEX_PIN31  : in    std_logic;                                            -- Mini PCIe Pin 31
    bPEX_PIN32  : inout std_logic;                                            -- Mini PCIe Pin 32
    iPEX_PIN33  : in    std_logic;                                            -- Mini PCIe Pin 33
    bPEX_PIN42  : inout std_logic;                                            -- Mini PCIe Pin 42
    bPEX_PIN44  : inout std_logic;                                            -- Mini PCIe Pin 44
    bPEX_PIN45  : inout std_logic;                                            -- Mini PCIe Pin 45
    bPEX_PIN46  : inout std_logic;                                            -- Mini PCIe Pin 46
    bPEX_PIN47  : inout std_logic;                                            -- Mini PCIe Pin 47
    bPEX_PIN48  : inout std_logic;                                            -- Mini PCIe Pin 48
    bPEX_PIN49  : inout std_logic;                                            -- Mini PCIe Pin 49
    bPEX_PIN51  : inout std_logic;                                            -- Mini PCIe Pin 51
    bWM_PIO1    : inout std_logic;                                            -- NINA PIO1
    bWM_PIO2    : inout std_logic;                                            -- NINA PIO2
    bWM_PIO3    : inout std_logic;                                            -- NINA PIO3
    bWM_PIO4    : inout std_logic;                                            -- NINA PIO4
    bWM_PIO5    : inout std_logic;                                            -- NINA PIO5
    bWM_PIO7    : inout std_logic;                                            -- NINA PIO7
    bWM_PIO8    : inout std_logic;                                            -- NINA PIO8
    bWM_PIO18   : inout std_logic;                                            -- NINA PIO18
    bWM_PIO20   : inout std_logic;                                            -- NINA PIO20
    bWM_PIO21   : inout std_logic;                                            -- NINA PIO21
    bWM_PIO27   : inout std_logic;                                            -- NINA PIO27
    bWM_PIO28   : inout std_logic;                                            -- NINA PIO28
    bWM_PIO29   : inout std_logic;                                            -- NINA PIO29
    bWM_PIO31   : inout std_logic;                                            -- NINA PIO31
    iWM_PIO32   : in    std_logic;                                            -- NINA PIO32
    bWM_PIO34   : inout std_logic;                                            -- NINA PIO34
    bWM_PIO35   : inout std_logic;                                            -- NINA PIO35
    bWM_PIO36   : inout std_logic;                                            -- NINA PIO36
    iWM_TX      : in    std_logic;                                            -- NINA TX
    oWM_RX      :   out std_logic;                                            -- NINA RX
    oWM_RESET   :   out std_logic;                                            -- NINA Reset
    oHDMI_TX    :   out std_logic_vector(2 downto 0);                         -- HDMI TX
    oHDMI_CLK   :   out std_logic;                                            -- HDMI Clock
    bHDMI_SDA   : inout std_logic;                                            -- HDMI SDA
    bHDMI_SCL   : inout std_logic;                                            -- HDMI SCL
    iHDMI_HPD   : in    std_logic;                                            -- HDMI Hot Plug Detect
    iMIPI_D     : in    std_logic_vector(1 downto 0);                         -- MIPI Data
    iMIPI_CLK   : in    std_logic;                                            -- MIPI Clock
    bMIPI_SDA   : inout std_logic;                                            -- MIPI SDA
    bMIPI_SCL   : inout std_logic;                                            -- MIPI SCL
    bMIPI_GP    : inout std_logic_vector(1 downto 0);                         -- MIPI General Purpose
    oFLASH_SCK  :   out std_logic;                                            -- QSPI Clock
    oFLASH_CS   :   out std_logic;                                            -- QSPI Chip Select
    oFLASH_MOSI :   out std_logic;                                            -- QSPI Master Out Slave In
    iFLASH_MISO : in    std_logic;                                            -- QSPI Master In Slave Out
    oFLASH_HOLD :   out std_logic;                                            -- QSPI Hold
    oFLASH_WP   :   out std_logic                                             -- QSPI Write Protect
  );
end entity MKRVIDOR4000_top;

architecture rtl of MKRVIDOR4000_top is
  ------------------------------------------------------------------------------
  -- CONSTANTS
  ------------------------------------------------------------------------------
  ------------------------------------------------------------------------------
  -- SIGNALS
  ------------------------------------------------------------------------------
  signal sys_clk   : std_logic;
  signal rRESETCNT  : unsigned(5 downto 0) := (others => '0');
  signal wCLK8      : std_logic;
  signal wCLK24     : std_logic;
  signal wCLK64     : std_logic;
  signal wCLK120    : std_logic;
  signal wMEM_CLK   : std_logic;
  signal wFLASH_CLK : std_logic;
  signal wVID_CLK   : std_logic;
  signal wVID_CLKx5 : std_logic;

  signal clk_cnt    : unsigned(31 downto 0);
  ------------------------------------------------------------------------------
  -- SIGNALS
  ------------------------------------------------------------------------------
  alias sys_rst_n   : std_logic is rRESETCNT(5);
  ------------------------------------------------------------------------------
  -- COMPONENTS
  ------------------------------------------------------------------------------
  component SYSTEM_PLL
  port
  (
    areset : in    std_logic := '0';
    inclk0 : in    std_logic := '0';
    c0     :   out std_logic;
    c1     :   out std_logic;
    c2     :   out std_logic;
    c3     :   out std_logic;
    c4     :   out std_logic;
    locked :   out std_logic
  );
  end component;

begin

  ------------------------------------------------------------------------------
  -- CLOCKS
  ------------------------------------------------------------------------------
  osc : cyclone10lp_oscillator
  port map (
    clkout => sys_clk,
    oscena => '1'
  );

  PLL_inst : SYSTEM_PLL
  port map (
    areset => '0',
    inclk0 => wCLK8,
    c0     => wCLK24,
    c1     => wCLK120,
    c2     => wMEM_CLK,
    c3     => oSDRAM_CLK,
    c4     => wFLASH_CLK,
    locked => open
  );

  ------------------------------------------------------------------------------
  -- RESETS
  ------------------------------------------------------------------------------
  process (sys_clk)
  begin
    if rising_edge(sys_clk) then
      if sys_rst_n /= '1' then
        rRESETCNT <= rRESETCNT + 1;
      end if;
    end if;
  end process;

  ------------------------------------------------------------------------------
  -- LOGIC
  ------------------------------------------------------------------------------
  wVID_CLK   <= wCLK24;
  wVID_CLKx5 <= wCLK120;
  wCLK8      <= iCLK;

  process (sys_clk)
  begin
    if rising_edge(sys_clk) then
      if sys_rst_n /= '1' then
        clk_cnt <= (others => '0');
      else
        clk_cnt <= clk_cnt + 1;
      end if;
    end if;
  end process;

  bMKR_D(7)  <= clk_cnt(27);

  ------------------------------------------------------------------------------
  -- ENTITIES
  ------------------------------------------------------------------------------

  ------------------------------------------------------------------------------
  -- IO
  ------------------------------------------------------------------------------

end architecture rtl;

blink-sketch.ino

#include <wiring_private.h>
#include "jtag.h"

// Pin Defines
#define TDI                               12
#define TDO                               15
#define TCK                               13
#define TMS                               14
#define MB_INT                            28
#define MB_INT_PIN                        31
#define SIGNAL_OUT                        41 //B5 L16
#define SIGNAL_IN                         33 //B2 N2
#define FPGA_HEARTBEAT                    7

#define no_data   0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0xFF, 0xFF, 0xFF, 0xFF, \
                  0x00, 0x00, 0x00, 0x00  \

#define NO_BOOTLOADER   no_data
#define NO_APP          no_data
#define NO_USER_DATA    no_data

__attribute__ ((used, section(".fpga_bitstream_signature")))
const unsigned char signatures[4096] = {
  //#include "signature.ttf"
  NO_BOOTLOADER,

  0x00, 0x00, 0x08, 0x00,
  0xA9, 0x6F, 0x1F, 0x00,   // Don't care.
  0x20, 0x77, 0x77, 0x77,
  0x2e, 0x73, 0x79, 0x73,
  0x74, 0x65, 0x6d, 0x65,
  0x73, 0x2d, 0x65, 0x6d,
  0x62, 0x61, 0x72, 0x71,
  0x75, 0x65, 0x73, 0x2e,
  0x66, 0x72, 0x20, 0x00,
  0x00, 0xff, 0xf0, 0x0f,
  0x01, 0x00, 0x00, 0x00,
  0x01, 0x00, 0x00, 0x00,   // Force

  NO_USER_DATA,
};
__attribute__ ((used, section(".fpga_bitstream")))
const unsigned char bitstream[] = {
  #include "app.h"
};

// the setup function runs once when you press reset or power the board
void setup() {
  int      ret;
  uint32_t ptr[1];

  pinPeripheral(30, PIO_AC_CLK);
  clockout(0, 1);
  delay(1000);

  // Init Jtag Port
  ret = jtagInit();
  mbPinSet();

  // Load FPGA user configuration
  ptr[0] = 0 | 3;
  mbEveSend(ptr, 1);

  // Give it delay
  delay(1000);

  // Disable all JTAG Pins (usefull for USB BLASTER connection)
  pinMode(TDO,            INPUT);
  pinMode(TMS,            INPUT);
  pinMode(TDI,            INPUT);
  pinMode(TCK,            INPUT);

  // Configure other share pins as input too
  pinMode(SIGNAL_IN,      INPUT);  // oSAM_INTstat
  pinMode(MB_INT_PIN,     INPUT);
  pinMode(MB_INT,         INPUT);
  pinMode(FPGA_HEARTBEAT, INPUT);
  pinMode(LED_BUILTIN,    OUTPUT);

  // Initialize output pins
  digitalWrite(LED_BUILTIN, 1);

  // Wait for serial port to connect. Needed for native USB port only
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Setup done");
}

// the loop function runs over and over again forever
void loop() {

  // Here we write the status of the FPGA_HEARTBEAT pin to the LED
  static uint oldstate = 2;
  uint        state;
  state = digitalRead(FPGA_HEARTBEAT);
  if (state != oldstate) {
    digitalWrite(LED_BUILTIN, ~state & 0x1);
    oldstate = state;
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.