FPGA应用笔记——除法器

FPGA应用笔记(一)——除法器

0.除法器简介

​ FPGA可以实现几乎所有的数字逻辑和时序,FPGA的速度很快,但是如果在用Verilog HDL编程时,把其加减乘除当作给STM32编程时的加减乘除的话,那就很有可能会被BUG缠绕。单片机编程和计算机编程都是在体系结构层编程,加减乘除还有浮点操作的具体实现都是不用去管的。但是FPGA则是从逻辑层面去编程,乘法(不包括与二的次幂相乘的乘法)和除法的使用都是要谨慎的,因为它在时序逻辑中,占用的时钟周期太多了,就算如果用组合逻辑去实现,那么除法完成时间也是不能忽略不计的。

​ 作为EE专业的学生,总是需要用到FPGA来进行高速信号处理,正好在这段时间来复习一下之前的Verilog HDL编程的知识。由于Verilog HDL从语法上看是一种类C语言,由于笔者有丰富的单片机编程经验,故也对C语言十分熟悉,所以很多语法相关的知识都不需要在文章中回顾。文章主要从编程方法和思路的角度来复习Verilog HDL.本项目基于Vivado 2018.01实现,没有用到FPGA做实物验证(这个行为不大对,但是考虑到本项目的目的,过程就从简了)

1.除法器的设计

1.1 需求分析

​ 我们要设计的是一款8-bit时序整数除法器,输入包括被除数、除数、时间信号和复位信号,得到的结果包括商和余数,以及结果有效信号,其中被除数和除数都是八位并行输入,商和余数也是八位并行输出。

1.2 算法设计

​ 我们可以先研究长除法的过程,从中提炼出除法器的实现算法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hTa6YMWI-1578666313609)(C:\Users\huyunbo\Desktop\学习笔记\FPGA\图1.gif)]

图一 长除法1010÷0011

​ 如图一,对于长除法1010÷0011,我们可以把这个过程分解为这样:

​ 1、先拿0011和0001比较,发现0011大于0001,故上0;

​ 2、再把0011和0010比较,发现依然大于,则还是上0;

​ 3、把0010和0101比较,0010小于0101,故我们在第三位上1,并用0011去减101得到100;

​ 4、再拿0011和0100比较,同3,第四位上1并算出0100-0011,得到的即为余数。

​ 从以上过程中,对于一个N-bit除以N-bit的除法,我们可以归纳出这样的算法:

​ 1、将被除数扩展为2N位记作A,除数也扩展为2N位并左移N位记作B,计数变量cnt = 0;

​ 2、将A左移一位;

​ 3、比较A和B高N位的大小,若[2N-1:N]A>[2N-1:N]B,则令A = A - B + 1。若cnt!=0x0F,则令cnt =

​ cnt+1,并回到第二步,若cnt == 0x0F,则进入第四步;

​ 4、计算结束,A的高N位即为余数,低N位为商。

1.3 时序设计

​ 因为是设计时序电路,所以一定要设计好到:“到了哪个时间节拍,做什么事情。”由于涉及到了算法,所以我们需要一个reg变量state来记录状态,确定什么状态执行什么操作。通过分析1.2中的算法,我们可以分析得到,state需要五种状态:

​ 1、空闲(idle)状态,在rst信号有效以及除数为0(运算无效)的时候处于此状态;

​ 2、初始化(init)状态。在除数或被除数发生变化或者rst失能时,需要重新计算结果,在初始化状态下给A、B重新

​ 赋值。

​ 3、计算状态1(cal1)。执行将A左移的操作;

​ 4、计算状态2(cal2)。执行算法的第三步中断步骤。

​ 5、完成状态(done)。在计算完成后,将结果输出,并使输出有效信号使能。

​ 在此我们使用单热码(single-hot code)来表示这五种状态,即0b00001,0b00010,0b00100,0b01000,

0b10000. 保证有记录状态的寄存器后,后续的编程工作也相对好做了。

2. 基于Verilog HDL的实现

parameter state_init = 4'b0000;
parameter state_idle = 4'b0001;
parameter state_cal1 = 4'b0010;
parameter state_cal2 = 4'b0011;
parameter state_done = 4'b0100;

