基于国产fpga的关于水声通信ofdm编码

2023-10-15 14:10

本文主要是介绍基于国产fpga的关于水声通信ofdm编码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


一、创建工程及文件

二、发送机主要模块

1、插入导频:虽然利用接收到的段训练序列、长训练序列可以进行信道均衡、频率偏差校正,但符号还会存在一定的剩余偏差,且偏差会随着时间的累积而累积,会造成所有子载波产生一定的相位偏移。因此,还需要不断地对参考相位进行跟踪。这样,就可以将数据经过映射后写进ram里面。

2、hermitian变换

通过共轭对称变换将数据的实部和虚部分开

3、ifft模块

IFFT (Inverse Fast Fourier Transform) 就是快速傅里叶逆变换。其为OFDM技术中的一个实现方式:各个子信道的正交调制和解调可以分别通过采用IDFT(Inverse Discrete Fourier Transform)和DFT实现,在子载波数很大的系统中,可以通过采用IFFT(Inverse Fast Fourier Transform)和FFT实现,随着大规模集成电路技术和DSP技术的发展,IFFT和FFT都是非常容易实现的。

4、添加循环前缀

在水声通信中,信道中存在大量干扰,为降低误码率,在发送机中添加循环前缀,在接收机中去除循环前缀,然后将数据存储在Ram里面,再读取,可以提高数据传输的准确性。

5、16QAM模块

16QAM是指包含16种符号的QAM调制方式。

16QAM 是用两路独立的正交 4ASK 信号叠加而成,4ASK 是用多电平信号去键控载波而得到的信号。它是 2ASK 调制的推广,和 2ASK 相比,这种调制的优点在于信息传输速率高。

16QAM是利用多进制振幅键控(MASK)和正交载波调制相结合产生的。

16QAM 是一种振幅相位联合键控信号。16QAM 的产生有 2 种方法:

(1)正交调幅法,它是有 2 路正交的四电平振幅键控信号叠加而成;

(2)复合相移法:它是用 2 路独立的四相位移相键控信号叠加而成

 主要就是将数据映射到16qam中,再将16qam转化为ofdm编码


三、发送机主要代码

发送机主要代码如下:

