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

简介: 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设计,对比普通结构以及乘法器复用结构
313 0
m基于FPGA的半带滤波器verilog设计,对比普通结构以及乘法器复用结构
|
存储 人工智能 BI
数字信号处理-05- FPGA常用运算模块-复数乘法器(二)
数字信号处理-05- FPGA常用运算模块-复数乘法器
760 0
数字信号处理-05- FPGA常用运算模块-复数乘法器(二)
|
异构计算
数字信号处理-05- FPGA常用运算模块-复数乘法器(一)
数字信号处理-05- FPGA常用运算模块-复数乘法器
1057 0
数字信号处理-05- FPGA常用运算模块-复数乘法器(一)
|
存储 IDE 开发工具
数字信号处理-02- FPGA常用运算模块-加减法器和乘法器
数字信号处理-02- FPGA常用运算模块-加减法器和乘法器
1107 0
数字信号处理-02- FPGA常用运算模块-加减法器和乘法器
|
算法
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
290 0
FPGA-阵列乘法器的设计(利用全加器 基于CRA阵列乘法器)
|
8天前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的变步长LMS自适应滤波器verilog实现,包括testbench
### 自适应滤波器仿真与实现简介 本项目基于Vivado2022a实现了变步长LMS自适应滤波器的FPGA设计。通过动态调整步长因子,该滤波器在收敛速度和稳态误差之间取得良好平衡,适用于信道均衡、噪声消除等信号处理应用。Verilog代码展示了关键模块如延迟单元和LMS更新逻辑。仿真结果验证了算法的有效性,具体操作可参考配套视频。
101 74
|
1月前
|
算法 数据安全/隐私保护 异构计算
基于FPGA的16QAM调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本项目基于FPGA实现了16QAM基带通信系统,包括调制、信道仿真、解调及误码率统计模块。通过Vivado2019.2仿真,设置不同SNR(如8dB、12dB),验证了软解调相较于传统16QAM系统的优越性,误码率显著降低。系统采用Verilog语言编写,详细介绍了16QAM软解调的原理及实现步骤,适用于高性能数据传输场景。
143 69
|
1月前
|
移动开发 算法 数据安全/隐私保护
基于FPGA的QPSK调制+软解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的QPSK调制解调系统,通过Vivado 2019.2进行仿真,展示了在不同信噪比(SNR=1dB, 5dB, 10dB)下的仿真效果。与普通QPSK系统相比,该系统的软解调技术显著降低了误码率。文章还详细阐述了QPSK调制的基本原理、信号采样、判决、解调及软解调的实现过程,并提供了Verilog核心程序代码。
70 26
|
6天前
|
存储 编解码 算法
基于FPGA的直接数字频率合成器verilog实现,包含testbench
本项目基于Vivado 2019.2实现DDS算法,提供完整无水印运行效果预览。DDS(直接数字频率合成器)通过数字信号处理技术生成特定频率和相位的正弦波,核心组件包括相位累加器、正弦查找表和DAC。相位累加器在每个时钟周期累加频率控制字,正弦查找表根据相位值输出幅度,DAC将数字信号转换为模拟电压。项目代码包含详细中文注释及操作视频。
|
2月前
|
算法 异构计算
基于FPGA的4ASK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的4-ASK调制解调系统的算法仿真效果、理论基础及Verilog核心程序。仿真在Vivado2019.2环境下进行,分别测试了SNR为20dB、15dB、10dB时的性能。理论部分概述了4-ASK的工作原理,包括调制、解调过程及其数学模型。Verilog代码实现了4-ASK调制器、加性高斯白噪声(AWGN)信道模拟、解调器及误码率计算模块。
74 8

热门文章

最新文章