verilog实现czt变换

Posted 者乎之类的

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了verilog实现czt变换相关的知识,希望对你有一定的参考价值。

没太有心思写具体过程了,仅记录设计(编代码)过程中的几个版本

原理及实现步骤




版本一

刚开始写不太会写,考虑数据流方式进行fft,ifft等操作,数据延迟搞不清,就将数据全部进行加载,类似于将串行数据流并行读入并使用,这样使用时就不用考虑延迟对不准数据使用错误了。
即:

//数据
wire signed [15:0]inputdata_r;  

gen_inputdata u_gen_inputdata(
    .clka(clk_in),
    .addra(inputdata_addr),
    .douta(inputdata_r)
); 

reg signed  [15:0]input_data[0:N-1];   
//装载din和wn   
always@(posedge clk_in or negedge rst_n)begin
	if(!rst_n)begin
		wndata_addr<=0;
		inputdata_addr<=0;
	end 
	else begin
		wndata_addr<=wndata_addr+1'b1;
		inputdata_addr<=inputdata_addr+1'b1;
	end 
end 

wire en_din[0:M-1];
genvar i;
wire [8:0] en_din_o;
assign en_din_o=inputdata_addr-1;
generate for (i=0;i<=M-1;i=i+1)begin:ram_loop
	assign en_din[i]=(en_din_o==i);
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		input_data[i]<=0;
  		input_dataimg[i]<=0;
  		wndatareal[i]<=0;
  		wndataimg[i]<=0;
  	end 
  	else if(en_din[i])begin
  		input_data[i]<=inputdata_r;
  		input_dataimg[i]<=inputdataimg_r;
  		wndatareal[i]<=wndatareal_r;
  		wndataimg[i]<=wndataimg_r;
  	end
  	else begin
  		input_data[i]<=input_data[i];
  		input_dataimg[i]<=input_dataimg[i];
  		wndatareal[i]<=wndatareal[i];
  		wndataimg[i]<=wndataimg[i];
  	end 
end 
end 
endgenerate

整体代码:

module czt(
    input clk_in,
    input rst_n,
    //input signed [15:0]inputdatareal_r,  
    //input signed [15:0]inputdataimg_r, 	 

    output [41:0]czt_datareal,
	output [41:0]czt_dataimg,
	output [42:0]czt_data
	 
    );
    
    
//常数定义
parameter N = 10'd512;     
parameter M = 10'd512;  
parameter L = 11'd1024;  

状态机
//reg [4:0] state=0;   //状态机
//reg [4:0] state_wn=0;   //装载wn
//reg [4:0] state_din=1;   //装载din
//reg [4:0] state_g=2;   //din*wn
//reg [4:0] state_h=3;   //装载h
//reg [4:0] state_fft4g=3;   //gfft运算

//地址
reg [8:0] wndata_addr;
reg [9:0] hdata_addr;
reg [8:0]inputdata_addr;     //输入数据查表地址

//数据
wire signed [15:0]inputdata_r;  
wire signed [15:0]inputdataimg_r; 

wire signed [31:0]wndatareal_r;  
wire signed [31:0]wndataimg_r; 

wire signed [31:0]hdatareal_r;  
wire signed [31:0]hdataimg_r; 


 
reg signed  [15:0]input_data[0:N-1];   
reg signed  [15:0]input_dataimg[0:N-1];   

reg signed [31:0]wndatareal[0:N-1];  
reg signed [31:0]wndataimg[0:N-1];  

reg signed [31:0]hdatareal[0:L-1];  
reg signed [31:0]hdataimg[0:L-1];  

reg signed [48:0]data_g_real[0:L-1];  
reg signed [48:0]data_g_img[0:L-1]; 
    
//装载din和wn   
always@(posedge clk_in or negedge rst_n)begin
	if(!rst_n)begin
		wndata_addr<=0;
		inputdata_addr<=0;
	end 
	else begin
		wndata_addr<=wndata_addr+1'b1;
		inputdata_addr<=inputdata_addr+1'b1;
	end 
end 
wire en_din[0:M-1];
genvar i;
wire [8:0] en_din_o;
assign en_din_o=inputdata_addr-1;
generate for (i=0;i<=M-1;i=i+1)begin:ram_loop
	assign en_din[i]=(en_din_o==i);
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		input_data[i]<=0;
  		input_dataimg[i]<=0;
  		wndatareal[i]<=0;
  		wndataimg[i]<=0;
  	end 
  	else if(en_din[i])begin
  		input_data[i]<=inputdata_r;
  		input_dataimg[i]<=inputdataimg_r;
  		wndatareal[i]<=wndatareal_r;
  		wndataimg[i]<=wndataimg_r;
  	end
  	else begin
  		input_data[i]<=input_data[i];
  		input_dataimg[i]<=input_dataimg[i];
  		wndatareal[i]<=wndatareal[i];
  		wndataimg[i]<=wndataimg[i];
  	end 
