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// DUC block 23 24module duc(input clock, 25 input reset, 26 input enable, 27 input [3:0] rate1, 28 input [3:0] rate2, 29 output strobe, 30 input [31:0] freq, 31 input [15:0] i_in, 32 input [15:0] q_in, 33 output [15:0] i_out, 34 output [15:0] q_out 35 ); 36 parameter bw = 16; 37 parameter zw = 16; 38 39 wire [15:0] i_interp_out, q_interp_out; 40 wire [31:0] phase; 41 42 wire strobe1, strobe2; 43 reg [3:0] strobe_ctr1,strobe_ctr2; 44 45 always @(posedge clock) 46 if(reset | ~enable) 47 strobe_ctr2 <= #1 4'd0; 48 else if(strobe2) 49 strobe_ctr2 <= #1 4'd0; 50 else 51 strobe_ctr2 <= #1 strobe_ctr2 + 4'd1; 52 53 always @(posedge clock) 54 if(reset | ~enable) 55 strobe_ctr1 <= #1 4'd0; 56 else if(strobe1) 57 strobe_ctr1 <= #1 4'd0; 58 else if(strobe2) 59 strobe_ctr1 <= #1 strobe_ctr1 + 4'd1; 60 61 62 assign strobe2 = enable & ( strobe_ctr2 == rate2 ); 63 assign strobe1 = strobe2 & ( strobe_ctr1 == rate1 ); 64 65 assign strobe = strobe1; 66 67 function [2:0] log_ceil; 68 input [3:0] val; 69 70 log_ceil = val[3] ? 3'd4 : val[2] ? 3'd3 : val[1] ? 3'd2 : 3'd1; 71 endfunction 72 73 wire [2:0] shift1 = log_ceil(rate1); 74 wire [2:0] shift2 = log_ceil(rate2); 75 76 cordic #(.bitwidth(bw),.zwidth(zw),.stages(16)) 77 cordic(.clock(clock), .reset(reset), .enable(enable), 78 .xi(i_interp_out), .yi(q_interp_out), .zi(phase[31:32-zw]), 79 .xo(i_out), .yo(q_out), .zo() ); 80 81 cic_interp_2stage #(.bw(bw),.N(4)) 82 interp_i(.clock(clock),.reset(reset),.enable(enable), 83 .strobe1(strobe1),.strobe2(strobe2),.strobe3(1'b1),.shift1(shift1),.shift2(shift2), 84 .signal_in(i_in),.signal_out(i_interp_out)); 85 86 cic_interp_2stage #(.bw(bw),.N(4)) 87 interp_q(.clock(clock),.reset(reset),.enable(enable), 88 .strobe1(strobe1),.strobe2(strobe2),.strobe3(1'b1),.shift1(shift1),.shift2(shift2), 89 .signal_in(q_in),.signal_out(q_interp_out)); 90 91 phase_acc #(.resolution(32)) 92 nco (.clk(clock),.reset(reset),.enable(enable), 93 .freq(freq),.phase(phase)); 94 95endmodule 96