Imported Upstream version 3.0
[debian/gnuradio] / usrp / fpga / sdr_lib / ddc.v
1 // -*- verilog -*-
2 //
3 //  USRP - Universal Software Radio Peripheral
4 //
5 //  Copyright (C) 2003 Matt Ettus
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License as published by
9 //  the Free Software Foundation; either version 2 of the License, or
10 //  (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin Street, Boston, MA  02110-1301  USA
20 //
21
22
23
24 // DDC block
25
26 module ddc(input clock,
27                         input reset,
28                         input enable,
29                         input [3:0] rate1,
30                         input [3:0] rate2,
31                         output strobe,
32                         input [31:0] freq,
33                         input [15:0] i_in,
34                         input [15:0] q_in,
35                         output [15:0] i_out,
36                         output [15:0] q_out
37                         );
38    parameter bw = 16;
39    parameter zw = 16;
40
41         wire [15:0] i_cordic_out, q_cordic_out;
42         wire [31:0] phase;
43
44         wire strobe1, strobe2;
45         reg [3:0] strobe_ctr1,strobe_ctr2;
46
47         always @(posedge clock)
48                 if(reset | ~enable)
49                         strobe_ctr2 <= #1 4'd0;
50                 else if(strobe2)
51                         strobe_ctr2 <= #1 4'd0;
52                 else    
53                         strobe_ctr2 <= #1 strobe_ctr2 + 4'd1;
54                                 
55         always @(posedge clock)
56                 if(reset | ~enable)
57                         strobe_ctr1 <= #1 4'd0;
58                 else if(strobe1)
59                         strobe_ctr1 <= #1 4'd0;
60                 else if(strobe2)
61                         strobe_ctr1 <= #1 strobe_ctr1 + 4'd1;
62                                 
63
64         assign strobe2 = enable & ( strobe_ctr2 == rate2 );
65         assign strobe1 = strobe2 & ( strobe_ctr1 == rate1 );
66
67         assign strobe = strobe1;
68
69         function [2:0] log_ceil;
70         input [3:0] val;
71         
72                 log_ceil = val[3] ? 3'd4 : val[2] ? 3'd3 : val[1] ? 3'd2 : 3'd1; 
73         endfunction     
74         
75         wire [2:0] shift1 = log_ceil(rate1);
76         wire [2:0] shift2 = log_ceil(rate2);
77         
78         cordic #(.bitwidth(bw),.zwidth(zw),.stages(16))
79                 cordic(.clock(clock), .reset(reset), .enable(enable),
80                         .xi(i_in), .yi(q_in), .zi(phase[31:32-zw]), 
81                         .xo(i_cordic_out), .yo(q_cordic_out), .zo()  );
82                 
83         cic_decim_2stage #(.bw(bw),.N(4)) 
84                 decim_i(.clock(clock),.reset(reset),.enable(enable),
85                         .strobe1(1'b1),.strobe2(strobe2),.strobe3(strobe1),.shift1(shift2),.shift2(shift1),
86                         .signal_in(i_cordic_out),.signal_out(i_out));
87                         
88         cic_decim_2stage #(.bw(bw),.N(4)) 
89                 decim_q(.clock(clock),.reset(reset),.enable(enable),
90                         .strobe1(1'b1),.strobe2(strobe2),.strobe3(strobe1),.shift1(shift2),.shift2(shift1),
91                         .signal_in(q_cordic_out),.signal_out(q_out));
92         
93         phase_acc #(.resolution(32))
94                 nco (.clk(clock),.reset(reset),.enable(enable),
95                         .freq(freq),.phase(phase));
96                 
97 endmodule