// CORDIC Phase-to-Amplitude Converter // Author: Michel Barbeau // Version: January 2, 2015 `timescale 1ns / 1ns module CORDIC(clock, pw, v1, v2); input clock; // pw=20-bit phase word (2^20=2pi radians) input [19:0] pw; // output unit vector is over 12 bits // v1 is the in-phase sample, v2 is the quadrature sample output reg signed [11:0] v1, v2; // phase word resulting from the rotation applied at each iteration reg signed [31:0] pw0, pw1, pw2, pw3, pw4, pw5, pw6, pw7, pw8, pw9, pw10; // In-phase resulting from each iteration reg signed [11:0] I0,I1, I2, I3, I4, I5, I6, I7, I8, I9, I10; // Quadrature resulting from each iteration reg signed [11:0] Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, Q10; always @ (posedge clock) begin // two most significant bits determine the quadrant case (pw[19:18]) 2'b01,2'b10: // in IInd or IIIrd quadrant begin I0 <= -12'sd1024; Q0 <= 12'sd0; pw0 <= pw - 32'sd524288; // = 2^19 (pi radians) end 2'b00,2'b11: // in Ist or IVth quadrant begin I0 <= 12'sd1024; Q0 <= 12'sd0; if (pw[18]) // in IVth quadrant pw0 <= pw - 32'sd1048576; // = 2^20 (2pi radians) else pw0 <= pw; end endcase // 1st rotation: arctan 1/2^0 = pi/4 radians equiv. 2^17 = d131072 if (pw0[31]) // phase word negative? begin // CCW pw1 <= pw0 + 32'sd131072; I1 <= I0 + Q0; Q1 <= Q0 - I0; end else begin //CW pw1 <= pw0 - 32'sd131072; I1 <= I0 - Q0; Q1 <= Q0 + I0; end // 2nd rotation: arctan 1/2^1 equiv. d77376 if (pw1[31]) // phase word negative? begin // CCW pw2 <= pw1 + 32'sd77376; I2 <= I1 + (Q1 >>> 1); Q2 <= Q1 - (I1 >>> 1); end else begin //CW pw2 <= pw1 - 32'sd77376; I2 <= I1 - (Q1 >>> 1); Q2 <= Q1 + (I1 >>> 1); end // 3rd rotation: arctan 1/2^2 equiv. d40884 if (pw2[31]) // phase word negative? begin // CCW pw3 <= pw2 + 32'sd40884; I3 <= I2 + (Q2 >>> 2); Q3 <= Q2 - (I2 >>> 2); end else begin //CW pw3 <= pw2 - 32'sd40884; I3 <= I2 - (Q2 >>> 2); Q3 <= Q2 + (I2 >>> 2); end // 4th rotation: arctan 1/2^3 equiv. d20753 if (pw3[31]) // phase word negative? begin // CCW pw4 <= pw3 + 32'sd20753; I4 <= I3 + (Q3 >>> 3); Q4 <= Q3 - (I3 >>> 3); end else begin //CW pw4 <= pw3 - 32'sd20753; I4 <= I3 - (Q3 >>> 3); Q4 <= Q3 + (I3 >>> 3); end // 5th rotation: arctan 1/2^4 equiv. d10417 if (pw4[31]) // phase word negative? begin // CCW pw5 <= pw4 + 32'sd10417; I5 <= I4 + (Q4 >>> 4); Q5 <= Q4 - (I4 >>> 4); end else begin //CW pw5 <= pw4 - 32'sd10417; I5 <= I4 - (Q4 >>> 4); Q5 <= Q4 + (I4 >>> 4); end // 6th rotation: arctan 1/2^5 equiv. d5214 if (pw5[31]) // phase word negative? begin // CCW pw6 <= pw5 + 32'sd5214; I6 <= I5 + (Q5 >>> 5); Q6 <= Q5 - (I1 >>> 5); end else begin //CW pw6 <= pw5 - 32'sd5214; I6 <= I5 - (Q5 >>> 5); Q6 <= Q5 + (I5 >>> 5); end // 7th rotation: arctan 1/2^6 equiv. d2607 if (pw6[31]) // phase word negative? begin // CCW pw7 <= pw6 + 32'sd2607; I7 <= I6 + (Q6 >>> 6); Q7 <= Q6 - (I6 >>> 6); end else begin //CW pw7 <= pw6 - 32'sd2607; I7 <= I6 - (Q6 >>> 6); Q7 <= Q6 + (I6 >>> 6); end // 8th rotation: arctan 1/2^7 equiv. d1304 if (pw7[31]) // phase word negative? begin // CCW pw8 <= pw7 + 32'sd1304; I8 <= I7 + (Q7 >>> 7); Q8 <= Q7 - (I7 >>> 7); end else begin //CW pw8 <= pw7 - 32'sd1304; I8 <= I7 - (Q7 >>> 7); Q8 <= Q7 + (I7 >>> 7); end // 9th rotation: arctan 1/2^8 equiv. d652 if (pw8[31]) // phase word negative? begin // CCW pw9 <= pw8 + 32'sd652; I9 <= I8 + (Q8 >>> 8); Q9 <= Q8 - (I8 >>> 8); end else begin //CW pw9 <= pw8 - 32'sd652; I9 <= I8 - (Q8 >>> 8); Q9 <= Q8 + (I8 >>> 8); end // 10th rotation: arctan 1/2^9 equiv. d326 if (pw9[31]) // phase word negative? begin // CCW pw10 <= pw9 + 32'sd326; I10 <= I9 + (Q9 >>> 9); Q10 <= Q9 - (I9 >>> 9); end else begin //CW pw10 <= pw9 - 32'sd326; I10 <= I9 - (Q9 >>> 9); Q10 <= Q9 + (I9 >>> 9); end v1 <= I10; v2 <= Q10; end endmodule