1
0
mirror of https://github.com/wfjm/w11.git synced 2026-05-04 07:09:48 +00:00
Files
wfjm.w11/rtl/vlib/xlib/s7_cmt_sfs_2_gsim.vhd
2019-07-12 19:01:49 +02:00

164 lines
5.2 KiB
VHDL

-- $Id: s7_cmt_sfs_2_gsim.vhd 1181 2019-07-08 17:00:50Z mueller $
-- SPDX-License-Identifier: GPL-3.0-or-later
-- Copyright 2018- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
------------------------------------------------------------------------------
-- Module Name: s7_cmt_sfs_2 - sim
-- Description: Series-7 CMT for dual-channel frequency synthesis
-- simple vhdl model, without Xilinx UNISIM primitives
--
-- Dependencies: -
-- Test bench: -
-- Target Devices: generic Series-7
-- Tool versions: viv 2017.2; ghdl 0.34
--
-- Revision History:
-- Date Rev Version Comment
-- 2018-11-18 1072 1.0 Initial version (derived from s7_cmt_sfs_3_gsim)
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.slvtypes.all;
use work.xlib.all;
entity s7_cmt_sfs_2 is -- 7-Series CMT for dual freq. synth.
generic (
VCO_DIVIDE : positive := 1; -- vco clock divide
VCO_MULTIPLY : positive := 1; -- vco clock multiply
OUT0_DIVIDE : positive := 1; -- output 0 divide
OUT1_DIVIDE : positive := 1; -- output 1 divide
CLKIN_PERIOD : real := 10.0; -- CLKIN period (def is 10.0 ns)
CLKIN_JITTER : real := 0.01; -- CLKIN jitter (def is 10 ps)
STARTUP_WAIT : boolean := false; -- hold FPGA startup till LOCKED
GEN_TYPE : string := "PLL"); -- PLL or MMCM
port (
CLKIN : in slbit; -- clock input
CLKOUT0 : out slbit; -- clock output 0
CLKOUT1 : out slbit; -- clock output 1
LOCKED : out slbit -- pll/mmcm locked
);
end s7_cmt_sfs_2;
architecture sim of s7_cmt_sfs_2 is
signal LOCKED0 : slbit := '1';
signal LOCKED1 : slbit := '1';
begin
proc_init : process
-- currently frequency limits taken from Artix-7 speed grade -1
constant f_vcomin_pll : integer := 800;
constant f_vcomax_pll : integer := 1600;
constant f_pdmin_pll : integer := 19;
constant f_pdmax_pll : integer := 450;
constant f_vcomin_mmcm : integer := 600;
constant f_vcomax_mmcm : integer := 1200;
constant f_pdmin_mmcm : integer := 10;
constant f_pdmax_mmcm : integer := 450;
variable t_vco : Delay_length := 0 ns;
variable t_vcomin : Delay_length := 0 ns;
variable t_vcomax : Delay_length := 0 ns;
variable t_pd : Delay_length := 0 ns;
variable t_pdmin : Delay_length := 0 ns;
variable t_pdmax : Delay_length := 0 ns;
begin
-- validate generics
if not (GEN_TYPE = "PLL" or GEN_TYPE = "MMCM") then
report "assert(GEN_TYPE='PLL' or GEN_TYPE='MMCM')"
severity failure;
end if;
if VCO_DIVIDE/=1 or VCO_MULTIPLY/=1 or
OUT0_DIVIDE/=1 or OUT1_DIVIDE/=1 then
if GEN_TYPE = "PLL" then
-- check DIV/MULT parameter range
if VCO_DIVIDE<1 or VCO_DIVIDE>56 or
VCO_MULTIPLY<2 or VCO_MULTIPLY>64 or
OUT0_DIVIDE<1 or OUT0_DIVIDE>128 or
OUT1_DIVIDE<1 or OUT1_DIVIDE>128
then
report
"assert(VCO_DIVIDE in 1:56 VCO_MULTIPLY in 2:64 OUTx_DIVIDE in 1:128)"
severity failure;
end if;
-- setup VCO and PD range check boundaries
t_vcomin := (1000 ns / f_vcomax_pll) - 1 ps;
t_vcomax := (1000 ns / f_vcomin_pll) + 1 ps;
t_pdmin := (1000 ns / f_pdmax_pll) - 1 ps;
t_pdmax := (1000 ns / f_pdmin_pll) + 1 ps;
end if; -- GEN_TYPE = "PLL"
if GEN_TYPE = "MMCM" then
-- check DIV/MULT parameter range
if VCO_DIVIDE<1 or VCO_DIVIDE>106 or
VCO_MULTIPLY<2 or VCO_MULTIPLY>64 or
OUT0_DIVIDE<1 or OUT0_DIVIDE>128 or
OUT1_DIVIDE<1 or OUT1_DIVIDE>128
then
report
"assert(VCO_DIVIDE in 1:106 VCO_MULTIPLY in 2:64 OUTx_DIVIDE in 1:128)"
severity failure;
end if;
-- setup VCO and PD range check boundaries
t_vcomin := (1000 ns / f_vcomax_mmcm) - 1 ps;
t_vcomax := (1000 ns / f_vcomin_mmcm) + 1 ps;
t_pdmin := (1000 ns / f_pdmax_mmcm) - 1 ps;
t_pdmax := (1000 ns / f_pdmin_mmcm) + 1 ps;
end if; -- GEN_TYPE = "MMCM"
-- now common check whether VCO and PD frequency is in range
t_pd := (1 ps * (1000.0*CLKIN_PERIOD)) * VCO_DIVIDE;
t_vco := t_pd / VCO_MULTIPLY;
if t_vco<t_vcomin or t_vco>t_vcomax then
report "assert(VCO frequency out of range)"
severity failure;
end if;
if t_pd<t_pdmin or t_pd>t_pdmax then
report "assert(PD frequency out of range)"
severity failure;
end if;
end if; -- one factor /= 1
wait;
end process proc_init;
-- generate clock
SFS0: sfs_gsim_core
generic map (
VCO_DIVIDE => VCO_DIVIDE,
VCO_MULTIPLY => VCO_MULTIPLY,
OUT_DIVIDE => OUT0_DIVIDE)
port map (
CLKIN => CLKIN,
CLKFX => CLKOUT0,
LOCKED => LOCKED0
);
SFS1: sfs_gsim_core
generic map (
VCO_DIVIDE => VCO_DIVIDE,
VCO_MULTIPLY => VCO_MULTIPLY,
OUT_DIVIDE => OUT1_DIVIDE)
port map (
CLKIN => CLKIN,
CLKFX => CLKOUT1,
LOCKED => LOCKED1
);
LOCKED <= LOCKED0 and LOCKED1;
end sim;