CORDIC算法实现FFT Verilog编译正确,怎么得到仿真时序图?
//-------------------------------------------------------------
// 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,像你说的时钟输入赋值不清楚怎么加,能不能帮忙看一下。
正在做这个。