verilog实现除法
FPGA自学笔记分享 2023-03-22

对于FPGA来说尽量不要做除法,因为比较消耗资源,可以用截位的方式实现对2的N次方的除法,比如N/2就等于N右移一位。

我们今天来讲使用移位减的方法实现一般的除法操作:

实现流程为:

1、将除数、被除数转换为正数,2、确定符号位;3、被除数从最高位开始取数,与除数比较: 被除数大于等于除数:商为1,余数为差值 被除数小于除数 :商为0,余数不变4、依次向下,直至结束输入数据I_data_ina为被除数,I_data_inb为除数:




input  wire                     I_data_en    , // 输入数据有效标志input  wire [C_DATA_WITH-1:0]   I_data_ina   , // 输入被除数input  wire [C_DATA_WITH-1:0]   I_data_inb   , // 输入除数output reg                      O_data_en    , // 输出数据有效标志

首先对符号位进行判断:




always @(posedge I_sys_clk) if(I_data_en) S_out_flag <= I_data_ina[C_DATA_WITH-1]^I_data_inb[C_DATA_WITH-1] ;

然后将被除数和除数进行取绝对值(这里为了方便做移位减法中的减法操作,将除数置为负数):


















/// 被除数转换为正数always @(posedge I_sys_clk) if(I_data_en) if(I_data_ina[C_DATA_WITH-1]) S_data_ina_abs <= ~I_data_ina + 1; else S_data_ina_abs <= I_data_ina ; else S_data_ina_abs <= (S_data_ina_abs <<1); /// 除数取负值always @(posedge I_sys_clk) if(I_data_en) if(I_data_inb[C_DATA_WITH-1]) S_data_inb_abs <= I_data_inb ; else S_data_inb_abs <= ~I_data_inb + 1;

然后就是循环移位求差值的过程了:






















/// 比较差值assign S_data_cut_temp = S_data_ina_temp + S_data_inb_abs ; /// 循环求差always @(posedge I_sys_clk) if(S_data_en[0]) begin S_data_ina_temp <= {{(C_DATA_WITH-1){1'b0}},S_data_ina_abs[C_DATA_WITH-2]}; S_data_out_temp <= {(C_DATA_WITH){1'b0}}; end else if(S_data_cut_temp[C_DATA_WITH-1]) begin S_data_ina_temp <= {S_data_ina_temp[C_DATA_WITH-2:0],S_data_ina_abs[C_DATA_WITH-2]}; S_data_out_temp <= {S_data_out_temp[C_DATA_WITH-2:0],1'b0}; end else begin S_data_ina_temp <= {S_data_cut_temp[C_DATA_WITH-2:0],S_data_ina_abs[C_DATA_WITH-2]}; S_data_out_temp <= {S_data_out_temp[C_DATA_WITH-2:0],1'b1}; end

代码在数据有效标志来了之后先将被除数的绝对值送入,将商置1,然后判断差值:差值大于等于0时,商为1,余数为差值,差值小于0时,商为0,余数不变。

最后仿真的结果为:



声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • 电源
  • DC
  • AC
  • 稳压
下载排行榜
更多
评测报告
更多
广告