w11 - vhd  0.752
W11 CPU core and support modules
s7_cmt_sfs_tb.vhd
Go to the documentation of this file.
1 -- $Id: s7_cmt_sfs_tb.vhd 984 2018-01-02 20:56:27Z mueller $
2 --
3 -- Copyright 2016- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 --
5 -- This program is free software; you may redistribute and/or modify it under
6 -- the terms of the GNU General Public License as published by the Free
7 -- Software Foundation, either version 3, or (at your option) any later version.
8 --
9 -- This program is distributed in the hope that it will be useful, but
10 -- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 -- for complete details.
13 --
14 ------------------------------------------------------------------------------
15 -- Module Name: s7_cmt_sfs_tb - sim
16 -- Description: Series-7 CMT for simple frequency synthesis (SIM only!)
17 -- simple vhdl model, without Xilinx UNISIM primitives
18 --
19 -- Dependencies: -
20 -- Test bench: -
21 -- Target Devices: generic Series-7
22 -- Tool versions: xst 14.7; viv 2015.4-2016.2; ghdl 0.31-0.33
23 --
24 -- Revision History:
25 -- Date Rev Version Comment
26 -- 2016-08-18 799 1.1.1 remove 'assert false' from report statements
27 -- 2016-04-09 760 1.1 BUGFIX: correct mmcm range check boundaries
28 -- 2016-02-20 734 1.0 Initial version (copied from s7_cmt_sfs_gsim)
29 ------------------------------------------------------------------------------
30 
31 library ieee;
32 use ieee.std_logic_1164.all;
33 
34 use work.slvtypes.all;
35 
36 entity s7_cmt_sfs_tb is -- 7-Series CMT for simple freq. synth.
37  generic (
38  VCO_DIVIDE : positive := 1; -- vco clock divide
39  VCO_MULTIPLY : positive := 1; -- vco clock multiply
40  OUT_DIVIDE : positive := 1; -- output divide
41  CLKIN_PERIOD : real := 10.0; -- CLKIN period (def is 10.0 ns)
42  CLKIN_JITTER : real := 0.01; -- CLKIN jitter (def is 10 ps)
43  STARTUP_WAIT : boolean := false; -- hold FPGA startup till LOCKED
44  GEN_TYPE : string := "PLL"); -- PLL or MMCM
45  port (
46  CLKIN : in slbit; -- clock input
47  CLKFX : out slbit; -- clock output (synthesized freq.)
48  LOCKED : out slbit -- pll/mmcm locked
49  );
50 end s7_cmt_sfs_tb;
51 
52 
53 architecture sim of s7_cmt_sfs_tb is
54 
55  signal CLK_DIVPULSE : slbit := '0';
56  signal CLKOUT_PERIOD : Delay_length := 0 ns;
57  signal R_CLKOUT : slbit := '0';
58  signal R_LOCKED : slbit := '0';
59 
60 begin
61 
62  proc_init : process
63 
64  -- currently frequency limits taken from Artix-7 speed grade -1
65  constant f_vcomin_pll: integer := 800;
66  constant f_vcomax_pll: integer := 1600;
67  constant f_pdmin_pll: integer := 19;
68  constant f_pdmax_pll: integer := 450;
69 
70  constant f_vcomin_mmcm: integer := 600;
71  constant f_vcomax_mmcm: integer := 1200;
72  constant f_pdmin_mmcm: integer := 10;
73  constant f_pdmax_mmcm: integer := 450;
74 
75  variable t_vco : Delay_length := 0 ns;
76  variable t_vcomin : Delay_length := 0 ns;
77  variable t_vcomax : Delay_length := 0 ns;
78  variable t_pd : Delay_length := 0 ns;
79  variable t_pdmin : Delay_length := 0 ns;
80  variable t_pdmax : Delay_length := 0 ns;
81 
82  begin
83  -- validate generics
84 
85 
86  if not (GEN_TYPE = "PLL" or GEN_TYPE = "MMCM") then
87  report "assert(GEN_TYPE='PLL' or GEN_TYPE='MMCM')"
88  severity failure;
89  end if;
90 
91  if VCO_DIVIDE/=1 or VCO_MULTIPLY/=1 or OUT_DIVIDE/=1 then
92 
93  if GEN_TYPE = "PLL" then
94  -- check DIV/MULT parameter range
95  if VCO_DIVIDE<1 or VCO_DIVIDE>56 or
96  VCO_MULTIPLY<2 or VCO_MULTIPLY>64 or
97  OUT_DIVIDE<1 or OUT_DIVIDE>128
98  then
99  report
100  "assert(VCO_DIVIDE in 1:56 VCO_MULTIPLY in 2:64 OUT_DIVIDE in 1:128)"
101  severity failure;
102  end if;
103  -- setup VCO and PD range check boundaries
104  t_vcomin := (1000 ns / f_vcomax_pll) - 1 ps;
105  t_vcomax := (1000 ns / f_vcomin_pll) + 1 ps;
106  t_pdmin := (1000 ns / f_pdmax_pll) - 1 ps;
107  t_pdmax := (1000 ns / f_pdmin_pll) + 1 ps;
108 
109  end if; -- GEN_TYPE = "PLL"
110 
111  if GEN_TYPE = "MMCM" then
112  -- check DIV/MULT parameter range
113  if VCO_DIVIDE<1 or VCO_DIVIDE>106 or
114  VCO_MULTIPLY<2 or VCO_MULTIPLY>64 or
115  OUT_DIVIDE<1 or OUT_DIVIDE>128
116  then
117  report
118  "assert(VCO_DIVIDE in 1:106 VCO_MULTIPLY in 2:64 OUT_DIVIDE in 1:128)"
119  severity failure;
120  end if;
121  -- setup VCO and PD range check boundaries
122  t_vcomin := (1000 ns / f_vcomax_mmcm) - 1 ps;
123  t_vcomax := (1000 ns / f_vcomin_mmcm) + 1 ps;
124  t_pdmin := (1000 ns / f_pdmax_mmcm) - 1 ps;
125  t_pdmax := (1000 ns / f_pdmin_mmcm) + 1 ps;
126 
127  end if; -- GEN_TYPE = "MMCM"
128 
129  -- now common check whether VCO and PD frequency is in range
130  t_pd := (1 ps * (1000.0*CLKIN_PERIOD)) * VCO_DIVIDE;
131  t_vco := t_pd / VCO_MULTIPLY;
132 
133  if t_vco<t_vcomin or t_vco>t_vcomax then
134  report "assert(VCO frequency out of range); t_cvo: "
135  & time'image(t_vco)
136  severity failure;
137  end if;
138 
139  if t_pd<t_pdmin or t_pd>t_pdmax then
140  report "assert(PD frequency out of range)"
141  severity failure;
142  end if;
143 
144  end if; -- one factor /= 1
145 
146  wait;
147  end process proc_init;
148 
149  proc_clkin : process (CLKIN)
150  variable t_lastclkin : time := 0 ns;
151  variable t_lastperiod : Delay_length := 0 ns;
152  variable t_period : Delay_length := 0 ns;
153  variable nclkin : integer := 1;
154  begin
155 
156  if CLKIN'event then
157  if CLKIN = '1' then -- if CLKIN rising edge
158 
159  if t_lastclkin > 0 ns then
160  t_lastperiod := t_period;
161  t_period := now - t_lastclkin;
162  CLKOUT_PERIOD <= (t_period * VCO_DIVIDE * OUT_DIVIDE) / VCO_MULTIPLY;
163  if t_lastperiod > 0 ns and abs(t_period-t_lastperiod) > 1 ps then
164  report "s7_cmt_sp_sfs: CLKIN unstable" severity warning;
165  end if;
166  end if;
167  t_lastclkin := now;
168 
169  if t_period > 0 ns then
170  nclkin := nclkin - 1;
171  if nclkin <= 0 then
172  nclkin := VCO_DIVIDE * OUT_DIVIDE;
173  CLK_DIVPULSE <= '1';
174  R_LOCKED <= '1';
175  end if;
176  end if;
177 
178  else -- if CLKIN falling edge
179  CLK_DIVPULSE <= '0';
180  end if;
181  end if;
182 
183  end process proc_clkin;
184 
185  proc_clkout : process
186  variable t_lastclkin : time := 0 ns;
187  variable t_lastperiod : Delay_length := 0 ns;
188  variable t_period : Delay_length := 0 ns;
189  variable nclkin : integer := 1;
190  begin
191 
192  loop
193  wait until CLK_DIVPULSE = '1';
194 
195  for i in 1 to VCO_MULTIPLY loop
196  R_CLKOUT <= '1';
197  wait for CLKOUT_PERIOD/2;
198  R_CLKOUT <= '0';
199  if i /= VCO_MULTIPLY then
200  wait for CLKOUT_PERIOD/2;
201  end if;
202  end loop; -- i
203 
204  end loop;
205 
206  end process proc_clkout;
207 
208  CLKFX <= R_CLKOUT;
209  LOCKED <= R_LOCKED;
210 
211 end sim;
slbit := '0' R_LOCKED
OUT_DIVIDEpositive := 1
CLKIN_JITTERreal := 0.01
Delay_length := 0 ns CLKOUT_PERIOD
slbit := '0' R_CLKOUT
out CLKFXslbit
slbit := '0' CLK_DIVPULSE
VCO_DIVIDEpositive := 1
CLKIN_PERIODreal := 10.0
GEN_TYPEstring := "PLL"
_library_ ieeeieee
in CLKINslbit
STARTUP_WAITboolean := false
VCO_MULTIPLYpositive := 1
std_logic slbit
Definition: slvtypes.vhd:39