end 
end 
endgenerate
            


//装载h
always@(posedge clk_in or negedge rst_n)begin
	if(!rst_n)begin
		hdata_addr<=0;
	end 
	else begin
		hdata_addr<=hdata_addr+1'b1;
	end 
end 
wire en_h[0:L-1];
wire [9:0] en_h_o;
assign en_h_o=hdata_addr-1;
generate for (i=0;i<=L-1;i=i+1)begin:ram_loop_h
	assign en_h[i]=(en_h_o==i);
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		hdatareal[i]<=0;
  		hdataimg[i]<=0;
  	end 
  	else if(en_h[i])begin
  		hdatareal[i]<=hdatareal_r;
  		hdataimg[i]<=hdataimg_r;
  	end
  	else begin
  		hdatareal[i]<=hdatareal[i];
  		hdataimg[i]<=hdataimg[i];
  	end 
end 
end 
endgenerate

//计算din*wn
generate for (i=0;i<=M-1;i=i+1)begin:loop_din_wn
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		data_g_real[i]<=0;
  		data_g_img[i]<=0;
  	end 
  	else begin
  		data_g_real[i]<=input_data[i]*wndatareal[i]-input_dataimg[i]*wndataimg[i];
  		data_g_img[i]<=input_data[i]*wndataimg[i]+input_dataimg[i]*wndatareal[i];
	end 
end 
end
endgenerate
	  		

generate for (i=M;i<=L-1;i=i+1)begin:loop_din_wn1
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		data_g_real[i]<=0;
  		data_g_img[i]<=0;
  	end 
  	else begin
  		data_g_real[i]<=0;
  		data_g_img[i]<=0;
	end 
end 
end
endgenerate


//准备fft1信号


reg start1,start1_r;
wire start;
assign start=start1 && !start1_r;
reg [9:0]fft_cnt;
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		fft_cnt<=0;
  	end
  	else begin
  		fft_cnt<=fft_cnt+1'b1;
  	end 
