1

I have Lattice iCE40 HX8K FPGA in 256 BGA package. I want to use one of the available PLL modules to transform external clock frequency of 37MHz to internal clock for use inside of the FPGA of 74MHz.

I used the "Configure PLL Module" in IceCube2 and used the following configuration: - PLL Type section: - GlobalNetworks to be Driven by PLL Output : 1; - Dedicated Clock Pad; - PLL Operation Modes: - No Compensation Mode; - Additional Delay Settings : No; - Frequency: - Input - 37MHz; - Output - 74MHz; - Others - nothing selected;

Then I get the two VHDL files - SO_pll.vhd and SO_pll_inst.vhd. I have file Design.vhd where my code is supposed to go. If I understand correctly Lattice documentation, I need to specify that my Design.vhd (its Entity) is top Level Module, which I did. I need to include SO_pll.vhd in the list of design files in IceCube2, which I did. And last - I need to use the template provided in SO_pll_inst.vhd to instantiate in my main code the PLL by port mapping the PLL signals to signals in my Design.vhd. Here comes the trouble - how to do it?

---Design.vhd---

library IEEE;
use IEEE.std_logic_1164.all;

entity Design is
port(
      I_CLK: in std_logic
    );
end entity Design;


    architecture RTL of Design is

signal S_CLK : std_logic;
signal S_RESET : std_logic;

begin

SO_pll_inst: SO_pll
port map(
          REFERENCECLK => I_CLK,
          PLLOUTCORE => open,
          PLLOUTGLOBAL => S_CLK,
          RESET => S_RESET
        );

end RTL;


    ---SO_pll_inst.vhd---Generated by IceCube2

    SO_pll_inst: SO_pll
    port map(
          REFERENCECLK => ,
          PLLOUTCORE => ,
          PLLOUTGLOBAL => ,
          RESET => 
            );



---SO_pll.vhd---Generated by IceCube2
library IEEE;
use IEEE.std_logic_1164.all;

entity SO_pll is
port(
      REFERENCECLK: in std_logic;
      RESET: in std_logic;
      PLLOUTCORE: out std_logic;
      PLLOUTGLOBAL: out std_logic
    );
end entity SO_pll;

architecture BEHAVIOR of SO_pll is
signal openwire : std_logic;
signal openwirebus : std_logic_vector (7 downto 0);
component SB_PLL40_CORE
  generic (
        --- Feedback
FEEDBACK_PATH : string := "SIMPLE"; -- String (simple, delay, 
phase_and_delay, external)
DELAY_ADJUSTMENT_MODE_FEEDBACK   : string := "FIXED"; 
DELAY_ADJUSTMENT_MODE_RELATIVE   : string := "FIXED"; 
SHIFTREG_DIV_MODE : bit_vector(1 downto 0)  := "00"; 
--  0-->Divide by 4, 1-->Divide by 7, 3 -->Divide by 5  
FDA_FEEDBACK    : bit_vector(3 downto 0)    := "0000"; 
--  Integer (0-15). 
FDA_RELATIVE    : bit_vector(3 downto 0)    := "0000";  
--  Integer (0-15).
PLLOUT_SELECT   : string := "GENCLK";

--- Use the spread sheet to populate the values below
DIVF    : bit_vector(6 downto 0); 
-- Determine a good default value
DIVR    : bit_vector(3 downto 0);
-- Determine a good default value
DIVQ    : bit_vector(2 downto 0);
-- Determine a good default value
FILTER_RANGE    : bit_vector(2 downto 0);
-- Determine a good default value

--- Additional C-Bits
ENABLE_ICEGATE  : bit := '0';

--- Test Mode Parameter 
TEST_MODE   : bit := '0';
EXTERNAL_DIVIDE_FACTOR  : integer := 1
-- Not Used by model, Added for PLL config GUI
   );
port (
    REFERENCECLK    : in std_logic;    -- Driven by core logic
    PLLOUTCORE  : out std_logic;   -- PLL output to core logic
    PLLOUTGLOBAL    : out std_logic;   -- PLL output to global network
    EXTFEEDBACK : in std_logic;    -- Driven by core logic
    DYNAMICDELAY    : in std_logic_vector (7 downto 0); -- Driven by core 
logic
    LOCK        : out std_logic;    -- Output of PLL
    BYPASS      : in std_logic;     -- Driven by core logic
    RESETB      : in std_logic;     -- Driven by core logic
    LATCHINPUTVALUE : in std_logic;     -- iCEGate Signal
    -- Test Pins
    SDO     : out std_logic;    -- Output of PLL
    SDI     : in std_logic;     -- Driven by core logic
    SCLK        : in std_logic      -- Driven by core logic
   );
