OpenCores
URL https://opencores.org/ocsvn/cordic_atan_iq/cordic_atan_iq/trunk

Subversion Repositories cordic_atan_iq

[/] [cordic_atan_iq/] [cordic_atan_iq.sv] - Rev 8

Compare with Previous | Blame | View Log

`ifndef _cordic_atan_iq_
`define _cordic_atan_iq_
`include "atan32_table.sv"

// Calc delay 32 clocks
module cordic_atan_iq(clk, IS, QS, angle, coe_radius);
        import ConstPkg::atan_table;    
        localparam STEPS = ConstPkg::STEPS;

        input wire clk; // todo: clk_ena
        input wire signed [29:0] IS, QS;
        output signed [31:0] angle;
        output [31:0] coe_radius; // sqrt(I^2 + Q^2) / K
        
        wire isign;
        reg isign_reg;
        reg signed [31:0] x[STEPS], y[STEPS-1]; // + 2 bit for carry (sqrt(2) * (1 + k)) todo: x unsigned and increase input vector width
        reg signed [31:0] a[STEPS-1:1];
        
        assign isign = IS < 'sh0;
        
        // rotate to working range -90..+90
        always_ff @(posedge clk) begin
                x[0] <= (isign) ? 32'sh0 - IS : 32'sh0 + IS;
                y[0] <= (isign) ? 32'sh0 + QS : 32'sh0 - QS; // invert y sign for true result sign
                isign_reg <= isign; // save rotate on 180 deg
        end
        
        always_ff @(posedge clk)
                if (y[0] > 'sh0)
                        begin
                                x[1] <= x[0] + y[0];
                                y[1] <= y[0] - x[0];
                                
                                if (isign_reg)
                                        a[1] <= signed'({1'b0, {31{1'b1}}}) - (atan_table[0] - 1'b1); // rotate 180 - 45 deg
                                else
                                        a[1] <= -atan_table[0]; // rotate -45 deg
                        end
                else
                        begin
                                x[1] <= x[0] - y[0];
                                y[1] <= y[0] + x[0];
                                
                                if (isign_reg)
                                        a[1] <= signed'({1'b1, {31{1'b0}}}) + atan_table[0]; // rotate -180 + 45 deg
                                else
                                        a[1] <= atan_table[0]; // rotate +45 deg
                        end
        
        genvar i;
        generate for(i = 2; i < STEPS-1; i++)
                begin :gen
                        always_ff @(posedge clk)
                                if (y[i-1] > 'sh0)
                                        begin
                                                x[i] <= x[i-1] + (y[i-1] >>> (i - 1));
                                                y[i] <= y[i-1] - (x[i-1] >>> (i - 1));
                                                a[i] <= a[i-1] - atan_table[i-1];
                                        end
                                else
                                        begin
                                                x[i] <= x[i-1] - (y[i-1] >>> (i - 1));
                                                y[i] <= y[i-1] + (x[i-1] >>> (i - 1));
                                                a[i] <= a[i-1] + atan_table[i-1];
                                        end
                end
        endgenerate
        
        always_ff @(posedge clk)
                if (y[STEPS-2] > 'sh0)
                        begin
                                x[STEPS-1] <= x[STEPS-2] + (y[STEPS-2] >>> (STEPS-2));
                                a[STEPS-1] <= a[STEPS-2] - atan_table[STEPS-2];
                        end
                else
                        begin
                                x[STEPS-1] <= x[STEPS-2] - (y[STEPS-2] >>> (STEPS-2));
                                a[STEPS-1] <= a[STEPS-2] + atan_table[STEPS-2];
                        end
        
        assign angle = a[STEPS-1];
        assign coe_radius = x[STEPS-1];

endmodule : cordic_atan_iq

`endif

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.