Lattice ICE5LP4K FPGA:如何将 HFOSC 添加到用户 vhdl

Lattice ICE5LP4K FPGA: How to add HFOSC to user vhdl

我在使用 Lattice ICE5LP4K 的内部振荡器时遇到问题。根据 iCE40 振荡器使用指南附录,verilog 中的代码应如下所示:

    SB_HFOSC OSCInst0 (
       .CLKHF_EN(ENCLKHF),
       .CLKHF_PU(CLKHF_POWERUP),
       .CLKHF(CLKHF)
     ) /* synthesis ROUTE_THROUGH_FABRIC= [0|1] */;
     Defparam OSCInst0.CLKHF_DIV = 2’b00;

我使用的代码库是 VHDL,因此我已将组件添加到我的体系结构中,如下所示:

  SB_HFOSC : OscInst0
    port map(
        CLKHF_EN  => RST_SYS_N;
        CLKHF_PU  => RST_SYS_N;
        CLKHF     => HFOSC_CLK_48MHZ
    );

当我尝试这样做时,我收到了与未定义组件 SB_HFOSC 相关的错误。然后我找到了这篇文章:lattice FPGA internal oscillator simulation issues,其中提到将晶格组件添加到您的项目文件中。

我在我的项目中添加了一个新文件,其中包含来自 sb_ice_syn_vital.vhd 的以下代码:

-----------------------------------------------------
---         SB_HFOSC        -------
------------------------------------------------
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use IEEE.Vital_Primitives.all;
use IEEE.VITAL_Timing.all;
entity  SB_HFOSC  is 
    generic( CLKHF_DIV: string:="0b00";
                Xon   : boolean := true;
                MsgOn : boolean := true;
                tipd_CLKHFEN: VitalDelayType01 := (0.000 ns, 0.000 ns);
                tipd_CLKHFPU: VitalDelayType01 := (0.000 ns, 0.000 ns);
                tpd_CLKHFEN_CLKHF : VitalDelayType01 := (0.000 ns, 0.000 ns);
                tpd_CLKHFPU_CLKHF : VitalDelayType01 := (0.000 ns, 0.000 ns)
); 
port(
    CLKHF : out std_logic;
    CLKHFEN  :in std_logic;
    CLKHFPU : in std_logic
    );
        attribute VITAL_LEVEL0 of               
    SB_HFOSC  : entity is true;
end SB_HFOSC ;

architecture SB_HFOSC_V of SB_HFOSC is
attribute VITAL_LEVEL0 of
    SB_HFOSC_V : architecture is true;
    signal CLKHFEN_ipd: std_ulogic := 'X';
    signal CLKHFPU_ipd: std_ulogic := 'X';
    signal CLKHF_sig  : std_ulogic  :='X';

component SB_HFOSC_CORE                 
generic( CLKHF_DIV: string:="0b00");    
port ( 
    CLKHF_PU : IN std_logic;
    CLKHF_EN : IN std_logic;
    CLKHF : OUT std_logic
);

end component;

begin
WireDelay : block
  begin
    VitalWireDelay (CLKHFEN_ipd, CLKHFEN, tipd_CLKHFEN);
    VitalWireDelay (CLKHFPU_ipd, CLKHFPU, tipd_CLKHFPU);
  end block;

LS: SB_HFOSC_CORE                    
GENERIC MAP (CLKHF_DIV => CLKHF_DIV)
port map(
    CLKHF_PU=> CLKHFPU_ipd,
    CLKHF_EN=> CLKHFEN,
    CLKHF=> CLKHF_sig
        );
VITALPathDelay :process (CLKHFEN_ipd,CLKHF_sig,CLKHFPU_ipd)
variable CLKHF_GlitchData : VitalGlitchDataType;  
variable CLKHF_zd  : std_ulogic :='X';
begin  
    CLKHF_zd:=CLKHF_sig;
