Project

General

Profile

Download (5.36 KB) Statistics
| Branch: | Tag: | Revision:
1 c62f5734 Christian Daniel
---------------------------------------------------------------------------------------------------
2
-- Filename    : usbrx_ssc.vhd
3
-- Project     : OsmoSDR FPGA Firmware
4
-- Purpose     : ATSAM3U SSC Interface
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_ssc is
33
	port(
34
		-- common
35
		clk     : in  std_logic;
36
		reset   : in  std_logic;
37
38
		-- config
39
		config  : in  usbrx_ssc_config_t;
40
		
41
		-- output
42
		in_clk  : in  std_logic;
43
		in_i    : in  signed(15 downto 0);
44
		in_q    : in  signed(15 downto 0);
45
		
46
		-- SSC interface
47
		ssc_clk : out std_logic;
48
		ssc_syn : out std_logic;
49
		ssc_dat : out std_logic
50
	);
51
end usbrx_ssc;
52
53
architecture rtl of usbrx_ssc is
54
55
	-- CLK generator
56
	signal cg_div   : unsigned(7 downto 0);
57
	signal cg_phase : std_logic;
58
	signal cg_tick  : std_logic;
59
	
60
	-- shift register
61
	signal sreg   : std_logic_vector(31 downto 0);
62
	signal remain : unsigned(5 downto 0);
63
	signal nxtsyn : std_logic;
64
65
	-- input latch
66
	signal lreg   : std_logic_vector(31 downto 0);
67
	signal filled : std_logic;
68
	
69
	-- helper function
70
	function to_signed(x : unsigned) return signed is
71
	begin
72
		return signed((not x(x'left)) & x(x'left-1 downto 0));
73
	end to_signed;
74
	function pack(i,q : unsigned) return slv32_t is
75
		variable res : slv32_t := (others=>'0');
76
	begin
77
		res(31 downto 32-i'length) := std_logic_vector(to_signed(i));
78
		res(15 downto 16-q'length) := std_logic_vector(to_signed(q));
79
		return res;
80
	end pack;
81
	function pack(i,q : signed) return slv32_t is
82
		variable res : slv32_t := (others=>'0');
83
	begin
84
		res(31 downto 32-i'length) := std_logic_vector(i);
85
		res(15 downto 16-q'length) := std_logic_vector(q);
86
		return res;
87
	end pack;
88
	
89
	-- debug
90
	signal counter1 : unsigned(15 downto 0);
91
	signal counter2 : unsigned(15 downto 0);
92
	
93
begin
94
	
95
	-- clock generator 
96
	process(clk)
97
	begin
98
		if rising_edge(clk) then
99
			-- set default values
100
			cg_tick <= '0';
101
			
102
			-- update clock-divider
103
			if cg_div=0 then
104
				-- toggle phase
105
				cg_phase <= not cg_phase;
106
				cg_div   <= config.clkdiv;
107
				
108
				-- set 'tick'-flag when generating falling edge
109
				if cg_phase='1' then
110
					cg_tick <= '1';
111
				end if;
112
			else
113
				-- stay in current phase
114
				cg_div <= cg_div-1;
115
			end if;
116
			
117
			-- update output
118
			ssc_clk <= cg_phase;
119
			
120
			-- handle reset
121
			if reset='1' then
122
				cg_div   <= (others=>'0');
123
				cg_phase <= '0';
124
				cg_tick  <= '0';
125
				ssc_clk  <= '0';
126
			end if;
127
		end if;
128
	end process;
129
	
130
	-- output shift register
131
	process(clk)
132
	begin
133
		if rising_edge(clk) then
134
			-- wait for output-clock
135
			if cg_tick='1' then
136
				-- update output
137
				ssc_dat <= sreg(sreg'left);
138
				ssc_syn <= nxtsyn;
139
				sreg    <= sreg(sreg'left-1 downto 0) & '0';
140
				nxtsyn  <= '0';
141
				
142
				-- consume bit
143
				if remain > 0 then
144
					remain <= remain - 1;
145
				end if;
146
				
147
				-- reload shift-register when possible
148
				if filled='1' and remain<=1 then
149
					filled <= '0';
150
					remain <= to_unsigned(32, remain'length);
151
					nxtsyn <= '1';
152
					sreg   <= lreg;
153
				end if;
154
			end if;
155
156
			-- handle incoming samples
157
			if in_clk='1' then
158
				if filled='0' then
159
					-- latch sample
160
					lreg   <= pack(in_i,in_q);
161
					filled <= '1';
162
					
163
					-- apply test-mode
164
					if config.tmode='1' then
165
						lreg <= pack(counter1,counter2);
166
						counter1 <= counter1 + 1;
167
						counter2 <= counter2 - 1;
168
					end if;
169
				else
170
					--> overflow
171
					report "usbrx_ssc: input too fast"
172
						severity warning;
173
				end if;
174
			end if;
175
				
176
			-- handle reset
177
			if reset='1' then
178
				sreg    <= (others=>'0');
179
				remain  <= (others=>'0');
180
				nxtsyn  <= '0';
181
				lreg    <= (others=>'0');
182
				filled  <= '0';
183
				ssc_syn <= '0';
184
				ssc_dat <= '0';
185
				counter1 <= (others=>'0');
186
				counter2 <= (others=>'1');
187
			end if;
188
		end if;
189
	end process;
190
	
191
end rtl;
Add picture from clipboard (Maximum size: 48.8 MB)