module divider(clk, rst_n, A,B,C,D,ov);
input clk;
input rst_n;
input [15:0]A;
input [15:0]B;
output [15:0]C;
output [15:0]D;
output ov;
/*寄存器需要初始化*/
reg output_valid = 0;

    reg [31:0] temp_a = 32'b0 ,temp_b = 32'b0;
reg [15:0] bufa = 16'b0,bufb = 16'b0;
reg [15:0] TMPA = 16'b0,TMPB = 16'b0;
reg [4:0]  state = state_idle;
reg [3:0]  cnt = 4'b0000;

assign ov = output_valid;
assign C = temp_a[15:0]  & {16{output_valid}};
assign D = temp_a[31:16] & {16{output_valid}};
    
always@(A or B)
begin
    bufa <= A;
    bufb <= B;
end

always@(posedge clk)
begin
if(rst_n)
begin
    case(state)
    state_idle:
    begin
      if(bufa===TMPA&&bufb===TMPB)
      begin
        state <= state_idle;
      end
      else
      begin
        TMPA <= bufa;
        TMPB <= bufb;
        state <= state_init;
        output_valid <= 0;
      end
    end
    state_init:
    begin
       temp_a[15:0] <= bufa;
       temp_b[31:16] <= bufb;
       state <= state_cal1;
       cnt <= 4'b0;
    end
    state_cal1:
    begin
        temp_a <= temp_a<<1;
        state <= state_cal2;
    end
    
    state_cal2:
    begin
        if(temp_a[31:16]>=temp_b[31:16])
        begin
            temp_a <= temp_a - temp_b + 1;
        end
        if(cnt === 4'b1111)
        begin
            state <= state_done;
        end
        else
        begin
            cnt <= cnt + 1;
            state <= state_cal1;
        end
    end
    state_done:
    begin
        output_valid <= 1;
    end
    default: state <= state_idle;
    endcase
end
else
    output_valid <= 0;
end
endmodule

3. 基于Vivado HLx的仿真结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-96fHZmmt-1578666313611)(C:\Users\huyunbo\Desktop\学习笔记\FPGA\批注 2019-09-13 193156.png)]

如图,Testbench输入: 被除数 A=12,除数B=3.

最后除法器算出了结果:商4余0.

4. 注意事项

1、用时序逻辑实现功能前,先用FSM将过程建模,再去用Verilog实现;

2、每一个寄存器一定都需要在定义的时候初始化!!!不然在仿真时会有玄学问题;

3、仿真结果可以证明用时序逻辑实现除法器效率极低,建议采用组合逻辑或者其它更高效的方式实现除法器。本次项目的目的只是为一个FPGA菜鸟进一步熟悉FSM编程。

  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FPGA自学笔记——设计与验证JMB FPGA(可编程逻辑门阵列)是一种可编程的硬件平台,可以实现各种数字电路的设计与验证。本文将简要介绍使用FPGA自学设计与验证JMB(低功耗、高效能、集成度高的多媒体芯片)的过程。 首先,我们需要了解JMB的功能和特性。JMB是一种面向多媒体应用的芯片,具备低功耗、高效能和高集成度的优势。我们需要详细研究JMB的硬件架构和内部模块,包括处理器核、存储器模块、图像和音频处理模块等。 接下来,我们可以使用FPGA开发板来设计和验证JMB。首先,我们需要熟悉FPGA设计工具,例如Vivado或Quartus等。这些工具提供了图形化界面和硬件描述语言(HDL)等设计方法。我们可以使用HDL编写JMB的功能模块,并将其综合为FPGA可执行的位流文件。 在设计完成后,我们需要验证JMB的功能和性能。我们可以使用仿真工具(例如ModelSim或ISE Simulator)来模拟JMB在不同情况下的行为。通过设计测试程序并运行仿真,我们可以验证JMB的各个模块是否正确地工作,是否满足设计要求。 在验证完成后,我们可以将位流文件下载到FPGA开发板中进行智能芯片的物理实现和测试。通过与外部设备的连接以及相关测试程序的运行,我们可以验证JMB在实际硬件中的功能和性能。 总结起来,学习FPGA设计与验证JMB,我们需要熟悉JMB的硬件架构和内部模块,并使用FPGA开发工具进行设计与验证。通过仿真和物理实现测试,我们可以验证JMB的功能和性能。这些过程需要理论知识和实践经验的结合,希望这些笔记能够给你提供一些参考和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值