VitalPathDelay01 (
      OutSignal                 => CLKHF,
      GlitchData                => CLKHF_GlitchData,
      OutSignalName             => "CLKHF",
      OutTemp                   => CLKHF_zd,
      Paths                     => (--0 =>(CLKHFEN_ipd'last_event, tpd_CLKHFEN_CLKHF, true),
                                    0 =>(CLKHFPU_ipd'last_event, tpd_CLKHFPU_CLKHF, true)),
      Mode                      => VitalTransport,
      Xon                       => Xon,
      MsgOn                     => MsgOn,
      MsgSeverity               => warning);
end process;

end     SB_HFOSC_V; 

我还添加了来自 vcomponent_vital.vhd:

的组件定义(到我的顶级架构)
component SB_HFOSC  is 
    generic( 
        CLKHF_DIV: string:="0b00";
        Xon   : boolean := true;
        MsgOn : boolean := true;
        tipd_CLKHFEN: VitalDelayType01 := (0.000 ns, 0.000 ns);
        tipd_CLKHFPU: VitalDelayType01 := (0.000 ns, 0.000 ns);
        tpd_CLKHFEN_CLKHF : VitalDelayType01 := (0.000 ns, 0.000 ns);
        tpd_CLKHFPU_CLKHF : VitalDelayType01 := (0.000 ns, 0.000 ns)
        ); 
    port(
        CLKHF : out std_logic;
        CLKHFEN  :in std_logic;
            CLKHFPU : in std_logic
        );
end  component;

当我尝试综合代码时,收到大量错误,所有错误似乎都与 "vitaldelaytype01" 和 "vital_level0" 未定义有关。正如您在上面的代码中看到的,我已经包含了 IEEE Vital 库。我尝试使用内置的 ICECube2 编译器和 Synplify Pro 进行编译,但在每种情况下都收到类似的错误。

我是否按照正确的流程在我的代码中实现 HFOSC?我是否需要下载 ICECube2 套件中未自动提供的其他库?

我能够通过莱迪思的客户支持门户解决这个问题。实例化lattice HFOSC IP block的正确流程如下:

在您的图书馆中包括:

library ice;

在您的组件定义中:

component SB_HFOSC  
GENERIC( CLKHF_DIV :string :="0b00");
PORT(
        CLKHFEN: IN STD_LOGIC ;
        CLKHFPU: IN STD_LOGIC;
        CLKHF:OUT STD_LOGIC
        );
END COMPONENT;

在您的实例实例化中:

   u_osc : SB_HFOSC
    GENERIC MAP(CLKHF_DIV =>"0b00")
    port map(
        CLKHFEN  => RST_SYS_N,
        CLKHFPU  => RST_SYS_N,
       CLKHF     => HFOSC_CLK_48MHZ
   );

记下引脚名称 - 它们与 Lattice 指南不同,这就是我在实例化组件时遇到问题的原因。

我在这个过程中学到的另一件有趣的事情是 HFOSC 块使用全局缓冲区,但 Lattice 工具无法预先识别,因此它可以 运行 在 post-合成P&R。要为 HFOSC 组件保留 8 个缓冲区之一,请将全局缓冲区总数限制为 7,如下所示(插入您的顶级架构定义):

attribute syn_global_buffers : integer;
attribute syn_global_buffers of struct : architecture is 7;

希望这对其他人有帮助!

罗布

iCEcube2 (2017.08.27940) 显然还没有准备好使用 "Lattice LSE Synthesis" 工具从包中取出 VHDL。

这是因为在 VERILOG 中定义的组件和 VHDL 在合成阶段看不到这些组件,除非您在 VHDL 中手动[重新]定义组件。有一个包含它们的 VHDL 包文件,但我发现其中有错误。

这是我的做法:

-将此文件添加到您的项目中:

<"icecube_installation_path">\LSE\userware\NT\SYNTHESIS_HEADERS\sb_ice40_components_syn.vhd

-修复其中的bug;编辑属性 ROUTE_THROUGH_FABRIC 以使用字符串类型而不是布尔值,并在使用它的地方使用“1”/“0”而不是 true/false。不这样做会导致 P&R 失败,但会通过综合。

-现在您可以将工作库添加到代码的顶部并像往常一样实例化:

library work;
use work.components.all;
--your code here--
osc:SB_HFOSC
generic map
(
  CLKHF_DIV     =>"0b10"    --12Mhz
)
port map
(
  CLKHFEN   =>'1',
  CLKHFPU   =>'1',
  CLKHF =>clk
);

这似乎适用于我的东西。

或者,使用板载 "Synplify Pro" 综合工具,如果我添加

library sb_ice40_components_syn;
use sb_ice40_components_syn.components.all;

到顶部,但是我在重置状态机方面遇到了严重的问题,所以我放弃了。我根本不明白如何在没有可用的内部系统级全局 set/reset 的情况下重置单热代码状态机。文档声称它在那里,但我找不到任何明确的文档如何使用它,至少不是 iCE40UL。