Project

General

Profile

Download (4.44 KB) Statistics
| Branch: | Tag: | Revision:
1
---------------------------------------------------------------------------------------------------
2
-- Filename    : usbrx_clkref.vhd
3
-- Project     : OsmoSDR FPGA Firmware
4
-- Purpose     : Reference Clock Measurement
5
---------------------------------------------------------------------------------------------------
6

    
7
-----------------------------------------------------------------------------------
8
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
9
-- written by Matthias Kleffel                                                   --
10
--                                                                               --
11
-- This program is free software; you can redistribute it and/or modify          --
12
-- it under the terms of the GNU General Public License as published by          --
13
-- the Free Software Foundation as version 3 of the License, or                  --
14
--                                                                               --
15
-- This program is distributed in the hope that it will be useful,               --
16
-- but WITHOUT ANY WARRANTY; without even the implied warranty of                --
17
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  --
18
-- GNU General Public License V3 for more details.                               --
19
--                                                                               --
20
-- You should have received a copy of the GNU General Public License             --
21
-- along with this program. If not, see <http://www.gnu.org/licenses/>.          --
22
-----------------------------------------------------------------------------------
23

    
24
library ieee;
25
	use ieee.std_logic_1164.all;
26
	use ieee.numeric_std.all;
27
library work;
28
	use work.all;
29
	use work.mt_toolbox.all;
30
	use work.usbrx.all;
31

    
32
entity usbrx_clkref is
33
	port(
34
		-- system clocks
35
		clk_sys  : in  std_logic;
36
		rst_sys  : in  std_logic;
37
		
38
		-- reference signal
39
		clk_ref  : in  std_logic;
40
		rst_ref  : in  std_logic;
41
		
42
		-- 1pps signal
43
		gps_1pps : in  std_logic;
44
		
45
		-- status
46
		status   : out usbrx_ref_status_t
47
	);
48
end usbrx_clkref;
49

    
50
architecture rtl of usbrx_clkref is
51

    
52
	-- deglitcher
53
	signal dgl_hist : std_logic_vector(3 downto 0);
54
	signal dgl_out  : std_logic;
55
	
56
	-- edge detection
57
	signal pps_last : std_logic;
58

    
59
	-- active counters
60
	signal cnt_lsb : unsigned(24 downto 0);
61
	
62
	-- latched counters
63
	signal lat_upd : std_logic;
64
	signal lat_lsb : unsigned(24 downto 0);
65
	signal lat_msb : unsigned(6 downto 0);
66

    
67
	-- output register
68
	signal out_upd : std_logic;
69
	signal out_lsb : unsigned(24 downto 0);
70
	signal out_msb : unsigned(6 downto 0);
71
	
72
begin
73
	
74
	-- reference counter
75
	process(clk_ref)
76
		variable cnt0,cnt1 : natural range 0 to 4;
77
		variable re : boolean;
78
	begin
79
		if rising_edge(clk_ref) then
80
			-- set default values
81
			lat_upd <= '0';
82
			
83
			-- deglitch pps signal
84
			dgl_hist <= dgl_hist(dgl_hist'left-1 downto 0) & gps_1pps;
85
			cnt0 := 0;
86
			cnt1 := 0;
87
			for i in dgl_hist'range loop
88
				if dgl_hist(i)='0' then
89
					cnt0 := cnt0 + 1;
90
				end if;
91
				if dgl_hist(i)='1' then
92
					cnt1 := cnt1 + 1;
93
				end if;
94
			end loop;
95
			if cnt0 >= 3 then
96
				dgl_out <= '0';
97
			elsif cnt1 >= 3 then
98
				dgl_out <= '1';
99
			end if;
100
			
101
			-- detect rising edge on pps
102
			pps_last <= dgl_out;
103
			re := (dgl_out='1' and pps_last='0');
104
			
105
			-- update counters
106
			if re then
107
				cnt_lsb <= to_unsigned(0, cnt_lsb'length);
108
				lat_lsb <= cnt_lsb;
109
				lat_msb <= lat_msb + 1;
110
				lat_upd <= '1';
111
			else
112
				cnt_lsb <= cnt_lsb + 1;
113
			end if;
114

    
115
			-- handle reset
116
			if rst_ref='1' then
117
				dgl_hist <= (others=>'0');
118
				dgl_out  <= '0';
119
				pps_last <= '0';
120
				cnt_lsb  <= (others=>'0');
121
				lat_upd  <= '0';
122
				lat_lsb  <= (others=>'0');
123
				lat_msb  <= (others=>'0');
124
			end if;
125
		end if;
126
	end process;
127

    
128
	-- bring update-pulse into correct clock domain
129
	syn: entity mt_sync_feedback
130
		port map (
131
			i_clk  => clk_ref,
132
			i_data => lat_upd,
133
			o_clk  => clk_sys,
134
			o_data => out_upd
135
		);
136
	
137
	-- output register
138
	process(clk_sys)
139
	begin
140
		if rising_edge(clk_sys) then
141
			-- update output when requested
142
			if out_upd='1' then
143
				out_lsb  <= lat_lsb;
144
				out_msb  <= lat_msb;
145
			end if;
146
			
147
			-- handle reset
148
			if rst_sys='1' then
149
				out_lsb  <= (others=>'0');
150
				out_msb  <= (others=>'0');
151
			end if;
152
		end if;
153
	end process;
154
	
155
	-- output status
156
	status.lsb <= out_lsb;
157
	status.msb <= out_msb;
158
end rtl;
(2-2/7)
Add picture from clipboard (Maximum size: 48.8 MB)