Cordic算法的FPGA实现(附代码)

FPGA新手,请多多指教
原理啥的就懒得说了,我看的是这个网页,比较详细
https://www.cnblogs.com/ninghechuan/p/8681006.html?utm_source=tuicool&utm

控制模块

module control(
    input [6:0]target,
	 input rst,
	 input clk,
	 input signed [26:0] xi,
	 input signed [26:0] yi,
	 input triggle,
	 
	 output reg [3:0] cnt,
	 output reg [26:0] cos_result,
    output reg signed [26:0] sin_result,
	 output reg [26:0]target_angle,
	 output reg cnt_start
	 );

reg [2:0] state;

parameter idle=3'b001;
parameter calculation=3'b010;
parameter finish=3'b100;


		always@(posedge rst or posedge clk)
			if(rst) begin
				state<=idle;
				target_angle<=0;
				cnt_start<=0;
				cos_result<=0;
				sin_result<=0;
				end
			else begin
					case(state)
						idle:begin 
								if(triggle) begin
									state<=calculation;
									target_angle<=(target<<<20);
									cnt_start<=1;
									end
								else begin
										state<=idle;
										cnt_start<=0;
									end
								end
							
						calculation:begin 
									if(cnt==15) begin 
										state<=finish;
										cnt_start<=0;
										end
									else begin
										state<=calculation;
										cnt_start<=1;
										end
								end
								
						finish:begin 
								state<=idle;
								cos_result<=xi;
								sin_result<=yi;
								end
							default:state<=idle;
						endcase
					end
					
		always@(posedge rst or posedge clk)
			if(rst) begin cnt<=0;
			end 
			else if(cnt_start) cnt<=cnt+1;
			else if(cnt==15) cnt<=0;
			else cnt<=cnt;

endmodule

计算模块

module calculation(
	input rst,
	input clk,
	input [26:0] target_angle,
	input [3:0] cnt,
	input cnt_start,
	
	output reg [26:0]xi,
	output reg [26:0]yi
    );

reg [26:0] theta;

parameter x=27'b000000010011011011101010101 ;//cos之积
parameter y=27'b000000000000000000000000000;
parameter theta0=27'b010110100000000000000000000;//
parameter theta1=27'b001101010010000101001110011;//
parameter theta2=27'b000111000001001010001110100;//
parameter theta3=27'b000011100100000000000010001;//
parameter theta4=27'b000001110010011100010101010;//
parameter theta5=27'b000000111001010001101111001;//
parameter theta6=27'b000000011100101001010100010;//
parameter theta7=27'b000000001110010100101101101;//
parameter theta8=27'b000000000111001010010111010;//
parameter theta9=27'b000000000011100101001011110;//
parameter theta10=27'b000000000001110010100101111;//
parameter theta11=27'b000000000000111001010010111;//
parameter theta12=27'b000000000000011100101001100;//
parameter theta13=27'b000000000000001110010100110;//
parameter theta14=27'b000000000000000111001010011;//
parameter theta15=27'b000000000000000011100101001;//


	always@(posedge rst or posedge clk)
		if(rst) begin
				theta<=0;
				xi<=x;
				yi<=y;
			end
		else
			begin case(cnt)
				0:begin if(cnt_start==0) begin 
									theta<=theta; 
									xi<=xi;
									yi<=yi;
								end
					else if(target_angle<=theta) 
								begin
									theta<=theta-theta0;
									xi<=xi+yi;
									yi<=yi-xi;
								end
							else begin
									theta<=theta+theta0;
									xi<=xi-yi;
									yi<=yi+xi;
								end
					end
				1:begin if(target_angle<=theta) begin
									theta<=theta-theta1;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta1;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				2:begin if(target_angle<=theta) begin
									theta<=theta-theta2;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta2;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				3:begin if(target_angle<=theta) begin
									theta<=theta-theta3;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta3;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				4:begin if(target_angle<=theta) begin
									theta<=theta-theta4;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta4;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				5:begin if(target_angle<=theta) begin
									theta<=theta-theta5;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta5;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				6:begin if(target_angle<=theta) begin
									theta<=theta-theta6;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta6;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				7:begin if(target_angle<=theta) begin
									theta<=theta-theta7;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta7;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				8:begin if(target_angle<=theta) begin
									theta<=theta-theta8;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta8;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				9:begin if(target_angle<=theta) begin
									theta<=theta-theta9;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta9;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				10:begin if(target_angle<=theta) begin
									theta<=theta-theta10;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta10;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				11:begin if(target_angle<=theta) begin
									theta<=theta-theta11;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta11;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				12:begin if(target_angle<=theta) begin
									theta<=theta-theta12;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta12;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				13:begin if(target_angle<=theta) begin
									theta<=theta-theta13;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta13;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				14:begin if(target_angle<=theta) begin
									theta<=theta-theta14;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta14;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				15:begin if(target_angle<=theta) begin
									theta<=theta-theta15;
									xi<=xi+(yi>>>cnt);
									yi<=yi-(xi>>>cnt);
									end
							else begin
								theta<=theta+theta15;
								xi<=xi-(yi>>>cnt);
								yi<=yi+(xi>>>cnt);
								end
					end
				default:;
			endcase
		end
		

endmodule

至于顶层文件,很简单就不贴了
仿真结果除以1048576,也就是2^20就得到了我们想要的结果

你可能感兴趣的:(FPGA)