module top_tra #(parameter WIDTH = 16) //Q2.14格式,即1位符号位,1位整数位,14位小数位,归一化处理后的结果//小数如何确定?即小数部分*2^14再转为二进制(input clk_10M,input clk_2_5M,input clk_50M,input rst_n,input tra_en,output dout_valid,output _CS,output DOUT,output _LDAC,output SCLK);reg trig_en;reg [8:0] tx_cnt;wire rx_data;wire map_pilot_valid;wire prbs_map_valid;wire pilot_her_valid;wire her_ifft_valid;wire ifft_cp_valid;wire out_flag;wire [5:0] map_pilot_index;wire [5:0] ifft_cp_index;wire [5:0] pilot_her_index;wire [WIDTH-1:0] map_pilot_real;wire [WIDTH-1:0] map_pilot_imag;wire [WIDTH-1:0] pilot_her_real;wire [WIDTH-1:0] pilot_her_imag;wire [WIDTH-1:0] her_ifft_real;wire [WIDTH-1:0] her_ifft_imag;wire [WIDTH-1:0] ifft_cp_real;wire [WIDTH-1:0] ifft_cp_imag;wire [WIDTH-1:0] cp_dac_imag;wire [WIDTH-1:0] cp_dac_real;always@(posedge clk_10M) beginif(!rst_n) begintx_cnt <= 1'b0;endelse beginif(tx_cnt == 319) begintx_cnt <= 1'b0;endelse begintx_cnt <= tx_cnt + 1'b1;endendendalways@(*) beginif(tx_cnt < 192)trig_en = 1'b1;elsetrig_en = 1'b0;endprbs15 prbs( //随机数产生.prbs_clk(clk_10M),.prbs_rst_n(rst_n),.trig_en(trig_en),.prbs15_en(tra_en),.prbs_out(rx_data),.dout_valid(prbs_map_valid));QAM16_MAP map( //qam映射.qam_clk(clk_10M),.din_valid(prbs_map_valid),.qam_din(rx_data),.dout_valid(map_pilot_valid),.qam_dout_imag(map_pilot_imag),.qam_dout_real(map_pilot_real),.qam_rst_n(rst_n),.dout_index(map_pilot_index));Insert_Pilot pilot (//导频.pilot_clk(clk_2_5M),.pilot_rst_n(rst_n),.din_valid(map_pilot_valid),.index(map_pilot_index),.pilot_imag_din(map_pilot_imag),.pilot_real_din(map_pilot_real),.pilot_imag_dout(pilot_her_imag),.pilot_real_dout(pilot_her_real),.dout_valid(pilot_her_valid),.dout_index(pilot_her_index));hermitian her_ins(//厄米特变换.her_clk(clk_2_5M),.her_rst_n(rst_n),.din_valid(pilot_her_valid),.din_index(pilot_her_index),.her_real_din(pilot_her_real),.her_imag_din(pilot_her_imag),.her_real_dout(her_ifft_real),.her_imag_dout(her_ifft_imag),.dout_valid(her_ifft_valid));ifft_clac ifft(//ifft.ifft_clk(clk_2_5M),.ifft_rst_n(rst_n),.din_valid(her_ifft_valid),.ifft_real_din(her_ifft_real),.ifft_imag_din(her_ifft_imag),.dout_valid(ifft_cp_valid),.ifft_real_dout(ifft_cp_real),.ifft_imag_dout(ifft_cp_imag),//.dout_exp(exp),.dout_index(ifft_cp_index));add_cyclic_prefix cp(//添加循环前缀.cp_clk(clk_2_5M),.cp_rst_n(rst_n),.din_valid(ifft_cp_valid),.cp_real_din(ifft_cp_real),.cp_imag_din(ifft_cp_imag),.din_index(ifft_cp_index),.dout_valid(dout_valid),.cp_real_dout(cp_dac_real//cp_real_dout),.cp_imag_dout(cp_imag_dout//cp_dac_imag));PmodDA da(//输出实部数据驱动pmodDA.DATA(cp_dac_real),.DA_drdy(dout_valid),.rst_n(rst_n),.clk(clk_50M),._CS(_CS),.DOUT(DOUT),._LDAC(_LDAC),.SCLK(SCLK));endmodule

2、插入导频模块

