FPGA Player

好记性不如烂笔头

导航

乘法器之五(混和式乘法器(Hybrid multiplication))

4)    混和式乘法器(Hybrid multiplication

混合乘法器模式结合了半并行和乘加两种乘法器模式,它有不同的两个输入位流,并且乘以不同的系数。

这种模式在象FFTs这样的有复数乘法应用中非常有用,复数信号通常包含实部和虚部两部份,所以乘法

实现的时候可以分开乘以不同的系数值。每个部份产生的部份积被累加产生最终的结果。

混合乘法器模式中,每个时钟周期里从两组输入数据中依次选取相同的位数拼接起来,送到到RAM块的

地址端口,低位先送。比如RAM块的地址端口只有四位时,那么从每个输入数据中依次选取2位来计算,

直到输入数据的所有位都被送入RAM块地址端口。这样,一个16位输入总线共需要八个时钟周期送入到

存储器。RAM块每个时钟周期的输出为特定一组输入位和系数的乘积之和。

图19显示了一个用RAM LUT实现两个16位输入,以及最高到15位的常系数的例子,两个输入分别标记为

“Input I”和“Input Q”。根据权位每个时钟周期移位累加从RAM块得到的部份积,一共要11个时钟

(其中八个时钟周期用于将输入数据移入到RAM块,外加三个时钟周期的流水延时)来完成乘法操作。

每次部份积的移位累加会增加两位。最后一次(也就是第八次)部份积累加后,乘法器产生一个32位输出。

输入数据的宽度决定了乘法器的输出位宽以及乘法器的延时。

 

图19中的例子是两个16位输入数据。虽然M512 RAM块可以配置成32X18位,能有5位地址(2^5=32),

但每次每个输入要同时送入相同的位数,故最多一次接收两位(总共是四位)。这个例子中,如果使用相同

的存储器块,输入的位宽决定着乘法器的输出位宽以及乘法器的延时。增加M512块的使用数目或者换成使

用更大的存储器块比如M4K RAM,就可以有效减小乘法器的延时,并且支持更大的系数位宽。

图20显示的是基于图19种例子的仿真结果。例子中有可选的流水级,两个乘数Iuput_I和Input_Q的值分

别是300和55,系数Ci和Cq的值分别是10和25。这样,乘法的结果是:

(Input_I X Ci)+ (Input_Q X Cq) = (300 X 10) + (55 X 25) = 4375

提醒:设计者可以选择减少流水的级数,不过如此会减小设计结果的Fmax

 表28和表29显示了分别用StratixII和Stratix器件实现两个16位输入、15位常系数混合乘法器例子的结果。

 

表29 用Stratix器件实现双输入、15位常系数混合乘法器的结果

 

表30和表31显示了分别用StratixII和Stratix器件实现15位变系数混合乘法器例子的结果。

自己写的程序,希望大家多多指教:

module mul_test
  #(parameter WIDTH = 18,
   WIDTHAD = 4)
    (input clk,
  input sclr,
  input sload_data,
  input[15:0] input_i,/*输入信号I*/
  input[15:0] input_q,/*输入信号Q*/
  output[31:0] result,
  output result_valid);
reg [31:0] result_r;
reg[17:0] rom_out;
reg[3:0] rom_add;
reg [15:0] input_i_r, input_q_r;
reg result_valid_r;
reg[5:1] i;

always@(posedge clk or negedge sclr)
begin
if(sclr == 0)
 begin
  result_r <= 32'd0;
  i <= 5'd0;
  input_i_r <= 16'd0;
  input_q_r <= 16'd0;
  rom_add <= 4'd0;
 end
else
 begin
  if(sload_data == 1)/*用来启动乘法器,先把输入数据固定起来*/
  begin
   i <= 5'd0;
   input_i_r <= input_i;
   input_q_r<= input_q;
   result_r <= 32'd0;
   rom_add <= 4'd0;
  end
 else
  begin
   
      rom_add <= {input_i_r[i+1],input_i_r[i],input_q_r[i+1],input_q_r[i]};
      
   i <= i + 5'd2;
     if(i == 5'd20)
     i <= 5'd0;
     if(i >= 6)/*此时才真正把ROM中的数据读出来*/
   result_r <= result_r + ({14'd0,rom_out} << i-6);/*累加过程*/
  end
 end
end
always@(posedge clk )
begin
 if(i == 5'd20)
 begin
   result_valid_r <= 1'b1;/*当最终结果输出时为1*/
  
  end
   
 else
  result_valid_r <= 1'b0;
end
lpm_rom rom1
(.address(rom_add), .inclock(clk), .outclock(clk), .q(rom_out));
defparam rom1.lpm_width = WIDTH;
defparam rom1.lpm_widthad = WIDTHAD;
defparam rom1.lpm_file = "mul_rom.mif";
assign result = result_r;
assign result_valid = result_valid_r;
endmodule

 

从上面仿真可以看出当i为6时rom_out才有输出所以会有 result_r <= result_r + ({14'd0,rom_out} << i-6);

本例中,input_i和input_q分别乘的系数为10和25,有65535X10+1X25 = 655375;

posted on 2012-08-15 16:45  中国的孩子  阅读(1101)  评论(0编辑  收藏  举报