end component;
begin
SO_pll_inst: SB_PLL40_CORE
-- Fin=37, Fout=74
generic map(
         DIVR => "0000",
         DIVF => "0001111",
         DIVQ => "011",
         FILTER_RANGE => "011",
         FEEDBACK_PATH => "SIMPLE",
         DELAY_ADJUSTMENT_MODE_FEEDBACK => "FIXED",
         FDA_FEEDBACK => "0000",
         DELAY_ADJUSTMENT_MODE_RELATIVE => "FIXED",
         FDA_RELATIVE => "0000",
         SHIFTREG_DIV_MODE => "00",
         PLLOUT_SELECT => "GENCLK",
         ENABLE_ICEGATE => '0'
       )
port map(
      REFERENCECLK => REFERENCECLK,
      PLLOUTCORE => PLLOUTCORE,
      PLLOUTGLOBAL => PLLOUTGLOBAL,
      EXTFEEDBACK => openwire,
      DYNAMICDELAY => openwirebus,
      RESETB => RESET,
      BYPASS => '0',
      LATCHINPUTVALUE => openwire,
      LOCK => open,
      SDI => openwire,
      SDO => open,
      SCLK => openwire
    );

end BEHAVIOR;

I just added Design.vhd and SO_pll.vhd to the list of design files. If I run synthesis with Lattice LSE the synthesis is successful, but the placer report says 0/2 PLLs used. If I run Synthesys with Synplify Pro placer report says 1/2 PLLs used,but I really cannot use it since I have not mapped the signals.

When I get the template from SO_pll_inst.vhd and place it inside of the architecture of Design.vhd I get the error message: "ERROR - synthesis: design.vhd(19): so_pll is not declared. VHDL-1241" Well, apparently I am missing something. If it is a template, I would expect just to map my signal and have it running. But no. Either I am doing something wrong, or...I am doing something wrong :) Please help.

Vasil
  • 21
  • 5
  • I only use verilog and have zero experience with vhdl but if I see it correctly the signal S_CLK has no legal load or has it? If not the PLL would be simply optimized away under verilog if I am not mistaken. Comparing your files with the verilog versions I make the guess that SO_pll_inst.vhd is only a demonstration how to instance the PLL and you actually only need to add SO_pll.vhd but you have to be careful with the PLLOUTCORE vs PLLOUTGLOBAL usage. One is for the clk fabric and the other for the general purpose. I had a lot of trouble with the correct combination back then. – Christian B. Jun 01 '19 at 10:35
  • OK, partial success. What I did was just copy all the content of architecture of SO_pll.vhd to the architecture of Design.vhd. Removed all files except Design.vhd in Design files list of IceCube2 and I have 1 out of 2 PLLs instantiated in placer report. So far so good. However, what is the point of the two files generated from the "Configure PLL Module" GUI? Still the correct way to do it is not clear to me. – Vasil Jun 01 '19 at 10:49
  • I think the intention of the "_inst" file is that is serves as "demonstration" or "copy this and you will be fine" example. BTH my expectations regarding quality of usability etc from lattice growth quite low over the time... the correct way is to include the SO_pll.vhd file in your project and then copy the instantiton code from the SO_pll_inst.vhd file into your desired place to be and fill out the port connections. – Christian B. Jun 01 '19 at 12:17
  • case closed @Vasil or are there still open questions? – Christian B. Jun 02 '19 at 09:41
  • Hi Christian,thank you for support. Well, no, I haven't made any progress. As I said I made it work, but having all the code, including PLL to my design file. The idea behind multiple design files does not seem to work. I get your explanation but anything I try is unsuccessful. If somebody can show me how to do it would be great. If not I will just continue "as is". Regarding your question about if S_CLK has legal load - in this case not, but for the purpose of PLL instantiation it does not make a difference, in my experience. – Vasil Jun 02 '19 at 17:06
  • maybe just give it a try and only include the SO_pll to your project and add a legal load to PLLOUTCORE (e.g. route it an output pin). – Christian B. Jun 02 '19 at 18:40

1 Answers1

1

Funny - I posted the question and I am posting the answer! :) here it goes:

---Design.vhd---

library IEEE;
use IEEE.std_logic_1164.all;

entity Design is
port(
      I_CLK: in std_logic;
      I_RESET: in std_logic;
      O_PLLOUTGLOBAL : out std_logic
    );
end entity Design;

architecture RTL of Design is

begin

SO_pll_inst: entity SO_pll
port map(
          REFERENCECLK => I_CLK,
          PLLOUTCORE => open,
          PLLOUTGLOBAL => O_PLLOUTGLOBAL,
          RESET => I_RESET
        );

end RTL;

So, as obvious from the file above the key is in the instantiating of the entity of the PLL file. I was missing the keyword "entity" before the name of the entity specified in the PLL file. As expected, I was doing something wrong.

Vasil
  • 21
  • 5
  • Here you used *"entity instantiation"* but you could probably also use *"component instantiation"* like described [here](https://vhdlwhiz.com/entity-instantiation-and-component-instantiation/). Can you also try this one out and report back if it works? – 71GA Jun 24 '21 at 11:33