Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / fpga / sdr_lib / cordic.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 module cordic(clock, reset, enable, xi, yi, zi, xo, yo, zo );
23    parameter bitwidth = 16;
24    parameter zwidth = 16;
25    
26    input clock;
27    input reset;
28    input enable;
29    input [bitwidth-1:0] xi, yi;
30    output [bitwidth-1:0] xo, yo;
31    input [zwidth-1:0] zi;
32    output [zwidth-1:0] zo;
33    
34    reg [bitwidth+1:0]    x0,y0;
35    reg [zwidth-2:0]      z0;
36    wire [bitwidth+1:0]   x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12;
37    wire [bitwidth+1:0]   y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12;
38    wire [zwidth-2:0] z1,z2,z3,z4,z5,z6,z7,z8,z9,z10,z11,z12;
39    
40    wire [bitwidth+1:0] xi_ext = {{2{xi[bitwidth-1]}},xi};
41    wire [bitwidth+1:0] yi_ext = {{2{yi[bitwidth-1]}},yi};
42
43    // Compute consts.  Would be easier if vlog had atan...
44    // see gen_cordic_consts.py
45    
46 `define c00 16'd8192
47 `define c01 16'd4836
48 `define c02 16'd2555
49 `define c03 16'd1297
50 `define c04 16'd651
51 `define c05 16'd326
52 `define c06 16'd163
53 `define c07 16'd81
54 `define c08 16'd41
55 `define c09 16'd20
56 `define c10 16'd10
57 `define c11 16'd5
58 `define c12 16'd3
59 `define c13 16'd1
60 `define c14 16'd1
61 `define c15 16'd0
62 `define c16 16'd0
63
64    always @(posedge clock)
65      if(reset)
66        begin
67           x0   <= #1 0; y0   <= #1 0;  z0   <= #1 0;
68        end
69      else if(enable)
70        begin
71           z0 <= #1 zi[zwidth-2:0];
72           case (zi[zwidth-1:zwidth-2])
73             2'b00, 2'b11 : 
74               begin
75                  x0 <= #1 xi_ext;
76                  y0 <= #1 yi_ext;
77               end
78             2'b01, 2'b10 :
79               begin
80                  x0 <= #1 -xi_ext;
81                  y0 <= #1 -yi_ext;
82               end
83           endcase // case(zi[zwidth-1:zwidth-2])
84        end // else: !if(reset)
85    
86    // FIXME need to handle variable number of stages
87    // FIXME should be able to narrow zwidth but quartus makes it bigger...
88    // This would be easier if arrays worked better in vlog...
89    cordic_stage #(bitwidth+2,zwidth-1,0) cordic_stage0 (clock,reset,enable,x0,y0,z0,`c00,x1,y1,z1);
90    cordic_stage #(bitwidth+2,zwidth-1,1) cordic_stage1 (clock,reset,enable,x1,y1,z1,`c01,x2,y2,z2);
91    cordic_stage #(bitwidth+2,zwidth-1,2) cordic_stage2 (clock,reset,enable,x2,y2,z2,`c02,x3,y3,z3);
92    cordic_stage #(bitwidth+2,zwidth-1,3) cordic_stage3 (clock,reset,enable,x3,y3,z3,`c03,x4,y4,z4);
93    cordic_stage #(bitwidth+2,zwidth-1,4) cordic_stage4 (clock,reset,enable,x4,y4,z4,`c04,x5,y5,z5);
94    cordic_stage #(bitwidth+2,zwidth-1,5) cordic_stage5 (clock,reset,enable,x5,y5,z5,`c05,x6,y6,z6);
95    cordic_stage #(bitwidth+2,zwidth-1,6) cordic_stage6 (clock,reset,enable,x6,y6,z6,`c06,x7,y7,z7);
96    cordic_stage #(bitwidth+2,zwidth-1,7) cordic_stage7 (clock,reset,enable,x7,y7,z7,`c07,x8,y8,z8);
97    cordic_stage #(bitwidth+2,zwidth-1,8) cordic_stage8 (clock,reset,enable,x8,y8,z8,`c08,x9,y9,z9);
98    cordic_stage #(bitwidth+2,zwidth-1,9) cordic_stage9 (clock,reset,enable,x9,y9,z9,`c09,x10,y10,z10);
99    cordic_stage #(bitwidth+2,zwidth-1,10) cordic_stage10 (clock,reset,enable,x10,y10,z10,`c10,x11,y11,z11);
100    cordic_stage #(bitwidth+2,zwidth-1,11) cordic_stage11 (clock,reset,enable,x11,y11,z11,`c11,x12,y12,z12);
101
102    assign xo = x12[bitwidth:1];  
103    assign yo = y12[bitwidth:1];
104    //assign xo = x12[bitwidth+1:2];  // CORDIC gain is ~1.6, plus gain from rotating vectors
105    //assign yo = y12[bitwidth+1:2];
106    assign zo = z12;               
107
108 endmodule // cordic
109