模加法器的FPGA实现

2019-04-13 12:33发布

模加法器是RNS-DSP设计中最重要的构建模块,它既可以用于加法们也可以通过索引算法用于乘法。模加法器的定义为:
对于两个整数AB,(AB[0,m)进行模m的加法运算定义为
C=m 其中当A+B=m时C=A+B-m m=m 通过verilog语言实现代码如下: //=========================================================
//文件名:  MPX_ADD.v
//功能:   模加法器,用于RNS_DSP
//     output=(x+y)%N
//     0<=x,y //=========================================================
module MPX_ADD
     #(parameter mod_width=7,//N的宽度
          N=125)    //模基数
     (
      clk,rst_n,
      addr1,addr2,
      mod_sum_value
     );
//=========================================================
//端口列表
//=========================================================
input [mod_width-1:0]   addr1,addr2;
input                   clk,rst_n;
output [mod_width-1:0]  mod_sum_value;
//=========================================================
//内部变量声明
//=========================================================
reg  [mod_width-1:0]  N_base=N;
reg  [mod_width-1:0]  mod_sum_value;
reg  [mod_width-1:0]  mod_sum_value_ns;
wire  [mod_width:0]   sum_mid_value=addr1+addr2;
//=========================================================
//逻辑实现
//=========================================================
always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  mod_sum_value<={mod_width{1'b0}};
 else
  mod_sum_value<=mod_sum_value_ns;
end  
always@(*)
begin
 if(sum_mid_value>=N_base)
  mod_sum_value_ns=sum_mid_value-N_base;
 else
  mod_sum_value_ns=sum_mid_value[mod_width-1:0];
end   
endmodule

为提高速度,可采用流水线技术,借鉴模加法器定理: 若C=m,令n取不小于以2为底m的对数的最小整数,,T=2^n-m则有 当A+B+T>=2^n时,C=2^n 否则C=A+B; T为修正量 通过verilog实现代码如下 //=========================================================
//文件名:  MPX_ADD_Pipline.v
//功能:   基于流水线技术模加法器,用于RNS_DSP
//         output=(x+y)%N
//         当addr1+addr2+(2^mod_width-N)有进位时,
//         output为addr1+addr2+(2^mod_width-N)低mod_width位
//         否则结果值位addr1+add2
//         0<=x,y //=========================================================
module MPX_ADD_Pipline
     #(parameter mod_width=7,//N的宽度
          N=125)    //模基数
     (
      clk,rst_n,
      addr1,addr2,
      mod_sum_value
     );
//=========================================================
//端口列表
//=========================================================
input  [mod_width-1:0] addr1,addr2;
input                  clk,rst_n;
output [mod_width-1:0] mod_sum_value;
//=========================================================
//内部变量声明
//=========================================================
reg    [mod_width-1:0] N_base=7'd0-N;
reg    [mod_width:0]  mod_sum_value_r1;
reg    [mod_width:0]  mod_sum_mid_r1;
reg    [mod_width-1:0]  mod_sum_value;
//=========================================================
//逻辑功能实现
//=========================================================
//第一级流水线
always@(posedge clk or negedge rst_n)  //计算addr1+addr2+(2^mod_width-N)
begin
 if(!rst_n)
  mod_sum_value_r1<={mod_width{1'b0}};
 else
  mod_sum_value_r1<=addr1+addr2;
end
always@(posedge clk or negedge rst_n)  //计算addr1+addr2+(2^mod_width-N)
begin
 if(!rst_n)
  mod_sum_mid_r1<={mod_width{1'b0}};
 else
  mod_sum_mid_r1<=addr1+addr2+N_base;
end
//第二级流水线
always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  mod_sum_value<={(mod_width-1){1'b0}};
 else if(mod_sum_value_r1[mod_width]||mod_sum_mid_r1[mod_width])
  mod_sum_value<=mod_sum_mid_r1[mod_width-1:0];
 // else if(mod_sum_mid_r1[mod_width])  //此时已排除addr1+addr2有进位,说明addr1+addr2>N
  // mod_sum_value<=mod_sum_mid_r1[mod_width-1:0]
 else
  mod_sum_value<=mod_sum_value_r1[mod_width-1:0];
end
endmodule