//功能插入导频//数据符号(Symbol)个数:48//导频符号个数:4//FFT点数:64//数据位宽:16module Insert_Pilot #(parameter DATAWIDTH = 16)(input pilot_clk, //时钟信号input pilot_rst_n, //复位信号,低有效input [5:0] index, //输入数据计数,index = 0~47input din_valid, //输入数据有效input [DATAWIDTH-1:0] pilot_real_din, //数据实部输入input [DATAWIDTH-1:0] pilot_imag_din, //数据虚部输入output reg [5:0] dout_index,output reg [DATAWIDTH-1:0] pilot_real_dout, //数据实部输出output reg [DATAWIDTH-1:0] pilot_imag_dout, //数据虚部输出output reg dout_valid ); //数据输出有效reg [DATAWIDTH-1:0] re_din_buf; //输入数据实部缓存reg [DATAWIDTH-1:0] im_din_buf; //输入数据虚部缓存reg din_en; //输入使能reg [5:0] index_reg; //输入数据标号reg dout_en; //数据输出使能reg read_en; //双口RAM读使能reg write_en; //双口RAM写使能reg wac; //双口RAM写地址控制reg rac;reg [6:0] write_addr; //双口RAM写地址reg [6:0] read_addr; //双口RAM读地址reg [DATAWIDTH-1:0] ram_real_din; //双口RAM实部输入缓存reg [DATAWIDTH-1:0] ram_imag_din; //双口RAM虚部输入缓存wire [DATAWIDTH-1:0] ram_real_dout; //双口RAM实部输出wire [DATAWIDTH-1:0] ram_imag_dout; //双口RAM虚部输出//为保证模块所有输入信号同步,在模块输入端口为所有信号加1级缓存always@(posedge pilot_clk) beginif(!pilot_rst_n) beginre_din_buf <= 0;im_din_buf <= 0;din_en <= 1'b0;index_reg <= 6'd0;endelse beginif(din_valid) beginre_din_buf <= pilot_real_din;im_din_buf <= pilot_imag_din;din_en <= din_valid;index_reg <= index;endelse beginre_din_buf <= 0;im_din_buf <= 0;din_en <= 1'b0;index_reg <= 6'd0;endendend//写数据模块always@(posedge pilot_clk) beginif(!pilot_rst_n) beginwrite_addr[6:0] <= 0;write_en <= 1'b0;ram_real_din <= 0;ram_imag_din <= 0;wac <= 1'b0;endelse beginif(din_en) beginwrite_addr[6] <= wac; //将wac信号作为RAM写地址缓存的最高位以控制数据写入RAM的不同部分/* if(index_reg <= 6'd4) //wac为0时写入RAM的低64bytes,反之,写入RAM的高64byteswrite_addr[5:0] <= index_reg + 6'd38;else if(index_reg <= 6'd17)write_addr[5:0] <= index_reg + 6'd39;else if(index_reg <= 6'd23)write_addr[5:0] <= index_reg + 6'd40;else if(index_reg <= 6'd29)write_addr[5:0] <= index_reg - 6'd23;else if(index_reg <= 6'd42)write_addr[5:0] <= index_reg - 6'd22;else if(index_reg <= 6'd47)write_addr[5:0] <= index_reg - 6'd21;elsewrite_addr[5:0] <= 0; *///demo中的导频插入代码/*case(index_reg)0,1,2,3,4:write_addr[5:0] <= index_reg + 6'd38;5,6,7,8,9,10,11,12,13,14,15,16,17:write_addr[5:0] <= index_reg + 6'd39;18,19,20,21,22,23:write_addr[5:0] <= index_reg + 6'd40;24,25,26,27,28,29:write_addr[5:0] <= index_reg - 6'd23;30,31,32,33,34,35,36,37,38,39,40,41,42:write_addr[5:0] <= index_reg - 6'd22;43,44,45,46,47:write_addr[5:0] <= index_reg - 6'd21;default:write_addr[5:0] <= 6'd0;endcase *///csdn上的导频代码case(index_reg)0,1,2,3,4:write_addr[5:0] <= index_reg + 6'd6;5,6,7,8,9,10,11,12,13,14,15,16,17:write_addr[5:0] <= index_reg + 6'd7;18,19,20,21,22,23:write_addr[5:0] <= index_reg + 6'd8;24,25,26,27,28,29:write_addr[5:0] <= index_reg + 6'd9;30,31,32,33,34,35,36,37,38,39,40,41,42:write_addr[5:0] <= index_reg + 6'd10;43,44,45,46,47:write_addr[5:0] <= index_reg + 6'd11;default:write_addr[5:0] <= 6'd0;endcasewrite_en <= 1'b1;ram_real_din <= re_din_buf;ram_imag_din <= im_din_buf;if(index_reg==47) begin//read_en <= 1'b1;wac <= ~wac;endelse ;endelse beginwrite_en <= 1'b0;write_addr[5:0] <= 0;ram_real_din <= 0;ram_imag_din <= 0;endendend//读数据模块always@(posedge pilot_clk) beginif(!pilot_rst_n) beginread_en <= 1'b0;dout_en <= 1'b0;rac <= 1'b0;endelse beginif(index_reg==24) beginread_en <= 1'b1;//wac <= ~wac;//dout_en <= 1'b1;endelse ;if(read_addr == 63 || read_addr == 127) begin//if( read_addr == 127)read_en <= 1'b0;//dout_en <= 1'b0;rac <= ~rac;endelse ;if(read_en)dout_en <= 1'b1;elsedout_en <= 1'b0;endend//计数器单元,输出计数信号作为双口RAM的读地址信号always@(posedge pilot_clk) beginif(!pilot_rst_n) beginread_addr[6] <= 0;read_addr <= 0;endelse beginif(read_en) beginread_addr[6] <= rac;read_addr[6:0] <= read_addr[6:0] + 1'b1;endelse ;endend//数据输出模块always@(posedge pilot_clk) beginif(!pilot_rst_n) beginpilot_real_dout <= 0;pilot_imag_dout <= 0;dout_valid <= 1'b0;endelse beginif(dout_en) beginpilot_real_dout <= ram_real_dout;pilot_imag_dout <= ram_imag_dout;dout_valid <= 1'b1;endelse beginpilot_real_dout <= 0;pilot_imag_dout <= 0;dout_valid <= 1'b0;endendend//输出计数模块0-63always@(posedge pilot_clk) beginif(!pilot_rst_n) begindout_index <= 0;endelse beginif(dout_valid) begindout_index <= dout_index + 1'b1;endelse begindout_index <= 0;endendendpilot_ram2part pilot_ram2port_re(.dia(ram_real_din),.addra(write_addr),.cea(write_en),.clka(pilot_clk),.dob(ram_real_dout),.addrb(read_addr),.ceb(read_en),.clkb(pilot_clk));pilot_ram2part pilot_ram2port_im(.dia(ram_imag_din),.addra(write_addr),.cea(write_en),.clka(pilot_clk),.dob(ram_imag_dout),.addrb(read_addr),.ceb(read_en),.clkb(pilot_clk));//调用双口RAM/*pilot_ram2port pilot_ram2port_re (.data ( ram_real_din ),.rdaddress ( read_addr ),.rdclock ( pilot_clk ),.rden ( read_en ),.wraddress ( write_addr ),.wrclock ( pilot_clk ),.wren ( write_en ),.q ( ram_real_dout ));pilot_ram2port pilot_ram2port_im (.data ( ram_imag_din ),.rdaddress ( read_addr ),.rdclock ( pilot_clk ),.rden ( read_en ),.wraddress ( write_addr ),.wrclock ( pilot_clk ),.wren ( write_en ),.q ( ram_imag_dout ));*/endmodule

