我做一个CORDIC算法产生正弦波的程序,用Q2编写,但是modelsim能仿真出来正弦波波形,但是signaltap抓的波形是上下相反的,一直找不到原因,希望高手能帮帮忙,谢谢啦!
下面是我的程序:
module NCO(clk,rst_n,ena,fre_chtr,pha_chtr,sin_out_r,cos_out_r,eps_out,da_clk,da_mode);
parameter DATA_WIDTH=28;
input clk;
input rst_n;
input ena;
input [DATA_WIDTH-1:0] fre_chtr;
input [DATA_WIDTH-1:0] pha_chtr;
output [9:0] sin_out_r;
output [9:0] cos_out_r;
output [DATA_WIDTH-1:0] eps_out;
output da_clk; //D/A时钟
output da_mode; //D/A数据模式选择
wire [DATA_WIDTH-1:0] cos_out;
wire [DATA_WIDTH-1:0] sin_out;
reg [DATA_WIDTH-1:0] phase_in;
reg [DATA_WIDTH-1:0] fre_chtr_reg;
assign da_mode = 1'b0; //D/A数据模式选择以二进制输入
assign da_clk = clk; //D/A时钟输出
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
fre_chtr_reg<=28'd0;
else
if(ena)
begin
fre_chtr_reg<=28'd5368709+fre_chtr_reg; //fre_chtr_reg;
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
phase_in<=28'd0;
else
if(ena)
begin
phase_in<=pha_chtr+fre_chtr_reg;
end
end
sincos u(.clk(clk),.rst_n(rst_n),.ena(ena),.phase_in(phase_in),.sin_out(sin_out),.cos_out(cos_out),.eps(eps_out));
assign sin_out_r=sin_out[27:18];
assign cos_out_r=cos_out[27:18];
endmodule
此帖出自
小平头技术问答
附件上面的图就是signaltap抓到的图形。
还有算法实现程序在下面:
module sincos(clk,rst_n,ena,phase_in,sin_out,cos_out,eps);
parameter DATA_WIDTH=28;
parameter PIPELINE=28;
input clk,rst_n,ena;
input [DATA_WIDTH-1:0] phase_in;
output [DATA_WIDTH-1:0] sin_out,cos_out,eps;
reg [DATA_WIDTH-1:0] sin_out,cos_out,eps;
reg [DATA_WIDTH-1:0] phase_in_reg;
reg [DATA_WIDTH-1:0] x[PIPELINE:0];
reg [DATA_WIDTH-1:0] y[PIPELINE:0];
reg [DATA_WIDTH-1:0] z[PIPELINE:0];
reg [1:0] quadrant[PIPELINE:0];
integer i;
//get real quadrant and map to first_n quadrant
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
phase_in_reg<=28'd0;
else
if(ena)
begin
case(phase_in[27:26])
2'b00:phase_in_reg<=phase_in;
2'b01:phase_in_reg<=phase_in-28'd67108864; //-pi/2
2'b10:phase_in_reg<=phase_in-28'd134217728;
2'b11:phase_in_reg<=phase_in-28'd201326592;
default: ;
endcase
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
x[0]<=28'd0;
y[0]<=28'd0;
z[0]<=28'd0;
end
else
if(ena)
begin
x[0]<=28'd81503715;// 0.60725*2^27
y[0]<=28'd0;
z[0]<=phase_in_reg;
end
end
//level1-level26
//level1
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
x[1]<=28'd0;
y[1]<=28'd0;
z[1]<=28'd0;
end
else
if(ena)
begin
if(z[0][27]==1'b0)
begin
x[1]<=x[0]-y[0];
y[1]<=y[0]+x[0];
z[1]<=z[0]-28'd33554432; //45deg
end
else
begin
x[1]<=x[0]+y[0];
y[1]<=y[0]-x[0];
z[1]<=z[0]+28'd33554432; //45deg
end
end
end
//level2
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
x[2]<=28'd0;
y[2]<=28'd0;
z[2]<=28'd0;
end
else
if(ena)
begin
if(z[1][27]==1'b0)
begin
x[2]<=x[1]-{y[1][DATA_WIDTH-1],y[1][DATA_WIDTH-1:1]};
y[2]<=y[1]+{x[1][DATA_WIDTH-1],x[1][DATA_WIDTH-1:1]};
z[2]<=z[1]-28'd19808338; //26deg
end
else
begin
x[2]<=x[1]+{y[1][DATA_WIDTH-1],y[1][DATA_WIDTH-1:1]};
y[2]<=y[1]-{x[1][DATA_WIDTH-1],x[1][DATA_WIDTH-1:1]};
z[2]<=z[1]+28'd19808338;
end
end
end
//level3
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
x[3]<=28'd0;
y[3]<=28'd0;
z[3]<=28'd0;
end
else
if(ena)
begin
if(z[2][27]==1'b0)
begin
x[3]<=x[2]-{{2{y[2][DATA_WIDTH-1]}},y[2][DATA_WIDTH-1:2]};
y[3]<=y[2]+{{2{x[2][DATA_WIDTH-1]}},x[2][DATA_WIDTH-1:2]};
z[3]<=z[2]-28'd10466181; //14deg
end
else
begin
x[3]<=x[2]+{{2{y[2][DATA_WIDTH-1]}},y[2][DATA_WIDTH-1:2]};
y[3]<=y[2]-{{2{x[2][DATA_WIDTH-1]}},x[2][DATA_WIDTH-1:2]};
z[3]<=z[2]+28'd10466181;
end
end
end
。
。
。
//level26
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
x[26]<=28'd0;
y[26]<=28'd0;
z[26]<=28'd0;
end
else
if(ena)
begin
if(z[25][27]==1'b0)
begin
x[26]<=x[25]-{{25{y[25][DATA_WIDTH-1]}},y[25][DATA_WIDTH-1:25]};
y[26]<=y[25]+{{25{x[25][DATA_WIDTH-1]}},x[25][DATA_WIDTH-1:25]};
z[26]<=z[25]-28'd1; //1deg
end
else
begin
x[26]<=x[25]+{{25{y[25][DATA_WIDTH-1]}},y[25][DATA_WIDTH-1:25]};
y[26]<=y[25]-{{25{x[25][DATA_WIDTH-1]}},x[25][DATA_WIDTH-1:25]};
z[26]<=z[25]+28'd1; //1deg
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
for(i=0;i<PIPELINE;i=i+1)
quadrant<=2'b00;
else
if(ena)
begin
for(i=0;i<PIPELINE;i=i+1)
quadrant[i+1]<=quadrant;
quadrant[0]<=phase_in[27:26];
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
sin_out<=28'd0;
cos_out<=28'd0;
eps<=28'd0;
end
else
if(ena)
case(quadrant[27])
2'b00:begin
sin_out<=y[26];
cos_out<=x[26];
eps<=z[26];
end
2'b01:begin
sin_out<=x[26];
cos_out<=~y[26]+1'b1;
eps<=z[26];
end
2'b10:begin
sin_out<=~y[26]+1'b1;
cos_out<=~x[26]+1'b1;
eps<=z[26];
end
2'b11:begin
sin_out<=~x[26]+1'b1;
cos_out<=y[26];
eps<=z[26];
end
endcase
end
endmodule
中间省略了一部分流水线。
希望哪位高手能给我说下问题,万分感谢啊。
一周热门 更多>