Last active
June 20, 2017 15:19
-
-
Save inkwisit/0a367f524a0ede2107aa7ff6a0b83cfe to your computer and use it in GitHub Desktop.
Cordic Algorithm for Quadrature Carrier Synthesis (Non-pipelined)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
module clockDivider #(parameter DIV_LENGTH = 8)( | |
input mainClock, | |
output clock | |
); | |
initial | |
begin | |
counter <= 8'b0; | |
end | |
assign clock = counter[DIV_LENGTH-1]; | |
reg [DIV_LENGTH-1:0]counter; | |
always@(posedge mainClock) | |
begin | |
counter <= counter + 1'b1; | |
end | |
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NET "mainClock" LOC = V10 | IOSTANDARD = LVCMOS33 | PERIOD = 100MHz ; | |
NET "cosine[9]" LOC = T3 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[8]" LOC = R3 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[7]" LOC = V5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[6]" LOC = U5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[5]" LOC = V4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[4]" LOC = T4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[3]" LOC = V7 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[2]" LOC = U7 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[1]" LOC = V9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "cosine[0]" LOC = T9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; | |
NET "strobe" LOC = T5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
module cordic3 #(parameter ANGLE_RESOLUTION = 10, OUTPUT_RESOLUTION = 10, LUT_SIZE = 3, DC_OFFSET = 10'd512)( | |
input angleLatch, | |
input mainClock, | |
input [ANGLE_RESOLUTION-1:0]angleInput, //from 2's compliment representation e.g., 230 = (230/360)*1024 = 1010001110 , in other ways it represent angle from -pi to pi in signed 2's compliment form | |
output reg [OUTPUT_RESOLUTION-1:0]cosine, | |
output reg [OUTPUT_RESOLUTION-1:0]sine, | |
output strobe | |
); | |
reg [ANGLE_RESOLUTION-1:0]angleAccumulator; | |
reg [LUT_SIZE-1:0]lookupTableIndex; | |
reg [OUTPUT_RESOLUTION-1:0]xNew; //10-bit number, MSB representing sign-bit //signed 2's compliment form | |
reg [OUTPUT_RESOLUTION-1:0]yNew; //10-bit number, MSB representing sign-bit //signed 2's compliment form | |
reg [ANGLE_RESOLUTION-1:0]angleInputReg; | |
wire [ANGLE_RESOLUTION-1:0]comparator; | |
wire [OUTPUT_RESOLUTION-1:0]yShifted; //signed 2's compliment | |
wire [OUTPUT_RESOLUTION-1:0]xShifted; //signed 2's compliment | |
wire [ANGLE_RESOLUTION-1:0]lookupTable[0:7]; //minimum angle value is 0.4476 at 8th place //ANGLE-3 for 1'st quadrant only | |
wire [ANGLE_RESOLUTION-1:0]rotationDirection; | |
assign yShifted = yNew >>> lookupTableIndex; //arithmetic shift right | |
assign xShifted = xNew >>> lookupTableIndex; //arithmetic shift right | |
assign strobe = (lookupTableIndex == 3'b000); | |
//assign rotationDirection = (angleAccumulator >= angleInputReg); | |
assign rotationDirection = angleInputReg - angleAccumulator; | |
always@(posedge mainClock) | |
begin | |
if(angleLatch == 1'b0) | |
begin | |
case(angleInput[9:8]) | |
2'b00: | |
begin | |
angleInputReg <= angleInput; | |
end | |
2'b11: | |
begin | |
angleInputReg <= -angleInput; // in case angle is 270(deg) = 10'b1100000000 then -angle = 0100000000 | |
end | |
2'b01: | |
begin | |
angleInputReg <= 10'b1000000000 - angleInput; //180 - angleInput | |
end | |
2'b10: | |
begin | |
angleInputReg <= 10'b1000000000 + angleInput; //180 + angleInput | |
end | |
endcase | |
xNew <= 10'b01_0011_0110; //511 * 0.6073 = 310 | |
yNew <= 10'b00_0000_0000; | |
lookupTableIndex <= 3'b000; | |
angleAccumulator <= 10'b00_0000_0000; | |
end | |
else | |
begin | |
xNew <= rotationDirection[ANGLE_RESOLUTION-1] ? (xNew + yShifted):(xNew - yShifted); | |
yNew <= rotationDirection[ANGLE_RESOLUTION-1] ? (yNew - xShifted):(yNew + xShifted); | |
angleAccumulator <= rotationDirection[ANGLE_RESOLUTION-1] ? (angleAccumulator - lookupTable[lookupTableIndex]):(angleAccumulator + lookupTable[lookupTableIndex]); | |
lookupTableIndex <= lookupTableIndex + 3'b1; | |
//$write(angleAccumulator); | |
end | |
end | |
always@(posedge mainClock) | |
begin | |
if(lookupTableIndex == 3'b111) | |
begin | |
case(angleInput[9:8]) //selecting the sign of functions using ASTC rule and adding an offset for +3.3V R2R DAC | |
2'b00: | |
begin | |
cosine <= xNew + DC_OFFSET; | |
sine <= yNew + DC_OFFSET; | |
end | |
2'b11: | |
begin | |
cosine <= xNew + DC_OFFSET; | |
sine <= -yNew + DC_OFFSET; | |
end | |
2'b01: | |
begin | |
cosine <= -xNew + DC_OFFSET; | |
sine <= yNew + DC_OFFSET; | |
end | |
2'b10: | |
begin | |
cosine <= -xNew + DC_OFFSET; | |
sine <= -yNew + DC_OFFSET; | |
end | |
endcase | |
end | |
end | |
//lookupTable for the angle //bin //decimal(deg) //exact(deg) | |
assign lookupTable[0] = 10'b0010000000; //128 //45.0000 //45.0000 | |
assign lookupTable[1] = 10'b0001001011; //75 //26.3672 //26.5651 | |
assign lookupTable[2] = 10'b0000100111; //39 //13.7109 //14.0362 | |
assign lookupTable[3] = 10'b0000010100; //20 //7.0313 //7.1250 | |
assign lookupTable[4] = 10'b0000001010; //10 //3.5156 //3.5763 | |
assign lookupTable[5] = 10'b0000000101; //5 //1.7578 //1.7899 | |
assign lookupTable[6] = 10'b0000000010; //2 //0.7031 //0.8952 | |
assign lookupTable[7] = 10'b0000000001; //1 //0.3516 //0.4476 | |
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
module DDS( | |
input mainClock, | |
output [9:0]cosine, | |
output [9:0]sine, | |
output reg [2:0]stateMachineCounter, | |
output reg angleLatch, | |
output strobe | |
); | |
reg [9:0]angleCounter; | |
cordic3 c0(.mainClock(clock),.angleInput(angleCounter),.angleLatch(angleLatch),.cosine(cosine),.sine(sine),.strobe(strobe)); | |
clockDivider c1(.mainClock(mainClock),.clock(clock)); | |
initial | |
begin | |
angleLatch <= 1'b0; | |
angleCounter <= 10'b0; | |
stateMachineCounter <= 3'b000; | |
end | |
always@(posedge clock) // (mainClock / 256) | |
begin | |
stateMachineCounter <= stateMachineCounter + 1'b1; | |
casez(stateMachineCounter) | |
3'b000: | |
begin | |
angleLatch <= 1'b0; // (clock / 8) | |
angleCounter <= angleCounter + 2'b11; | |
end | |
3'b1??,3'b01?,3'b001: | |
begin | |
angleLatch <= 1'b1; | |
end | |
endcase | |
end | |
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`timescale 1ns / 1ps | |
module test_DDS; | |
// Inputs | |
reg mainClock; | |
// Outputs | |
wire [9:0] cosine; | |
wire [9:0] sine; | |
wire strobe; | |
wire [2:0]stateMachineCounter; | |
wire angleLatch; | |
// Instantiate the Unit Under Test (UUT) | |
DDS uut ( | |
.mainClock(mainClock), | |
.cosine(cosine), | |
.sine(sine), | |
.strobe(strobe), | |
.stateMachineCounter(stateMachineCounter), | |
.angleLatch(angleLatch) | |
); | |
initial begin | |
// Initialize Inputs | |
mainClock = 0; | |
// Wait 100 ns for global reset to finish | |
// Add stimulus here | |
end | |
always | |
begin | |
#5 mainClock = ~mainClock; | |
end | |
endmodule | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment