FPGA-设计一个定点乘法器(原码一位乘法器)

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: FPGA-设计一个定点乘法器(原码一位乘法器)

 定点数指小数点在数中的位置是固定不变的,通常有定点整数和定点小数。在对小数点位置作出选择之后,运算中的所有数均应统一为定点整数或定点小数,在运算中不再考虑小数问题。

定点数就是指小数点的位置固定不变,小数点的位置通常有两种约定方式:定点整数(纯整数,小数点在最低有效值位之后 比如:100.)和定点小数(纯小数,小数点在最高有(效数值位之前 比如:.101)。
(1)定义:数据中小数点位置固定不变的数 2)种类:定点整数 
(3)小数点在符号位与有效位之间。 
注:定点数受字长的限制,超出范围会有溢出。

首先着手原码的乘法运算设计


1、原码一位乘法:

根据计算机组成原理书上的算法流程结构可以得出:

迭代的过程入下:

1)取最低位进行判断

2)若最低位的值为1.则将上一步的部分积P与X相加,若最低位为0则不操作

3)右移一位,产生本次部分积

module array_multiplier(clk,rst_n,mul_x,mul_y,res
    );
  input              clk    ;//系统时钟
  input             rst_n   ;//复位信号
  input       [3:0] mul_x  ;//被乘数
  input       [3:0] mul_y  ;//乘数
  output  reg [7:0] res    ;//结果
  reg         [3:0] mul_p  ;//部分积
  reg                c      ;//进位信号
  reg         [3:0] mul_y0 ;//储存乘数
  reg                en     ;//使能信号
  //使能信号模块
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      en<=1'b0;
    end
    else if(mul_x==1'b0||mul_y==1'b0)begin
      en<=1'b0;
    end
    else if(cnt==8'd3)begin
      en<=1'b1;
    end
    else begin
      en<=en;
    end
  end
  //逻辑控制模块(计数)
  reg [7:0] cnt;
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      cnt<=1'b0;
    end
    else if(en==1'b1)begin
      cnt<=8'd0;
    end
    else if(cnt==8'd3)begin
      cnt<=8'd0;
    end
    else begin
      cnt<=cnt+1'b1;
    end
  end
  //逻辑控制模块(加)
  reg con_add_en;
  always@(*)begin
    if(en==1'b1)begin
      con_add_en=1'b1;
    end
    else if(mul_y0[0]==1'b1)begin
      con_add_en=1'b0;
    end 
    else begin
      con_add_en=1'b1;
    end
  end
  //
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      mul_p=1'b0;
      c=1'b0;
      mul_y0=mul_y;
    end
    else if(en==1'b1)begin
      mul_p=mul_p;
      mul_y0=mul_y0;
    end
    else if(con_add_en==1'b0)begin
      {c,mul_p[3:0]}=mul_x[3:0]+{c,mul_p[3:0]};
      {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1;
    end
    else begin
      {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1;
    end
  end
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      res<=1'b0;
    end
    else if(mul_x==1'b0||mul_y==1'b0)begin
      res<=1'b0;
    end
    else if(en==1'b1)begin
      res<={mul_p,mul_y0[3:0]};
    end
    else begin
      res<=res;
    end
  end
endmodule
module array_multiplier(clk,rst_n,mul_x,mul_y,res
    );
  input              clk    ;//系统时钟
  input             rst_n   ;//复位信号
  input       [3:0] mul_x  ;//被乘数
  input       [3:0] mul_y  ;//乘数
  output  reg [7:0] res    ;//结果
  reg         [3:0] mul_p  ;//部分积
  reg                c      ;//进位信号
  reg         [3:0] mul_y0 ;//储存乘数
  reg                en     ;//使能信号
  //使能信号模块
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      en<=1'b0;
    end
    else if(mul_x==1'b0||mul_y==1'b0)begin
      en<=1'b0;
    end
    else if(cnt==8'd3)begin
      en<=1'b1;
    end
    else begin
      en<=en;
    end
  end
  //逻辑控制模块(计数)
  reg [7:0] cnt;
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      cnt<=1'b0;
    end
    else if(en==1'b1)begin
      cnt<=8'd0;
    end
    else if(cnt==8'd3)begin
      cnt<=8'd0;
    end
    else begin
      cnt<=cnt+1'b1;
    end
  end
  //逻辑控制模块(加)
  reg con_add_en;
  always@(*)begin
    if(en==1'b1)begin
      con_add_en=1'b1;
    end
    else if(mul_y0[0]==1'b1)begin
      con_add_en=1'b0;
    end 
    else begin
      con_add_en=1'b1;
    end
  end
  //
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      mul_p=1'b0;
      c=1'b0;
      mul_y0=mul_y;
    end
    else if(en==1'b1)begin
      mul_p=mul_p;
      mul_y0=mul_y0;
    end
    else if(con_add_en==1'b0)begin
      {c,mul_p[3:0]}=mul_x[3:0]+{c,mul_p[3:0]};
      {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1;
    end
    else begin
      {c,mul_p[3:0],mul_y0[3:0]}={c,mul_p[3:0],mul_y0[3:0]}>>1;
    end
  end
  always@(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
      res<=1'b0;
    end
    else if(mul_x==1'b0||mul_y==1'b0)begin
      res<=1'b0;
    end
    else if(en==1'b1)begin
      res<={mul_p,mul_y0[3:0]};
    end
    else begin
      res<=res;
    end
  end
endmodule

仿真测试:(13*11)


image.png

目录
相关文章
|
移动开发 算法 异构计算
m基于FPGA的半带滤波器verilog设计,对比普通结构以及乘法器复用结构
m基于FPGA的半带滤波器verilog设计,对比普通结构以及乘法器复用结构
623 0
m基于FPGA的半带滤波器verilog设计,对比普通结构以及乘法器复用结构
|
存储 人工智能 BI
数字信号处理-05- FPGA常用运算模块-复数乘法器(二)
数字信号处理-05- FPGA常用运算模块-复数乘法器
1263 0
数字信号处理-05- FPGA常用运算模块-复数乘法器(二)
|
异构计算
数字信号处理-05- FPGA常用运算模块-复数乘法器(一)
数字信号处理-05- FPGA常用运算模块-复数乘法器
1800 0
数字信号处理-05- FPGA常用运算模块-复数乘法器(一)
|
存储 IDE 开发工具
数字信号处理-02- FPGA常用运算模块-加减法器和乘法器
数字信号处理-02- FPGA常用运算模块-加减法器和乘法器
2023 0
数字信号处理-02- FPGA常用运算模块-加减法器和乘法器
|
算法
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
710 0
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
|
算法 数据安全/隐私保护 异构计算
基于FPGA的变步长LMS自适应滤波器verilog实现,包括testbench
### 自适应滤波器仿真与实现简介 本项目基于Vivado2022a实现了变步长LMS自适应滤波器的FPGA设计。通过动态调整步长因子,该滤波器在收敛速度和稳态误差之间取得良好平衡,适用于信道均衡、噪声消除等信号处理应用。Verilog代码展示了关键模块如延迟单元和LMS更新逻辑。仿真结果验证了算法的有效性,具体操作可参考配套视频。
656 74
|
算法 数据安全/隐私保护 异构计算
基于FPGA的16QAM调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本项目基于FPGA实现了16QAM基带通信系统,包括调制、信道仿真、解调及误码率统计模块。通过Vivado2019.2仿真,设置不同SNR(如8dB、12dB),验证了软解调相较于传统16QAM系统的优越性,误码率显著降低。系统采用Verilog语言编写,详细介绍了16QAM软解调的原理及实现步骤,适用于高性能数据传输场景。
772 69
|
机器学习/深度学习 算法 数据安全/隐私保护
基于FPGA的SNN脉冲神经网络之LIF神经元verilog实现,包含testbench
本项目展示了 LIF(Leaky Integrate-and-Fire)神经元算法的实现与应用,含无水印运行效果预览。基于 Vivado2019.2 开发,完整代码配有中文注释及操作视频。LIF 模型模拟生物神经元特性,通过积分输入信号并判断膜电位是否达阈值产生脉冲,相较于 Hodgkin-Huxley 模型更简化,适合大规模神经网络模拟。核心程序片段示例,助您快速上手。
|
算法 数据安全/隐私保护 异构计算
基于LSB最低有效位的音频水印嵌入提取算法FPGA实现,包含testbench和MATLAB对比
本项目展示了一种基于FPGA的音频水印算法,采用LSB(最低有效位)技术实现版权保护与数据追踪功能。使用Vivado2019.2和Matlab2022a开发,完整代码含中文注释及操作视频。算法通过修改音频采样点的最低有效位嵌入水印,人耳难以察觉变化。然而,面对滤波或压缩等攻击时,水印提取可能受影响。该项目运行效果无水印干扰,适合实时应用场景,核心逻辑简单高效,时间复杂度低。
|
算法 数据安全/隐私保护 异构计算
基于FPGA的2ASK+帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可设置SNR
本内容展示了基于Vivado2019.2的算法仿真效果,包括设置不同信噪比(SNR=8db和20db)下的结果及整体波形。同时,详细介绍了2ASK调制解调技术的原理与实现,即通过改变载波振幅传输二进制信号,并提供数学公式支持。此外,还涉及帧同步理论,用于确定数据帧起始位置。最后,给出了Verilog核心程序代码,实现了2ASK解调与帧同步功能,结合DDS模块生成载波信号,完成信号处理流程。
319 0

热门文章

最新文章