From: Adrian Weber Date: Wed, 4 May 2022 14:32:20 +0000 (+0200) Subject: Pll and reset handler for 240MHz on ECP5 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=f71c672ca848f0ebd8702a30c9da087cea7a4c85;p=dirich.git Pll and reset handler for 240MHz on ECP5 --- diff --git a/code/clock_reset_handler_240.vhd b/code/clock_reset_handler_240.vhd new file mode 100644 index 0000000..efedc2b --- /dev/null +++ b/code/clock_reset_handler_240.vhd @@ -0,0 +1,145 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + +library work; + use work.trb_net_components.all; + use work.trb_net_std.all; + use work.trb3_components.all; + use work.config.all; + +entity clock_reset_handler_240 is + port ( + CLOCK_IN : in std_logic; -- oscillator + RESET_FROM_NET : in std_logic; + SEND_RESET_IN : in std_logic := '0'; + + BUS_RX : in CTRLBUS_RX; + BUS_TX : out CTRLBUS_TX; + + RESET_OUT : out std_logic; + CLEAR_OUT : out std_logic; + GSR_OUT : out std_logic; + + RAW_CLK_OUT : out std_logic; -- 200/240 MHz for FPGA fabric + SYS_CLK_OUT : out std_logic; -- 100/120 MHz for FPGA fabric + REF_CLK_OUT : out std_logic; -- 200/240 internal reference clock + REF_CLK_240_OUT : out std_logic; + + DEBUG_OUT : out std_logic_vector(31 downto 0) + ); +end entity; + +architecture clock_reset_handler_240_arch of clock_reset_handler_240 is + +attribute syn_keep : boolean; +attribute syn_preserve : boolean; +signal clock_100, clock_120, clock_200, clock_240, clock_200_raw: std_logic; +signal sys_clk_i : std_logic; +signal timer : unsigned(24 downto 0) := (others => '0'); +signal clear_n_i : std_logic := '0'; +signal reset_i, reset_rising, last_reset_i : std_logic; +signal debug_reset_handler : std_logic_vector(15 downto 0); +signal send_reset_detect, trb_reset_i : std_logic := '0'; +signal pll_lock, pll_lock_200, pll_lock_240 : std_logic; + +attribute syn_keep of clear_n_i : signal is true; +attribute syn_preserve of clear_n_i : signal is true; + +begin + + +SYS_CLK_OUT <= sys_clk_i; +GSR_OUT <= not pll_lock or clear_n_i; + +THE_PLL : entity work.pll_240_100 --PLL with 200 MHz input! + port map( + CLKI => CLOCK_IN, + CLKOP => clock_200_raw, + CLKOS => clock_100, + CLKOS2 => clock_200, --clock_240, + CLKOS3 => clock_120, + LOCK => pll_lock_200 + ); + +THE_PLL_240 : entity work.pll_200_240 --PLL with 240 MHz input! + port map( + CLKI => clock_200_raw, + CLKOP => clock_240, + LOCK => pll_lock_240 + ); + + pll_lock <= pll_lock_200 and pll_lock_240; + + REF_CLK_240_OUT <= clock_240; + +gen_slow_clock : if USE_120_MHZ = 0 generate + RAW_CLK_OUT <= clock_200_raw; + sys_clk_i <= clock_100; + REF_CLK_OUT <= clock_200_raw; +end generate; +gen_fast_clock : if USE_120_MHZ = 1 generate + RAW_CLK_OUT <= clock_240; + sys_clk_i <= clock_120; + REF_CLK_OUT <= clock_240; +end generate; + + +clear_n_i <= timer(22) when rising_edge(clock_200_raw); + +process begin + wait until rising_edge(sys_clk_i); + + if timer(22) = '1' then + timer <= timer; + elsif reset_rising = '1' then + timer <= (others => '0'); + elsif pll_lock = '1' then + timer <= timer + 1; + end if; +end process; + + +--------------------------------------------------------------------------- +-- Reset generation +--------------------------------------------------------------------------- +THE_RESET_HANDLER : trb_net_reset_handler + generic map( + RESET_DELAY => x"FEEE" + ) + port map( + CLEAR_IN => '0', -- reset input (high active, async) + CLEAR_N_IN => clear_n_i, -- reset input (low active, async) + CLK_IN => clock_200_raw, -- raw master clock, NOT from PLL/DLL! + SYSCLK_IN => sys_clk_i, -- PLL/DLL remastered clock + PLL_LOCKED_IN => pll_lock, -- master PLL lock signal (async) + RESET_IN => '0', -- general reset signal (SYSCLK) + TRB_RESET_IN => trb_reset_i, -- TRBnet reset signal (SYSCLK) + CLEAR_OUT => CLEAR_OUT, -- async reset out, USE WITH CARE! + RESET_OUT => reset_i, -- synchronous reset out (SYSCLK) + DEBUG_OUT => debug_reset_handler + ); + +RESET_OUT <= reset_i; +send_reset_detect <= SEND_RESET_IN when rising_edge(clock_200_raw); +trb_reset_i <= RESET_FROM_NET or (send_reset_detect and not SEND_RESET_IN); + +last_reset_i <= reset_i when rising_edge(clock_200_raw); +reset_rising <= reset_i and not last_reset_i; + +--------------------------------------------------------------------------- +-- Slow clock for DCDC converters +--------------------------------------------------------------------------- +DEBUG_OUT(0) <= pll_lock; +DEBUG_OUT(1) <= clear_n_i; +DEBUG_OUT(15 downto 2) <= debug_reset_handler(15 downto 2); +DEBUG_OUT(31 downto 16) <= (others => '0'); + +BUS_TX.data <= (others => '0'); +BUS_TX.unknown <= '1'; +BUS_TX.ack <= '0'; +BUS_TX.nack <= '0'; + + + +end architecture; diff --git a/cores/ecp5/pll_200_240.ipx b/cores/ecp5/pll_200_240.ipx new file mode 100644 index 0000000..7076f39 --- /dev/null +++ b/cores/ecp5/pll_200_240.ipx @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/cores/ecp5/pll_200_240.lpc b/cores/ecp5/pll_200_240.lpc new file mode 100644 index 0000000..28e9ba3 --- /dev/null +++ b/cores/ecp5/pll_200_240.lpc @@ -0,0 +1,93 @@ +[Device] +Family=ecp5um +PartType=LFE5UM-85F +PartName=LFE5UM-85F-8BG381C +SpeedGrade=8 +Package=CABGA381 +OperatingCondition=COM +Status=P + +[IP] +VendorName=Lattice Semiconductor Corporation +CoreType=LPM +CoreStatus=Demo +CoreName=PLL +CoreRevision=5.8 +ModuleName=pll_200_240 +SourceFormat=VHDL +ParameterFileVersion=1.0 +Date=04/22/2022 +Time=15:36:31 + +[Parameters] +Verilog=0 +VHDL=1 +EDIF=1 +Destination=Synplicity +Expression=None +Order=None +IO=0 +CLKI_FREQ=200.00 +CLKI_DIV=5 +ENABLE_HBW=DISABLED +REFERENCE=0 +IOBUF=LVDS +CLKOP_FREQ=240.00 +CLKOP_TOL=0.0 +CLKOP_DIV=2 +CLKOP_ACTUAL_FREQ=240.000000 +CLKOP_MUXA=DISABLED +CLKOS_Enable=DISABLED +CLKOS_FREQ=100.00 +CLKOS_TOL=0.0 +CLKOS_DIV=1 +CLKOS_ACTUAL_FREQ= +CLKOS_MUXB=DISABLED +CLKOS2_Enable=DISABLED +CLKOS2_FREQ=100.00 +CLKOS2_TOL=0.0 +CLKOS2_DIV=1 +CLKOS2_ACTUAL_FREQ= +CLKOS2_MUXC=DISABLED +CLKOS3_Enable=DISABLED +CLKOS3_FREQ=100.00 +CLKOS3_TOL=0.0 +CLKOS3_DIV=1 +CLKOS3_ACTUAL_FREQ= +CLKOS3_MUXD=DISABLED +FEEDBK_PATH=CLKOP +CLKFB_DIV=6 +FRACN_ENABLE=DISABLED +FRACN_DIV= +VCO_RATE=480.000 +PLL_BW=4.775 +CLKOP_DPHASE=0 +CLKOP_APHASE=0.00 +CLKOP_TRIM_POL=Rising +CLKOP_TRIM_DELAY=0 +CLKOS_DPHASE=0 +CLKOS_APHASE=0.00 +CLKOS_TRIM_POL=Rising +CLKOS_TRIM_DELAY=0 +CLKOS2_DPHASE=0 +CLKOS2_APHASE=0.00 +CLKOS2_TRIM_POL=Rising +CLKOS2_TRIM_DELAY=0 +CLKOS3_DPHASE=0 +CLKOS3_APHASE=0.00 +CLKOS3_TRIM_POL=Rising +CLKOS3_TRIM_DELAY=0 +CLKSEL_ENA=DISABLED +DPHASE_SOURCE=STATIC +ENABLE_CLKOP=DISABLED +ENABLE_CLKOS=DISABLED +ENABLE_CLKOS2=DISABLED +ENABLE_CLKOS3=DISABLED +STDBY_ENABLE=DISABLED +PLLRST_ENA=DISABLED +PLL_LOCK_MODE=ENABLED +PLL_LOCK_STK=DISABLED +PLL_USE_SMI=DISABLED + +[Command] +cmd_line= -w -n pll_200_240 -lang vhdl -synth synplify -arch sa5p00m -type pll -fin 200.00 -fclkop 240.00 -fclkop_tol 0.0 -phase_cntl STATIC -lock -fb_mode 1 diff --git a/cores/ecp5/pll_200_240.vhd b/cores/ecp5/pll_200_240.vhd new file mode 100644 index 0000000..8af25c6 --- /dev/null +++ b/cores/ecp5/pll_200_240.vhd @@ -0,0 +1,71 @@ +-- VHDL netlist generated by SCUBA Diamond (64-bit) 3.11.2.446 +-- Module Version: 5.7 +--/usr/local/diamond/3.11_x64/ispfpga/bin/lin64/scuba -w -n pll_200_240 -lang vhdl -synth synplify -arch sa5p00m -type pll -fin 200.00 -fclkop 240.00 -fclkop_tol 0.0 -phase_cntl STATIC -lock -fb_mode 1 + +-- Fri Apr 22 15:36:31 2022 + +library IEEE; +use IEEE.std_logic_1164.all; +library ecp5um; +use ecp5um.components.all; + +entity pll_200_240 is + port ( + CLKI: in std_logic; + CLKOP: out std_logic; + LOCK: out std_logic); +end pll_200_240; + +architecture Structure of pll_200_240 is + + -- internal signal declarations + signal REFCLK: std_logic; + signal CLKOP_t: std_logic; + signal scuba_vhi: std_logic; + signal scuba_vlo: std_logic; + + attribute FREQUENCY_PIN_CLKOP : string; + attribute FREQUENCY_PIN_CLKI : string; + attribute ICP_CURRENT : string; + attribute LPF_RESISTOR : string; + attribute FREQUENCY_PIN_CLKOP of PLLInst_0 : label is "240.000000"; + attribute FREQUENCY_PIN_CLKI of PLLInst_0 : label is "200.000000"; + attribute ICP_CURRENT of PLLInst_0 : label is "9"; + attribute LPF_RESISTOR of PLLInst_0 : label is "8"; + attribute syn_keep : boolean; + attribute NGD_DRC_MASK : integer; + attribute NGD_DRC_MASK of Structure : architecture is 1; + +begin + -- component instantiation statements + scuba_vhi_inst: VHI + port map (Z=>scuba_vhi); + + scuba_vlo_inst: VLO + port map (Z=>scuba_vlo); + + PLLInst_0: EHXPLLL + generic map (PLLRST_ENA=> "DISABLED", INTFB_WAKE=> "DISABLED", + STDBY_ENABLE=> "DISABLED", DPHASE_SOURCE=> "DISABLED", + CLKOS3_FPHASE=> 0, CLKOS3_CPHASE=> 0, CLKOS2_FPHASE=> 0, + CLKOS2_CPHASE=> 0, CLKOS_FPHASE=> 0, CLKOS_CPHASE=> 0, + CLKOP_FPHASE=> 0, CLKOP_CPHASE=> 1, PLL_LOCK_MODE=> 0, + CLKOS_TRIM_DELAY=> 0, CLKOS_TRIM_POL=> "FALLING", + CLKOP_TRIM_DELAY=> 0, CLKOP_TRIM_POL=> "FALLING", + OUTDIVIDER_MUXD=> "DIVD", CLKOS3_ENABLE=> "DISABLED", + OUTDIVIDER_MUXC=> "DIVC", CLKOS2_ENABLE=> "DISABLED", + OUTDIVIDER_MUXB=> "DIVB", CLKOS_ENABLE=> "DISABLED", + OUTDIVIDER_MUXA=> "DIVA", CLKOP_ENABLE=> "ENABLED", CLKOS3_DIV=> 1, + CLKOS2_DIV=> 1, CLKOS_DIV=> 1, CLKOP_DIV=> 2, CLKFB_DIV=> 6, + CLKI_DIV=> 5, FEEDBK_PATH=> "CLKOP") + port map (CLKI=>CLKI, CLKFB=>CLKOP_t, PHASESEL1=>scuba_vlo, + PHASESEL0=>scuba_vlo, PHASEDIR=>scuba_vlo, + PHASESTEP=>scuba_vlo, PHASELOADREG=>scuba_vlo, + STDBY=>scuba_vlo, PLLWAKESYNC=>scuba_vlo, RST=>scuba_vlo, + ENCLKOP=>scuba_vlo, ENCLKOS=>scuba_vlo, ENCLKOS2=>scuba_vlo, + ENCLKOS3=>scuba_vlo, CLKOP=>CLKOP_t, CLKOS=>open, + CLKOS2=>open, CLKOS3=>open, LOCK=>LOCK, INTLOCK=>open, + REFCLK=>REFCLK, CLKINTFB=>open); + + CLKOP <= CLKOP_t; +end Structure;