3、hermitian变换

module hermitian #(parameter WIDTH = 16)(input her_clk,input her_rst_n,input din_valid,input [5:0] din_index,input [WIDTH-1:0] her_real_din,input [WIDTH-1:0] her_imag_din,output reg dout_valid,output reg [WIDTH-1:0] her_real_dout,output reg [WIDTH-1:0] her_imag_dout);reg write_en;reg read_en;reg wctr;reg rctr;reg [6:0] write_addrA;reg [6:0] write_addrB;reg [6:0] read_addr;reg [WIDTH-1:0] ramA_real_din;reg [WIDTH-1:0] ramA_imag_din;wire [WIDTH-1:0] ramA_real_dout;wire [WIDTH-1:0] ramA_imag_dout;reg [WIDTH:0] ramA_real_buf;reg [WIDTH:0] ramA_imag_buf;reg [WIDTH-1:0] ramB_real_din;reg [WIDTH-1:0] ramB_imag_din;wire [WIDTH-1:0] ramB_real_dout;wire [WIDTH-1:0] ramB_imag_dout;reg [WIDTH:0] ramB_real_buf;reg [WIDTH:0] ramB_imag_buf;reg [WIDTH:0] sum_real;reg [WIDTH:0] sum_imag;reg real_reg;reg imag_reg;//reg [5:0] addr_cnt;reg [5:0] dout_index;reg dout_en;//wctr=0,rctr=0分别像RAM中0-63写读数据,wctr=1,rctr=1分别像RAM中64-127写读数据,always@(posedge her_clk) beginif(!her_rst_n) beginwctr <= 0;rctr <= 0;endelse beginif(din_index == 63)wctr <= ~wctr;else ;if(read_addr==63 || read_addr ==127) beginrctr <= ~rctr;endelse ;endend//写地址转换模块always@(posedge her_clk) beginif(!her_rst_n) beginwrite_addrA <= 0;write_addrB <= 0;endelse beginwrite_addrA[6] <= wctr;write_addrB[6] <= wctr;write_addrB[5:0] <= din_index;if(din_index == 0) beginwrite_addrA[5:0] <= din_index;endelse beginwrite_addrA[5:0] <= 64 - din_index;endendend//求数列共轭always@(posedge her_clk) beginif(!her_rst_n) beginwrite_en <= 1'b0;ramA_real_din <= 0;ramA_imag_din <= 0;ramB_real_din <= 0;ramB_imag_din <= 0;endelse beginif(din_valid) beginwrite_en <= 1'b1;ramA_real_din <= her_real_din; //实部相同ramA_imag_din <= ~her_imag_din + 1'b1; //虚部相反ramB_real_din <= her_real_din;ramB_imag_din <= her_imag_din;endelse beginwrite_en <= 1'b0;ramA_real_din <= 0;ramA_imag_din <= 0;ramB_real_din <= 0;ramB_imag_din <= 0;endendend//控制读信号模块always@(posedge her_clk) beginif(!her_rst_n) beginread_en <= 0;endelse beginif(din_index==63) beginread_en <= 1'b1;endelse ;if(read_addr==63 || read_addr ==127) beginread_en <= 1'b0;endelse ;if(read_en)dout_en <= 1'b1;elsedout_en <= 1'b0;endend//求和,除2always@(posedge her_clk) beginif(!her_rst_n) beginher_real_dout <= 0;her_imag_dout <= 0;dout_valid <= 0;endelse beginif(dout_en) beginher_real_dout <= (ramA_real_buf + ramB_real_buf)>>1;her_imag_dout <= (ramA_imag_buf + ramB_imag_buf)>>1;//sum_real <= ramA_real_buf + ramB_real_buf;//sum_imag <= ramA_imag_buf + ramB_imag_buf;her_real_dout <= sum_real[WIDTH:1];her_imag_dout <= sum_imag[WIDTH:1];dout_valid <= 1'b1;endelse beginher_real_dout <= 0;her_imag_dout <= 0;dout_valid <= 0;endendend//64计数模块always@(posedge her_clk) beginif(!her_rst_n) begindout_index <= 0;endelse beginif(dout_valid ) begindout_index<= dout_index + 1'b1;endelse begindout_index <= 0;endendend//读地址模块always@(posedge her_clk) beginif(!her_rst_n) beginread_addr <= 0;endelse beginif(read_en ) beginread_addr[6] <= rctr;read_addr[5:0] <= read_addr[5:0] + 1'b1;endelse beginread_addr[5:0] <= 0;endendend//符号扩展1位,防止求和时溢出导致计算结果错误always@(*) begin//if(!her_rst_n) begin// ramA_real_buf = 0;// ramA_imag_buf = 0;// ramB_real_buf = 0;// ramB_imag_buf = 0;//end//else beginif(dout_en) beginif(ramA_real_dout[15] == 0)ramA_real_buf = {1'b0,ramA_real_dout};elseramA_real_buf = {1'b1,ramA_real_dout};if(ramA_imag_dout[15] == 0)ramA_imag_buf = {1'b0,ramA_imag_dout};elseramA_imag_buf = {1'b1,ramA_imag_dout};if(ramB_real_dout[15] == 0)ramB_real_buf = {1'b0,ramB_real_dout};elseramB_real_buf = {1'b1,ramB_real_dout};if(ramB_imag_dout[15] == 0)ramB_imag_buf = {1'b0,ramB_imag_dout};elseramB_imag_buf = {1'b1,ramB_imag_dout};sum_real = ramA_real_buf + ramB_real_buf;sum_imag = ramA_imag_buf + ramB_imag_buf;endelse beginramA_real_buf = 0;ramA_imag_buf = 0;ramB_real_buf = 0;ramB_imag_buf = 0;sum_real = 0;sum_imag = 0;end//endend//调用128*16双口RAMher_ram2port herA_ram2port_im (.dia ( ramA_imag_din ),.addra ( write_addrA ),.clka ( her_clk ),.cea ( write_en ),.addrb ( read_addr ),.clkb ( her_clk ),.ceb ( read_en ),.dob ( ramA_imag_dout ));her_ram2port herA_ram2port_re (.dia ( ramA_real_din ),.addra ( write_addrA ),.clka ( her_clk ),.cea ( write_en ),.addrb ( read_addr ),.clkb ( her_clk ),.ceb ( read_en ),.dob ( ramA_real_dout ));her_ram2port herB_ram2port_im (.dia ( ramA_imag_din ),.addra ( write_addrB ),.clka ( her_clk ),.cea ( write_en ),.addrb ( read_addr ),.clkb ( her_clk ),.ceb ( read_en ),.dob ( ramB_imag_dout ));her_ram2port herB_ram2port_re (.dia ( ramA_real_din ),.addra ( write_addrB ),.clka ( her_clk ),.cea ( write_en ),.addrb ( read_addr ),.clkb ( her_clk ),.ceb ( read_en ),.dob ( ramB_real_dout ));endmodule

