1 |
2 |
jclaytons |
--------------------------------------------------------------------------
|
2 |
|
|
-- Package of bit sync and DPLL components
|
3 |
|
|
--
|
4 |
|
|
--
|
5 |
|
|
--
|
6 |
|
|
|
7 |
|
|
library IEEE;
|
8 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
9 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
10 |
|
|
use IEEE.MATH_REAL.ALL;
|
11 |
|
|
|
12 |
|
|
package bit_sync_pack is
|
13 |
|
|
|
14 |
|
|
-- Component declarations not provided any more.
|
15 |
|
|
-- With VHDL '93 and newer, component declarations are allowed,
|
16 |
|
|
-- but not required.
|
17 |
|
|
--
|
18 |
|
|
-- Please to use direct instantiation instead, for example:
|
19 |
|
|
--
|
20 |
|
|
-- instance_name : entity work.entity_name(beh)
|
21 |
|
|
--
|
22 |
|
|
|
23 |
|
|
end bit_sync_pack;
|
24 |
|
|
|
25 |
|
|
-------------------------------------------------------------------------------
|
26 |
|
|
-- Maximum-cycle Linear Feedback Shift Register (MLFSR)
|
27 |
|
|
-------------------------------------------------------------------------------
|
28 |
|
|
--
|
29 |
|
|
-- Author: John Clayton
|
30 |
|
|
-- Date : Dec. 18, 2015 Started Coding, drawing inspiration from online
|
31 |
|
|
-- resources.
|
32 |
|
|
-- Apr. 19, 2018 Corrected the entity name to actually match the
|
33 |
|
|
-- module name : mlfsr
|
34 |
|
|
--
|
35 |
|
|
-- Description
|
36 |
|
|
-------------------------------------------------------------------------------
|
37 |
|
|
-- This module applies a modulo 2 polynomial as feedback to a shift register
|
38 |
|
|
-- in order to generate a maximum-cycle pseudo random sequence.
|
39 |
|
|
-- The maximum cycle is length 2^N-1 bits, where N is the number of bits
|
40 |
|
|
-- in the shift register.
|
41 |
|
|
--
|
42 |
|
|
-- Generic parameters control the length of the shift register, and the
|
43 |
|
|
-- particular polynomial taps applied. The polynomial is not completely
|
44 |
|
|
-- generic, in the sense that only up to four taps can be implemented.
|
45 |
|
|
-- This constraint was deemed acceptable, since for any shift register
|
46 |
|
|
-- of length N stages, a maximum cycle output can be obtained using either
|
47 |
|
|
-- two or four taps.
|
48 |
|
|
--
|
49 |
|
|
-- The polynomials are assumed to have two or four non-zero terms, in addition
|
50 |
|
|
-- to the zeroth order term, which is always a 1.
|
51 |
|
|
--
|
52 |
|
|
-- For those who are curious, the binary Galois representation is used here.
|
53 |
|
|
--
|
54 |
|
|
-- The tap inputs are natural numbers which represent the position of the tap
|
55 |
|
|
-- within the shift register. If tap position is set to zero, then the tap is
|
56 |
|
|
-- not used. Please don't get funky with this. If you are implementing a
|
57 |
|
|
-- polynomial with two terms only, set POLY_C and POLY_D to zero. POLY_A
|
58 |
|
|
-- sets the length of the shift register, so it must not be set to zero.
|
59 |
|
|
-- Is this copascetic with you?
|
60 |
|
|
--
|
61 |
|
|
-- In order to obtain a maximum cycle output, there must always be an even
|
62 |
|
|
-- number of taps used, and the positions of the taps must be relatively prime.
|
63 |
|
|
-- Note that these conditions are necessary, but not sufficient, to produce
|
64 |
|
|
-- the maximum-cycle output. Any polynomial which *does* produce the maximum
|
65 |
|
|
-- cycle output is called "primitive."
|
66 |
|
|
--
|
67 |
|
|
-- Many examples of primitive polynomials are listed in various tables.
|
68 |
|
|
-- This module was coded while referring to "Table of Linear Feedback Shift
|
69 |
|
|
-- Registers" by Roy Ward and Tim Molteno.
|
70 |
|
|
--
|
71 |
|
|
-- Some "primitive polynomials" are:
|
72 |
|
|
-- 2,1
|
73 |
|
|
-- 3,2
|
74 |
|
|
-- 4,3
|
75 |
|
|
-- 5,3
|
76 |
|
|
-- 5,4,3,2
|
77 |
|
|
-- 6,5
|
78 |
|
|
-- 6,5,3,2
|
79 |
|
|
-- 7,6
|
80 |
|
|
-- 7,6,5,4
|
81 |
|
|
-- 16,14,13,11
|
82 |
|
|
-- 24,23,21,20
|
83 |
|
|
-- 32,30,26,25
|
84 |
|
|
-- 64,63,61,60
|
85 |
|
|
-- 128,127,126,121
|
86 |
|
|
-- 255,203
|
87 |
|
|
-- 256,254,251,246
|
88 |
|
|
-- 511,501
|
89 |
|
|
-- 512,510,507,504
|
90 |
|
|
-- 785,693
|
91 |
|
|
-- 1024,1015,1002,1001
|
92 |
|
|
-- 2048,2035,2034,2029
|
93 |
|
|
-- 4096,4095,4081,4069
|
94 |
|
|
--
|
95 |
|
|
-- The number of bits in the shift register is equal to the polynomial's
|
96 |
|
|
-- order, and also equal to the highest tap position number.
|
97 |
|
|
--
|
98 |
|
|
|
99 |
|
|
library IEEE;
|
100 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
101 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
102 |
|
|
use IEEE.MATH_REAL.ALL;
|
103 |
|
|
|
104 |
|
|
entity mlfsr is
|
105 |
|
|
generic(
|
106 |
|
|
POLY_A : natural := 8; -- Polynomial tap, also number of bits in shift register
|
107 |
|
|
POLY_B : natural := 6; -- Polynomial tap, less than POLY_A
|
108 |
|
|
POLY_C : natural := 5; -- Polynomial tap, less than POLY_B
|
109 |
|
|
POLY_D : natural := 4 -- Polynomial tap, less than POLY_C
|
110 |
|
|
);
|
111 |
|
|
port (
|
112 |
|
|
-- System Clock and Clock Enable
|
113 |
|
|
sys_rst_n : in std_logic;
|
114 |
|
|
sys_clk : in std_logic;
|
115 |
|
|
sys_clk_en : in std_logic;
|
116 |
|
|
|
117 |
|
|
-- Sequence Output
|
118 |
|
|
pn_seq_o : out std_logic
|
119 |
|
|
|
120 |
|
|
);
|
121 |
|
|
end mlfsr;
|
122 |
|
|
|
123 |
|
|
architecture beh of mlfsr is
|
124 |
|
|
|
125 |
|
|
-- Constants
|
126 |
|
|
|
127 |
|
|
-- Functions & associated types
|
128 |
|
|
|
129 |
|
|
-- Signal Declarations
|
130 |
|
|
signal sr : unsigned(POLY_A-1 downto 0);
|
131 |
|
|
signal sr_next : unsigned(POLY_A-1 downto 0);
|
132 |
|
|
|
133 |
|
|
begin
|
134 |
|
|
|
135 |
|
|
process (sys_clk, sys_rst_n)
|
136 |
|
|
begin
|
137 |
|
|
if (sys_rst_n='0') then
|
138 |
|
|
sr <= (others=>'1');
|
139 |
|
|
elsif (sys_clk'event and sys_clk='1') then
|
140 |
|
|
if (sys_clk_en='1') then
|
141 |
|
|
sr <= sr_next;
|
142 |
|
|
end if; -- sys_clk_en
|
143 |
|
|
end if; -- sys_clk
|
144 |
|
|
end process;
|
145 |
|
|
|
146 |
|
|
gen_sr_next : for i in 0 to POLY_A-2 generate
|
147 |
|
|
sr_next(i) <= sr(i+1) xor sr(0) when (i=POLY_B or i=POLY_C or i=POLY_D) else
|
148 |
|
|
sr(i+1);
|
149 |
|
|
end generate gen_sr_next;
|
150 |
|
|
sr_next(sr_next'length-1) <= sr(0);
|
151 |
|
|
|
152 |
|
|
pn_seq_o <= sr(0);
|
153 |
|
|
|
154 |
|
|
end beh;
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
-------------------------------------------------------------------------------
|
158 |
|
|
-- PCM signal bit period detector
|
159 |
|
|
-------------------------------------------------------------------------------
|
160 |
|
|
--
|
161 |
|
|
-- Author: John Clayton
|
162 |
|
|
-- Date : Jan. 31, 2012 Started Coding, drawing from various other sources.
|
163 |
|
|
-- Created description.
|
164 |
|
|
-- Feb. 6, 2012 Simulated and refined code. Added output register.
|
165 |
|
|
-- Mar. 16, 2012 Made load_o a registered signal, so that the load
|
166 |
|
|
-- pulses emerge when the new period information does.
|
167 |
|
|
--
|
168 |
|
|
--
|
169 |
|
|
-- Description
|
170 |
|
|
-------------------------------------------------------------------------------
|
171 |
|
|
-- This module applies a finite state machine controlled series of
|
172 |
|
|
-- measurements to an incoming digital data signal, and uses the measurements
|
173 |
|
|
-- to arrive at an estimate of the incoming signal's bit rate.
|
174 |
|
|
--
|
175 |
|
|
-- A successive approximation technique is used.
|
176 |
|
|
--
|
177 |
|
|
-- The way it works is as follows: There are synchronizing flip-flops placed
|
178 |
|
|
-- to prevent metastability issues with the incoming signal. Edge detectors
|
179 |
|
|
-- are then created using the outputs of these flip-flops.
|
180 |
|
|
--
|
181 |
|
|
-- The number of sys_clks between edges is then directly measured using a
|
182 |
|
|
-- counter, and these counts are fed into a successive approximation loop by
|
183 |
|
|
-- which the Baud interval (shortest interval between pulses) is first measured.
|
184 |
|
|
-- Then, based on this measurement, another measurement is taken over two Baud
|
185 |
|
|
-- intervals. This measurement is then used as the basis for a new measurement
|
186 |
|
|
-- covering four Baud intervals, and so forth. Each new measurement covers the
|
187 |
|
|
-- a period of 2^N Baud intervals, or bit times, where the highest N is set by
|
188 |
|
|
-- generics.
|
189 |
|
|
--
|
190 |
|
|
-- Note that noise can cause the initial Baud interval to be incorrect, which
|
191 |
|
|
-- will eventually cause the subsequent measurements to fail, and the state
|
192 |
|
|
-- machine will revert back and take a new Baud interval measurement. Therefore,
|
193 |
|
|
-- no attempt is made to average several initial Baud interval measurements.
|
194 |
|
|
--
|
195 |
|
|
-- The result of the ultimate 2^N bit times measurement can be interpreted as a
|
196 |
|
|
-- measurement of the bit-period of the incoming data or clock signal, made
|
197 |
|
|
-- more accurate through averaging over 2^N intervals. Therefore, the final
|
198 |
|
|
-- measurement of 2^Nmax Baud intervals is composed of an integer portion and
|
199 |
|
|
-- a fractional portion, the fractional portion being the Nmax least significant
|
200 |
|
|
-- bits of the period output.
|
201 |
|
|
--
|
202 |
|
|
-- By setting Nmax and taking the requisite amount of time to make the full 2^Nmax
|
203 |
|
|
-- bit-period measurement, results of "arbitrary precision" can therefore be
|
204 |
|
|
-- obtained.
|
205 |
|
|
--
|
206 |
|
|
-- The successive approximation approach is used in order to effectively home
|
207 |
|
|
-- in on the correct measurement, incrementally approaching the value by starting
|
208 |
|
|
-- with a direct measurement of the shortest interval - which is understood to
|
209 |
|
|
-- represent a single bit-period. Since the signal might not have a transition
|
210 |
|
|
-- at every bit-period, there is a statistical component to the way in which the
|
211 |
|
|
-- successive approximation works.
|
212 |
|
|
--
|
213 |
|
|
-- Essentially, a number of attempts are made, starting at any given edge, and
|
214 |
|
|
-- extending through 2^N of the best-estimate "baud intervals" and looking for
|
215 |
|
|
-- another edge at around the expected time. The edge may occur earlier or later
|
216 |
|
|
-- than the predicted time, and so the approach takes this into account. Each
|
217 |
|
|
-- successful measurement is then multiplied by two via bit-shifting, and used
|
218 |
|
|
-- as the basis for the succeeding measurement. So each measurement uses the
|
219 |
|
|
-- current best estimate of period, to take a new measurement which covers twice
|
220 |
|
|
-- as many bit times, so that each new result is essentially twice as precise
|
221 |
|
|
-- as its predecessor.
|
222 |
|
|
--
|
223 |
|
|
-- The number of attempts to be made for each measurement step is determined by
|
224 |
|
|
-- a generic setting. The assumption is that edges are expected to be present
|
225 |
|
|
-- approximately 50% of the time, and so the probability of performing any given
|
226 |
|
|
-- measurement successfully is 1-(1/2^READS). By setting READS sufficiently
|
227 |
|
|
-- high, as compared to Nmax, the overall probability of successfully
|
228 |
|
|
-- "bootstrapping" all the way into a precise final bit-period measurement can
|
229 |
|
|
-- be made high enough to become practical and useful.
|
230 |
|
|
--
|
231 |
|
|
-- One of the important practical assumptions made about the incoming signal is
|
232 |
|
|
-- that the amount of jitter present in the signal edges is small compared to
|
233 |
|
|
-- the overall desired measurement precision. Another assumption is that the
|
234 |
|
|
-- frequency drift of the incoming signal is low. There is a "window" of
|
235 |
|
|
-- allowed variation from the expected edge location which this module considers
|
236 |
|
|
-- as "valid" measurements. When the sum of jitter and phase variation due to
|
237 |
|
|
-- frequency drift produces edges that fall outside that window, the measurement
|
238 |
|
|
-- will fail despite the reasonably high probability that an edge is lurking
|
239 |
|
|
-- somewhere just outside the allowed window.
|
240 |
|
|
--
|
241 |
|
|
-- The size of the window is set via generics, and it is implemented as a +/-
|
242 |
|
|
-- tolerance through a clever technique in which the measurement counter during
|
243 |
|
|
-- the "HONE" state is allowed to count down to zero, after which it begins to
|
244 |
|
|
-- count up again. At the time of the closing edge, the value in the counter is
|
245 |
|
|
-- compared with the window threshold, and the counter value then represents the
|
246 |
|
|
-- absolute value of the variation of the overall measured 2^N bit-time interval
|
247 |
|
|
-- from its expectation value.
|
248 |
|
|
--
|
249 |
|
|
-- It is intended that this module be instantiated multiple times inside a digital
|
250 |
|
|
-- bit-sync module, once for measuring the bit-period of the reference PCM data
|
251 |
|
|
-- signal, and once for measuring the bit-period of the generated clock. In that
|
252 |
|
|
-- way the measurements will be "apples to apples" and any bias present in one
|
253 |
|
|
-- measurement should be identical in the other.
|
254 |
|
|
--
|
255 |
|
|
-- By comparing the measured periods, the clock signal can then be adjusted so that
|
256 |
|
|
-- its frequency tracks that of the incoming data signal for slow variations,
|
257 |
|
|
-- without requiring Fourier analysis, or the use of mathematical multipliers or
|
258 |
|
|
-- dividers.
|
259 |
|
|
--
|
260 |
|
|
-- This frequency tracking loop is to be a slow outer loop within the bit-sync,
|
261 |
|
|
-- with a faster phase tracking loop as the inner feedback loop.
|
262 |
|
|
--
|
263 |
|
|
|
264 |
|
|
library IEEE;
|
265 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
266 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
267 |
|
|
use IEEE.MATH_REAL.ALL;
|
268 |
|
|
|
269 |
|
|
library work;
|
270 |
|
|
use work.function_pack.all;
|
271 |
|
|
|
272 |
|
|
entity bit_period_detector is
|
273 |
|
|
generic(
|
274 |
|
|
USE_ANY_EDGE : integer := 1; -- 0=Rising edges only, 1=Use any edge
|
275 |
|
|
WINDOW_SIZE : integer := 2; -- sys_clk variation allowed around closing edge
|
276 |
|
|
IDLE_CLOCKS : integer := 511; -- sys_clk periods before input "idle" is called
|
277 |
|
|
BAUD_READS : integer := 255; -- Number of baud interval transition measurements tried
|
278 |
|
|
INTERVAL_READS : integer := 16; -- Number of 2^N interval read attempts to make
|
279 |
|
|
INTEGER_WIDTH : integer := 16; -- Bits in integer part of period measurement
|
280 |
|
|
FRACTION_WIDTH : integer := 4 -- Bits in fractional part of period measurement
|
281 |
|
|
);
|
282 |
|
|
port (
|
283 |
|
|
-- System Clock and Clock Enable
|
284 |
|
|
sys_rst_n : in std_logic;
|
285 |
|
|
sys_clk : in std_logic;
|
286 |
|
|
sys_clk_en : in std_logic;
|
287 |
|
|
|
288 |
|
|
-- Signal input
|
289 |
|
|
signal_i : in std_logic;
|
290 |
|
|
|
291 |
|
|
-- outputs
|
292 |
|
|
s_edge_o : out std_logic; -- Strobe marking edges of signal_i which are used.
|
293 |
|
|
period_o : out unsigned(INTEGER_WIDTH+FRACTION_WIDTH-1 downto 0);
|
294 |
|
|
load_o : out std_logic;
|
295 |
|
|
idle_o : out std_logic
|
296 |
|
|
);
|
297 |
|
|
end bit_period_detector;
|
298 |
|
|
|
299 |
|
|
architecture beh of bit_period_detector is
|
300 |
|
|
|
301 |
|
|
-- Constants
|
302 |
|
|
constant IDLE_COUNT_WIDTH : integer := timer_width(IDLE_CLOCKS);
|
303 |
|
|
constant BAUD_COUNT_WIDTH : integer := timer_width(BAUD_READS);
|
304 |
|
|
constant INTERVAL_COUNT_WIDTH : integer := bit_width(INTERVAL_READS);
|
305 |
|
|
constant PERIOD_WIDTH : integer := INTEGER_WIDTH+FRACTION_WIDTH;
|
306 |
|
|
constant N_WIDTH : integer := timer_width(FRACTION_WIDTH);
|
307 |
|
|
|
308 |
|
|
-- Functions & associated types
|
309 |
|
|
|
310 |
|
|
-- Signal Declarations
|
311 |
|
|
signal period : unsigned(PERIOD_WIDTH-1 downto 0);
|
312 |
|
|
signal s_r1 : std_logic;
|
313 |
|
|
signal s_r2 : std_logic;
|
314 |
|
|
signal s_edge : std_logic;
|
315 |
|
|
signal c_count : unsigned(PERIOD_WIDTH-1 downto 0); -- Used to count sys_clks between transitions
|
316 |
|
|
signal c_count_next : unsigned(PERIOD_WIDTH-1 downto 0); -- This is c_count+1
|
317 |
|
|
signal c_count_x2 : unsigned(PERIOD_WIDTH-1 downto 0);
|
318 |
|
|
signal p_count : unsigned(PERIOD_WIDTH-1 downto 0); -- Used to count sys_clks to window closure
|
319 |
|
|
signal p_count_dir : std_logic; -- High=counting up, Low=counting down
|
320 |
|
|
signal baud_tries : unsigned(BAUD_COUNT_WIDTH-1 downto 0); -- Counts baud interval assessments
|
321 |
|
|
signal period_tries : unsigned(INTERVAL_COUNT_WIDTH-1 downto 0); -- Counts period interval assessments
|
322 |
|
|
signal idle_count : unsigned(IDLE_COUNT_WIDTH-1 downto 0); -- Counts sys_clk periods with no signal transition
|
323 |
|
|
type P_STATE_TYPE is (IDLE, MEASURE_BAUD, HONE);
|
324 |
|
|
signal p_state : P_STATE_TYPE;
|
325 |
|
|
signal n : unsigned(N_WIDTH-1 downto 0);
|
326 |
|
|
|
327 |
|
|
begin
|
328 |
|
|
|
329 |
|
|
c_count_next <= c_count+1;
|
330 |
|
|
--c_count_x2 <= c_count_next(c_count_next'length-2 downto 0) & '0';
|
331 |
|
|
--c_count_x2 <= c_count_next + c_count; -- An attempt to "dither" or eliminate bias...
|
332 |
|
|
c_count_x2 <= c_count(c_count'length-2 downto 0) & '1';
|
333 |
|
|
|
334 |
|
|
process (sys_clk, sys_rst_n)
|
335 |
|
|
begin
|
336 |
|
|
if (sys_rst_n='0') then
|
337 |
|
|
s_r1 <= '0';
|
338 |
|
|
s_r2 <= '0';
|
339 |
|
|
c_count <= (others=>'0');
|
340 |
|
|
p_count <= (others=>'1');
|
341 |
|
|
p_count_dir <= '0'; -- Counts down, until zero is reached...
|
342 |
|
|
baud_tries <= (others=>'0');
|
343 |
|
|
period_tries <= (others=>'0');
|
344 |
|
|
idle_count <= to_unsigned(IDLE_CLOCKS,idle_count'length);
|
345 |
|
|
period <= (others=>'0');
|
346 |
|
|
p_state <= IDLE;
|
347 |
|
|
n <= (others=>'0');
|
348 |
|
|
period_o <= (others=>'1');
|
349 |
|
|
load_o <= '0';
|
350 |
|
|
elsif (sys_clk'event and sys_clk='1') then
|
351 |
|
|
if (sys_clk_en='1') then
|
352 |
|
|
-- Defaults
|
353 |
|
|
load_o <= '0';
|
354 |
|
|
|
355 |
|
|
-- Two layers of flip-flops, to mitigate metastability
|
356 |
|
|
s_r1 <= signal_i;
|
357 |
|
|
s_r2 <= s_r1;
|
358 |
|
|
|
359 |
|
|
-- Update the period counter
|
360 |
|
|
-- It can be cleared by other logic statements below
|
361 |
|
|
c_count <= c_count_next;
|
362 |
|
|
|
363 |
|
|
-- Update the window counter
|
364 |
|
|
-- It can be cleared by other logic statements below
|
365 |
|
|
if (p_count_dir='1') then
|
366 |
|
|
p_count <= p_count+1;
|
367 |
|
|
else
|
368 |
|
|
-- When counting down, there is a counter direction reversal
|
369 |
|
|
-- which is used for implementing the tracking window +/-
|
370 |
|
|
if (p_count=0) then
|
371 |
|
|
p_count_dir <= p_count_dir xor '1';
|
372 |
|
|
p_count <= p_count+1;
|
373 |
|
|
else
|
374 |
|
|
p_count <= p_count-1;
|
375 |
|
|
end if;
|
376 |
|
|
end if;
|
377 |
|
|
|
378 |
|
|
-- Period State Machine
|
379 |
|
|
case (p_state) is
|
380 |
|
|
|
381 |
|
|
when IDLE =>
|
382 |
|
|
if (s_edge='1') then
|
383 |
|
|
p_state <= MEASURE_BAUD;
|
384 |
|
|
period <= (others=>'1');
|
385 |
|
|
p_count <= (others=>'1');
|
386 |
|
|
p_count_dir <= '0';
|
387 |
|
|
c_count <= (others=>'0');
|
388 |
|
|
n <= (others=>'0');
|
389 |
|
|
end if;
|
390 |
|
|
|
391 |
|
|
when MEASURE_BAUD =>
|
392 |
|
|
if (s_edge='1') then
|
393 |
|
|
if (baud_tries=BAUD_READS) then
|
394 |
|
|
baud_tries <= (others=>'0');
|
395 |
|
|
period_tries <= (others=>'0');
|
396 |
|
|
p_state <= HONE;
|
397 |
|
|
p_count <= period;
|
398 |
|
|
p_count_dir <= '0'; -- Count down for HONE
|
399 |
|
|
c_count <= (others=>'0');
|
400 |
|
|
else
|
401 |
|
|
baud_tries <= baud_tries+1;
|
402 |
|
|
if (c_count_next<period) then
|
403 |
|
|
period <= c_count_next;
|
404 |
|
|
end if;
|
405 |
|
|
c_count <= (others=>'0');
|
406 |
|
|
end if;
|
407 |
|
|
end if;
|
408 |
|
|
|
409 |
|
|
when HONE =>
|
410 |
|
|
-- look for edges
|
411 |
|
|
if (s_edge='1') then
|
412 |
|
|
if (p_count <= WINDOW_SIZE) then
|
413 |
|
|
if (n<FRACTION_WIDTH) then
|
414 |
|
|
period <= c_count_x2;
|
415 |
|
|
p_count <= c_count_x2;
|
416 |
|
|
p_count_dir <= '0'; -- Count down
|
417 |
|
|
c_count <= (others=>'0');
|
418 |
|
|
n <= n+1;
|
419 |
|
|
elsif n=FRACTION_WIDTH then
|
420 |
|
|
p_state <= MEASURE_BAUD;
|
421 |
|
|
period <= (others=>'1');
|
422 |
|
|
p_count <= (others=>'1');
|
423 |
|
|
p_count_dir <= '0';
|
424 |
|
|
c_count <= (others=>'0');
|
425 |
|
|
n <= (others=>'0');
|
426 |
|
|
period_o <= c_count;
|
427 |
|
|
load_o <= '1';
|
428 |
|
|
end if;
|
429 |
|
|
elsif (p_count_dir='1') then -- If the window has passed...
|
430 |
|
|
if (period_tries<INTERVAL_READS-1) then
|
431 |
|
|
period_tries <= period_tries+1;
|
432 |
|
|
-- Adjust the period slightly, to improve odds of success with a tight window...
|
433 |
|
|
--p_count <= period-1;
|
434 |
|
|
p_count <= period;
|
435 |
|
|
p_count_dir <= '0'; -- Count down
|
436 |
|
|
c_count <= (others=>'0');
|
437 |
|
|
else
|
438 |
|
|
p_state <= MEASURE_BAUD;
|
439 |
|
|
period <= (others=>'1');
|
440 |
|
|
p_count <= (others=>'1');
|
441 |
|
|
p_count_dir <= '0';
|
442 |
|
|
c_count <= (others=>'0');
|
443 |
|
|
n <= (others=>'0');
|
444 |
|
|
end if;
|
445 |
|
|
end if;
|
446 |
|
|
end if; -- s_edge='1'
|
447 |
|
|
|
448 |
|
|
end case;
|
449 |
|
|
|
450 |
|
|
-- Update the idle counter
|
451 |
|
|
-- This must follow the state transition logic, since it can
|
452 |
|
|
-- override it, and force the state to IDLE
|
453 |
|
|
if (s_edge='1') then
|
454 |
|
|
idle_count <= to_unsigned(IDLE_CLOCKS,idle_count'length);
|
455 |
|
|
else
|
456 |
|
|
if (idle_count=0) then
|
457 |
|
|
p_state <= IDLE;
|
458 |
|
|
else
|
459 |
|
|
idle_count <= idle_count-1;
|
460 |
|
|
end if;
|
461 |
|
|
end if;
|
462 |
|
|
|
463 |
|
|
end if; -- sys_clk_en
|
464 |
|
|
end if; -- sys_clk
|
465 |
|
|
end process;
|
466 |
|
|
|
467 |
|
|
-- Implement edge detector. Generic determines if all edges are used, or
|
468 |
|
|
-- just the rising edges.
|
469 |
|
|
s_edge <= s_r1 xor s_r2 when (USE_ANY_EDGE=1) else s_r1 and not s_r2;
|
470 |
|
|
|
471 |
|
|
s_edge_o <= s_edge;
|
472 |
|
|
idle_o <= '1' when p_state=IDLE else '0';
|
473 |
|
|
|
474 |
|
|
end beh;
|
475 |
|
|
|
476 |
|
|
|
477 |
|
|
-------------------------------------------------------------------------------
|
478 |
|
|
-- PCM signal period histogram checker
|
479 |
|
|
-------------------------------------------------------------------------------
|
480 |
|
|
--
|
481 |
|
|
-- Author: John Clayton
|
482 |
|
|
-- Date : May 8, 2013 Copied code from bit_period_detector,
|
483 |
|
|
-- Created description.
|
484 |
|
|
-- May 16, 2013 Checked the unit using simulation, and it
|
485 |
|
|
-- looks pretty good. Added ODD_N_LIMIT generic
|
486 |
|
|
-- to prevent long intervals from always ending
|
487 |
|
|
-- up in the oddball bin, due to uncertainty
|
488 |
|
|
-- in measurement of the Baud interval.
|
489 |
|
|
-- Aug. 8, 2013 Corrected mathematical error in the averaging
|
490 |
|
|
-- signal, and added i_count_b resets during
|
491 |
|
|
-- Baud interval measurements, to prevent idle
|
492 |
|
|
-- detection logic from triggering erroneously.
|
493 |
|
|
-- July 21, 2015 Added logic to prevent freq accumulator from
|
494 |
|
|
-- missing counts when i_count_b>=ODD_N_LIMIT.
|
495 |
|
|
--
|
496 |
|
|
-- Description
|
497 |
|
|
-------------------------------------------------------------------------------
|
498 |
|
|
-- This module uses a finite state machine and some counters and comparators
|
499 |
|
|
-- to measure the Baud interval of an incoming signal. In other words, it
|
500 |
|
|
-- measures the shortest interval between signal edges, in units of sys_clks.
|
501 |
|
|
--
|
502 |
|
|
-- The unit takes measurements constantly. However, when the input is
|
503 |
|
|
-- idle, then no histogram data is updated as the unit remains in the
|
504 |
|
|
-- Baud interval measurement mode.
|
505 |
|
|
--
|
506 |
|
|
-- Once activity is detected on the selected signal input, a series of
|
507 |
|
|
-- intrvls_i intervals is measured with the true signal to find a Baud
|
508 |
|
|
-- interval measurement. Following this, another series of the same
|
509 |
|
|
-- number of intervals is taken, but this time with the input signal
|
510 |
|
|
-- inverted. The two results are compared. If the two results differ by
|
511 |
|
|
-- more than +/- window_i sys_clks, then the signal is declared to have a
|
512 |
|
|
-- duty cycle which is unacceptably far from 50%, and the bad_duty_o
|
513 |
|
|
-- output is asserted.
|
514 |
|
|
--
|
515 |
|
|
-- After an acceptable duty cycle is found, the Baud interval is calculated
|
516 |
|
|
-- as the average of both the true and inverted signal Baud interval
|
517 |
|
|
-- measurements, and this value is updated to the output baud_o.
|
518 |
|
|
--
|
519 |
|
|
-- Following the baud interval cycle, the unit switches into histogram
|
520 |
|
|
-- and frequency measurement mode. The internal histogram bin counters
|
521 |
|
|
-- are reset, and a set of intrvls_i intervals is measured. Each
|
522 |
|
|
-- interval is analyzed to see if it is within +/- window_i sys_clks of
|
523 |
|
|
-- an integer multiple N of the Baud interval. Based on the N value
|
524 |
|
|
-- found by the analysis, the appropriate histogram bin count is incremented.
|
525 |
|
|
-- Each interval found which is outside the allowable +/- variation is
|
526 |
|
|
-- an "oddball" interval, resulting in incrementing the bo_count value.
|
527 |
|
|
--
|
528 |
|
|
-- <<<Editorial Note>>>
|
529 |
|
|
-- (Skip this note if you don't feel super excited about the analysis of
|
530 |
|
|
-- PCM telemetry waveforms.)
|
531 |
|
|
--
|
532 |
|
|
-- During simulation, it was found that the uncertainty in measuring long
|
533 |
|
|
-- intervals, being cumulative, causes the oddball count bin to be
|
534 |
|
|
-- incremented when in the purest sense it should not be. This is due
|
535 |
|
|
-- to the inability of this module to measure Baud intervals with
|
536 |
|
|
-- fractional accuracy. Although more precise Baud average measurements
|
537 |
|
|
-- could be performed fairly easily, it would neccesitate a complete
|
538 |
|
|
-- rewrite of this unit in order to divide a measured interval by the
|
539 |
|
|
-- precise Baud interval. Such subtlety is beyond the scope of this
|
540 |
|
|
-- effort. Therefore, the "oddball" bin count will only be incremented
|
541 |
|
|
-- for N values less than the constant ODD_N_LIMIT. Intervals longer
|
542 |
|
|
-- than this will not be considered oddball, effectively allowing
|
543 |
|
|
-- them to be properly counted in the bn_count bin.
|
544 |
|
|
-- <<<End Editorial Note>>>
|
545 |
|
|
--
|
546 |
|
|
-- When the entire set of intrvls_i intervals have been measured and
|
547 |
|
|
-- analyzed, the histogram counts are updated to the outputs, and the
|
548 |
|
|
-- process is repeated again.
|
549 |
|
|
--
|
550 |
|
|
-- Histogram bins are defined as follows:
|
551 |
|
|
--
|
552 |
|
|
-- b1_count = # of intervals equal to the Baud interval
|
553 |
|
|
-- b2_count = # of intervals equal to 2x the Baud interval
|
554 |
|
|
-- b3_count = # of intervals in which N is in the range [3..bo_limit_i]
|
555 |
|
|
-- bn_count = # of intervals in which N exceeds bo_limit_i
|
556 |
|
|
-- bo_count = # of oddball intervals
|
557 |
|
|
--
|
558 |
|
|
-- The idea behind this histogram is that squarewave clocks, such as the
|
559 |
|
|
-- self-test 10kHz "IO_sense" signal, result in histograms with high
|
560 |
|
|
-- totals in the b1 bin only, while biphase signals result in histograms
|
561 |
|
|
-- with high totals in the b1 and b2 bins, with an expected equal split.
|
562 |
|
|
-- NRZ-L and RNRZ-L will produce non-zero counts in the b3 bin. NRZ-L
|
563 |
|
|
-- can produce non-negligible counts in the bn bin, depending on the
|
564 |
|
|
-- longest runs of zero or one present in the signal, while the RNRZ-L
|
565 |
|
|
-- input will yield a zero value in the bn bin, for suitably chosen
|
566 |
|
|
-- n_value_i.
|
567 |
|
|
--
|
568 |
|
|
-- Whenever bo_count exceeds the bo_limit_i threshold, the unit exits
|
569 |
|
|
-- histogram and frequency measurement mode, and reverts back to the
|
570 |
|
|
-- baud interval and duty cycle checking mode, without erasing any
|
571 |
|
|
-- previous measurements which are present at the outputs.
|
572 |
|
|
--
|
573 |
|
|
-- While in histogram population mode, a simultaneous frequency
|
574 |
|
|
-- measurement is being performed. After each successful interval analysis,
|
575 |
|
|
-- the resulting N value is accumulated into a running total. After
|
576 |
|
|
-- one second of operation, the accumulator value represents the frequency
|
577 |
|
|
-- of baud intervals per second, hence the symbol frequency from which
|
578 |
|
|
-- bit rate can be immediately deduced. Each one second interval frequency
|
579 |
|
|
-- reading is updated to the output register, the accumulator is cleared,
|
580 |
|
|
-- and the frequency measurement process proceeds onward for another
|
581 |
|
|
-- second.
|
582 |
|
|
--
|
583 |
|
|
|
584 |
|
|
library IEEE;
|
585 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
586 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
587 |
|
|
use IEEE.MATH_REAL.ALL;
|
588 |
|
|
|
589 |
|
|
library work;
|
590 |
|
|
use work.function_pack.all;
|
591 |
|
|
|
592 |
|
|
entity period_histogram_checker is
|
593 |
|
|
generic(
|
594 |
|
|
SYS_CLK_RATE : real := 50000000.0;
|
595 |
|
|
NUM_CHAN : natural := 8; -- Number of channels to select from
|
596 |
|
|
LOG2_NUM_CHAN : natural := 3; -- Bits needed for channel selection
|
597 |
|
|
ODD_N_LIMIT : natural := 4; -- Upper cutoff for bo_count_o intervals to be tallied
|
598 |
|
|
PERIOD_BITS : natural := 14; -- Number of bits in Baud interval measurement
|
599 |
|
|
HIST_BITS : natural := 8 -- Number of bits in histogram bin counters
|
600 |
|
|
);
|
601 |
|
|
port (
|
602 |
|
|
-- System Clock and Clock Enable
|
603 |
|
|
sys_rst_n : in std_logic;
|
604 |
|
|
sys_clk : in std_logic;
|
605 |
|
|
sys_clk_en : in std_logic;
|
606 |
|
|
|
607 |
|
|
-- PCM signal inputs
|
608 |
|
|
pcm_i : in unsigned(NUM_CHAN-1 downto 0);
|
609 |
|
|
|
610 |
|
|
-- Settings & Control
|
611 |
|
|
pcm_sel_i : in unsigned(LOG2_NUM_CHAN-1 downto 0);
|
612 |
|
|
window_i : in unsigned(3 downto 0); -- sys_clks of variation allowed when checking intervals
|
613 |
|
|
intrvls_i : in unsigned(HIST_BITS-1 downto 0); -- Number of intervals per histogram
|
614 |
|
|
bo_limit_i : in unsigned(HIST_BITS-1 downto 0); -- Number of oddball intervals tolerated per histogram cycle.
|
615 |
|
|
n_value_i : in unsigned(4 downto 0); -- N value for bn_count histogram bin
|
616 |
|
|
|
617 |
|
|
-- outputs
|
618 |
|
|
bad_duty_o : out std_logic;
|
619 |
|
|
b1_count_o : out unsigned(HIST_BITS-1 downto 0);
|
620 |
|
|
b2_count_o : out unsigned(HIST_BITS-1 downto 0);
|
621 |
|
|
b3_count_o : out unsigned(HIST_BITS-1 downto 0);
|
622 |
|
|
bn_count_o : out unsigned(HIST_BITS-1 downto 0);
|
623 |
|
|
bo_count_o : out unsigned(HIST_BITS-1 downto 0);
|
624 |
|
|
baud_o : out unsigned(PERIOD_BITS-1 downto 0);
|
625 |
|
|
freq_o : out unsigned(31 downto 0);
|
626 |
|
|
idle_o : out std_logic; -- High indicates signal is inactive for too long.
|
627 |
|
|
new_o : out std_logic -- High pulse indicates new measurements were posted.
|
628 |
|
|
);
|
629 |
|
|
end period_histogram_checker;
|
630 |
|
|
|
631 |
|
|
architecture beh of period_histogram_checker is
|
632 |
|
|
|
633 |
|
|
-- Constants
|
634 |
|
|
constant SECOND_BITS : natural := timer_width(SYS_CLK_RATE);
|
635 |
|
|
|
636 |
|
|
-- Functions & associated types
|
637 |
|
|
|
638 |
|
|
-- Signal Declarations
|
639 |
|
|
signal baud_count : unsigned(PERIOD_BITS-1 downto 0);
|
640 |
|
|
signal baud_p_val : unsigned(PERIOD_BITS-1 downto 0);
|
641 |
|
|
signal baud_n_val : unsigned(PERIOD_BITS-1 downto 0);
|
642 |
|
|
signal baud_delta : unsigned(3 downto 0);
|
643 |
|
|
signal intrvl_delta : unsigned(3 downto 0);
|
644 |
|
|
signal baud_sum : unsigned(PERIOD_BITS downto 0);
|
645 |
|
|
signal baud_avg : unsigned(PERIOD_BITS-1 downto 0);
|
646 |
|
|
signal i_count_a : unsigned(PERIOD_BITS-1 downto 0);
|
647 |
|
|
signal i_count_b : unsigned(10 downto 0); -- up to 2047 symbol periods per interval
|
648 |
|
|
signal baud_num : unsigned(HIST_BITS-1 downto 0);
|
649 |
|
|
signal intrvl_num : unsigned(HIST_BITS-1 downto 0);
|
650 |
|
|
signal b1_count : unsigned(HIST_BITS-1 downto 0);
|
651 |
|
|
signal b2_count : unsigned(HIST_BITS-1 downto 0);
|
652 |
|
|
signal b3_count : unsigned(HIST_BITS-1 downto 0);
|
653 |
|
|
signal bn_count : unsigned(HIST_BITS-1 downto 0);
|
654 |
|
|
signal bo_count : unsigned(HIST_BITS-1 downto 0);
|
655 |
|
|
signal freq : unsigned(31 downto 0);
|
656 |
|
|
signal second_count : unsigned(SECOND_BITS-1 downto 0);
|
657 |
|
|
type P_STATE_TYPE is (BAUD_P1, BAUD_P2, BAUD_N1, BAUD_N2, DUTY_CHECK, HISTO1, HISTO2);
|
658 |
|
|
signal p_state : P_STATE_TYPE;
|
659 |
|
|
signal s_r1 : std_logic;
|
660 |
|
|
signal s_r2 : std_logic;
|
661 |
|
|
signal s_edge : std_logic;
|
662 |
|
|
signal s_rising : std_logic;
|
663 |
|
|
signal s_falling : std_logic;
|
664 |
|
|
signal idle : std_logic;
|
665 |
|
|
signal pcm_sel_r1 : unsigned(LOG2_NUM_CHAN-1 downto 0);
|
666 |
|
|
|
667 |
|
|
begin
|
668 |
|
|
|
669 |
|
|
-- Provide outputs
|
670 |
|
|
baud_sum <= resize(baud_p_val,baud_sum'length) + resize(baud_n_val,baud_sum'length);
|
671 |
|
|
baud_avg <= baud_sum(baud_sum'length-1 downto 1); -- Divide by 2
|
672 |
|
|
idle_o <= idle;
|
673 |
|
|
|
674 |
|
|
-- Form edge detectors
|
675 |
|
|
s_edge <= s_r1 xor s_r2;
|
676 |
|
|
s_rising <= '1' when s_r1='1' and s_r2='0' else '0';
|
677 |
|
|
s_falling <= '1' when s_r1='0' and s_r2='1' else '0';
|
678 |
|
|
|
679 |
|
|
-- Form difference between positive and negative Baud intervals
|
680 |
|
|
baud_delta <= resize(unsigned(abs(signed(baud_p_val)-signed(baud_n_val))),baud_delta'length);
|
681 |
|
|
-- Form difference between interval subtraction remainder and Baud intervals
|
682 |
|
|
intrvl_delta <= resize(baud_avg-i_count_a,intrvl_delta'length);
|
683 |
|
|
|
684 |
|
|
-- State machine
|
685 |
|
|
process (sys_clk, sys_rst_n)
|
686 |
|
|
begin
|
687 |
|
|
if (sys_rst_n='0') then
|
688 |
|
|
s_r1 <= '0';
|
689 |
|
|
s_r2 <= '0';
|
690 |
|
|
baud_count <= (others=>'0');
|
691 |
|
|
baud_p_val <= (others=>'1');
|
692 |
|
|
baud_n_val <= (others=>'1');
|
693 |
|
|
i_count_a <= to_unsigned(1,i_count_a'length);
|
694 |
|
|
i_count_b <= (others=>'0');
|
695 |
|
|
intrvl_num <= to_unsigned(0,intrvl_num'length);
|
696 |
|
|
baud_num <= to_unsigned(0,baud_num'length);
|
697 |
|
|
b1_count <= (others=>'0');
|
698 |
|
|
b2_count <= (others=>'0');
|
699 |
|
|
b3_count <= (others=>'0');
|
700 |
|
|
bn_count <= (others=>'0');
|
701 |
|
|
bo_count <= (others=>'0');
|
702 |
|
|
b1_count_o <= (others=>'0');
|
703 |
|
|
b2_count_o <= (others=>'0');
|
704 |
|
|
b3_count_o <= (others=>'0');
|
705 |
|
|
bn_count_o <= (others=>'0');
|
706 |
|
|
bo_count_o <= (others=>'0');
|
707 |
|
|
freq <= (others=>'0');
|
708 |
|
|
freq_o <= (others=>'0');
|
709 |
|
|
idle <= '0';
|
710 |
|
|
bad_duty_o <= '0';
|
711 |
|
|
second_count <= str2u("0000001",second_count'length);
|
712 |
|
|
p_state <= BAUD_P1;
|
713 |
|
|
baud_o <= (others=>'0');
|
714 |
|
|
new_o <= '0';
|
715 |
|
|
pcm_sel_r1 <= (others=>'0');
|
716 |
|
|
elsif (sys_clk'event and sys_clk='1') then
|
717 |
|
|
if (sys_clk_en='1') then
|
718 |
|
|
|
719 |
|
|
-- Handle one second timer
|
720 |
|
|
second_count <= second_count+1;
|
721 |
|
|
|
722 |
|
|
-- Defaults
|
723 |
|
|
new_o <= '0';
|
724 |
|
|
|
725 |
|
|
-- Two layers of flip-flops, to mitigate metastability
|
726 |
|
|
s_r1 <= pcm_i(to_integer(pcm_sel_i));
|
727 |
|
|
s_r2 <= s_r1;
|
728 |
|
|
|
729 |
|
|
-- Keep last selection, to detect changes
|
730 |
|
|
pcm_sel_r1 <= pcm_sel_i;
|
731 |
|
|
|
732 |
|
|
-- Measure intervals when signal is not idle
|
733 |
|
|
if (idle='0') then
|
734 |
|
|
if i_count_b=((2**i_count_b'length)-1) then
|
735 |
|
|
idle <= '1';
|
736 |
|
|
i_count_a <= to_unsigned(1,i_count_a'length);
|
737 |
|
|
i_count_b <= (others=>'0');
|
738 |
|
|
elsif i_count_a>=baud_avg then
|
739 |
|
|
i_count_a <= to_unsigned(1,i_count_a'length);
|
740 |
|
|
i_count_b <= i_count_b+1;
|
741 |
|
|
else
|
742 |
|
|
i_count_a <= i_count_a+1;
|
743 |
|
|
end if;
|
744 |
|
|
end if;
|
745 |
|
|
-- Exit idle condition at any edge
|
746 |
|
|
if (s_edge='1') then
|
747 |
|
|
idle <= '0';
|
748 |
|
|
end if;
|
749 |
|
|
|
750 |
|
|
-- Period State Machine
|
751 |
|
|
case (p_state) is
|
752 |
|
|
|
753 |
|
|
when BAUD_P1 =>
|
754 |
|
|
if (s_rising='1') then
|
755 |
|
|
p_state <= BAUD_P2;
|
756 |
|
|
baud_count <= (others=>'0');
|
757 |
|
|
end if;
|
758 |
|
|
|
759 |
|
|
when BAUD_P2 =>
|
760 |
|
|
baud_count <= baud_count+1;
|
761 |
|
|
if (s_falling='1') then
|
762 |
|
|
baud_num <= baud_num+1; -- record that another interval is measured
|
763 |
|
|
if (baud_count+1<baud_p_val) then
|
764 |
|
|
baud_p_val <= baud_count+1;
|
765 |
|
|
end if;
|
766 |
|
|
if (baud_num=intrvls_i) then
|
767 |
|
|
p_state <= BAUD_N1;
|
768 |
|
|
baud_num <= to_unsigned(1,baud_num'length);
|
769 |
|
|
else
|
770 |
|
|
p_state <= BAUD_P1;
|
771 |
|
|
i_count_b <= (others=>'0');
|
772 |
|
|
end if;
|
773 |
|
|
end if;
|
774 |
|
|
|
775 |
|
|
when BAUD_N1 =>
|
776 |
|
|
if (s_falling='1') then
|
777 |
|
|
p_state <= BAUD_N2;
|
778 |
|
|
baud_count <= (others=>'0');
|
779 |
|
|
end if;
|
780 |
|
|
|
781 |
|
|
when BAUD_N2 =>
|
782 |
|
|
baud_count <= baud_count+1;
|
783 |
|
|
if (s_rising='1') then
|
784 |
|
|
baud_num <= baud_num+1; -- record that another interval is measured
|
785 |
|
|
if (baud_count+1<baud_n_val) then
|
786 |
|
|
baud_n_val <= baud_count+1;
|
787 |
|
|
end if;
|
788 |
|
|
if (baud_num=intrvls_i) then
|
789 |
|
|
p_state <= DUTY_CHECK;
|
790 |
|
|
baud_num <= to_unsigned(1,baud_num'length);
|
791 |
|
|
else
|
792 |
|
|
p_state <= BAUD_N1;
|
793 |
|
|
i_count_b <= (others=>'0');
|
794 |
|
|
end if;
|
795 |
|
|
end if;
|
796 |
|
|
|
797 |
|
|
when DUTY_CHECK =>
|
798 |
|
|
if (baud_delta>window_i) then
|
799 |
|
|
bad_duty_o <= '1';
|
800 |
|
|
baud_num <= to_unsigned(1,baud_num'length);
|
801 |
|
|
p_state <= BAUD_P1;
|
802 |
|
|
elsif (s_edge='1') then
|
803 |
|
|
bad_duty_o <= '0';
|
804 |
|
|
baud_o <= baud_avg;
|
805 |
|
|
i_count_a <= to_unsigned(1,i_count_a'length);
|
806 |
|
|
i_count_b <= (others=>'0');
|
807 |
|
|
p_state <= HISTO1;
|
808 |
|
|
end if;
|
809 |
|
|
|
810 |
|
|
when HISTO1 =>
|
811 |
|
|
-- If an edge is encountered, then
|
812 |
|
|
-- close out the last Baud period.
|
813 |
|
|
if (s_edge='1') then
|
814 |
|
|
intrvl_num <= intrvl_num+1;
|
815 |
|
|
i_count_a <= to_unsigned(1,i_count_a'length);
|
816 |
|
|
-- The ODD_N_LIMIT term here allows "oddball" intervals with high N
|
817 |
|
|
-- to be tallied normally, since measurement uncertainty renders the
|
818 |
|
|
-- window_i value check useless for large N anyway.
|
819 |
|
|
if (i_count_a<=window_i or i_count_b>=ODD_N_LIMIT) then -- means i_count_b has already been incremented.
|
820 |
|
|
if (i_count_a<=window_i) then
|
821 |
|
|
freq <= freq+i_count_b;
|
822 |
|
|
else
|
823 |
|
|
freq <= freq+i_count_b+1;
|
824 |
|
|
end if;
|
825 |
|
|
i_count_b <= (others=>'0');
|
826 |
|
|
if (i_count_b=1) then
|
827 |
|
|
b1_count <= b1_count+1;
|
828 |
|
|
elsif (i_count_b=2) then
|
829 |
|
|
b2_count <= b2_count+1;
|
830 |
|
|
elsif (i_count_b>2) and (i_count_b<n_value_i) then
|
831 |
|
|
b3_count <= b3_count+1;
|
832 |
|
|
else
|
833 |
|
|
bn_count <= bn_count+1;
|
834 |
|
|
end if;
|
835 |
|
|
elsif (intrvl_delta<=window_i) then -- means i_count_b hasn't been incremented yet, but needs to.
|
836 |
|
|
i_count_b <= i_count_b+1;
|
837 |
|
|
p_state <= HISTO2;
|
838 |
|
|
else
|
839 |
|
|
freq <= freq+i_count_b;
|
840 |
|
|
i_count_b <= (others=>'0');
|
841 |
|
|
bo_count <= bo_count+1;
|
842 |
|
|
end if;
|
843 |
|
|
-- Transferring histogram totals to the outputs after the
|
844 |
|
|
-- final interval measurement has higher priority than the
|
845 |
|
|
-- incrementing of counts in the bins, so this is placed
|
846 |
|
|
-- after the increment logic.
|
847 |
|
|
if (intrvl_num>=intrvls_i) then
|
848 |
|
|
p_state <= HISTO1; -- Abandon any excursions to HISTO2 at this point!
|
849 |
|
|
i_count_b <= (others=>'0'); -- starting a brand new measurement
|
850 |
|
|
new_o <= '1';
|
851 |
|
|
intrvl_num <= to_unsigned(0,intrvl_num'length);
|
852 |
|
|
b1_count_o <= b1_count;
|
853 |
|
|
b2_count_o <= b2_count;
|
854 |
|
|
b3_count_o <= b3_count;
|
855 |
|
|
bn_count_o <= bn_count;
|
856 |
|
|
bo_count_o <= bo_count;
|
857 |
|
|
b1_count <= (others=>'0');
|
858 |
|
|
b2_count <= (others=>'0');
|
859 |
|
|
b3_count <= (others=>'0');
|
860 |
|
|
bn_count <= (others=>'0');
|
861 |
|
|
bo_count <= (others=>'0');
|
862 |
|
|
if (bo_count>=bo_limit_i) then
|
863 |
|
|
p_state <= BAUD_P1;
|
864 |
|
|
end if;
|
865 |
|
|
end if;
|
866 |
|
|
end if;
|
867 |
|
|
-- Transfer frequency count to outputs each second
|
868 |
|
|
if (second_count>=integer(SYS_CLK_RATE)) then
|
869 |
|
|
freq <= (others=>'0');
|
870 |
|
|
freq_o <= freq;
|
871 |
|
|
second_count <= to_unsigned(1,second_count'length);
|
872 |
|
|
end if;
|
873 |
|
|
|
874 |
|
|
-- This is an "extra" state used to allow i_count_b to increment,
|
875 |
|
|
-- witout incurring an extra adder...
|
876 |
|
|
when HISTO2 =>
|
877 |
|
|
p_state <= HISTO1;
|
878 |
|
|
i_count_b <= (others=>'0');
|
879 |
|
|
-- increment histogram counts.
|
880 |
|
|
freq <= freq+i_count_b;
|
881 |
|
|
if (i_count_b=1) then
|
882 |
|
|
b1_count <= b1_count+1;
|
883 |
|
|
elsif (i_count_b=2) then
|
884 |
|
|
b2_count <= b2_count+1;
|
885 |
|
|
elsif (i_count_b>2) and (i_count_b<n_value_i) then
|
886 |
|
|
b3_count <= b3_count+1;
|
887 |
|
|
else
|
888 |
|
|
bn_count <= bn_count+1;
|
889 |
|
|
end if;
|
890 |
|
|
-- Transfer frequency count to outputs each second
|
891 |
|
|
if (second_count>=integer(SYS_CLK_RATE)) then
|
892 |
|
|
freq <= (others=>'0');
|
893 |
|
|
freq_o <= freq;
|
894 |
|
|
second_count <= to_unsigned(1,second_count'length);
|
895 |
|
|
end if;
|
896 |
|
|
|
897 |
|
|
end case;
|
898 |
|
|
|
899 |
|
|
-- Force state to BAUD_P if idle input is detected
|
900 |
|
|
if (idle='1' or pcm_sel_i/=pcm_sel_r1) then
|
901 |
|
|
p_state <= BAUD_P1;
|
902 |
|
|
baud_count <= (others=>'1');
|
903 |
|
|
intrvl_num <= to_unsigned(0,intrvl_num'length);
|
904 |
|
|
baud_num <= to_unsigned(0,intrvl_num'length);
|
905 |
|
|
b1_count <= (others=>'0');
|
906 |
|
|
b2_count <= (others=>'0');
|
907 |
|
|
b3_count <= (others=>'0');
|
908 |
|
|
bn_count <= (others=>'0');
|
909 |
|
|
bo_count <= (others=>'0');
|
910 |
|
|
b1_count_o <= (others=>'0');
|
911 |
|
|
b2_count_o <= (others=>'0');
|
912 |
|
|
b3_count_o <= (others=>'0');
|
913 |
|
|
bn_count_o <= (others=>'0');
|
914 |
|
|
bo_count_o <= (others=>'0');
|
915 |
|
|
freq <= (others=>'0');
|
916 |
|
|
freq_o <= (others=>'0');
|
917 |
|
|
baud_p_val <= (others=>'1');
|
918 |
|
|
baud_n_val <= (others=>'1');
|
919 |
|
|
end if;
|
920 |
|
|
|
921 |
|
|
end if; -- sys_clk_en
|
922 |
|
|
end if; -- sys_clk
|
923 |
|
|
end process;
|
924 |
|
|
|
925 |
|
|
end beh;
|
926 |
|
|
|
927 |
|
|
---------------------------------------------------------------------------------
|
928 |
|
|
-- PCM Input front end
|
929 |
|
|
-------------------------------------------------------------------------------
|
930 |
|
|
--
|
931 |
|
|
-- Author: John Clayton
|
932 |
|
|
-- Date : May 9, 2013 Started coding. Wrote description.
|
933 |
|
|
-- May 11, 2013 Finished initial coding, simulated.
|
934 |
|
|
-- Nov. 1, 2013 Added bit synchronizer interface port.
|
935 |
|
|
-- Added description of required clock polarity,
|
936 |
|
|
-- since this unit requires a falling edge in the
|
937 |
|
|
-- middle of the data bit, to work properly.
|
938 |
|
|
-- Because of this dependency, added clock
|
939 |
|
|
-- inversion support.
|
940 |
|
|
-- July 16, 2015 Modified clock output so that the rising edge
|
941 |
|
|
-- is in the middle of the data bit.
|
942 |
|
|
--
|
943 |
|
|
--
|
944 |
|
|
-- Description
|
945 |
|
|
-------------------------------------------------------------------------------
|
946 |
|
|
-- This module selects from among the available inputs, and uses input
|
947 |
|
|
-- settings to operate on the incoming signal. It can remove
|
948 |
|
|
-- biphase line coding, and derandomize PCM data.
|
949 |
|
|
--
|
950 |
|
|
-- The PCM clock must have a falling edge in the middle of the PCM data bit,
|
951 |
|
|
-- for this unit to work correctly.
|
952 |
|
|
--
|
953 |
|
|
-- The taps used in derandomizing are programmable based on the input
|
954 |
|
|
-- dr_taps_i.
|
955 |
|
|
--
|
956 |
|
|
-- The baud_i input is used during biphase line code removal, as a way
|
957 |
|
|
-- to count the correct number of sys_clk periods so that the FSM can
|
958 |
|
|
-- remove the biphase coding, resulting in NRZ data.
|
959 |
|
|
--
|
960 |
|
|
-- A digital bit synchronizer interface port is included in this module.
|
961 |
|
|
-- If use_sync_i='0' then the sync_clk_i and sync_dat_i inputs are
|
962 |
|
|
-- ignored. If use_sync_i='1' then the clk_sel_i input no longer
|
963 |
|
|
-- affects the selected clock, since the bit synchronizer clock is
|
964 |
|
|
-- used instead of selecting an input from sig_i.
|
965 |
|
|
--
|
966 |
|
|
-- One final note: Since biphase line code removal includes clock
|
967 |
|
|
-- recovery, when biphase_i='1' the sync_clk_i input is not used,
|
968 |
|
|
-- although the data is taken from sync_dat_i.
|
969 |
|
|
--
|
970 |
|
|
-- The sys_rst_n input is an asynchronous reset.
|
971 |
|
|
|
972 |
|
|
library IEEE;
|
973 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
974 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
975 |
|
|
use IEEE.MATH_REAL.ALL;
|
976 |
|
|
|
977 |
|
|
library work;
|
978 |
|
|
use work.function_pack.all;
|
979 |
|
|
|
980 |
|
|
entity pcm_input_front_end is
|
981 |
|
|
generic(
|
982 |
|
|
NUM_CHAN : natural := 4; -- Number of channels to select from
|
983 |
|
|
LOG2_NUM_CHAN : natural := 2; -- Bits needed for channel selection
|
984 |
|
|
BAUD_BITS : natural := 10; -- Bits used in Baud interval counting
|
985 |
|
|
DERAND_BITS : natural := 16
|
986 |
|
|
);
|
987 |
|
|
port (
|
988 |
|
|
-- System Clock and Clock Enable
|
989 |
|
|
sys_rst_n : in std_logic;
|
990 |
|
|
sys_clk : in std_logic;
|
991 |
|
|
sys_clk_en : in std_logic;
|
992 |
|
|
fast_clk : in std_logic; -- A clock faster than sys_clk, for biphase line code removal
|
993 |
|
|
|
994 |
|
|
-- PCM signal inputs
|
995 |
|
|
sig_i : in unsigned(NUM_CHAN-1 downto 0);
|
996 |
|
|
|
997 |
|
|
-- Signal selection settings
|
998 |
|
|
clk_sel_i : in unsigned(LOG2_NUM_CHAN-1 downto 0);
|
999 |
|
|
dat_sel_i : in unsigned(LOG2_NUM_CHAN-1 downto 0);
|
1000 |
|
|
|
1001 |
|
|
-- Line Code Settings
|
1002 |
|
|
dr_taps_i : in unsigned(DERAND_BITS-1 downto 0);
|
1003 |
|
|
baud_i : in unsigned(BAUD_BITS-1 downto 0);
|
1004 |
|
|
derandom_i : in std_logic;
|
1005 |
|
|
clk_inv_i : in std_logic;
|
1006 |
|
|
dat_inv_i : in std_logic;
|
1007 |
|
|
biphase_i : in std_logic;
|
1008 |
|
|
mark_i : in std_logic;
|
1009 |
|
|
level_i : in std_logic;
|
1010 |
|
|
|
1011 |
|
|
-- Bit Synchronizer Interface Port
|
1012 |
|
|
-- If no synchronizer is present, simply tie use_sync_i to '0'
|
1013 |
|
|
use_sync_i : in std_logic;
|
1014 |
|
|
pcm_dat_o : out std_logic;
|
1015 |
|
|
sync_dat_i : in std_logic;
|
1016 |
|
|
sync_clk_i : in std_logic;
|
1017 |
|
|
|
1018 |
|
|
-- signal outputs
|
1019 |
|
|
nrzl_dat_o : out std_logic;
|
1020 |
|
|
nrzl_clk_o : out std_logic
|
1021 |
|
|
);
|
1022 |
|
|
end pcm_input_front_end;
|
1023 |
|
|
|
1024 |
|
|
architecture beh of pcm_input_front_end is
|
1025 |
|
|
|
1026 |
|
|
-- Constants
|
1027 |
|
|
|
1028 |
|
|
-- Functions & associated types
|
1029 |
|
|
|
1030 |
|
|
-- Signal Declarations
|
1031 |
|
|
signal pcm_in : std_logic;
|
1032 |
|
|
signal pcm_in_r1 : std_logic;
|
1033 |
|
|
signal pcm_in_r2 : std_logic;
|
1034 |
|
|
signal pcm_edge : std_logic;
|
1035 |
|
|
signal clk_in : std_logic;
|
1036 |
|
|
signal clk_in_r1 : std_logic;
|
1037 |
|
|
signal clk_in_r2 : std_logic;
|
1038 |
|
|
signal clk_nrzl_falling : std_logic;
|
1039 |
|
|
signal baud_count : unsigned(BAUD_BITS-1 downto 0);
|
1040 |
|
|
signal nrzl_clk_r1 : std_logic;
|
1041 |
|
|
signal nrzl_clk_r2 : std_logic;
|
1042 |
|
|
signal pcm_nrzl : std_logic;
|
1043 |
|
|
signal pcm_a : std_logic;
|
1044 |
|
|
signal pcm_a_r1 : std_logic;
|
1045 |
|
|
signal pcm_unbi : std_logic;
|
1046 |
|
|
signal pcm_derand : std_logic;
|
1047 |
|
|
signal derand_sr : unsigned(DERAND_BITS-1 downto 0);
|
1048 |
|
|
signal bp_clk : std_logic;
|
1049 |
|
|
signal bp_clk_r1 : std_logic;
|
1050 |
|
|
signal half_baud : unsigned(BAUD_BITS-1 downto 0);
|
1051 |
|
|
|
1052 |
|
|
signal pcm_dat_l : std_logic;
|
1053 |
|
|
signal pcm_dat_lr1 : std_logic;
|
1054 |
|
|
signal pcm_dat_lr2 : std_logic;
|
1055 |
|
|
|
1056 |
|
|
signal pcm_clk_l : std_logic;
|
1057 |
|
|
signal pcm_clk_lr1 : std_logic;
|
1058 |
|
|
signal pcm_clk_lr2 : std_logic;
|
1059 |
|
|
|
1060 |
|
|
type FSM_STATE_TYPE is (SCAN_BAUD1, SCAN_BAUD2, CLK1, CLK2, DAT1, DAT2);
|
1061 |
|
|
signal fsm_state : FSM_STATE_TYPE;
|
1062 |
|
|
|
1063 |
|
|
-- Signals used to synchronize the output to the sys_clk rate
|
1064 |
|
|
signal nrzl_clk_choice : std_logic;
|
1065 |
|
|
signal nrzl_clk_s : unsigned(1 downto 0);
|
1066 |
|
|
signal nrzl_dat_choice : std_logic;
|
1067 |
|
|
signal nrzl_dat_s : unsigned(1 downto 0);
|
1068 |
|
|
|
1069 |
|
|
begin
|
1070 |
|
|
|
1071 |
|
|
-- Select the desired signals
|
1072 |
|
|
-- These selections are run through two stages of flip-flops for
|
1073 |
|
|
-- metastability mitigation.
|
1074 |
|
|
pcm_dat_l <= sig_i(to_integer(dat_sel_i)) xor dat_inv_i; -- data inversion support
|
1075 |
|
|
pcm_clk_l <= sig_i(to_integer(clk_sel_i)) xor clk_inv_i; -- clock inversion support
|
1076 |
|
|
|
1077 |
|
|
-- Provide the selected data signal to the bit synchronizer port
|
1078 |
|
|
pcm_dat_o <= pcm_dat_lr2;
|
1079 |
|
|
|
1080 |
|
|
-- Select desired inputs
|
1081 |
|
|
-- For biphase, the clock input gets totally ignored
|
1082 |
|
|
pcm_in <= pcm_dat_lr2 when use_sync_i='0' else sync_dat_i;
|
1083 |
|
|
clk_in <= pcm_clk_lr2 when use_sync_i='0' else sync_clk_i;
|
1084 |
|
|
|
1085 |
|
|
-- Create PCM clock falling edge signal
|
1086 |
|
|
clk_nrzl_falling <= '1' when nrzl_clk_r1='0' and nrzl_clk_r2='1' else '0';
|
1087 |
|
|
|
1088 |
|
|
-- Select which signals get sent out
|
1089 |
|
|
pcm_a <= pcm_in_r2 when biphase_i='0' else pcm_unbi;
|
1090 |
|
|
nrzl_dat_choice <= pcm_nrzl when derandom_i='0' else pcm_derand;
|
1091 |
|
|
nrzl_clk_r1 <= clk_in_r1 when biphase_i='0' else bp_clk;
|
1092 |
|
|
nrzl_clk_r2 <= clk_in_r2 when biphase_i='0' else bp_clk_r1;
|
1093 |
|
|
nrzl_clk_choice <= nrzl_clk_r2; -- (rising edge is in middle of data bit.)
|
1094 |
|
|
|
1095 |
|
|
--------------------------
|
1096 |
|
|
-- Synchronize outputs to sys_clk
|
1097 |
|
|
proc_sync_out: Process(sys_rst_n,sys_clk)
|
1098 |
|
|
begin
|
1099 |
|
|
if (sys_rst_n = '0') then
|
1100 |
|
|
nrzl_clk_s <= (others=>'0');
|
1101 |
|
|
nrzl_dat_s <= (others=>'0');
|
1102 |
|
|
elsif (sys_clk'event AND sys_clk='1') then
|
1103 |
|
|
nrzl_clk_s(0) <= nrzl_clk_choice;
|
1104 |
|
|
nrzl_clk_s(1) <= nrzl_clk_s(0);
|
1105 |
|
|
nrzl_dat_s(0) <= nrzl_dat_choice;
|
1106 |
|
|
nrzl_dat_s(1) <= nrzl_dat_s(0);
|
1107 |
|
|
end if;
|
1108 |
|
|
end process;
|
1109 |
|
|
nrzl_clk_o <= nrzl_clk_s(1);
|
1110 |
|
|
nrzl_dat_o <= nrzl_dat_s(1);
|
1111 |
|
|
|
1112 |
|
|
-- Create an "either edge" detector on pcm_in
|
1113 |
|
|
pcm_edge <= pcm_in_r1 xor pcm_in_r2;
|
1114 |
|
|
|
1115 |
|
|
-- Formulate a signal which represents half the Baud interval
|
1116 |
|
|
half_baud <= '0' & baud_i(BAUD_BITS-1 downto 1);
|
1117 |
|
|
|
1118 |
|
|
--------------------------
|
1119 |
|
|
-- Remove biphase and recover clock
|
1120 |
|
|
process (fast_clk, sys_rst_n)
|
1121 |
|
|
begin
|
1122 |
|
|
if (sys_rst_n='0') then
|
1123 |
|
|
fsm_state <= SCAN_BAUD1;
|
1124 |
|
|
bp_clk <= '0';
|
1125 |
|
|
bp_clk_r1 <= '0';
|
1126 |
|
|
pcm_in_r1 <= '0';
|
1127 |
|
|
pcm_in_r2 <= '0';
|
1128 |
|
|
clk_in_r1 <= '0';
|
1129 |
|
|
clk_in_r2 <= '0';
|
1130 |
|
|
pcm_unbi <= '0';
|
1131 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1132 |
|
|
pcm_dat_lr1 <= '0';
|
1133 |
|
|
pcm_dat_lr2 <= '0';
|
1134 |
|
|
pcm_clk_lr1 <= '0';
|
1135 |
|
|
pcm_clk_lr2 <= '0';
|
1136 |
|
|
elsif (fast_clk'event and fast_clk='1') then
|
1137 |
|
|
-- Metastability mitigation flip-flops
|
1138 |
|
|
pcm_dat_lr1 <= pcm_dat_l;
|
1139 |
|
|
pcm_dat_lr2 <= pcm_dat_lr1;
|
1140 |
|
|
pcm_clk_lr1 <= pcm_clk_l;
|
1141 |
|
|
pcm_clk_lr2 <= pcm_clk_lr1;
|
1142 |
|
|
|
1143 |
|
|
-- Handle the Baud interval counter
|
1144 |
|
|
baud_count <= baud_count+1;
|
1145 |
|
|
|
1146 |
|
|
--if (sys_clk_en='1') then
|
1147 |
|
|
-- default values
|
1148 |
|
|
|
1149 |
|
|
-- delayed version of signals for edge detection
|
1150 |
|
|
bp_clk_r1 <= bp_clk;
|
1151 |
|
|
pcm_in_r1 <= pcm_in;
|
1152 |
|
|
pcm_in_r2 <= pcm_in_r1;
|
1153 |
|
|
clk_in_r1 <= clk_in;
|
1154 |
|
|
clk_in_r2 <= clk_in_r1;
|
1155 |
|
|
|
1156 |
|
|
-- Finite State Machine
|
1157 |
|
|
case (fsm_state) is
|
1158 |
|
|
|
1159 |
|
|
when SCAN_BAUD1 =>
|
1160 |
|
|
if (pcm_edge='1') then
|
1161 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1162 |
|
|
elsif (baud_count=baud_i) then
|
1163 |
|
|
baud_count <= to_unsigned(0,baud_count'length);
|
1164 |
|
|
fsm_state <= SCAN_BAUD2;
|
1165 |
|
|
end if;
|
1166 |
|
|
|
1167 |
|
|
when SCAN_BAUD2 =>
|
1168 |
|
|
if (pcm_edge='1') then
|
1169 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1170 |
|
|
fsm_state <= SCAN_BAUD1;
|
1171 |
|
|
elsif (baud_count=half_baud) then
|
1172 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1173 |
|
|
fsm_state <= CLK1;
|
1174 |
|
|
end if;
|
1175 |
|
|
|
1176 |
|
|
when CLK1 =>
|
1177 |
|
|
if (pcm_edge='1') then
|
1178 |
|
|
baud_count <= to_unsigned(0,baud_count'length);
|
1179 |
|
|
fsm_state <= CLK2;
|
1180 |
|
|
pcm_unbi <= pcm_in_r2;
|
1181 |
|
|
bp_clk <= '0';
|
1182 |
|
|
elsif (baud_count=baud_i) then
|
1183 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1184 |
|
|
fsm_state <= SCAN_BAUD1;
|
1185 |
|
|
end if;
|
1186 |
|
|
|
1187 |
|
|
when CLK2 =>
|
1188 |
|
|
if (pcm_edge='1') then
|
1189 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1190 |
|
|
fsm_state <= SCAN_BAUD1;
|
1191 |
|
|
elsif (baud_count=half_baud) then
|
1192 |
|
|
baud_count <= to_unsigned(0,baud_count'length);
|
1193 |
|
|
fsm_state <= DAT1;
|
1194 |
|
|
end if;
|
1195 |
|
|
|
1196 |
|
|
when DAT1 =>
|
1197 |
|
|
if (pcm_edge='1') then
|
1198 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1199 |
|
|
fsm_state <= DAT2;
|
1200 |
|
|
bp_clk <= '1';
|
1201 |
|
|
elsif (baud_count=half_baud) then
|
1202 |
|
|
baud_count <= to_unsigned(0,baud_count'length);
|
1203 |
|
|
fsm_state <= DAT2;
|
1204 |
|
|
bp_clk <= '1';
|
1205 |
|
|
end if;
|
1206 |
|
|
|
1207 |
|
|
when DAT2 =>
|
1208 |
|
|
if (pcm_edge='1') then
|
1209 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1210 |
|
|
fsm_state <= SCAN_BAUD1;
|
1211 |
|
|
elsif (baud_count=half_baud) then
|
1212 |
|
|
baud_count <= to_unsigned(1,baud_count'length);
|
1213 |
|
|
fsm_state <= CLK1;
|
1214 |
|
|
end if;
|
1215 |
|
|
|
1216 |
|
|
when others =>
|
1217 |
|
|
null;
|
1218 |
|
|
end case;
|
1219 |
|
|
|
1220 |
|
|
--end if; -- sys_clk_en
|
1221 |
|
|
end if; -- sys_clk
|
1222 |
|
|
end process;
|
1223 |
|
|
|
1224 |
|
|
--------------------------
|
1225 |
|
|
-- Process to remove mark/space coding
|
1226 |
|
|
proc_unmark: Process(sys_rst_n,fast_clk)
|
1227 |
|
|
begin
|
1228 |
|
|
if (sys_rst_n = '0') then
|
1229 |
|
|
pcm_nrzl <= '0';
|
1230 |
|
|
pcm_a_r1 <= '0';
|
1231 |
|
|
elsif (fast_clk'event AND fast_clk='1') then
|
1232 |
|
|
if (clk_nrzl_falling='1') then
|
1233 |
|
|
pcm_a_r1 <= pcm_a; -- pcm_a already synchronized... just need one flip-flop.
|
1234 |
|
|
if (level_i='1') then
|
1235 |
|
|
pcm_nrzl <= pcm_a_r1; -- Default : No coding to be removed, just delay the input.
|
1236 |
|
|
else
|
1237 |
|
|
if (mark_i='1') then
|
1238 |
|
|
pcm_nrzl <= pcm_a xor pcm_a_r1; -- In Mark, '1' is represented by change in level
|
1239 |
|
|
else
|
1240 |
|
|
pcm_nrzl <= not (pcm_a xor pcm_a_r1); -- In Space, '0' is represented by change in level
|
1241 |
|
|
end if;
|
1242 |
|
|
end if;
|
1243 |
|
|
end if;
|
1244 |
|
|
end if;
|
1245 |
|
|
end process;
|
1246 |
|
|
|
1247 |
|
|
--------------------------
|
1248 |
|
|
-- Derandomizer shift register
|
1249 |
|
|
proc_derand_sr: Process(sys_rst_n,fast_clk)
|
1250 |
|
|
begin
|
1251 |
|
|
if (sys_rst_n = '0') then
|
1252 |
|
|
derand_sr <= (others=>'0');
|
1253 |
|
|
elsif (fast_clk'event AND fast_clk='1') then
|
1254 |
|
|
if (clk_nrzl_falling='1') then
|
1255 |
|
|
derand_sr <= derand_sr(derand_sr'length-2 downto 0) & pcm_nrzl;
|
1256 |
|
|
end if;
|
1257 |
|
|
end if;
|
1258 |
|
|
end process;
|
1259 |
|
|
pcm_derand <= pcm_nrzl xor u_recursive_parity(derand_sr and dr_taps_i);
|
1260 |
|
|
|
1261 |
|
|
end beh;
|
1262 |
|
|
|
1263 |
|
|
---------------------------------------------------------------------------------
|
1264 |
|
|
-- Digital Phase Locked Loop (With Alexander "Bang-Bang" Phase Detector)
|
1265 |
|
|
-------------------------------------------------------------------------------
|
1266 |
|
|
--
|
1267 |
|
|
-- Author: John Clayton
|
1268 |
|
|
-- Date : Mar. 26, 2014 Obtained code from Jacob Fenton, tested it in
|
1269 |
|
|
-- simulation. Formatted the code to suit my own
|
1270 |
|
|
-- personal coding style, and added the constant
|
1271 |
|
|
-- lebensraum.
|
1272 |
|
|
-- Sep. 20, 2017 Added kp_1 and ki_1 to extend kp_i and ki_i to
|
1273 |
|
|
-- P_BITS length, prior to applying shift_right.
|
1274 |
|
|
-- This restores the precision that was being
|
1275 |
|
|
-- truncated, and allows getting rid of the
|
1276 |
|
|
-- user-defined resize function.
|
1277 |
|
|
--
|
1278 |
|
|
-- Description
|
1279 |
|
|
-------------------------------------------------------------------------------
|
1280 |
|
|
-- This module includes an NCO (squarewave DDS), a lowpass filter and
|
1281 |
|
|
-- an Alexander "bang-bang" type phase detector configured as a
|
1282 |
|
|
-- digital PLL.
|
1283 |
|
|
--
|
1284 |
|
|
-- The original design was set up, coded and simulated by
|
1285 |
|
|
-- Jacob Fenton.
|
1286 |
|
|
--
|
1287 |
|
|
-- This version includes a bandwidth reduction input to allow for
|
1288 |
|
|
-- reducing the loop bandwidth once lock has been achieved.
|
1289 |
|
|
--
|
1290 |
|
|
-- -------------------------------------------------------------
|
1291 |
|
|
-- Functional Description:
|
1292 |
|
|
-- -------------------------------------------------------------
|
1293 |
|
|
-- The following constants, taken from Jacob Fenton's testbench,
|
1294 |
|
|
-- serve to illustrate how to adjust the settings:
|
1295 |
|
|
--
|
1296 |
|
|
-- constant NCO_BITS : integer := 32;
|
1297 |
|
|
-- constant P_BITS : integer := 32;
|
1298 |
|
|
-- constant I_BITS : integer := 32;
|
1299 |
|
|
-- constant sysclk : real := 50.0E+6;--fpga sys_clk rate
|
1300 |
|
|
-- constant baud : real := 3.0E+6;--expected data rate
|
1301 |
|
|
-- constant dmp_fctr : real := 0.7071;
|
1302 |
|
|
-- constant pi : real := 3.14159;
|
1303 |
|
|
-- constant bw : real := (0.005*baud);--desired dpll bandwidth as percentage of baud rate
|
1304 |
|
|
-- constant ko : real := (pi*sysclk)/("**"(2,real(NCO_BITS-1)));--nco gain (rad/sec)
|
1305 |
|
|
-- constant kd : real := ((sysclk/baud)*2.0)/pi;--phase detector gain (1/rad)
|
1306 |
|
|
-- constant kp : integer:= integer((dmp_fctr*2.0*2.0*pi*bw)/(ko*kd));
|
1307 |
|
|
-- constant ki : integer:= integer(("**"(2.0*pi*bw,2))/(sysclk*ko*kd));--need to make sure that with settings this value > 0, at some point use fixed point numbers
|
1308 |
|
|
-- constant w : integer:= integer(2.0*("**"(2,real(NCO_BITS-1)))/(sysclk/baud));
|
1309 |
|
|
--
|
1310 |
|
|
-- -------------------------------------------------------------
|
1311 |
|
|
|
1312 |
|
|
library ieee;
|
1313 |
|
|
use ieee.std_logic_1164.all;
|
1314 |
|
|
use ieee.numeric_std.all;
|
1315 |
|
|
|
1316 |
|
|
entity dpll_alex_bw_adjust is
|
1317 |
|
|
generic (
|
1318 |
|
|
NCO_BITS : integer := 32;
|
1319 |
|
|
KP_I_BITS : integer := 24;
|
1320 |
|
|
KI_I_BITS : integer := 24;
|
1321 |
|
|
K_FRAC_BITS : integer := 8;
|
1322 |
|
|
GAIN_DIV : integer := 3
|
1323 |
|
|
);
|
1324 |
|
|
port(
|
1325 |
|
|
sys_clk : in std_logic;
|
1326 |
|
|
sys_rst_n : in std_logic;
|
1327 |
|
|
sys_clk_en : in std_logic;
|
1328 |
|
|
clear_i : in std_logic;
|
1329 |
|
|
dat_i : in std_logic;
|
1330 |
|
|
w_i : in unsigned(NCO_BITS-1 downto 0);
|
1331 |
|
|
kp_i : in unsigned(KP_I_BITS-1 downto 0);
|
1332 |
|
|
ki_i : in unsigned(KI_I_BITS-1 downto 0);
|
1333 |
|
|
bit_lock_i : in std_logic;
|
1334 |
|
|
dat_o : out std_logic;
|
1335 |
|
|
clk_o : out std_logic
|
1336 |
|
|
);
|
1337 |
|
|
end dpll_alex_bw_adjust;
|
1338 |
|
|
|
1339 |
|
|
architecture beh of dpll_alex_bw_adjust is
|
1340 |
|
|
|
1341 |
|
|
constant P_BITS : integer := KP_I_BITS+K_FRAC_BITS;
|
1342 |
|
|
constant I_BITS : integer := KI_I_BITS+K_FRAC_BITS;
|
1343 |
|
|
constant zero : unsigned(P_BITS-2 downto 0) := (others => '0');
|
1344 |
|
|
|
1345 |
|
|
signal lpf_o : unsigned(P_BITS-1 downto 0);
|
1346 |
|
|
signal int_acum : unsigned(P_BITS-1 downto 0);
|
1347 |
|
|
signal kp_1 : unsigned(P_BITS-1 downto 0);
|
1348 |
|
|
signal ki_1 : unsigned(I_BITS-1 downto 0);
|
1349 |
|
|
signal kp_new : unsigned(P_BITS-1 downto 0);
|
1350 |
|
|
signal ki_new : unsigned(I_BITS-1 downto 0);
|
1351 |
|
|
signal nco_acum : unsigned(NCO_BITS-1 downto 0);
|
1352 |
|
|
signal up : std_logic;
|
1353 |
|
|
signal dn : std_logic;
|
1354 |
|
|
signal reg1 : std_logic;
|
1355 |
|
|
signal reg2 : std_logic;
|
1356 |
|
|
signal reg3 : std_logic;
|
1357 |
|
|
signal reg4 : std_logic;
|
1358 |
|
|
signal nco_clk : std_logic;
|
1359 |
|
|
|
1360 |
|
|
begin
|
1361 |
|
|
|
1362 |
|
|
clk_o <= nco_clk;
|
1363 |
|
|
dat_o <= reg4;
|
1364 |
|
|
|
1365 |
|
|
nco : process(sys_clk, sys_rst_n)
|
1366 |
|
|
begin
|
1367 |
|
|
if (sys_rst_n = '0') then
|
1368 |
|
|
nco_acum <= (others=>'0'); -- was w_i
|
1369 |
|
|
nco_clk <= '0';
|
1370 |
|
|
elsif rising_edge(sys_clk) then
|
1371 |
|
|
if (sys_clk_en='1') then
|
1372 |
|
|
if lpf_o(P_BITS-1) = '0' then --check sign of lpf_o
|
1373 |
|
|
nco_acum <= nco_acum + w_i + unsigned(shift_right(signed(lpf_o),K_FRAC_BITS)) + (zero & lpf_o(9));
|
1374 |
|
|
else
|
1375 |
|
|
nco_acum <= nco_acum + w_i - not(unsigned(shift_right(signed(lpf_o),K_FRAC_BITS))) + 1 - (zero & lpf_o(9));
|
1376 |
|
|
end if;
|
1377 |
|
|
nco_clk <= nco_acum(NCO_BITS-1);
|
1378 |
|
|
end if; -- sys_clk_en
|
1379 |
|
|
end if; -- sys_clk
|
1380 |
|
|
end process nco;
|
1381 |
|
|
|
1382 |
|
|
lpf : process(sys_clk, sys_rst_n)
|
1383 |
|
|
begin
|
1384 |
|
|
if (sys_rst_n = '0') then
|
1385 |
|
|
lpf_o <= (others=>'0');
|
1386 |
|
|
int_acum <= (others=> '0');
|
1387 |
|
|
elsif rising_edge(sys_clk) then
|
1388 |
|
|
if (sys_clk_en='1') then
|
1389 |
|
|
if (up = '1' and dn = '0') then --indicates need to speed up
|
1390 |
|
|
lpf_o <= int_acum + kp_new;
|
1391 |
|
|
int_acum <= int_acum + ki_new;
|
1392 |
|
|
elsif (up = '0' and dn = '1') then --indicates need to slow down
|
1393 |
|
|
lpf_o <= int_acum - kp_new;
|
1394 |
|
|
int_acum <= int_acum - ki_new;
|
1395 |
|
|
end if;
|
1396 |
|
|
end if; -- sys_clk_en
|
1397 |
|
|
end if; -- sys_clk
|
1398 |
|
|
end process lpf;
|
1399 |
|
|
|
1400 |
|
|
-- Adjust the bandwidth based on the bit_lock_i input
|
1401 |
|
|
kp_1 <= kp_i & to_unsigned(0,K_FRAC_BITS);
|
1402 |
|
|
kp_new <= shift_right(kp_1,gain_div) when bit_lock_i='1' else kp_1;
|
1403 |
|
|
-- John Clayton noted: Mathematically, according to the formulae given, reducing bandwidth by
|
1404 |
|
|
-- a certain amount entails a direct division of kp_i, but the ki_i factor should be divided by
|
1405 |
|
|
-- the square of the reduction factor...
|
1406 |
|
|
ki_1 <= ki_i & to_unsigned(0,K_FRAC_BITS);
|
1407 |
|
|
ki_new <= shift_right(ki_1,2*gain_div) when bit_lock_i='1' else ki_1;
|
1408 |
|
|
|
1409 |
|
|
up <= reg4 xor reg1;
|
1410 |
|
|
dn <= reg2 xor reg4;
|
1411 |
|
|
|
1412 |
|
|
alex_pfd : process(nco_clk, sys_rst_n)
|
1413 |
|
|
begin
|
1414 |
|
|
if (sys_rst_n = '0') then
|
1415 |
|
|
reg1 <= '0';
|
1416 |
|
|
reg2 <= '0';
|
1417 |
|
|
reg3 <= '0';
|
1418 |
|
|
reg4 <= '0';
|
1419 |
|
|
elsif rising_edge(nco_clk) then
|
1420 |
|
|
reg1 <= dat_i;
|
1421 |
|
|
reg2 <= reg1;
|
1422 |
|
|
reg4 <= reg3;
|
1423 |
|
|
elsif falling_edge(nco_clk) then
|
1424 |
|
|
reg3 <= dat_i;
|
1425 |
|
|
end if;
|
1426 |
|
|
end process alex_pfd;
|
1427 |
|
|
|
1428 |
|
|
end beh;
|
1429 |
|
|
|
1430 |
|
|
|
1431 |
|
|
---------------------------------------------------------------------------------
|
1432 |
|
|
-- Bit Sync lock detector Module
|
1433 |
|
|
-------------------------------------------------------------------------------
|
1434 |
|
|
--
|
1435 |
|
|
-- Author: Jacob Fenton, with modifications by John Clayton
|
1436 |
|
|
-- Date : Jan. 26, 2012 Obtained code from Jacob Fenton, wrote header
|
1437 |
|
|
-- and description.
|
1438 |
|
|
--
|
1439 |
|
|
-- Description
|
1440 |
|
|
-------------------------------------------------------------------------------
|
1441 |
|
|
-- This module implements a bit synchronization lock detection function.
|
1442 |
|
|
--
|
1443 |
|
|
-- The bit synchronizer lock detector makes the initial assumption that the
|
1444 |
|
|
-- bit synchronizer is not locked.
|
1445 |
|
|
-- The bit synchronizer lock detection mechanism starts a countdown from
|
1446 |
|
|
-- BIT_CNT_MAX. Whenever a change is detected on the data signal, the
|
1447 |
|
|
-- accompanying clock signal is also checked for changes. If a change
|
1448 |
|
|
-- is present, the counter is decremented, otherwise the counter is
|
1449 |
|
|
-- incremented. However, the counter is not allowed to "roll over"
|
1450 |
|
|
-- past zero or BIT_CNT_MAX. Once the counter reaches a value below
|
1451 |
|
|
-- BIT_CNT_1, the bit synchronizer is said to be in a locked state.
|
1452 |
|
|
-- In order to be counted valid, the bit synchronizer clock edge must
|
1453 |
|
|
-- be present either at the same or previous system clock edge as the
|
1454 |
|
|
-- data transition.
|
1455 |
|
|
--
|
1456 |
|
|
-- When the count surpasses BIT_CNT_2, the bit synchronizer is said to
|
1457 |
|
|
-- be in an unlocked state. Thus, the BIT_CNT_2 and BIT_CNT_1 thresholds
|
1458 |
|
|
-- can be set so as to produce a desired amount of hysteresis in the lock
|
1459 |
|
|
-- determination algorithm. Note that BIT_CNT_2 must be higher than
|
1460 |
|
|
-- BIT_CNT_1 to be of any effect at all. If BIT_CNT_2 is less than or
|
1461 |
|
|
-- equal to BIT_CNT_1, then once lock is achieved, it will never be
|
1462 |
|
|
-- declared lost until after a reset.
|
1463 |
|
|
--
|
1464 |
|
|
-- Another observation about this module is that it assumes the bit
|
1465 |
|
|
-- synchronizer always produces a clock edge within one system clock
|
1466 |
|
|
-- cycle of the time when a data edge occurs, which is not a strict
|
1467 |
|
|
-- requirement on bit synchronizers in general. In fact, the heuristic
|
1468 |
|
|
-- "digital bit synchronizer" does not meet this requirement, implying
|
1469 |
|
|
-- that this module's requirements on data transition and clock transition
|
1470 |
|
|
-- proximity would need to be relaxed in order to use it with the
|
1471 |
|
|
-- digital bit synchronizer.
|
1472 |
|
|
--
|
1473 |
|
|
-- One final observation is that the initial lock takes BIT_CNT_MAX
|
1474 |
|
|
-- bit-synchronizer clocks to occur, while reacquisition of lock after
|
1475 |
|
|
-- losing it can be as rapid as (BIT_CNT_2-BIT_CNT_1) bit synchronizer clocks.
|
1476 |
|
|
--
|
1477 |
|
|
|
1478 |
|
|
library IEEE;
|
1479 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
1480 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
1481 |
|
|
use IEEE.MATH_REAL.ALL;
|
1482 |
|
|
|
1483 |
|
|
library work;
|
1484 |
|
|
use work.function_pack.all;
|
1485 |
|
|
|
1486 |
|
|
entity bitsync_lock_detector is
|
1487 |
|
|
generic (
|
1488 |
|
|
BIT_CNT_MAX : integer := 255;
|
1489 |
|
|
BIT_CNT_1 : integer := 5;
|
1490 |
|
|
BIT_CNT_2 : integer := 15
|
1491 |
|
|
);
|
1492 |
|
|
port(
|
1493 |
|
|
sys_clk : in std_logic;
|
1494 |
|
|
sys_rst_n : in std_logic;
|
1495 |
|
|
sys_clk_en : in std_logic;
|
1496 |
|
|
dat_i : in std_logic;
|
1497 |
|
|
pll_clk : in std_logic;
|
1498 |
|
|
lock_o : out std_logic
|
1499 |
|
|
);
|
1500 |
|
|
end bitsync_lock_detector;
|
1501 |
|
|
|
1502 |
|
|
architecture beh of bitsync_lock_detector is
|
1503 |
|
|
|
1504 |
|
|
signal bit_cntr : unsigned(bit_width(BIT_CNT_MAX)-1 downto 0);
|
1505 |
|
|
signal dat_chng : std_logic;
|
1506 |
|
|
signal bit_lock : std_logic;
|
1507 |
|
|
signal dat_reg1 : std_logic;
|
1508 |
|
|
signal dat_reg2 : std_logic;
|
1509 |
|
|
signal pll_clk_chng : std_logic;
|
1510 |
|
|
signal pll_clk_reg1 : std_logic;
|
1511 |
|
|
signal pll_clk_reg2 : std_logic;
|
1512 |
|
|
|
1513 |
|
|
begin
|
1514 |
|
|
|
1515 |
|
|
dat_chng <= dat_i xor dat_reg2;
|
1516 |
|
|
pll_clk_chng <= pll_clk xor pll_clk_reg2;
|
1517 |
|
|
lock_o <= bit_lock;
|
1518 |
|
|
|
1519 |
|
|
bit_lock_proc : process(sys_rst_n, sys_clk)
|
1520 |
|
|
begin
|
1521 |
|
|
if (sys_rst_n = '0') then
|
1522 |
|
|
bit_cntr <= to_unsigned(bit_cnt_max,bit_cntr'length);
|
1523 |
|
|
dat_reg1 <= '0';
|
1524 |
|
|
dat_reg2 <= '0';
|
1525 |
|
|
pll_clk_reg1 <= '0';
|
1526 |
|
|
pll_clk_reg2 <= '0';
|
1527 |
|
|
bit_lock <= '0';
|
1528 |
|
|
elsif rising_edge(sys_clk) then
|
1529 |
|
|
if (sys_clk_en='1') then
|
1530 |
|
|
dat_reg1 <= dat_i;
|
1531 |
|
|
dat_reg2 <= dat_reg1;
|
1532 |
|
|
pll_clk_reg1 <= pll_clk;
|
1533 |
|
|
pll_clk_reg2 <= pll_clk_reg1;
|
1534 |
|
|
if bit_cntr < bit_cnt_1 then
|
1535 |
|
|
bit_lock <= '1';
|
1536 |
|
|
elsif bit_cntr > bit_cnt_2 then
|
1537 |
|
|
bit_lock <='0';
|
1538 |
|
|
end if;
|
1539 |
|
|
|
1540 |
|
|
if dat_chng = '1' then
|
1541 |
|
|
if (pll_clk_chng = '1') and (bit_cntr > 0) then
|
1542 |
|
|
bit_cntr <= bit_cntr-1;
|
1543 |
|
|
elsif (pll_clk_chng = '0') and (bit_cntr < bit_cnt_max) then
|
1544 |
|
|
bit_cntr <= bit_cntr+1;
|
1545 |
|
|
end if;
|
1546 |
|
|
end if;
|
1547 |
|
|
end if; -- sys_clk_en
|
1548 |
|
|
end if; -- sys_clk
|
1549 |
|
|
|
1550 |
|
|
|
1551 |
|
|
end process bit_lock_proc;
|
1552 |
|
|
|
1553 |
|
|
end beh;
|
1554 |
|
|
|
1555 |
|
|
|
1556 |
|
|
---------------------------------------------------------------------------------
|
1557 |
|
|
-- Digital Bit Sync Module
|
1558 |
|
|
-------------------------------------------------------------------------------
|
1559 |
|
|
--
|
1560 |
|
|
-- Author: John Clayton
|
1561 |
|
|
-- Date : Jan. 26, 2012 Started Coding, drawing from various other sources.
|
1562 |
|
|
-- Created description.
|
1563 |
|
|
-- Feb. 10, 2012 Achieved good results in simulation. Cleaned up
|
1564 |
|
|
-- the code, and re-wrote the description.
|
1565 |
|
|
-- Feb. 13, 2012 Tested via simulation. Added new state transition
|
1566 |
|
|
-- from PHASE_TRACK to FREQ_SEEK state. Added
|
1567 |
|
|
-- "tweak_bias_trigger" to prevent this transition from
|
1568 |
|
|
-- being taken too quickly after entry into PHASE_TRACK.
|
1569 |
|
|
-- Mar. 16, 2012 Added logic to use delta phase zero crossings as the
|
1570 |
|
|
-- trigger for exiting FREQ_SEEK. This facilitates
|
1571 |
|
|
-- proper exit with low frequency signals, when the
|
1572 |
|
|
-- period changes are large. Removed ADJUST state.
|
1573 |
|
|
-- Added FREQ_SEEK2 state for medium granularity
|
1574 |
|
|
-- frequency search.
|
1575 |
|
|
-- Oct. 30, 2013 Added "freq_seek_i" input to allow external enabling
|
1576 |
|
|
-- of the "auto frequency seeking" feature. When
|
1577 |
|
|
-- "freq_seek_i" is low, the unit operates in the
|
1578 |
|
|
-- PHASE_TRACK state only. Moved other generic settings
|
1579 |
|
|
-- over to signal inputs, in anticipation of making
|
1580 |
|
|
-- a register connected bit_sync module. Changed module
|
1581 |
|
|
-- name to "bit_sync_digital." Added "use_alex_i" input
|
1582 |
|
|
-- to select between heuristic and Alexander DPLL
|
1583 |
|
|
-- techniques. Added Alexander DPLL version.
|
1584 |
|
|
-- Nov. 14, 2014 Added alex_kp_i and alex_ki_i inputs.
|
1585 |
|
|
--
|
1586 |
|
|
--
|
1587 |
|
|
-- Description
|
1588 |
|
|
-------------------------------------------------------------------------------
|
1589 |
|
|
-- This module applies a finite state machine controlled series of
|
1590 |
|
|
-- phase and bit-period measurements to an incoming data signal, and
|
1591 |
|
|
-- uses the measurements to guide the operation of a direct digital
|
1592 |
|
|
-- synthesizer (DDS) which creates an output clock signal to accompany the
|
1593 |
|
|
-- data stream.
|
1594 |
|
|
--
|
1595 |
|
|
-- Because the incoming data signal is sampled in a purely bi-level way,
|
1596 |
|
|
-- and may contain sequences of adjacent '1' and '0' values, direct
|
1597 |
|
|
-- measurement of the frequency is difficult. Similarly, direct measurement
|
1598 |
|
|
-- of the period is also difficult. In this case, the decision was made
|
1599 |
|
|
-- to measure period between transitions. Using Fourier analysis to make
|
1600 |
|
|
-- measurements in the frequency domain should also be possible in theory,
|
1601 |
|
|
-- however this has been ruled out due to the complexity and resource
|
1602 |
|
|
-- utilization demanded by the FFT approach.
|
1603 |
|
|
--
|
1604 |
|
|
-- Precise bit-period measurements are performed on the incoming data stream
|
1605 |
|
|
-- and the generated clock signal using a statistical successive
|
1606 |
|
|
-- approximation technique described in the "bit_period_detector" module.
|
1607 |
|
|
-- Two bit_period_detector modules are instantiated, one for the data
|
1608 |
|
|
-- and one for the clock. The bit_period_detector modules contain
|
1609 |
|
|
-- synchronizing flip-flops to mitigate metastability issues when feeding
|
1610 |
|
|
-- in signals from other clock domains.
|
1611 |
|
|
--
|
1612 |
|
|
-- The data signal is expected to be digital in nature, with transitions
|
1613 |
|
|
-- that are rapid enough to be measured without significant noise-related
|
1614 |
|
|
-- jitter. The data is also required to be a bi-level signal in which the
|
1615 |
|
|
-- symbols, or data bits, are of reasonably uniform symbol period.
|
1616 |
|
|
-- It is expected that there be transitions at least every 2^PERIOD_I_WIDTH
|
1617 |
|
|
-- symbol periods, and that there be at least one baud interval every
|
1618 |
|
|
-- BAUD_RD_TRIES intervals, where an interval is defined as the time
|
1619 |
|
|
-- between two transitions, and a "baud interval" is defined as the
|
1620 |
|
|
-- shortest expected interval. Intervals shorter than the baud interval
|
1621 |
|
|
-- would only be caused by noise...
|
1622 |
|
|
-- It is also expected that the signal be stable in frequency, so that
|
1623 |
|
|
-- any drift or frequency variation can be tracked by a slowly responding
|
1624 |
|
|
-- frequency feedback loop, while the phase of the generated clock can
|
1625 |
|
|
-- track the phase of the data signal in a much more rapidly responding
|
1626 |
|
|
-- feedback loop.
|
1627 |
|
|
--
|
1628 |
|
|
-- For the phase locking loop, whenever a transition is found in the data,
|
1629 |
|
|
-- the DDS phase accumulator is checked to see how close it is to producing
|
1630 |
|
|
-- a transition. Any value above or below zero at that point in time is
|
1631 |
|
|
-- viewed as a "residual phase" which ideally should not be present.
|
1632 |
|
|
-- A window of values is defined in which the residual phase is considered
|
1633 |
|
|
-- small enough to ignore. However, if the residula phase exceeds the
|
1634 |
|
|
-- threshold, the DDS phase accumulator is reset to zero, thus keeping the
|
1635 |
|
|
-- output clock in good phase syncronization with the data. The closer the
|
1636 |
|
|
-- DDS output frequency is to the actual frequency of the incoming data bits,
|
1637 |
|
|
-- the more bit periods of "freewheeling drift" can be tolerated.
|
1638 |
|
|
-- The drift time is defined as any time period during which there are no
|
1639 |
|
|
-- transitions in the incoming data stream.
|
1640 |
|
|
--
|
1641 |
|
|
-- In order to continuously refine the frequency setting of the DDS during
|
1642 |
|
|
-- phase tracking, at the time the phase accumulator is being reset to zero,
|
1643 |
|
|
-- the sign of the residual phase is checked. This is fed into an up/down
|
1644 |
|
|
-- counter which integrates this residual phase "error" signal. When the
|
1645 |
|
|
-- integrated error signal becomes high enough, the frequency setting is
|
1646 |
|
|
-- adjusted to minimize the frequency error in the future.
|
1647 |
|
|
--
|
1648 |
|
|
-- The sys_rst_n input is an asynchronous reset.
|
1649 |
|
|
|
1650 |
|
|
library IEEE;
|
1651 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
1652 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
1653 |
|
|
use IEEE.MATH_REAL.ALL;
|
1654 |
|
|
|
1655 |
|
|
library work;
|
1656 |
|
|
use work.bit_sync_pack.all;
|
1657 |
|
|
|
1658 |
|
|
entity bit_sync_digital is
|
1659 |
|
|
generic(
|
1660 |
|
|
ALEX_K_BITS : integer := 32; -- Number of bits in Alexander DPLL coefficients
|
1661 |
|
|
ALEX_K_FRAC : integer := 8; -- How many of the ALEX_K_BITS are used for fractional representation
|
1662 |
|
|
ALEX_GAIN_ADJ : integer := 2; -- How many bits to reduce KP_i and KI_i during lock
|
1663 |
|
|
FSTEP_FINE : integer := 2**4; -- Used during PHASE_TRACK
|
1664 |
|
|
PHASE_WIDTH : integer := 33; -- Bits in the phase accumulator
|
1665 |
|
|
LOCK_VAL : integer := 4; -- Period mismatch limit to obtain lock
|
1666 |
|
|
DROP_LOCK_VAL : integer := 12; -- Period mismatch tolerance during lock
|
1667 |
|
|
PERIOD_I_WIDTH : integer := 16; -- Integer width of period measurements
|
1668 |
|
|
PERIOD_F_WIDTH : integer := 2; -- Fractional width of period measurements
|
1669 |
|
|
IDLE_CLOCKS : integer := 2**16; -- sys_clk periods before signal is called idle
|
1670 |
|
|
BAUD_READS : integer := 127; -- Period baud interval read attempts
|
1671 |
|
|
INTERVAL_READS : integer := 64; -- Period interval read attempts
|
1672 |
|
|
WINDOW_SIZE : integer := 3 -- Period variation window, in sys_clks
|
1673 |
|
|
);
|
1674 |
|
|
port (
|
1675 |
|
|
-- System Clock and Clock Enable
|
1676 |
|
|
sys_rst_n : in std_logic;
|
1677 |
|
|
sys_clk : in std_logic;
|
1678 |
|
|
sys_clk_en : in std_logic;
|
1679 |
|
|
|
1680 |
|
|
-- Frequency calibration clk enable
|
1681 |
|
|
cal_clk_en : in std_logic;
|
1682 |
|
|
|
1683 |
|
|
-- Settings
|
1684 |
|
|
freq_i : in unsigned(PHASE_WIDTH-2 downto 0);
|
1685 |
|
|
freq_seek_i : in std_logic;
|
1686 |
|
|
use_alex_i : in std_logic;
|
1687 |
|
|
alex_kp_i : in unsigned(ALEX_K_BITS-ALEX_K_FRAC-1 downto 0);
|
1688 |
|
|
alex_ki_i : in unsigned(ALEX_K_BITS-ALEX_K_FRAC-1 downto 0);
|
1689 |
|
|
|
1690 |
|
|
-- Reference data input
|
1691 |
|
|
dat_i : in std_logic;
|
1692 |
|
|
|
1693 |
|
|
-- indicators and outputs
|
1694 |
|
|
idle_o : out std_logic;
|
1695 |
|
|
lock_o : out std_logic;
|
1696 |
|
|
dat_o : out std_logic;
|
1697 |
|
|
clk_o : out std_logic
|
1698 |
|
|
);
|
1699 |
|
|
end bit_sync_digital;
|
1700 |
|
|
|
1701 |
|
|
architecture beh of bit_sync_digital is
|
1702 |
|
|
|
1703 |
|
|
-- Constants
|
1704 |
|
|
constant PERIOD_T_WIDTH : integer := PERIOD_I_WIDTH+PERIOD_F_WIDTH;
|
1705 |
|
|
constant TWEAK_BIAS_WIDTH : integer := 6;
|
1706 |
|
|
constant ALEX_NCO_BITS : integer := 33;
|
1707 |
|
|
constant ALEX_W_SHIFT : integer := 2**(ALEX_NCO_BITS-PHASE_WIDTH);
|
1708 |
|
|
|
1709 |
|
|
-- Functions & associated types
|
1710 |
|
|
|
1711 |
|
|
-- Signal Declarations
|
1712 |
|
|
signal phase : unsigned(PHASE_WIDTH-1 downto 0);
|
1713 |
|
|
signal phase_next : unsigned(PHASE_WIDTH-1 downto 0);
|
1714 |
|
|
signal freq : unsigned(PHASE_WIDTH-1 downto 0);
|
1715 |
|
|
signal locked : std_logic;
|
1716 |
|
|
signal locked_a : std_logic;
|
1717 |
|
|
signal delta_p : signed(PERIOD_T_WIDTH-1 downto 0);
|
1718 |
|
|
signal phase_tweak : std_logic;
|
1719 |
|
|
signal tweak_bias : unsigned(TWEAK_BIAS_WIDTH-1 downto 0);
|
1720 |
|
|
signal tweak_bias_trigger : std_logic;
|
1721 |
|
|
signal lock : std_logic;
|
1722 |
|
|
signal unlock : std_logic;
|
1723 |
|
|
|
1724 |
|
|
signal clk_period : unsigned(PERIOD_T_WIDTH-1 downto 0);
|
1725 |
|
|
signal clk_p_load : std_logic;
|
1726 |
|
|
signal clk_p_idle : std_logic;
|
1727 |
|
|
|
1728 |
|
|
signal dat_period : unsigned(PERIOD_T_WIDTH-1 downto 0);
|
1729 |
|
|
signal dat_p_load : std_logic;
|
1730 |
|
|
signal dat_p_idle : std_logic;
|
1731 |
|
|
signal dat_s_edge : std_logic;
|
1732 |
|
|
|
1733 |
|
|
signal dat_r1 : std_logic;
|
1734 |
|
|
signal dat_r2 : std_logic;
|
1735 |
|
|
|
1736 |
|
|
type FSM_STATE_TYPE is (INIT, PHASE_TRACK);
|
1737 |
|
|
signal fsm_state : FSM_STATE_TYPE;
|
1738 |
|
|
|
1739 |
|
|
-- Common output signals
|
1740 |
|
|
signal idle : std_logic;
|
1741 |
|
|
signal clk_l : std_logic;
|
1742 |
|
|
signal dat_l : std_logic;
|
1743 |
|
|
|
1744 |
|
|
-- Heuristic output signals
|
1745 |
|
|
signal dat_h : std_logic;
|
1746 |
|
|
signal clk_h : std_logic;
|
1747 |
|
|
|
1748 |
|
|
-- Alexander output signals
|
1749 |
|
|
signal dat_a : std_logic;
|
1750 |
|
|
signal clk_a : std_logic;
|
1751 |
|
|
|
1752 |
|
|
-- Miscellaneous Alexander signals
|
1753 |
|
|
signal clear_a : std_logic;
|
1754 |
|
|
signal alex_w_i : unsigned(ALEX_NCO_BITS-1 downto 0);
|
1755 |
|
|
|
1756 |
|
|
begin
|
1757 |
|
|
|
1758 |
|
|
|
1759 |
|
|
clk_p : entity work.bit_period_detector(beh)
|
1760 |
|
|
generic map(
|
1761 |
|
|
USE_ANY_EDGE => 0, -- 0=Rising edges only, 1=Use any edge
|
1762 |
|
|
WINDOW_SIZE => WINDOW_SIZE,
|
1763 |
|
|
IDLE_CLOCKS => IDLE_CLOCKS, -- sys_clk periods before input "idle" is called
|
1764 |
|
|
BAUD_READS => BAUD_READS, -- Number of baud interval transition measurements tried
|
1765 |
|
|
INTERVAL_READS => INTERVAL_READS, -- Number of 2^N interval read attempts to make
|
1766 |
|
|
INTEGER_WIDTH => PERIOD_I_WIDTH, -- Bits in integer part of period measurement
|
1767 |
|
|
FRACTION_WIDTH => PERIOD_F_WIDTH -- Bits in fractional part of period measurement
|
1768 |
|
|
)
|
1769 |
|
|
port map(
|
1770 |
|
|
-- System Clock and Clock Enable
|
1771 |
|
|
sys_rst_n => sys_rst_n,
|
1772 |
|
|
sys_clk => sys_clk,
|
1773 |
|
|
sys_clk_en => sys_clk_en,
|
1774 |
|
|
|
1775 |
|
|
-- Signal input
|
1776 |
|
|
signal_i => clk_l,
|
1777 |
|
|
|
1778 |
|
|
-- outputs
|
1779 |
|
|
s_edge_o => open,
|
1780 |
|
|
period_o => clk_period,
|
1781 |
|
|
load_o => clk_p_load,
|
1782 |
|
|
idle_o => clk_p_idle
|
1783 |
|
|
);
|
1784 |
|
|
|
1785 |
|
|
dat_p : entity work.bit_period_detector(beh)
|
1786 |
|
|
generic map(
|
1787 |
|
|
USE_ANY_EDGE => 1, -- 0=Rising edges only, 1=Use any edge
|
1788 |
|
|
WINDOW_SIZE => WINDOW_SIZE,
|
1789 |
|
|
IDLE_CLOCKS => IDLE_CLOCKS, -- sys_clk periods before input "idle" is called
|
1790 |
|
|
BAUD_READS => BAUD_READS, -- Number of baud interval transition measurements tried
|
1791 |
|
|
INTERVAL_READS => INTERVAL_READS, -- Number of 2^N interval read attempts to make
|
1792 |
|
|
INTEGER_WIDTH => PERIOD_I_WIDTH, -- Bits in integer part of period measurement
|
1793 |
|
|
FRACTION_WIDTH => PERIOD_F_WIDTH -- Bits in fractional part of period measurement
|
1794 |
|
|
)
|
1795 |
|
|
port map(
|
1796 |
|
|
-- System Clock and Clock Enable
|
1797 |
|
|
sys_rst_n => sys_rst_n,
|
1798 |
|
|
sys_clk => sys_clk,
|
1799 |
|
|
sys_clk_en => sys_clk_en,
|
1800 |
|
|
|
1801 |
|
|
-- Signal input
|
1802 |
|
|
signal_i => dat_i,
|
1803 |
|
|
|
1804 |
|
|
-- outputs
|
1805 |
|
|
s_edge_o => dat_s_edge,
|
1806 |
|
|
period_o => dat_period,
|
1807 |
|
|
load_o => dat_p_load,
|
1808 |
|
|
idle_o => dat_p_idle
|
1809 |
|
|
);
|
1810 |
|
|
|
1811 |
|
|
-- Calculate the difference in period, used for frequency seeking
|
1812 |
|
|
-- and lock detection.
|
1813 |
|
|
delta_p <= signed(clk_period) - signed(dat_period);
|
1814 |
|
|
|
1815 |
|
|
-- Calculate the next phase value, used in phase locking
|
1816 |
|
|
phase_next <= phase + freq_i when freq_seek_i='0' else
|
1817 |
|
|
phase + freq;
|
1818 |
|
|
|
1819 |
|
|
-- Create a tweak bias "trigger" signal that indicates when the accumulated bias
|
1820 |
|
|
-- is sufficient to take action. Currently the trigger is set to the middle of
|
1821 |
|
|
-- the range of possible tweak_bias values.
|
1822 |
|
|
tweak_bias_trigger <= '1' when (tweak_bias=(2**(tweak_bias'length-1))) else '0';
|
1823 |
|
|
|
1824 |
|
|
process (sys_clk, sys_rst_n)
|
1825 |
|
|
begin
|
1826 |
|
|
if (sys_rst_n='0') then
|
1827 |
|
|
phase <= to_unsigned(0,phase'length); -- Initial value
|
1828 |
|
|
fsm_state <= INIT;
|
1829 |
|
|
locked <= '0';
|
1830 |
|
|
phase_tweak <= '0';
|
1831 |
|
|
tweak_bias <= (others=>'0');
|
1832 |
|
|
dat_h <= '0';
|
1833 |
|
|
dat_r1 <= '0';
|
1834 |
|
|
dat_r2 <= '0';
|
1835 |
|
|
freq <= (others=>'0');
|
1836 |
|
|
elsif (sys_clk'event and sys_clk='1') then
|
1837 |
|
|
if (sys_clk_en='1') then
|
1838 |
|
|
-- default values
|
1839 |
|
|
phase_tweak <= '0';
|
1840 |
|
|
|
1841 |
|
|
-- Delay the data going through
|
1842 |
|
|
dat_r1 <= dat_i;
|
1843 |
|
|
dat_r2 <= dat_r1;
|
1844 |
|
|
dat_h <= dat_r2;
|
1845 |
|
|
|
1846 |
|
|
-- Update phase register
|
1847 |
|
|
-- The phase value can be overwritten during phase tracking
|
1848 |
|
|
-- (see code below)
|
1849 |
|
|
if (cal_clk_en='1') then
|
1850 |
|
|
phase <= phase_next;
|
1851 |
|
|
end if;
|
1852 |
|
|
|
1853 |
|
|
-- Finite State Machine
|
1854 |
|
|
case (fsm_state) is
|
1855 |
|
|
|
1856 |
|
|
when INIT =>
|
1857 |
|
|
freq <= '0' & freq_i; -- Start at the requested frequency
|
1858 |
|
|
fsm_state <= PHASE_TRACK;
|
1859 |
|
|
|
1860 |
|
|
when PHASE_TRACK =>
|
1861 |
|
|
if (clk_p_load='1' or dat_p_load='1') then
|
1862 |
|
|
if locked='0' and lock='1' then
|
1863 |
|
|
locked<='1';
|
1864 |
|
|
elsif locked='1' and unlock='1' then
|
1865 |
|
|
fsm_state <= INIT;
|
1866 |
|
|
locked<='0';
|
1867 |
|
|
end if;
|
1868 |
|
|
end if;
|
1869 |
|
|
if (locked='1' and (clk_p_idle='1' or dat_p_idle='1')) then
|
1870 |
|
|
locked <= '0';
|
1871 |
|
|
fsm_state <= INIT;
|
1872 |
|
|
elsif (dat_s_edge='1') then
|
1873 |
|
|
-- Check to see if phase is outside the allowed window.
|
1874 |
|
|
-- If inside the window, no adjustment is needed.
|
1875 |
|
|
if (abs(signed(phase_next))>signed(freq)) then
|
1876 |
|
|
|
1877 |
|
|
if (phase_next(phase_next'length-1)='1') then
|
1878 |
|
|
tweak_bias <= tweak_bias+1;
|
1879 |
|
|
if tweak_bias_trigger='1' then
|
1880 |
|
|
if (freq_seek_i='1') then
|
1881 |
|
|
freq <= freq + FSTEP_FINE;
|
1882 |
|
|
end if;
|
1883 |
|
|
tweak_bias<=(others=>'0'); -- Reset the bias integrator
|
1884 |
|
|
end if;
|
1885 |
|
|
else
|
1886 |
|
|
tweak_bias <= tweak_bias-1;
|
1887 |
|
|
if tweak_bias_trigger='1' then
|
1888 |
|
|
if (freq_seek_i='1') then
|
1889 |
|
|
freq <= freq - FSTEP_FINE;
|
1890 |
|
|
end if;
|
1891 |
|
|
tweak_bias<=(others=>'0'); -- Reset the bias integrator
|
1892 |
|
|
end if;
|
1893 |
|
|
end if;
|
1894 |
|
|
phase_tweak <= '1';
|
1895 |
|
|
-- phase <= to_unsigned(0,phase'length); -- This adjustment works, but is rather "harsh"
|
1896 |
|
|
phase <= phase(phase'length-1) & phase(phase'length-1 downto 1); -- sign extended divide by 2. This approach is "softer."
|
1897 |
|
|
|
1898 |
|
|
end if;
|
1899 |
|
|
end if;
|
1900 |
|
|
|
1901 |
|
|
end case;
|
1902 |
|
|
|
1903 |
|
|
end if; -- sys_clk_en
|
1904 |
|
|
end if; -- sys_clk
|
1905 |
|
|
end process;
|
1906 |
|
|
|
1907 |
|
|
idle <= dat_p_idle;
|
1908 |
|
|
lock <= '1' when abs(delta_p)<LOCK_VAL else '0';
|
1909 |
|
|
unlock <= '0' when abs(delta_p)<DROP_LOCK_VAL else '1';
|
1910 |
|
|
clk_h <= not phase(PHASE_WIDTH-1);
|
1911 |
|
|
|
1912 |
|
|
|
1913 |
|
|
-- Instantiate the Alexander digital PLL
|
1914 |
|
|
|
1915 |
|
|
dpll_1: entity work.dpll_alex_bw_adjust(beh)
|
1916 |
|
|
generic map(
|
1917 |
|
|
NCO_BITS => ALEX_NCO_BITS,
|
1918 |
|
|
KP_I_BITS => ALEX_K_BITS-ALEX_K_FRAC,
|
1919 |
|
|
KI_I_BITS => ALEX_K_BITS-ALEX_K_FRAC,
|
1920 |
|
|
K_FRAC_BITS => ALEX_K_FRAC,
|
1921 |
|
|
GAIN_DIV => ALEX_GAIN_ADJ
|
1922 |
|
|
)
|
1923 |
|
|
port map(
|
1924 |
|
|
sys_clk => sys_clk,
|
1925 |
|
|
sys_rst_n => sys_rst_n,
|
1926 |
|
|
sys_clk_en => cal_clk_en,
|
1927 |
|
|
clear_i => clear_a,
|
1928 |
|
|
dat_i => dat_i,
|
1929 |
|
|
w_i => alex_w_i,
|
1930 |
|
|
kp_i => alex_kp_i,
|
1931 |
|
|
ki_i => alex_ki_i,
|
1932 |
|
|
bit_lock_i => locked_a, -- NOTE: ADD logical enable to this signal!!!
|
1933 |
|
|
dat_o => dat_a,
|
1934 |
|
|
clk_o => clk_a
|
1935 |
|
|
);
|
1936 |
|
|
alex_w_i <= to_unsigned(ALEX_W_SHIFT*to_integer(freq_i),alex_w_i'length);
|
1937 |
|
|
|
1938 |
|
|
-- As it is currently constituted, this lock detector can not
|
1939 |
|
|
-- be used with the heuristic bit synchronizer, because its requirements
|
1940 |
|
|
-- for counting the clock valid to the data are based on times when the
|
1941 |
|
|
-- data is transitioning, and its requirements are too strict to work
|
1942 |
|
|
-- with the heuristic bit synchronizer outputs.
|
1943 |
|
|
fenton_lock_detector : entity work.bitsync_lock_detector(beh)
|
1944 |
|
|
generic map(
|
1945 |
|
|
BIT_CNT_MAX => 255,
|
1946 |
|
|
BIT_CNT_1 => 5,
|
1947 |
|
|
BIT_CNT_2 => 15
|
1948 |
|
|
)
|
1949 |
|
|
port map(
|
1950 |
|
|
sys_clk => sys_clk,
|
1951 |
|
|
sys_rst_n => sys_rst_n,
|
1952 |
|
|
sys_clk_en => cal_clk_en,
|
1953 |
|
|
dat_i => dat_i,
|
1954 |
|
|
pll_clk => clk_a,
|
1955 |
|
|
lock_o => locked_a
|
1956 |
|
|
);
|
1957 |
|
|
|
1958 |
|
|
|
1959 |
|
|
-- Keep the DPLL cleared when not being used.
|
1960 |
|
|
-- The "use_alex_i" input can be pulsed low briefly to
|
1961 |
|
|
-- reset the Alexander PLL.
|
1962 |
|
|
clear_a <= not use_alex_i;
|
1963 |
|
|
|
1964 |
|
|
-- Select the desired outputs
|
1965 |
|
|
idle_o <= idle;
|
1966 |
|
|
lock_o <= locked when use_alex_i='0' else locked_a;
|
1967 |
|
|
dat_l <= dat_h when use_alex_i='0' else dat_a;
|
1968 |
|
|
clk_l <= clk_h when use_alex_i='0' else clk_a;
|
1969 |
|
|
dat_o <= dat_l;
|
1970 |
|
|
clk_o <= clk_l;
|
1971 |
|
|
|
1972 |
|
|
end beh;
|
1973 |
|
|
|
1974 |
|
|
|
1975 |
|
|
-------------------------------------------------------------------------------
|
1976 |
|
|
-- PCM Analyzer - with 32 bit registers
|
1977 |
|
|
-------------------------------------------------------------------------------
|
1978 |
|
|
--
|
1979 |
|
|
-- Author: John Clayton
|
1980 |
|
|
-- Date : May 17, 2013 Created this module by copying and modifying code
|
1981 |
|
|
-- from another module.
|
1982 |
|
|
-- July 13, 2013 Revamped the register structure and added an instance
|
1983 |
|
|
-- of "pcm_input_front_end" to allow removal of line
|
1984 |
|
|
-- codes from incoming signals, prior to sending the
|
1985 |
|
|
-- NRZL data to a "Modally Allocated Temporal
|
1986 |
|
|
-- Correlation Histogram" (MATCH) unit for pattern
|
1987 |
|
|
-- detection and measurements of the period between
|
1988 |
|
|
-- pattern occurrences.
|
1989 |
|
|
--
|
1990 |
|
|
-- Description
|
1991 |
|
|
-------------------------------------------------------------------------------
|
1992 |
|
|
-- This module instantiates a "period_histogram_checker" and then adds registers
|
1993 |
|
|
-- for control and readout of it. In addition to the period_histogram_checker,
|
1994 |
|
|
-- there is a "pcm_input_front_end" which can remove line codes, resulting in
|
1995 |
|
|
-- NRZL data. The NRZL data is then routed into a "Modally Allocated Temporal
|
1996 |
|
|
-- Correlation Histogram" (M.A.T.C.H.) unit for detection of patterns and
|
1997 |
|
|
-- measurement of the period between pattern occurrences.
|
1998 |
|
|
--
|
1999 |
|
|
-- The registers are summarized as follows:
|
2000 |
|
|
--
|
2001 |
|
|
-- Address Structure Function
|
2002 |
|
|
-- ------- --------- -----------------------------------------------------
|
2003 |
|
|
-- 0x0 (31:0) pcm_input_front_end settings
|
2004 |
|
|
-- 0x1 (27:0) PCM interval settings
|
2005 |
|
|
-- 0x2 (I:0) Intervals to measure per histogram. I=HIST_BITS-1
|
2006 |
|
|
-- 0x3 (D:0) Derandomizer taps. D=DERAND_BITS-1
|
2007 |
|
|
-- 0x4 (31:0) M.A.T.C.H. interval and results (read only)
|
2008 |
|
|
-- 0x5 (31:0) Pattern lower limit
|
2009 |
|
|
-- 0x6 (31:0) Pattern upper limit
|
2010 |
|
|
-- 0x7 (31:0) Bit synchronizer frequency
|
2011 |
|
|
-- 0x8 (1:0) Binary Status bits
|
2012 |
|
|
-- 0x9 (H:0) Histogram bin 1 result
|
2013 |
|
|
-- 0xA (H:0) Histogram bin 2 result
|
2014 |
|
|
-- 0xB (H:0) Histogram bin 3 result
|
2015 |
|
|
-- 0xC (H:0) Histogram bin N result
|
2016 |
|
|
-- 0xD (H:0) Histogram bin "oddball" result
|
2017 |
|
|
-- 0xE (B:0) Baud interval measurement. B=PERIOD_BITS-1.
|
2018 |
|
|
-- 0xF (31:0) Frequency measurement in Bauds per second.
|
2019 |
|
|
--
|
2020 |
|
|
-- Notes on Registers:
|
2021 |
|
|
--
|
2022 |
|
|
-- (0x0) pcm_input_front_end settings
|
2023 |
|
|
--
|
2024 |
|
|
-- Bits (31:16) contain the Baud interval expected for the incoming
|
2025 |
|
|
-- signal. This is used only when decoding biphase.
|
2026 |
|
|
-- Bit (15) contains the setting for the derandomizer
|
2027 |
|
|
-- '0' means do not use derandomization
|
2028 |
|
|
-- '1' means use derandomization
|
2029 |
|
|
-- Bit (14) contains the setting for input data inversion.
|
2030 |
|
|
-- '0' means do not invert the data signal
|
2031 |
|
|
-- '1' means invert the data signal
|
2032 |
|
|
-- Bit (13) contains the setting for biphase line code removal
|
2033 |
|
|
-- Note that when this setting is used, the Baud interval
|
2034 |
|
|
-- setting is important.
|
2035 |
|
|
-- '0' means do not treat the data as biphase
|
2036 |
|
|
-- '1' means treat the data as biphase
|
2037 |
|
|
-- Bit (12) contains the setting for differential line code removal.
|
2038 |
|
|
-- The term "MARK" means that a change in level of the input
|
2039 |
|
|
-- data stream represents a '1', while no change represents
|
2040 |
|
|
-- a '0'.
|
2041 |
|
|
-- '0' means treat the data as SPACE encoded
|
2042 |
|
|
-- '1' means treat the data as MARK encoded
|
2043 |
|
|
-- Bit (11) contains the setting for LEVEL encoding
|
2044 |
|
|
-- '0' means treat the data as differentially encoded.
|
2045 |
|
|
-- '1' means treat the data as level encoded
|
2046 |
|
|
-- Bit (10) contains the setting for long search. Set this bit
|
2047 |
|
|
-- to cause pattern timeouts after 2^INTRVL_BITS bits.
|
2048 |
|
|
-- When cleared, the pattern interval timeout is 16384 bits.
|
2049 |
|
|
-- Bits (9:4) contain the search pattern size
|
2050 |
|
|
-- Bits (3:0) contain the data input selection
|
2051 |
|
|
--
|
2052 |
|
|
-- (0x1) PCM Interval Settings
|
2053 |
|
|
--
|
2054 |
|
|
-- Bit 31 : Bad duty bit. (Read only)
|
2055 |
|
|
--
|
2056 |
|
|
-- This bit is set to indicate that the positive and negative Baud
|
2057 |
|
|
-- intervals measured differ by more than the register 0x1
|
2058 |
|
|
-- window setting. In this case, it is assumed that the signal
|
2059 |
|
|
-- has a duty cycle which is unacceptably far from the ideal of
|
2060 |
|
|
-- 50%, and measurements cannot continue. However, while this
|
2061 |
|
|
-- bit is set, Baud interval measurements continue. If at any
|
2062 |
|
|
-- time the result becomes favorable, then the bad duty bit
|
2063 |
|
|
-- is cleared, and measurements proceed for a histogram.
|
2064 |
|
|
--
|
2065 |
|
|
-- Bit 30 : (Read only)
|
2066 |
|
|
-- Idle bit, set when the input has not transitioned for I sys_clk
|
2067 |
|
|
-- periods, where:
|
2068 |
|
|
--
|
2069 |
|
|
-- I=1023*T
|
2070 |
|
|
--
|
2071 |
|
|
-- (where T is normally the average of the positive
|
2072 |
|
|
-- and negative baud interval measurements, called "baud_avg")
|
2073 |
|
|
--
|
2074 |
|
|
-- Note that this means there are essentially two cases:
|
2075 |
|
|
-- Case 1 : A signal is active, and then becomes idle.
|
2076 |
|
|
-- In this case the baud_avg value is already
|
2077 |
|
|
-- determined, and T is usually a small number of
|
2078 |
|
|
-- sys_clk periods.
|
2079 |
|
|
-- Case 2 : The signal has never been active.
|
2080 |
|
|
-- In this case, the unit is trying to measure
|
2081 |
|
|
-- for the baud_avg value, but it cannot. Therefore
|
2082 |
|
|
-- the default value of baud_avg is used. Since the
|
2083 |
|
|
-- default is the highest possible value, being
|
2084 |
|
|
-- 2^PERIOD_BITS-1 sys_clk periods, the resulting
|
2085 |
|
|
-- value of T can be quite large.
|
2086 |
|
|
-- For example, if PERIOD_BITS is 14, then we
|
2087 |
|
|
-- have I=1023*16383 = 16759809 sys_clk periods,
|
2088 |
|
|
-- which is approximately 336 milliseconds.
|
2089 |
|
|
--
|
2090 |
|
|
-- Bits (27:16) Oddball interval limit
|
2091 |
|
|
--
|
2092 |
|
|
-- This field determines how many oddball intervals can occur during the
|
2093 |
|
|
-- process of constructing the histogram, before the process is abandoned.
|
2094 |
|
|
-- If too many intervals show up with oddball lengths, then the current histogram
|
2095 |
|
|
-- counts are cleared and the unit reverts back to measuring the baud interval
|
2096 |
|
|
-- in order to start the process over again. When this happens, no results are
|
2097 |
|
|
-- posted to the outputs. This is an indicator of a noisy input signal.
|
2098 |
|
|
--
|
2099 |
|
|
-- Bits (12:8) Bin N value
|
2100 |
|
|
--
|
2101 |
|
|
-- This field contains the N-value that is used when separating interval
|
2102 |
|
|
-- measurements for storage into the histogram. There are only four main
|
2103 |
|
|
-- bins in this histogram:
|
2104 |
|
|
-- Bin 1 : Counts intervals of 1 Baud
|
2105 |
|
|
-- Bin 2 : Counts intervals of 2 Bauds
|
2106 |
|
|
-- Bin 3 : Counts intervals of [3..(N-value)-1] Bauds, inclusive.
|
2107 |
|
|
-- Bin N : Counts intervals of [N-value..1023] Bauds.
|
2108 |
|
|
--
|
2109 |
|
|
-- The Bin N catches any measurements that exceed N-value Bauds. The longest
|
2110 |
|
|
-- measured interval is currently limited to 2047 Bauds by the size of the
|
2111 |
|
|
-- counter "i_count_b", which is not adjustable by generics.
|
2112 |
|
|
--
|
2113 |
|
|
-- Bits (3:0) Interval uncertainty allowance window.
|
2114 |
|
|
--
|
2115 |
|
|
-- This field holds the setting for measurement uncertainty. All interval
|
2116 |
|
|
-- measurements are tallied to their appropriate histogram bin. In the case
|
2117 |
|
|
-- of intervals less than or equal to ODD_N_LIMIT Baud intervals, the interval
|
2118 |
|
|
-- measurement must be within +/- W sys_clk periods of an integer multiple of
|
2119 |
|
|
-- the Baud interval, or else it is considered "oddball" and must be tallied
|
2120 |
|
|
-- in the bo_count result. The measurement window is not used for intervals
|
2121 |
|
|
-- longer than ODD_N_LIMIT Bauds because the measured Baud value is not
|
2122 |
|
|
-- precise enough to be able to accurately determine whether a measurement
|
2123 |
|
|
-- is "oddball" or not. Therefore, all intervals greater than ODD_N_LIMIT
|
2124 |
|
|
-- Bauds are considered valid measurements for the histogram.
|
2125 |
|
|
--
|
2126 |
|
|
-- (0x2) Intervals per histogram.
|
2127 |
|
|
--
|
2128 |
|
|
-- This number should be set to any desired value between one and 2^HIST_BITS-1
|
2129 |
|
|
-- inclusive. The number of intervals in the histogram can be adjusted by this
|
2130 |
|
|
-- setting.
|
2131 |
|
|
--
|
2132 |
|
|
-- (0x3) pcm_input_front_end derandomizer taps
|
2133 |
|
|
--
|
2134 |
|
|
-- Bits (D:0) where D=DERAND_BITS-1
|
2135 |
|
|
-- Contains the taps which are used in derandomization.
|
2136 |
|
|
-- For example, to remove +15RNRZL randomization, this
|
2137 |
|
|
-- register would be set to 0x00006000
|
2138 |
|
|
--
|
2139 |
|
|
-- (0x4) M.A.T.C.H. interval and results (read only)
|
2140 |
|
|
--
|
2141 |
|
|
-- M.A.T.C.H. = Modally Allocated Temporal Correlation Histogram
|
2142 |
|
|
-- This histogram is comprised of only three "bins",
|
2143 |
|
|
-- the center being the mode, and the flanking bins
|
2144 |
|
|
-- being the count of intervals measured less than
|
2145 |
|
|
-- or greater than the mode, respectively.
|
2146 |
|
|
--
|
2147 |
|
|
-- Bit (31) Match timeout. It is set whenever an interval timed out.
|
2148 |
|
|
-- The timeout can be either 16384 bits (for minor frames) or
|
2149 |
|
|
-- 2^21 bits (for major frames), depending on the
|
2150 |
|
|
-- "long_search" bit in register 0x0.
|
2151 |
|
|
-- Writes to register 0x0, 0x5 or 0x6 clear this bit.
|
2152 |
|
|
--
|
2153 |
|
|
-- Bits (15:12) contain the most recent measurement number. Each time
|
2154 |
|
|
-- the measurement number increments, it implies that sixteen
|
2155 |
|
|
-- new intervals have been measured and tallyed into the
|
2156 |
|
|
-- histogram bins. The reported mode can also change
|
2157 |
|
|
-- whenever the measurement number increments. This field
|
2158 |
|
|
-- is useful for SW to determine if the current measurement
|
2159 |
|
|
-- is a newly reported one.
|
2160 |
|
|
--
|
2161 |
|
|
-- Bits (11:8) Histogram bin for intervals less than the mode.
|
2162 |
|
|
--
|
2163 |
|
|
-- Bits (7:4) Histogram bin for intervals equaling the mode.
|
2164 |
|
|
--
|
2165 |
|
|
-- Bits (3:0) Histogram bin for intervals greater than the mode.
|
2166 |
|
|
--
|
2167 |
|
|
-- (0x5) Lower Limit register
|
2168 |
|
|
--
|
2169 |
|
|
-- The contents of this register are used when searching for patterns.
|
2170 |
|
|
-- A mask of N ones (right justified) is generated and ANDed with this
|
2171 |
|
|
-- value to arrive at a comparison lower threshold, which is compared
|
2172 |
|
|
-- with the N least significant bits of the serial to parallel shift
|
2173 |
|
|
-- register.
|
2174 |
|
|
--
|
2175 |
|
|
-- (0x6) Upper Limit register
|
2176 |
|
|
--
|
2177 |
|
|
-- The contents of this register are used when searching for patterns.
|
2178 |
|
|
-- A mask of N ones (right justified) is generated and ANDed with this
|
2179 |
|
|
-- value to arrive at a comparison upper threshold, which is compared
|
2180 |
|
|
-- with the N least significant bits of the serial to parallel shift
|
2181 |
|
|
-- register.
|
2182 |
|
|
--
|
2183 |
|
|
-- (0x7) bit_sync_digital frequency setting
|
2184 |
|
|
--
|
2185 |
|
|
-- This value is calibrated to be in units of Fsys_clk/(2^33) Hz, and it
|
2186 |
|
|
-- can range up to 25 MHz with a 50 MHz system clock. This bit
|
2187 |
|
|
-- synchronizer is not guaranteed to work well at the highest frequency
|
2188 |
|
|
-- settings as it approaches the Nyquist limit, and DDS jitter noise
|
2189 |
|
|
-- prevents correct timing. Settings up to 8 MHz are expected to work
|
2190 |
|
|
-- well.
|
2191 |
|
|
--
|
2192 |
|
|
-- (0x8) Pattern Timeout and Pattern Mode (Measured interval in bits)
|
2193 |
|
|
--
|
2194 |
|
|
-- Bits (23:0) contain the most recently measured pattern occurrence
|
2195 |
|
|
-- interval in bits. Since patterns can occur with
|
2196 |
|
|
-- different intervals, this field reports the most
|
2197 |
|
|
-- recent statistical mode of interval measurements,
|
2198 |
|
|
-- with the requirement that over 50% of the measurements
|
2199 |
|
|
-- must report the same interval before it is deemed to
|
2200 |
|
|
-- be the "new mode."
|
2201 |
|
|
--
|
2202 |
|
|
-- (0x9) Histogram bin 1
|
2203 |
|
|
-- (0xA) Histogram bin 2
|
2204 |
|
|
-- (0xB) Histogram bin 3
|
2205 |
|
|
-- (0xC) Histogram bin N
|
2206 |
|
|
-- (0xD) Histogram bin O
|
2207 |
|
|
--
|
2208 |
|
|
-- These registers contain the count of intervals which measured the designated
|
2209 |
|
|
-- number of Bauds in length. Bins 1 and 2 are for 1 and 2 Bauds, while bin 3
|
2210 |
|
|
-- includes intervals of between [3 and N-1] Bauds. Bin N contains the number
|
2211 |
|
|
-- of intervals that equaled or exceeded N Bauds. Bin O contains the number of
|
2212 |
|
|
-- oddball length bins, which only include intervals of less than or equal to
|
2213 |
|
|
-- ODD_N_LIMIT Bauds.
|
2214 |
|
|
--
|
2215 |
|
|
-- (0xE) Baud interval measurement
|
2216 |
|
|
--
|
2217 |
|
|
-- This register contains the measured average baud interval, in units of sys_clk
|
2218 |
|
|
-- periods.
|
2219 |
|
|
--
|
2220 |
|
|
-- (0xF) Frequency measurement
|
2221 |
|
|
--
|
2222 |
|
|
-- This register contains the measured Baud frequency of the incoming signal. This
|
2223 |
|
|
-- measurement is in units of Bauds/second, and it takes an entire second for each
|
2224 |
|
|
-- new measurement to be produced.
|
2225 |
|
|
--
|
2226 |
|
|
-- The sys_rst_n input is an asynchronous reset.
|
2227 |
|
|
|
2228 |
|
|
library IEEE;
|
2229 |
|
|
use IEEE.STD_LOGIC_1164.ALL;
|
2230 |
|
|
use IEEE.NUMERIC_STD.ALL;
|
2231 |
|
|
use IEEE.MATH_REAL.ALL;
|
2232 |
|
|
|
2233 |
|
|
library work;
|
2234 |
|
|
use work.function_pack.all;
|
2235 |
|
|
use work.bit_sync_pack.all;
|
2236 |
|
|
use work.signal_conditioning_pack.all;
|
2237 |
|
|
|
2238 |
|
|
entity pcm_analyzer is
|
2239 |
|
|
generic(
|
2240 |
|
|
SYS_CLK_RATE : real := 50000000.0;
|
2241 |
|
|
NUM_CHAN : natural := 8; -- Number of channels to select from
|
2242 |
|
|
LOG2_NUM_CHAN : natural := 3; -- Bits needed for channel selection
|
2243 |
|
|
ODD_N_LIMIT : natural := 4; -- Upper cutoff for bo_count_o intervals to be tallied
|
2244 |
|
|
PERIOD_BITS : natural := 14; -- Number of bits in Baud interval measurement
|
2245 |
|
|
HIST_BITS : natural := 12; -- Number of bits in histogram bin counters
|
2246 |
|
|
DEF_R_0 : unsigned(31 downto 0) := str2u("00042884",32); -- PCM front end settings
|
2247 |
|
|
DEF_R_1 : unsigned(31 downto 0) := str2u("00011006",32); -- PCM Interval settings
|
2248 |
|
|
DEF_R_2 : unsigned(31 downto 0) := str2u("00000400",32); -- Intervals per histogram
|
2249 |
|
|
DEF_R_3 : unsigned(31 downto 0) := str2u("00006000",32); -- Derandomizer taps
|
2250 |
|
|
DEF_R_5 : unsigned(31 downto 0) := str2u("00FAF300",32); -- lower threshold
|
2251 |
|
|
DEF_R_6 : unsigned(31 downto 0) := str2u("00FAF3FF",32); -- upper threshold
|
2252 |
|
|
DEF_R_7 : unsigned(31 downto 0) := str2u("33333333",32); -- bit synchronizer frequency
|
2253 |
|
|
DEF_R_Z : unsigned(31 downto 0) := str2u("00000000",32) -- Value returned for nonexistent reg.
|
2254 |
|
|
);
|
2255 |
|
|
port (
|
2256 |
|
|
-- System Clock and Clock Enable
|
2257 |
|
|
sys_rst_n : in std_logic;
|
2258 |
|
|
sys_clk : in std_logic;
|
2259 |
|
|
sys_clk_en : in std_logic;
|
2260 |
|
|
fast_clk : in std_logic; -- A clock faster than sys_clk, for biphase line code removal
|
2261 |
|
|
|
2262 |
|
|
-- Bus interface
|
2263 |
|
|
adr_i : in unsigned(3 downto 0);
|
2264 |
|
|
sel_i : in std_logic;
|
2265 |
|
|
we_i : in std_logic;
|
2266 |
|
|
dat_i : in unsigned(31 downto 0);
|
2267 |
|
|
dat_o : out unsigned(31 downto 0);
|
2268 |
|
|
ack_o : out std_logic;
|
2269 |
|
|
|
2270 |
|
|
-- PCM signal inputs
|
2271 |
|
|
pcm_i : in unsigned(NUM_CHAN-1 downto 0);
|
2272 |
|
|
|
2273 |
|
|
-- Indicator of new results
|
2274 |
|
|
new_o : out std_logic
|
2275 |
|
|
|
2276 |
|
|
);
|
2277 |
|
|
end pcm_analyzer;
|
2278 |
|
|
|
2279 |
|
|
architecture beh of pcm_analyzer is
|
2280 |
|
|
|
2281 |
|
|
-- Constants
|
2282 |
|
|
constant DAT_SIZE : natural := 32;
|
2283 |
|
|
constant DERAND_BITS : natural := 16;
|
2284 |
|
|
constant BAUD_BITS : natural := 14;
|
2285 |
|
|
constant INTRVL_BITS : natural := 21;
|
2286 |
|
|
constant CLK_TIMEOUT : natural := 65535;
|
2287 |
|
|
|
2288 |
|
|
-- Internal signal declarations
|
2289 |
|
|
-- PCM front end signals
|
2290 |
|
|
signal pcm_dr_taps : unsigned(DERAND_BITS-1 downto 0);
|
2291 |
|
|
signal pcm_baud : unsigned(BAUD_BITS-1 downto 0);
|
2292 |
|
|
signal pcm_baud_reg : unsigned(15 downto 0);
|
2293 |
|
|
signal pcm_derandom : std_logic;
|
2294 |
|
|
signal pcm_dat_inv : std_logic;
|
2295 |
|
|
signal pcm_biphase : std_logic;
|
2296 |
|
|
signal pcm_mark : std_logic;
|
2297 |
|
|
signal pcm_level : std_logic;
|
2298 |
|
|
signal pcm_dat_selection : unsigned(LOG2_NUM_CHAN-1 downto 0);
|
2299 |
|
|
signal pcm_dat_sel_reg : unsigned(3 downto 0);
|
2300 |
|
|
signal pcm_selected_sig : std_logic;
|
2301 |
|
|
signal nrzl_dat : std_logic;
|
2302 |
|
|
signal nrzl_clk : std_logic;
|
2303 |
|
|
signal nrzl_clk_edge : std_logic;
|
2304 |
|
|
-- Bit synchronizer signals
|
2305 |
|
|
signal sync_dat : std_logic;
|
2306 |
|
|
signal sync_clk : std_logic;
|
2307 |
|
|
signal sync_freq : unsigned(31 downto 0);
|
2308 |
|
|
-- "MATCH" signals
|
2309 |
|
|
signal reg_value_size : unsigned(5 downto 0);
|
2310 |
|
|
signal reg_upper_limit : unsigned(31 downto 0);
|
2311 |
|
|
signal reg_lower_limit : unsigned(31 downto 0);
|
2312 |
|
|
signal value_mask : unsigned(31 downto 0);
|
2313 |
|
|
signal value_match : std_logic;
|
2314 |
|
|
signal match_measurement : unsigned(7 downto 0); -- 4 msbs reported
|
2315 |
|
|
signal match_sr : unsigned(31 downto 0);
|
2316 |
|
|
signal match_icount : unsigned(INTRVL_BITS-1 downto 0);
|
2317 |
|
|
signal match_mode_c_0 : unsigned(3 downto 0);
|
2318 |
|
|
signal match_mode_c_1 : unsigned(3 downto 0);
|
2319 |
|
|
signal match_bin_less : unsigned(3 downto 0);
|
2320 |
|
|
signal match_bin_mode : unsigned(3 downto 0);
|
2321 |
|
|
signal match_bin_more : unsigned(3 downto 0);
|
2322 |
|
|
signal match_out_less : unsigned(3 downto 0);
|
2323 |
|
|
signal match_out_mode : unsigned(3 downto 0);
|
2324 |
|
|
signal match_out_more : unsigned(3 downto 0);
|
2325 |
|
|
signal match_mode_reported : unsigned(INTRVL_BITS-1 downto 0);
|
2326 |
|
|
signal match_mode_current : unsigned(INTRVL_BITS-1 downto 0);
|
2327 |
|
|
signal match_mode_interval_0 : unsigned(INTRVL_BITS-1 downto 0);
|
2328 |
|
|
signal match_mode_interval_1 : unsigned(INTRVL_BITS-1 downto 0);
|
2329 |
|
|
signal match_timeout : std_logic;
|
2330 |
|
|
signal match_tlimit : unsigned(INTRVL_BITS-1 downto 0);
|
2331 |
|
|
signal long_search : std_logic;
|
2332 |
|
|
signal clk_icount : unsigned(bit_width(CLK_TIMEOUT)-1 downto 0);
|
2333 |
|
|
|
2334 |
|
|
-- PCM signal analyzer signals
|
2335 |
|
|
signal reg_window : unsigned(3 downto 0);
|
2336 |
|
|
signal reg_intrvls : unsigned(HIST_BITS-1 downto 0);
|
2337 |
|
|
signal reg_bo_limit : unsigned(HIST_BITS-1 downto 0);
|
2338 |
|
|
signal reg_n_value : unsigned(4 downto 0);
|
2339 |
|
|
signal bad_duty : std_logic;
|
2340 |
|
|
signal b1_count : unsigned(HIST_BITS-1 downto 0);
|
2341 |
|
|
signal b2_count : unsigned(HIST_BITS-1 downto 0);
|
2342 |
|
|
signal b3_count : unsigned(HIST_BITS-1 downto 0);
|
2343 |
|
|
signal bn_count : unsigned(HIST_BITS-1 downto 0);
|
2344 |
|
|
signal bo_count : unsigned(HIST_BITS-1 downto 0);
|
2345 |
|
|
signal baud : unsigned(PERIOD_BITS-1 downto 0);
|
2346 |
|
|
signal freq : unsigned(31 downto 0);
|
2347 |
|
|
signal idle : std_logic;
|
2348 |
|
|
|
2349 |
|
|
|
2350 |
|
|
-----------------------------------------------------------------------------
|
2351 |
|
|
begin
|
2352 |
|
|
|
2353 |
|
|
-- Register read mux
|
2354 |
|
|
with (adr_i) select
|
2355 |
|
|
dat_o <=
|
2356 |
|
|
pcm_baud_reg & pcm_derandom & pcm_dat_inv & pcm_biphase & pcm_mark & pcm_level & long_search & reg_value_size & pcm_dat_sel_reg
|
2357 |
|
|
when "0000",
|
2358 |
|
|
bad_duty & idle & "00" & reg_bo_limit & "000" & reg_n_value & "0000" & reg_window
|
2359 |
|
|
when "0001",
|
2360 |
|
|
resize(reg_intrvls,DAT_SIZE) when "0010",
|
2361 |
|
|
resize(pcm_dr_taps,DAT_SIZE) when "0011",
|
2362 |
|
|
match_timeout & "000000000000000" & match_measurement(7 downto 4) & match_out_less & match_out_mode & match_out_more
|
2363 |
|
|
when "0100",
|
2364 |
|
|
reg_lower_limit when "0101",
|
2365 |
|
|
reg_upper_limit when "0110",
|
2366 |
|
|
sync_freq when "0111",
|
2367 |
|
|
resize(match_mode_reported,DAT_SIZE) when "1000",
|
2368 |
|
|
resize(b1_count,DAT_SIZE) when "1001",
|
2369 |
|
|
resize(b2_count,DAT_SIZE) when "1010",
|
2370 |
|
|
resize(b3_count,DAT_SIZE) when "1011",
|
2371 |
|
|
resize(bn_count,DAT_SIZE) when "1100",
|
2372 |
|
|
resize(bo_count,DAT_SIZE) when "1101",
|
2373 |
|
|
resize(baud,DAT_SIZE) when "1110",
|
2374 |
|
|
resize(freq,DAT_SIZE) when "1111",
|
2375 |
|
|
DEF_R_Z when others;
|
2376 |
|
|
|
2377 |
|
|
-- Create acknowledge signal
|
2378 |
|
|
ack_o <= sel_i;
|
2379 |
|
|
|
2380 |
|
|
-- Handle bus writes to registers
|
2381 |
|
|
reg_proc: process(sys_clk, sys_rst_n)
|
2382 |
|
|
begin
|
2383 |
|
|
if (sys_rst_n='0') then
|
2384 |
|
|
elsif (sys_clk'event and sys_clk='1') then
|
2385 |
|
|
if (sys_clk_en='1') then
|
2386 |
|
|
end if;
|
2387 |
|
|
end if;
|
2388 |
|
|
end process;
|
2389 |
|
|
|
2390 |
|
|
-- Resize selection fields appropriately
|
2391 |
|
|
pcm_dat_selection <= resize(pcm_dat_sel_reg,pcm_dat_selection'length);
|
2392 |
|
|
-- Resize baud interval bits appropriately
|
2393 |
|
|
pcm_baud <= resize(pcm_baud_reg,pcm_baud'length);
|
2394 |
|
|
|
2395 |
|
|
|
2396 |
|
|
pcm_ife : entity work.pcm_input_front_end(beh)
|
2397 |
|
|
generic map(
|
2398 |
|
|
NUM_CHAN => NUM_CHAN, -- Number of channels to select from
|
2399 |
|
|
LOG2_NUM_CHAN => LOG2_NUM_CHAN, -- Bits needed for channel selection
|
2400 |
|
|
BAUD_BITS => BAUD_BITS, -- Bits used in Baud interval counting
|
2401 |
|
|
DERAND_BITS => DERAND_BITS
|
2402 |
|
|
)
|
2403 |
|
|
port map(
|
2404 |
|
|
-- System Clock and Clock Enable
|
2405 |
|
|
sys_rst_n => sys_rst_n,
|
2406 |
|
|
sys_clk => sys_clk,
|
2407 |
|
|
sys_clk_en => sys_clk_en,
|
2408 |
|
|
fast_clk => fast_clk, -- A clock faster than sys_clk, for biphase line code removal
|
2409 |
|
|
|
2410 |
|
|
-- PCM signal inputs
|
2411 |
|
|
sig_i => pcm_i,
|
2412 |
|
|
|
2413 |
|
|
-- Signal selection settings
|
2414 |
|
|
clk_sel_i => (others=>'0'),
|
2415 |
|
|
dat_sel_i => pcm_dat_selection,
|
2416 |
|
|
|
2417 |
|
|
-- Line Code Settings
|
2418 |
|
|
dr_taps_i => pcm_dr_taps,
|
2419 |
|
|
baud_i => pcm_baud,
|
2420 |
|
|
derandom_i => pcm_derandom,
|
2421 |
|
|
clk_inv_i => '0',
|
2422 |
|
|
dat_inv_i => pcm_dat_inv,
|
2423 |
|
|
biphase_i => pcm_biphase,
|
2424 |
|
|
mark_i => pcm_mark,
|
2425 |
|
|
level_i => pcm_level,
|
2426 |
|
|
|
2427 |
|
|
-- Bit Synchronizer Interface Port
|
2428 |
|
|
-- If no synchronizer is present, simply tie use_sync_i to '0'
|
2429 |
|
|
use_sync_i => '1',
|
2430 |
|
|
pcm_dat_o => pcm_selected_sig, -- feeds digital bit synchronizer
|
2431 |
|
|
sync_dat_i => sync_dat,
|
2432 |
|
|
sync_clk_i => sync_clk,
|
2433 |
|
|
|
2434 |
|
|
-- signal outputs
|
2435 |
|
|
nrzl_dat_o => nrzl_dat,
|
2436 |
|
|
nrzl_clk_o => nrzl_clk
|
2437 |
|
|
);
|
2438 |
|
|
|
2439 |
|
|
bit_sync : entity work.bit_sync_digital(beh)
|
2440 |
|
|
generic map(
|
2441 |
|
|
ALEX_K_BITS => 32, -- Number of bits in Alexander DPLL coefficients
|
2442 |
|
|
ALEX_K_FRAC => 8, -- How many of the ALEX_K_BITS are used for fractional representation
|
2443 |
|
|
ALEX_GAIN_ADJ => 2, -- How many bits to reduce KP_i and KI_i during lock
|
2444 |
|
|
FSTEP_FINE => 2**4, -- Frequency increment during phase track
|
2445 |
|
|
PHASE_WIDTH => sync_freq'length+1, -- Bits in the phase accumulator
|
2446 |
|
|
LOCK_VAL => 4, -- Period mismatch to obtain lock
|
2447 |
|
|
DROP_LOCK_VAL => 12, -- Period mismatch to drop lock
|
2448 |
|
|
PERIOD_I_WIDTH => 16, -- Integer width of period measurements
|
2449 |
|
|
PERIOD_F_WIDTH => 2, -- Fractional width of period measurements
|
2450 |
|
|
IDLE_CLOCKS => 2**16, -- sys_clk periods before signal is called idle
|
2451 |
|
|
BAUD_READS => 127, -- Period baud interval read attempts
|
2452 |
|
|
INTERVAL_READS => 64, -- Period interval read attempts
|
2453 |
|
|
WINDOW_SIZE => 3 -- Period variation window, in sys_clks
|
2454 |
|
|
)
|
2455 |
|
|
port map(
|
2456 |
|
|
-- System Clock and Clock Enable
|
2457 |
|
|
sys_rst_n => sys_rst_n,
|
2458 |
|
|
sys_clk => sys_clk,
|
2459 |
|
|
sys_clk_en => sys_clk_en,
|
2460 |
|
|
|
2461 |
|
|
-- Frequency calibration clk enable
|
2462 |
|
|
cal_clk_en => sys_clk_en,
|
2463 |
|
|
|
2464 |
|
|
-- Settings
|
2465 |
|
|
freq_i => sync_freq,
|
2466 |
|
|
freq_seek_i => '0',
|
2467 |
|
|
use_alex_i => '0',
|
2468 |
|
|
alex_kp_i => "000000000001011111010101",
|
2469 |
|
|
alex_ki_i => "000000000000000000000010",
|
2470 |
|
|
|
2471 |
|
|
-- Reference data input
|
2472 |
|
|
dat_i => pcm_selected_sig,
|
2473 |
|
|
|
2474 |
|
|
-- indicators and outputs
|
2475 |
|
|
idle_o => open,
|
2476 |
|
|
lock_o => open,
|
2477 |
|
|
dat_o => sync_dat,
|
2478 |
|
|
clk_o => sync_clk
|
2479 |
|
|
);
|
2480 |
|
|
|
2481 |
|
|
-- Detect rising edges of sync_clk
|
2482 |
|
|
nrzl_clk_edge_detector : entity work.edge_detector(beh)
|
2483 |
|
|
generic map(
|
2484 |
|
|
DETECT_RISING => 1,
|
2485 |
|
|
DETECT_FALLING => 0
|
2486 |
|
|
)
|
2487 |
|
|
port map(
|
2488 |
|
|
-- System Clock and Clock Enable
|
2489 |
|
|
sys_rst_n => sys_rst_n,
|
2490 |
|
|
sys_clk => sys_clk,
|
2491 |
|
|
sys_clk_en => sys_clk_en,
|
2492 |
|
|
|
2493 |
|
|
-- Input Signal
|
2494 |
|
|
sig_i => nrzl_clk,
|
2495 |
|
|
|
2496 |
|
|
-- Output pulse
|
2497 |
|
|
pulse_o => nrzl_clk_edge
|
2498 |
|
|
);
|
2499 |
|
|
|
2500 |
|
|
-- Formulate an interval time limit based on the
|
2501 |
|
|
-- "long_search" bit.
|
2502 |
|
|
match_tlimit <= to_unsigned((2**match_tlimit'length)-1,match_tlimit'length) when long_search='1' else
|
2503 |
|
|
to_unsigned(16383,match_tlimit'length);
|
2504 |
|
|
|
2505 |
|
|
--------------------------
|
2506 |
|
|
-- (Register writes are done here)
|
2507 |
|
|
-- M.A.T.C.H. logic
|
2508 |
|
|
matching_proc: Process(sys_rst_n,sys_clk)
|
2509 |
|
|
begin
|
2510 |
|
|
if (sys_rst_n = '0') then
|
2511 |
|
|
-- related to registers
|
2512 |
|
|
pcm_baud_reg <= DEF_R_0(31 downto 16);
|
2513 |
|
|
pcm_derandom <= DEF_R_0(15);
|
2514 |
|
|
pcm_dat_inv <= DEF_R_0(14);
|
2515 |
|
|
pcm_biphase <= DEF_R_0(13);
|
2516 |
|
|
pcm_mark <= DEF_R_0(12);
|
2517 |
|
|
pcm_level <= DEF_R_0(11);
|
2518 |
|
|
long_search <= DEF_R_0(10);
|
2519 |
|
|
reg_value_size <= DEF_R_0(9 downto 4);
|
2520 |
|
|
pcm_dat_sel_reg <= DEF_R_0(3 downto 0);
|
2521 |
|
|
reg_window <= DEF_R_1(3 downto 0);
|
2522 |
|
|
reg_n_value <= DEF_R_1(12 downto 8);
|
2523 |
|
|
reg_bo_limit <= DEF_R_1(HIST_BITS-1+16 downto 16);
|
2524 |
|
|
reg_intrvls <= DEF_R_2(HIST_BITS-1 downto 0);
|
2525 |
|
|
pcm_dr_taps <= DEF_R_3(DERAND_BITS-1 downto 0);
|
2526 |
|
|
reg_lower_limit <= DEF_R_5;
|
2527 |
|
|
reg_upper_limit <= DEF_R_6;
|
2528 |
|
|
sync_freq <= DEF_R_7;
|
2529 |
|
|
-- related to match unit
|
2530 |
|
|
match_measurement <= (others=>'0');
|
2531 |
|
|
match_sr <= (others=>'0');
|
2532 |
|
|
match_icount <= to_unsigned(1,match_icount'length);
|
2533 |
|
|
match_mode_c_0 <= (others=>'0');
|
2534 |
|
|
match_mode_c_1 <= (others=>'0');
|
2535 |
|
|
match_bin_less <= (others=>'0');
|
2536 |
|
|
match_bin_mode <= (others=>'0');
|
2537 |
|
|
match_bin_more <= (others=>'0');
|
2538 |
|
|
match_out_less <= (others=>'0');
|
2539 |
|
|
match_out_mode <= (others=>'0');
|
2540 |
|
|
match_out_more <= (others=>'0');
|
2541 |
|
|
match_mode_reported <= (others=>'0');
|
2542 |
|
|
match_mode_current <= (others=>'0');
|
2543 |
|
|
match_mode_interval_0 <= (others=>'0');
|
2544 |
|
|
match_mode_interval_1 <= (others=>'0');
|
2545 |
|
|
match_timeout <= '0';
|
2546 |
|
|
clk_icount <= (others=>'0');
|
2547 |
|
|
elsif (sys_clk'event AND sys_clk='1') then
|
2548 |
|
|
if (sys_clk_en='1') then
|
2549 |
|
|
if (nrzl_clk_edge='1') then
|
2550 |
|
|
clk_icount <= (others=>'0');
|
2551 |
|
|
match_sr <= match_sr(match_sr'length-2 downto 0) & nrzl_dat;
|
2552 |
|
|
match_icount <= match_icount+1;
|
2553 |
|
|
-- Check for a pattern match, or the maximum interval
|
2554 |
|
|
if (value_match='1' or match_icount=match_tlimit) then
|
2555 |
|
|
if (value_match='0') then
|
2556 |
|
|
match_timeout <= '1';
|
2557 |
|
|
end if;
|
2558 |
|
|
match_measurement <= match_measurement+1;
|
2559 |
|
|
match_icount <= to_unsigned(1,match_icount'length);
|
2560 |
|
|
-- Tally up the new result
|
2561 |
|
|
if (match_icount>match_mode_current) then
|
2562 |
|
|
match_bin_more <= match_bin_more+1;
|
2563 |
|
|
elsif (match_icount=match_mode_current) then
|
2564 |
|
|
match_bin_mode <= match_bin_mode+1;
|
2565 |
|
|
else
|
2566 |
|
|
match_bin_less <= match_bin_less+1;
|
2567 |
|
|
end if;
|
2568 |
|
|
-- Handle the "mode searching fingers"
|
2569 |
|
|
if (match_mode_interval_0=0) then
|
2570 |
|
|
match_mode_interval_0 <= match_icount;
|
2571 |
|
|
match_mode_c_0 <= match_mode_c_0+1;
|
2572 |
|
|
elsif (match_icount=match_mode_interval_0) then
|
2573 |
|
|
match_mode_c_0 <= match_mode_c_0+1;
|
2574 |
|
|
end if;
|
2575 |
|
|
if (match_mode_interval_1=0 and match_mode_interval_0/=0 and match_icount/=match_mode_interval_0) then
|
2576 |
|
|
match_mode_interval_1 <= match_icount;
|
2577 |
|
|
match_mode_c_1 <= match_mode_c_1+1;
|
2578 |
|
|
elsif (match_icount=match_mode_interval_1 and match_icount/=match_mode_interval_0) then
|
2579 |
|
|
match_mode_c_1 <= match_mode_c_1+1;
|
2580 |
|
|
end if;
|
2581 |
|
|
-- Provide output after every 16 counts
|
2582 |
|
|
if (match_measurement(3 downto 0)="1111") then
|
2583 |
|
|
match_out_more <= match_bin_more;
|
2584 |
|
|
match_out_mode <= match_bin_mode;
|
2585 |
|
|
match_out_less <= match_bin_less;
|
2586 |
|
|
match_bin_more <= (others=>'0');
|
2587 |
|
|
match_bin_mode <= (others=>'0');
|
2588 |
|
|
match_bin_less <= (others=>'0');
|
2589 |
|
|
-- Change to new mode if appropriate
|
2590 |
|
|
if (match_mode_c_0>7) then
|
2591 |
|
|
match_mode_current <= match_mode_interval_0;
|
2592 |
|
|
match_mode_reported <= match_mode_current;
|
2593 |
|
|
elsif (match_mode_c_1>7) then
|
2594 |
|
|
match_mode_current <= match_mode_interval_1;
|
2595 |
|
|
match_mode_reported <= match_mode_current;
|
2596 |
|
|
end if;
|
2597 |
|
|
match_mode_c_0 <= (others=>'0');
|
2598 |
|
|
match_mode_c_1 <= (others=>'0');
|
2599 |
|
|
match_mode_interval_0 <= (others=>'0');
|
2600 |
|
|
match_mode_interval_1 <= (others=>'0');
|
2601 |
|
|
end if;
|
2602 |
|
|
end if;
|
2603 |
|
|
else
|
2604 |
|
|
clk_icount <= clk_icount+1;
|
2605 |
|
|
if (clk_icount=CLK_TIMEOUT) then
|
2606 |
|
|
clk_icount <= (others=>'0');
|
2607 |
|
|
match_timeout <= '1';
|
2608 |
|
|
match_measurement <= match_measurement+1;
|
2609 |
|
|
end if;
|
2610 |
|
|
end if; -- nrzl_clk_edge
|
2611 |
|
|
|
2612 |
|
|
-- Handle bus writes to registers
|
2613 |
|
|
if (sel_i='1' and we_i='1') then
|
2614 |
|
|
case (adr_i) is
|
2615 |
|
|
when "0000" =>
|
2616 |
|
|
pcm_baud_reg <= dat_i(31 downto 16);
|
2617 |
|
|
pcm_derandom <= dat_i(15);
|
2618 |
|
|
pcm_dat_inv <= dat_i(14);
|
2619 |
|
|
pcm_biphase <= dat_i(13);
|
2620 |
|
|
pcm_mark <= dat_i(12);
|
2621 |
|
|
pcm_level <= dat_i(11);
|
2622 |
|
|
long_search <= dat_i(10);
|
2623 |
|
|
reg_value_size <= dat_i(9 downto 4);
|
2624 |
|
|
pcm_dat_sel_reg <= dat_i(3 downto 0);
|
2625 |
|
|
match_timeout <= '0';
|
2626 |
|
|
when "0001" =>
|
2627 |
|
|
reg_window <= dat_i(3 downto 0);
|
2628 |
|
|
reg_n_value <= dat_i(12 downto 8);
|
2629 |
|
|
reg_bo_limit <= dat_i(27 downto 16);
|
2630 |
|
|
when "0010" =>
|
2631 |
|
|
reg_intrvls <= dat_i(HIST_BITS-1 downto 0);
|
2632 |
|
|
when "0011" =>
|
2633 |
|
|
pcm_dr_taps <= dat_i(pcm_dr_taps'length-1 downto 0);
|
2634 |
|
|
when "0101" =>
|
2635 |
|
|
reg_lower_limit <= dat_i;
|
2636 |
|
|
match_timeout <= '0';
|
2637 |
|
|
when "0110" =>
|
2638 |
|
|
reg_upper_limit <= dat_i;
|
2639 |
|
|
match_timeout <= '0';
|
2640 |
|
|
when "0111" =>
|
2641 |
|
|
sync_freq <= dat_i;
|
2642 |
|
|
when others => null;
|
2643 |
|
|
end case;
|
2644 |
|
|
end if;
|
2645 |
|
|
|
2646 |
|
|
end if; -- sys_clk_en
|
2647 |
|
|
end if; -- sys_clk
|
2648 |
|
|
end process;
|
2649 |
|
|
|
2650 |
|
|
--------------------------
|
2651 |
|
|
-- Check to see if the shift register value is a match
|
2652 |
|
|
value_mask <= Shift_Left(to_unsigned(1,value_mask'length),to_integer(reg_value_size))-1;
|
2653 |
|
|
value_match <= '1' when ((value_mask and match_sr)>=(value_mask and reg_lower_limit)) and ((value_mask and match_sr)<=(value_mask and reg_upper_limit)) else '0';
|
2654 |
|
|
|
2655 |
|
|
----------------------
|
2656 |
|
|
-- signal period histogram checker.
|
2657 |
|
|
phc_0 : entity work.period_histogram_checker(beh)
|
2658 |
|
|
generic map(
|
2659 |
|
|
SYS_CLK_RATE => SYS_CLK_RATE,
|
2660 |
|
|
NUM_CHAN => NUM_CHAN,
|
2661 |
|
|
LOG2_NUM_CHAN => LOG2_NUM_CHAN,
|
2662 |
|
|
ODD_N_LIMIT => ODD_N_LIMIT,
|
2663 |
|
|
PERIOD_BITS => PERIOD_BITS,
|
2664 |
|
|
HIST_BITS => HIST_BITS
|
2665 |
|
|
)
|
2666 |
|
|
port map(
|
2667 |
|
|
-- System Clock and Clock Enable
|
2668 |
|
|
sys_rst_n => sys_rst_n,
|
2669 |
|
|
sys_clk => sys_clk,
|
2670 |
|
|
sys_clk_en => sys_clk_en,
|
2671 |
|
|
|
2672 |
|
|
-- PCM signal inputs
|
2673 |
|
|
pcm_i => pcm_i,
|
2674 |
|
|
|
2675 |
|
|
-- Settings & Control
|
2676 |
|
|
pcm_sel_i => pcm_dat_selection,
|
2677 |
|
|
window_i => reg_window,
|
2678 |
|
|
intrvls_i => reg_intrvls,
|
2679 |
|
|
bo_limit_i => reg_bo_limit,
|
2680 |
|
|
n_value_i => reg_n_value,
|
2681 |
|
|
|
2682 |
|
|
-- outputs
|
2683 |
|
|
bad_duty_o => bad_duty,
|
2684 |
|
|
b1_count_o => b1_count,
|
2685 |
|
|
b2_count_o => b2_count,
|
2686 |
|
|
b3_count_o => b3_count,
|
2687 |
|
|
bn_count_o => bn_count,
|
2688 |
|
|
bo_count_o => bo_count,
|
2689 |
|
|
baud_o => baud,
|
2690 |
|
|
freq_o => freq,
|
2691 |
|
|
idle_o => idle,
|
2692 |
|
|
new_o => new_o
|
2693 |
|
|
);
|
2694 |
|
|
|
2695 |
|
|
|
2696 |
|
|
end beh;
|
2697 |
|
|
|
2698 |
|
|
|
2699 |
|
|
---------------------------------------------------------------------------------
|
2700 |
|
|
-- Digital Phase Locked Loop (With Alexander "Bang-Bang" Phase Detector)
|
2701 |
|
|
-------------------------------------------------------------------------------
|
2702 |
|
|
--
|
2703 |
|
|
-- Author: John Clayton
|
2704 |
|
|
-- Date : Mar. 26, 2012 Having already tested the auto-generated code version
|
2705 |
|
|
-- of this module, and finding it satisfactory, I am
|
2706 |
|
|
-- recoding the module by hand, in order to streamline
|
2707 |
|
|
-- and parameterize it.
|
2708 |
|
|
-- Mar. 28, 2012 Adding synchronization flip flop chain, also delaying
|
2709 |
|
|
-- the clock to line it up with the data output.
|
2710 |
|
|
--
|
2711 |
|
|
--
|
2712 |
|
|
-- Description
|
2713 |
|
|
-------------------------------------------------------------------------------
|
2714 |
|
|
-- This module includes an NCO (squarewave DDS), a lowpass filter and
|
2715 |
|
|
-- an Alexander "bang-bang" type phase detector configured as a
|
2716 |
|
|
-- digital PLL.
|
2717 |
|
|
--
|
2718 |
|
|
-- The original design was set up, coded and simulated by
|
2719 |
|
|
-- Jacob Fenton.
|
2720 |
|
|
--
|
2721 |
|
|
-- -------------------------------------------------------------
|
2722 |
|
|
-- Functional Description:
|
2723 |
|
|
-- -------------------------------------------------------------
|
2724 |
|
|
-- The following constants, taken from Jacob Fenton's testbench,
|
2725 |
|
|
-- serve to illustrate how to adjust the settings:
|
2726 |
|
|
--
|
2727 |
|
|
-- constant NCO_BITS : integer := 32;
|
2728 |
|
|
-- constant P_BITS : integer := 32;
|
2729 |
|
|
-- constant I_BITS : integer := 32;
|
2730 |
|
|
-- constant sysclk : real := 50.0E+6;--fpga sys_clk rate
|
2731 |
|
|
-- constant baud : real := 3.0E+6;--expected data rate
|
2732 |
|
|
-- constant dmp_fctr : real := 0.7071;
|
2733 |
|
|
-- constant pi : real := 3.14159;
|
2734 |
|
|
-- constant bw : real := (0.005*baud);--desired dpll bandwidth as percentage of baud rate
|
2735 |
|
|
-- constant ko : real := (pi*sysclk)/("**"(2,real(NCO_BITS-1)));--nco gain (rad/sec)
|
2736 |
|
|
-- constant kd : real := ((sysclk/baud)*2.0)/pi;--phase detector gain (1/rad)
|
2737 |
|
|
-- constant kp : integer:= integer((dmp_fctr*2.0*2.0*pi*bw)/(ko*kd));
|
2738 |
|
|
-- constant ki : integer:= integer(("**"(2.0*pi*bw,2))/(sysclk*ko*kd));--need to make sure that with settings this value > 0, at some point use fixed point numbers
|
2739 |
|
|
-- constant w : integer:= integer(2.0*("**"(2,real(NCO_BITS-1)))/(sysclk/baud));
|
2740 |
|
|
--
|
2741 |
|
|
-- -------------------------------------------------------------
|
2742 |
|
|
library ieee;
|
2743 |
|
|
use ieee.std_logic_1164.all;
|
2744 |
|
|
use ieee.numeric_std.all;
|
2745 |
|
|
|
2746 |
|
|
entity dpll_alex is
|
2747 |
|
|
generic (
|
2748 |
|
|
NCO_BITS : integer := 32;
|
2749 |
|
|
P_BITS : integer := 26;
|
2750 |
|
|
I_BITS : integer := 12
|
2751 |
|
|
);
|
2752 |
|
|
port(
|
2753 |
|
|
sys_clk : in std_logic;
|
2754 |
|
|
sys_rst_n : in std_logic;
|
2755 |
|
|
sys_clk_en : in std_logic;
|
2756 |
|
|
clear_i : in std_logic;
|
2757 |
|
|
dat_i : in std_logic;
|
2758 |
|
|
w_i : in unsigned(NCO_BITS-1 downto 0);
|
2759 |
|
|
kp_i : in unsigned(P_BITS-1 downto 0);
|
2760 |
|
|
ki_i : in unsigned(I_BITS-1 downto 0);
|
2761 |
|
|
dat_o : out std_logic;
|
2762 |
|
|
clk_o : out std_logic
|
2763 |
|
|
);
|
2764 |
|
|
end dpll_alex;
|
2765 |
|
|
|
2766 |
|
|
|
2767 |
|
|
architecture beh of dpll_alex is
|
2768 |
|
|
|
2769 |
|
|
signal lpf_o : unsigned(P_BITS-1 downto 0);
|
2770 |
|
|
signal int_acum : unsigned(P_BITS-1 downto 0);
|
2771 |
|
|
signal nco_acum : unsigned(NCO_BITS-1 downto 0);
|
2772 |
|
|
signal up : std_logic;
|
2773 |
|
|
signal dn : std_logic;
|
2774 |
|
|
signal reg1 : std_logic;
|
2775 |
|
|
signal reg2 : std_logic;
|
2776 |
|
|
signal reg3 : std_logic;
|
2777 |
|
|
signal reg4 : std_logic;
|
2778 |
|
|
signal nco_clk : std_logic;
|
2779 |
|
|
|
2780 |
|
|
begin
|
2781 |
|
|
|
2782 |
|
|
clk_o <= nco_clk;
|
2783 |
|
|
dat_o <= reg4;
|
2784 |
|
|
|
2785 |
|
|
nco : process(sys_clk, sys_rst_n)
|
2786 |
|
|
begin
|
2787 |
|
|
if (sys_rst_n = '0') then
|
2788 |
|
|
nco_acum <= w_i;
|
2789 |
|
|
nco_clk <= '0';
|
2790 |
|
|
elsif rising_edge(sys_clk) then
|
2791 |
|
|
if (sys_clk_en='1') then
|
2792 |
|
|
if lpf_o(P_BITS-1) = '0' then --check sign of lpf_o
|
2793 |
|
|
nco_acum <= nco_acum + w_i + lpf_o;
|
2794 |
|
|
else
|
2795 |
|
|
nco_acum <= nco_acum + w_i - not(lpf_o) + 1;
|
2796 |
|
|
end if;
|
2797 |
|
|
nco_clk <= nco_acum(NCO_BITS-1);
|
2798 |
|
|
end if; -- sys_clk_en
|
2799 |
|
|
end if; -- sys_clk
|
2800 |
|
|
end process nco;
|
2801 |
|
|
|
2802 |
|
|
lpf : process(sys_clk, sys_rst_n)
|
2803 |
|
|
begin
|
2804 |
|
|
if (sys_rst_n = '0') then
|
2805 |
|
|
lpf_o <= (others=>'0');
|
2806 |
|
|
int_acum <= (others=> '0');
|
2807 |
|
|
elsif rising_edge(sys_clk) then
|
2808 |
|
|
if (sys_clk_en='1') then
|
2809 |
|
|
if (up = '1' and dn = '0') then --indicates need to speed up
|
2810 |
|
|
lpf_o <= int_acum + kp_i;
|
2811 |
|
|
int_acum <= int_acum + ki_i;
|
2812 |
|
|
elsif (up = '0' and dn = '1') then --indicates need to slow down
|
2813 |
|
|
lpf_o <= int_acum - kp_i;
|
2814 |
|
|
int_acum <= int_acum - ki_i;
|
2815 |
|
|
end if;
|
2816 |
|
|
end if; -- sys_clk_en
|
2817 |
|
|
end if; -- sys_clk
|
2818 |
|
|
end process lpf;
|
2819 |
|
|
|
2820 |
|
|
up <= reg4 xor reg1;
|
2821 |
|
|
dn <= reg4 xor reg2;
|
2822 |
|
|
|
2823 |
|
|
alex_pfd : process(nco_clk, sys_rst_n)
|
2824 |
|
|
begin
|
2825 |
|
|
if (sys_rst_n = '0') then
|
2826 |
|
|
reg1 <= '0';
|
2827 |
|
|
reg2 <= '0';
|
2828 |
|
|
reg3 <= '0';
|
2829 |
|
|
reg4 <= '0';
|
2830 |
|
|
elsif rising_edge(nco_clk) then
|
2831 |
|
|
reg1 <= dat_i;
|
2832 |
|
|
reg2 <= reg1;
|
2833 |
|
|
reg4 <= reg3;
|
2834 |
|
|
elsif falling_edge(nco_clk) then
|
2835 |
|
|
reg3 <= dat_i;
|
2836 |
|
|
end if;
|
2837 |
|
|
end process alex_pfd;
|
2838 |
|
|
|
2839 |
|
|
end beh;
|
2840 |
|
|
|
2841 |
|
|
|