模加法器的FPGA实现
2019-04-13 12:33发布
生成海报
模加法器是RNS-DSP设计中最重要的构建模块,它既可以用于加法们也可以通过索引算法用于乘法。模加法器的定义为:
对于两个整数A、B,(A,B∈[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
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