4、流水线设计ifft
 

功能:ifft变换//方法:自己设计的 FFT IP CORE//结构:流水线//定点数数据格式: 字长 16 bit// 符号位 1 bit// 整数位 1 bit// 小数位 14 bitmodule ifft_clac #(parameter WIDTH = 16) (input ifft_clk,input ifft_rst_n,input din_valid,input [WIDTH-1:0] ifft_real_din,input [WIDTH-1:0] ifft_imag_din,//output [5:0] dout_exp,output dout_valid,output reg [5:0] dout_index,output [WIDTH-1:0] ifft_real_dout,output [WIDTH-1:0] ifft_imag_dout);reg [5:0] frame_cnt;reg sink_valid;reg sent_valid;reg [WIDTH-1:0] sink_real;reg [WIDTH-1:0] sink_imag;reg [WIDTH+1:0] sent_real; //18位reg [WIDTH+1:0] sent_imag; //18位wire [WIDTH+1:0] out_real;wire [WIDTH+1:0] out_imag;wire [5:0]oaddr;//wire sink_ready;wire source_ready;wire inverse;wire [1:0] sink_error;//wire sink_sop;//wire sink_eop;//wire source_sop;//wire source_eop;//wire [1:0] source_error;//wire source_valid;//wire source_exp;assign inverse = 1'b1; // '0' => FFT ,'1' => IFFTassign sink_error = 2'b0; //no input errorassign source_ready = 1'b1;//assign sink_sop = (frame_cnt == 0 & sink_valid== 1'b1) ? 1'b1 : 1'b0 ;//assign sink_eop = ( frame_cnt == 63) ? 1'b1 : 1'b0;//输入控制模块always@(posedge ifft_clk) beginif(!ifft_rst_n) beginsink_valid <= 1'b0;sink_real <= 0;sink_imag <= 0;endelse beginif(din_valid) beginsink_valid <= din_valid;sink_real <= ifft_real_din;sink_imag <= ifft_imag_din;sent_valid <= din_valid;endelse beginsink_valid <= 1'b0;sink_real <= 0;sink_imag <= 0;endendend//64计数模块always@(posedge ifft_clk) beginif(!ifft_rst_n) beginframe_cnt <= 1'b0;endelse beginif(sink_valid) beginframe_cnt <= frame_cnt + 1'b1;endelse beginframe_cnt <= 1'b0;endendend//16位转18位always@(posedge ifft_clk) beginif(!ifft_rst_n) beginsent_real <= 18'b0;sent_imag <= 18'b0;endelse beginif(sent_valid) beginsent_real <= {sink_real,2'b0};sent_imag <= {sink_imag,2'b0};endelse beginsent_real <= 18'b0;sent_imag <= 18'b0;endendend//输出计数模块0-63always@(posedge ifft_clk) beginif(!ifft_rst_n) begindout_index <= 0;endelse beginif(dout_valid) begindout_index <= dout_index + 1'b1;endelse begindout_index <= 0;endendend/*always@(posedge ifft_clk) beginif(!ifft_rst_n) beginifft_real_dout <= 0;ifft_imag_dout <= 0;endelse beginif(dout_valid) beginifft_real_dout <= out_real[17:2];ifft_imag_dout <= out_imag[17:2];endelse beginifft_real_dout <= 'b0;ifft_imag_dout <= 'b0;endendend*/assign ifft_real_dout = out_real[17:2];assign ifft_imag_dout = out_imag[17:2];//调用fft ip核/* fft_core ifft_ins(.clk(ifft_clk),.reset_n(ifft_rst_n),.inverse(inverse),.sink_valid(sink_valid),.sink_sop(sink_sop),.sink_eop(sink_eop),.sink_real(sink_real),.sink_imag(sink_imag),.sink_error(sink_error),.source_ready(source_ready),.sink_ready(sink_ready),.source_error(source_error),.source_sop(source_sop),.source_eop(source_eop),.source_valid(dout_valid),.source_exp(),.source_real(ifft_real_dout),//16位.source_imag(ifft_imag_dout));*/FFT_IFFT #(.FFT_IFFT_P(1), // FFT_IFFT_P 1 0,1 0:FFT;1:IFFT.TOTAL_STAGE_P(6), // TOTAL_STAGE_P 6 3~11 FFT/IFFT阶数.DIV_EXP (6), // DIV_EXP TOTAL_STAGE_P 末尾数据处理.MULT_OP_DLY_P(2), // MULT_OP_DLY_P 2 2,6 乘法器运算时延 MULT_WIDTH_P 18 9,18 FFT/IFFT运算数据实部与虚部位宽.MULT_WIDTH_P(18))IFFT(.iclk(ifft_clk),.rst_n(ifft_rst_n),//.FFT_IFFT_inverse(inverse),.ien(sink_valid),.iaddr(frame_cnt),//考虑是否有问题.iReal(sent_real),//18位.iImag(sent_imag),.oen(dout_valid),.oaddr(oaddr),.oReal(out_real),//18位,需要修改.oImag(out_imag)//18位,需要修改);endmodule

