微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > CORDIC算法实现FFT Verilog编译正确,怎么得到仿真时序图?

CORDIC算法实现FFT Verilog编译正确,怎么得到仿真时序图?

时间:10-02 整理:3721RD 点击:




//-------------------------------------------------------------
// Designer    : W
// Date        : 2008.12.16
// Discription :Cordic with computation of modulus and angle.
//-------------------------------------------------------------
module fft_cordic( dout_i,
                         dout_q,
                         din_i,
                         din_q,
                         target_ang,
                         clk,
                         rst          );
//parameters definations
parameter    INPUT_WIDTH       =16;//signed fractioanl [1].[15]
parameter    INTERNAL_WIDTH       =17;//signed fractioanl [2].[15]
parameter    OUTPUT_WIDTH         =17;//signed fractioanl [2].[15]
parameter    ANGLE_WIDTH          =32;//signed fractioanl [10].[22]
parameter    ITERATION            =16;//Up to 16 mostly
//cordic angles
parameter atan_inf =
32'b0001011010_0000000000000000000000;
parameter atan_1_1 =
32'b0000101101_0000000000000000000000;
parameter atan_1_2 =
32'b0000011010_1001000010100111001100;
parameter atan_1_4 =
32'b0000001110_0000100101000111010000;
parameter atan_1_8 =
32'b0000000111_0010000000000001000100;
parameter atan_1_16 =
32'b0000000011_1001001110001010101001;
parameter atan_1_32 =
32'b0000000001_1100101000110111100101;
parameter atan_1_64 =
32'b0000000000_1110010100101010000110;
parameter atan_1_128 =
32'b0000000000_0111001010010110110101;
parameter atan_1_256 =
32'b0000000000_0011100101001011101001;
parameter atan_1_512 =
32'b0000000000_0001110010100101110110;
parameter atan_1_1024 =
32'b0000000000_0000111001010010111011;
parameter atan_1_2048 =
32'b0000000000_0000011100101001011101;
parameter atan_1_4096 =
32'b0000000000_0000001110010100101110;
parameter atan_1_8192 =
32'b0000000000_0000000111001010010111;
parameter atan_1_16384 =
32'b0000000000_0000000011100101001011;
parameter atan_1_32768 =
32'b0000000000_0000000001110010100101;
//integers
integer                          stage;
integer                          signext;
//extend output width to avoid overflow
output [(OUTPUT_WIDTH-1):0]           dout_i; //signed fractioanl [2].[15]
output [(OUTPUT_WIDTH-1):0]           dout_q; //signed fractioanl [2].[15]
input  [(INPUT_WIDTH-1):0]            din_i; //signed fractional [1].[15]
input  [(INPUT_WIDTH-1):0]            din_q; //signed fractional [1].[15]
input [(ANGLE_WIDTH-1):0]             target_ang;//signed fractional [10].[22]
input                                 clk; //149MHz in 2C device;166MHz in 3C device
input                                 rst; //active hign reset
//reg
reg    [(INTERNAL_WIDTH-1):0]         din_i_pipe[0:ITERATION];
//register
reg    [(INTERNAL_WIDTH-1):0]         din_q_pipe[0:ITERATION];
//register
reg    [(ANGLE_WIDTH-1):0]            ang_accum[0:ITERATION];
//register
reg    [(INTERNAL_WIDTH-1):0]         x_shift_wire;
//combinational wire
reg    [(INTERNAL_WIDTH-1):0]         y_shift_wire;
//combinational wire
reg    [(ANGLE_WIDTH-1):0]            current_angle; //internal wire
//wire
wire   [(OUTPUT_WIDTH-1):0]           dout_i; //output wire
wire   [(OUTPUT_WIDTH-1):0]           dout_q; //output wire
//extend output width to avoid overflow
assign dout_i = din_i_pipe[ITERATION];//connect the ouput wire to the last interation reg
assign dout_q = din_q_pipe[ITERATION];//connect the ouput wire to the last interation reg
//
always   @(posedge clk or posedge rst)
   if (rst)   //reset all register
      for (stage=0; stage<=ITERATION; stage=stage+1) begin
          din_i_pipe[stage] <= {INTERNAL_WIDTH{1'b0}};
          din_q_pipe[stage] <= {INTERNAL_WIDTH{1'b0}};
          ang_accum[stage] <= {ANGLE_WIDTH{1'b0}};
      end
      
   else begin
      //extend 1-bit to avoid internal result overflow
      din_i_pipe[0] <={din_i[INPUT_WIDTH-1],din_i};
      din_q_pipe[0] <={din_q[INPUT_WIDTH-1],din_q};
      //cordic iterations (45 26.56 14.03 7.12 ... degree rotaions)
      for (stage=1; stage<=ITERATION; stage=stage+1) begin
      //(not generally good practice to mix blocking and non-blocking assignments in same process)
         // define rotaion angle in the current iteration
         case(stage)
         1: current_angle=atan_1_1;
         2: current_angle=atan_1_2;
         3: current_angle=atan_1_4;
         4: current_angle=atan_1_8;
         5: current_angle=atan_1_16;
         6: current_angle=atan_1_32;
         7: current_angle=atan_1_64;
         8: current_angle=atan_1_128;
         9: current_angle=atan_1_256;
         10: current_angle=atan_1_512;
         11: current_angle=atan_1_1024;
         12: current_angle=atan_1_2048;
         13: current_angle=atan_1_4096;
         14: current_angle=atan_1_8192;
         15: current_angle=atan_1_16384;
         16: current_angle=atan_1_32768;
         endcase
         //shift right and reserve the sign
         x_shift_wire = din_i_pipe[stage-1] >> (stage-1);
         y_shift_wire = din_q_pipe[stage-1] >> (stage-1);
         for (signext=(INTERNAL_WIDTH-stage); signext < INTERNAL_WIDTH;signext=signext + 1) begin
         x_shift_wire[signext] = din_i_pipe[stage-1][(INTERNAL_WIDTH-1)];  
         y_shift_wire[signext] = din_q_pipe[stage-1][(INTERNAL_WIDTH-1)];
         end
         //cordic equations
         if (ang_accum[stage-1]>target_ang) begin
             din_i_pipe[stage] <= din_i_pipe[stage-1]-y_shift_wire;
             din_q_pipe[stage] <= din_q_pipe[stage-1]+x_shift_wire;
             ang_accum[stage] <= ang_accum[stage-1] + (~current_angle+{{(ANGLE_WIDTH-1){1'b0}},1'b1} );
         end
         else begin
             din_i_pipe[stage] <= din_i_pipe[stage-1]+y_shift_wire;
             din_q_pipe[stage] <= din_q_pipe[stage-1]-x_shift_wire;
             ang_accum[stage] <= ang_accum[stage-1] + current_angle;
         end
       end//'for' end
   end //'else' end
endmodule

我用的Quartus8.1,所以直接在里面进行编译仿真。程序编译正确,能够在Quartus中生成模块电路图,但是图形仿真有点问题,是不是我在波形文件.vwf中clock,rst设置有问题,还是少设置什么了?还请大神指导一下。
[attach]601272[/attach]

不懂,帮顶!

有输入应该就可以了,把输入的IQ赋值,时钟给了应该就可以计算出来了。自己写个testbench

把输入时钟和输入IQ给激励就有输出了

自己顶一下



    你好,我用的是Quartus8.1,能不能直接仿真出来?刚开始学testbench不知道怎么加激励。
module fft_cordic_tb  ;
parameter OUTPUT_WIDTH  = 17 ;
parameter atan_1_512  = 469366 ;
parameter atan_1_1  = 188743680 ;
parameter atan_1_64  = 3754630 ;
parameter atan_1_2  = 111421900 ;
parameter atan_1_4096  = 58670 ;
parameter ANGLE_WIDTH  = 32 ;
parameter atan_1_8192  = 29335 ;
parameter INPUT_WIDTH  = 16 ;
parameter ITERATION  = 16 ;
parameter atan_1_4  = 58872272 ;
parameter atan_1_256  = 938729 ;
parameter atan_inf  = 377487360 ;
parameter atan_1_32  = 7507429 ;
parameter atan_1_16384  = 14667 ;
parameter atan_1_2048  = 117341 ;
parameter atan_1_1024  = 234683 ;
parameter atan_1_16  = 15000233 ;
parameter atan_1_8  = 29884484 ;
parameter INTERNAL_WIDTH  = 17 ;
parameter atan_1_32768  = 7333 ;
parameter atan_1_128  = 1877429 ;
  reg  [ANGLE_WIDTH-1:0]  target_ang   ;
  wire  [OUTPUT_WIDTH-1:0]  dout_q   ;
  wire  [OUTPUT_WIDTH-1:0]  dout_i   ;
  reg    rst   ;
  reg    clk   ;
  reg  [INPUT_WIDTH-1:0]  din_q   ;
  reg  [INPUT_WIDTH-1:0]  din_i   ;
  fft_cordic    #( OUTPUT_WIDTH , atan_1_512 , atan_1_1 , atan_1_64 , atan_1_2 , atan_1_4096 , ANGLE_WIDTH , atan_1_8192 , INPUT_WIDTH , ITERATION , atan_1_4 , atan_1_256 , atan_inf , atan_1_32 , atan_1_16384 , atan_1_2048 , atan_1_1024 , atan_1_16 , atan_1_8 , INTERNAL_WIDTH , atan_1_32768 , atan_1_128  )
   DUT  (
       .target_ang (target_ang ) ,
      .dout_q (dout_q ) ,
      .dout_i (dout_i ) ,
      .rst (rst ) ,
      .clk (clk ) ,
      .din_q (din_q ) ,
      .din_i (din_i ) );
endmodule
这是生成的testbench但还有些你讲的IQ赋值,时钟不懂怎么加,能不能帮忙看一下。



    我用的Quartusii8.1应该怎么加时钟和激励?上面图形方针是在.vwf直接设置的时钟



    我用的Quartusii8.1,本来想着不用第三方的Modelsim直接方针的,
module fft_cordic_tb  ;
parameter OUTPUT_WIDTH  = 17 ;
parameter atan_1_512  = 469366 ;
parameter atan_1_1  = 188743680 ;
parameter atan_1_64  = 3754630 ;
parameter atan_1_2  = 111421900 ;
parameter atan_1_4096  = 58670 ;
parameter ANGLE_WIDTH  = 32 ;
parameter atan_1_8192  = 29335 ;
parameter INPUT_WIDTH  = 16 ;
parameter ITERATION  = 16 ;
parameter atan_1_4  = 58872272 ;
parameter atan_1_256  = 938729 ;
parameter atan_inf  = 377487360 ;
parameter atan_1_32  = 7507429 ;
parameter atan_1_16384  = 14667 ;
parameter atan_1_2048  = 117341 ;
parameter atan_1_1024  = 234683 ;
parameter atan_1_16  = 15000233 ;
parameter atan_1_8  = 29884484 ;
parameter INTERNAL_WIDTH  = 17 ;
parameter atan_1_32768  = 7333 ;
parameter atan_1_128  = 1877429 ;
  reg  [ANGLE_WIDTH-1:0]  target_ang   ;
  wire  [OUTPUT_WIDTH-1:0]  dout_q   ;
  wire  [OUTPUT_WIDTH-1:0]  dout_i   ;
  reg    rst   ;
  reg    clk   ;
  reg  [INPUT_WIDTH-1:0]  din_q   ;
  reg  [INPUT_WIDTH-1:0]  din_i   ;
  fft_cordic    #( OUTPUT_WIDTH , atan_1_512 , atan_1_1 , atan_1_64 , atan_1_2 , atan_1_4096 , ANGLE_WIDTH , atan_1_8192 , INPUT_WIDTH , ITERATION , atan_1_4 , atan_1_256 , atan_inf , atan_1_32 , atan_1_16384 , atan_1_2048 , atan_1_1024 , atan_1_16 , atan_1_8 , INTERNAL_WIDTH , atan_1_32768 , atan_1_128  )
   DUT  (
       .target_ang (target_ang ) ,
      .dout_q (dout_q ) ,
      .dout_i (dout_i ) ,
      .rst (rst ) ,
      .clk (clk ) ,
      .din_q (din_q ) ,
      .din_i (din_i ) );
endmodule
这是我在Modelsim中生成的testbench,像你说的时钟输入赋值不清楚怎么加,能不能帮忙看一下。

正在做这个。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top