CORDIC算法基于FPGA的信号发生器设计。

2019-03-25 09:14发布

我做一个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   此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
liucome199
2019-03-25 12:11
< /

附件上面的图就是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

 

中间省略了一部分流水线。

希望哪位高手能给我说下问题,万分感谢啊。

一周热门 更多>