四、IO口约束

 

 按照芯片原理图配置好管脚。

完成之后开始编译。

点击HDL2Bit FLow,完成编译。

 


总结

本文主要就是介绍了代码片段及其主要的模块,完整代码放在百度网盘。

链接:https://pan.baidu.com/s/1I-SDn-ZgoLV0jMqSZkW-KA提取码:kbnl

这篇关于基于国产fpga的关于水声通信ofdm编码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/218222

相关文章

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

vue2 组件通信

props + emits props:用于接收父组件传递给子组件的数据。可以定义期望从父组件接收的数据结构和类型。‘子组件不可更改该数据’emits:用于定义组件可以向父组件发出的事件。这允许父组件监听子组件的事件并作出响应。(比如数据更新) props检查属性 属性名类型描述默认值typeFunction指定 prop 应该是什么类型,如 String, Number, Boolean,

form表单提交编码的问题

浏览器在form提交后,会生成一个HTTP的头部信息"content-type",标准规定其形式为Content-type: application/x-www-form-urlencoded; charset=UTF-8        那么我们如果需要修改编码,不使用默认的,那么可以如下这样操作修改编码,来满足需求: hmtl代码:   <meta http-equiv="Conte

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

4-4.Andorid Camera 之简化编码模板(获取摄像头 ID、选择最优预览尺寸)

一、Camera 简化思路 在 Camera 的开发中,其实我们通常只关注打开相机、图像预览和关闭相机,其他的步骤我们不应该花费太多的精力 为此,应该提供一个工具类,它有处理相机的一些基本工具方法,包括获取摄像头 ID、选择最优预览尺寸以及打印相机参数信息 二、Camera 工具类 CameraIdResult.java public class CameraIdResult {