四级流水线的复数乘法器

66 篇文章 23 订阅
58 篇文章 27 订阅

在学习openofdm过程中,看到作者进行复数乘法运算时用了专用的ip,我简单尝试了一下在vivado下进行调用(原作者是在ISE生产复数乘法器并调用),觉得vivado下的复数乘法器应该有BUG,觉得一个复数乘法器是很简单的事,没有必要调用IP,直接自己写一个就好,无非就是处理乘法时候编译器会自动例化内嵌DSP模块。考虑用在数据流处理环境下,就直接写成流水线的处理方式吧。

module complex_multiplier_rtl(

input aclk ,  s_axis_a_tvalid , s_axis_b_tvalid, 
input signed [31:0]  s_axis_a_tdata ,s_axis_b_tdata , 
output reg [63:0]m_axis_dout_tdata ,
output  signed    m_axis_dout_tvalid  );

 //(a+bi)(c+di)=(ac-bd)+(bc+ad)i。
wire valid = s_axis_a_tvalid & s_axis_b_tvalid ; 
reg  [3:0] do_it ; always@ (posedge aclk)  do_it <= {  do_it[2:0], valid } ;
assign m_axis_dout_tvalid = do_it[3] ;

reg  signed [15:0] a ,b,c,d ;
always @ (posedge aclk )  a <= s_axis_a_tdata[31:16] ;
always @ (posedge aclk )  b <= s_axis_a_tdata[15:0] ; //0

always @ (posedge aclk )  c <= s_axis_b_tdata[31:16] ;
always @ (posedge aclk )  d <= s_axis_b_tdata[15:0] ;

reg  signed  [31:0]ac,bd,bc,ad ;
always @ (posedge aclk ) ac <= a * c  ; //1
always @ (posedge aclk ) bd <= b * d  ;
always @ (posedge aclk ) bc <= b * c  ;
always @ (posedge aclk ) ad <= a * d  ;

reg   signed  [31:0] ac_m_bd ,bc_p_ad ;

always @ (posedge aclk ) ac_m_bd <= ac - bd ;//2
always @ (posedge aclk ) bc_p_ad <= bc + ad ;

always @ (posedge aclk ) m_axis_dout_tdata[63:0] <={  ac_m_bd[31:0] ,bc_p_ad[31:0]  } ; //3

endmodule 

数据输入输出接口对应关系如下图:

两个复数 (a+bi)和(c+di)相乘得到结果是(e+fi),其中abcd都是16位的,实例化如下:

wire [15:0] a,b,c,d,e,f ;
complex_multiplier_rtl  abcdef (
  .aclk (aclk ),  
.s_axis_a_tvalid (do_mul), 
.s_axis_b_tvalid (do_mul), 
.s_axis_a_tdata ({a,b}),
.s_axis_b_tdata({c,d}) , 
.m_axis_dout_tdata ({e,f}),
.m_axis_dout_tvalid(valid) 
 );

应用在OPENOFDM替代以前需要用XILINX IP的复数乘法器,下面是仿真波形,得到正确结果。可以看到延迟四个周期。

OK,完活。

在资源足够,时序满足的前提下,可以尝试调整减小周期数为3,甚至尝试为2,注意延迟寄存器抽头要做对应修改。

我的店 TQTT.TAOBAO.COM 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值