verilog实现开根号运算代码及仿真
FPGA自学笔记分享 2023-03-22


首先定义端口如下,输入位宽参数化,开根号的结果位宽是输入位宽的一半,余数多保留3位。代码在输入数据有效时进行计算,输出开根号的结果和余数。

module cm_sqrt #( parameter C_DATA_WITH_IN     = 32                 , parameter C_DATA_WITH_OUT    = C_DATA_WITH_IN/2   , parameter C_DATA_WITH_REM    = C_DATA_WITH_OUT+3  )( input wire                         I_sys_clk   , /// 系统时钟 input wire                         I_data_en   , /// 数据有效标志,与数据对齐 input wire [C_DATA_WITH_IN-1:0]    I_data_in   , /// 输入数据 output reg                          O_data_en   , /// 数据有效标志,与数据对齐 output reg  [C_DATA_WITH_OUT-1:0]   O_data_out  , /// 开根号的结果 output reg  [C_DATA_WITH_REM-1:0]   O_data_rem  ); /// 余数

根据开根号原理,首先对最高两位进行判断:

如果是1,取高四位减b100,得到余数为差值,同时开根号的结果赋值为1;

如果是0,直接取高四位得到余数,开根号结果为0;













always @(posedge I_sys_clk) if(I_data_en) if(|I_data_in[C_DATA_WITH_IN-1:C_DATA_WITH_IN-2])       /// 高位是1,取高四位减b100,得到余数 begin S_data_out <= {{(C_DATA_WITH_OUT-1){1'b0}},1'b1}; S_data_rem <= {{(C_DATA_WITH_REM-5){1'b0}},I_data_in[C_DATA_WITH_IN-1:C_DATA_WITH_IN-4]}-3'b100; end else /// 高位是0,直接取高四位得到余数 begin S_data_out <= {{(C_DATA_WITH_OUT-1){1'b0}},1'b0}; S_data_rem <= {{(C_DATA_WITH_REM-5){1'b0}},I_data_in[C_DATA_WITH_IN-1:C_DATA_WITH_IN-4]}; end

然后算下一步的余数是否大于(2a+1),其中a是当前开根号的结果*2,


assign S_data_rem_cut = S_data_rem -  {1'b0,S_data_out[C_DATA_WITH_OUT-1:0],2'b0} - 1'b1;

如果大于,则开根号的结果为1,新的余数为{差值,输入的下两位},否则开根号的结果为0,新的余数为{当前余数,输入的下两位}。











 if(S_data_rem_cut[C_DATA_WITH_REM-1])                   /// 判断是否大于 2*a+1 begin S_data_out <= {S_data_out[C_DATA_WITH_OUT-2:0],1'b0}; S_data_rem <= {S_data_rem[C_DATA_WITH_REM-3:0],S_data_in[C_DATA_WITH_IN-5:C_DATA_WITH_IN-6]}; end else begin S_data_out <= {S_data_out[C_DATA_WITH_OUT-2:0],1'b1}; S_data_rem <= {S_data_rem_cut[C_DATA_WITH_REM-3:0],S_data_in[C_DATA_WITH_IN-5:C_DATA_WITH_IN-6]}; end

循环上述操作即可得到最终开根号的结果。

以上文中的例子详细说明图如下:

1、首先判断高两bit大于1,直接将高4bit减去3‘b100,得到余数为b11;

2、然后判断b11是否大于2a+1(此时a为b10),即b11是否大于101,判断结果为小于101;

3、新的余数变为b1101,开根号的结果为10,判断b1101是否大于2a+1(此时a为b100),即b1101是否大于1001,判断结果大于1001,差值为b100;

4、新的余数变为b10010,开根号的结果为101,判断b10010是否大于2a+1(此时a为b1010),即b10010是否大于b10101,判断结果小于。

5、循环结束,开根号的结果为b1010,余数为b10010。

使用随机数仿真如下,输入为随机数,仿真证明代码功能正常:

详细的视频教程见B站视频:【FPGA设计之verilog实现开根号】 https://www.bilibili.com/video/BV1we4y1U7zW/?share_source=copy_web&vd_source=9736f43bc2eebc284f4fbbe5805247a7


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