end 
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		start1<=0;
  	end 
  	else if(fft_cnt==10'd1023)begin
  		start1<=1;
  	end 
  	else begin
  		start1<=start1;
  	end 
end 
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		start1_r<=0;
  	end 
  	else begin
  		start1_r<=start1;
  	end 
end 

  		
  		
  		
  		
  		
  		

wire fwd_inv,fwd_inv_we,fwd_inv_ifft;

reg fwd_inv_we1,fwd_inv_we1_r;
assign fwd_inv=1;
assign fwd_inv_ifft=0;
assign fwd_inv_we=(fwd_inv_we1 && !fwd_inv_we1_r);
always@(posedge clk_in or negedge rst_n)begin
  	if(!rst_n)begin
  		fwd_inv_we1<=1'b0;
  		fwd_inv_we1_r<=1'b0;
  	end 
  	else begin
  		fwd_inv_we1<=1'b1;
  		fwd_inv_we1_r<=fwd_inv_we1;
  	end 
end 


reg signed[31:0]xn_re,xn_im;




always@(posedge clk_in or negedge rst_n)begin
	if(!rst_n)begin
		xn_re<=32'b0;
		xn_im<=32'b0;
	end 
	else begin
		xn_re<=data_g_real[fft_cnt][48:17];
		xn_im<=data_g_img[fft_cnt][48:17];
	end 
end 
    wire rfd;
	wire busy;
	wire edone;
	wire done;
	wire dv;
	wire [9:0] xn_index;
	wire [9:0] xk_index;
	wire signed[42:0] xk_re;
	wire signed[42:0] xk_im;
		
	
		






 
  		
// Instantiate the Unit Under Test (UUT)
	fft1 fft4mul (
		.clk(clk_in), 
		.start(start), 
		.fwd_inv(fwd_inv), 
		.fwd_inv_we(fwd_inv_we), 
		.rfd(rfd), 
		.busy(busy), 
		.edone(edone), 
		.done(done), 
		.dv(dv), 
		.xn_re(xn_re), 
		.xn_im(xn_im), 
		.xn_index(xn_index), 
		.xk_index(xk_index), 
		.xk_re(xk_re), 
		.xk_im(xk_im)
	);




//hfft

    wire rfd1;
	wire busy1;
	wire edone1;
	wire done1;
	wire dv1;
	wire [9:0] xn_index1;
	wire [9:0] xk_index1;
	wire signed[42:0] xk_re1;
	wire signed[42:0] xk_im1;
reg signed[31:0]xn_re1,xn_im1;

always@(posedge clk_in or negedge rst_n)begin
	if(!rst_n)begin
		xn_re1<=32'b0;
		xn_im1<=32'b0;
	end 
	else begin
		xn_re1<=hdatareal[fft_cnt];
		xn_im1<=hdatareal[fft_cnt];
	end 
end 		

fft1 fft4h (
		.clk(clk_in), 
		.start(start), 
		.fwd_inv(fwd_inv), 
		.fwd_inv_we(fwd_inv_we), 
		.rfd(rfd1), 
		.busy(busy1), 
		.edone(edone1), 
		.done(done1), 
		.dv(dv1), 
		.xn_re(xn_re1), 
		.xn_im(xn_im1), 
		.xn_index(xn_index1), 
		.xk_index(xk_index1), 
		.xk_re(xk_re1), 
		.xk_im(xk_im1)
	);



/
//两fft后相乘
reg signed [35:0]q_re_j,q_im_j;
wire signed[16:0] xk_re_j,xk_re1_j,xk_im_j,xk_im1_j;
assign xk_re_j=xk_re[34:18];
assign xk_re1_j=xk_re1[38:22];
assign xk_im_j=xk_im[34:18];
assign xk_im1_j=xk_im1[38:22];

always@(posedge clk_in or negedge rst_n)begin
	if(!rst_n)begin
		q_re_j<=32'b0;
		q_im_j<=32'b0;
	end 
	else begin
		q_re_j<=xk_re_j*xk_re1_j-xk_im_j*xk_im1_j;
		q_im_j<=xk_re_j*xk_im1_j+xk_re1_j*xk_im_j;
	end 
end 
wire signed [31:0]q_re,q_im;
assign q_re=q_re_j[32:1];
assign q_im=q_im_j[32:1];
/
//ifft
    wire rfd2;
	wire busy2;
	wire edone2;
	wire done2;
	wire dv2;
	wire [9:0] xn_index2;
	wire [9:0] xk_index2;
	wire signed[42:0] xk_re2;
	wire signed[42:0] xk_im2;





fft1 ifft (
		.clk(clk_in), 
		.start(edone1), 
		.fwd_inv(fwd_inv_ifft), 
		.fwd_inv_we(fwd_inv_we), 
		.rfd(rfd2), 
		.busy(busy2), 
		.edone(edone2), 
		.done(done2), 
		.dv(dv2), 
		.xn_re(q_re), 
		.xn_im(q_im), 
		.xn_index(xn_index2), 
		.xk_index(xk_index2), 
		.xk_re(xk_re2), 
		.xk_im(xk_im2)
	); 


assign czt_datareal=xk_re2[42]?(~xk_re2+1):xk_re2;
assign czt_dataimg=xk_im2[42]?(~xk_im2+1):xk_im2;
assign czt_data=czt_datareal+czt_dataimg;










            
gen_inputdata u_gen_inputdata(
    .clka(clk_in),
    .addra(inputdata_addr),
    .douta(inputdata_r)
); 
gen_inputdata_img u_gen_inputdata_img(
    .clka(clk_in),
    .addra(inputdata_addr),
    .douta(inputdataimg_r)
); 
gen_wn gen_wn_real(
    .clka(clk_in),
    .addra(wndata_addr),
    .douta(wndatareal_r)
); 

gen_wn_img gen_wn_imag(
    .clka(clk_in),
    .addra(wndata_addr),
    .douta(wndataimg_r)
); 


gen_h gen_h_real(
    .clka(clk_in),
    .addra(hdata_addr),
    .douta(hdatareal_r)
); 

gen_h_img gen_h_imag(
    .clka(clk_in),
    .addra(hdata_addr),
    .Notepad++编辑器——Verilog代码片段直接编译

FPGA小波变换基于FPGA的图像9/7整数小波变换verilog实现

IDCT-FPGA基于FPGA的IDCT变换的verilog实现

基于至简设计法实现的PWM调制verilog

基于FPGA的64点fft变换verilog开发

基于FPGA的OFDM-QPSK链路verilog实现