• 【FPGA数学公式】使用FPGA实现常用数学公式


    公式1:

    C=Z1/30

           由于在FPGA中进行的数据输入是串行的输入,我们需要做这么一个操作,即将输入的数据存入存储器中,然后每输入一个数据,按一个确定,说明数据已经输入,然后将数据存入存储器中,最后将输入的三十个数据从存储器中读取,然后求平均即可。

        由于除以30不是2的幂次方,所以除以30需要做以下的操作。即通过查找的方法将值从ROM中读取,然后实现除以30的操作。或者使用除法IP核,本系统我们采用的方法是除法IP核的方法来实现除以30的算法。

    1. always @(posedge i_clk or posedge i_rst)
    2. begin
    3. if(i_rst)
    4. begin
    5. sums <= 20'd0;
    6. sums1 <= 20'd0;
    7. sums2 <= 20'd0;
    8. sums3 <= 20'd0;
    9. sums4 <= 20'd0;
    10. sums5 <= 20'd0;
    11. sums6 <= 20'd0;
    12. sums7 <= 20'd0;
    13. sums8 <= 20'd0;
    14. sums9 <= 20'd0;
    15. sums10 <= 20'd0;
    16. sums11 <= 20'd0;
    17. sums12 <= 20'd0;
    18. sums13 <= 20'd0;
    19. sums14 <= 20'd0;
    20. sums15 <= 20'd0;
    21. sums16 <= 20'd0;
    22. sumst1 <= 20'd0;
    23. sumst2 <= 20'd0;
    24. sumst3 <= 20'd0;
    25. sumst4 <= 20'd0;
    26. sumst5 <= 20'd0;
    27. sumst6 <= 20'd0;
    28. sumst7 <= 20'd0;
    29. sumst8 <= 20'd0;
    30. sumstt1 <= 20'd0;
    31. sumstt2 <= 20'd0;
    32. sumstt3 <= 20'd0;
    33. sumstt4 <= 20'd0;
    34. sumsttt1 <= 20'd0;
    35. sumsttt2 <= 20'd0;
    36. end
    37. else begin
    38. sums1 <= i_data1 + i_data2;
    39. sums2 <= i_data3 + i_data4;
    40. sums3 <= i_data5 + i_data6;
    41. sums4 <= i_data7 + i_data8;
    42. sums5 <= i_data9 + i_data10;
    43. sums6 <= i_data11 + i_data12;
    44. sums7 <= i_data13 + i_data14;
    45. sums8 <= i_data15 + i_data16;
    46. sums9 <= i_data17 + i_data18;
    47. sums10 <= i_data19 + i_data20;
    48. sums11 <= i_data21 + i_data22;
    49. sums12 <= i_data23 + i_data24;
    50. sums13 <= i_data25 + i_data26;
    51. sums14 <= i_data27 + i_data28;
    52. sums15 <= i_data29;
    53. sums16 <= i_data30;
    54. sumst1 <= sums1 + sums2;
    55. sumst2 <= sums3 + sums4;
    56. sumst3 <= sums5 + sums6;
    57. sumst4 <= sums7 + sums8;
    58. sumst5 <= sums9 + sums10;
    59. sumst6 <= sums11 + sums12;
    60. sumst7 <= sums13 + sums14;
    61. sumst8 <= sums15 + sums16;
    62. sumstt1 <= sumst1 + sumst2;
    63. sumstt2 <= sumst3 + sumst4;
    64. sumstt3 <= sumst5 + sumst6;
    65. sumstt4 <= sumst7 + sumst8;
    66. sumsttt1 <= sumstt1 + sumstt2;
    67. sumsttt2 <= sumstt3 + sumstt4;
    68. sums <= sumsttt1 + sumsttt2;
    69. end
    70. end
    71. divider divider_u(
    72. .clk (i_clk),
    73. .dividend (sums),
    74. .divisor (16'd30),
    75. .quotient (o_average),
    76. .remainder (),
    77. .rfd ()
    78. );

    除法采用IP核实现;其仿真如下所示:

    其标准的运算值为:

    368.886;和我们的仿真值比较接近;

    公式2:

    C=[Σ(A1×B1)/(4×D1)] ×100%

    只要输入的数据为A1,B1,D1,然后通过乘法IP核和除法IP核实现公式的运算结果;

    实现步骤为:

    公式1:A1×B1

    公式2:4×D1

    公式3:[Σ(A1×B1)/(4×D1)]

    公式4:1000*C。得到的结果为%0。

    1. always @(posedge i_clk or posedge i_rst)
    2. begin
    3. if(i_rst)
    4. begin
    5. r1 <= 22'd0;
    6. r2 <= 32'd0;
    7. r3 <= 32'd0;
    8. r4 <= 32'd0;
    9. end
    10. else begin
    11. r1 <= i_A1 * i_B1;
    12. r2 <= 10'd1000 * r1;
    13. r3 <= 16'd4 * i_D1;
    14. r4 <= r3;
    15. end
    16. end
    17. divider2 divider2_u(
    18. .clk (i_clk),
    19. .dividend (r2),
    20. .divisor (r4),
    21. .quotient (o_C),
    22. .remainder (),
    23. .rfd ()
    24. );

    其仿真结果如下所示:

    这里为了计算的精度,我们选择的是千分之一的单位,所以最后的结果C为千分之XX。换算为%只要将结果除以10即可。

    公式3:

    C4=(Z2-Z3)/Z2×100%

        首先计算Z2-Z3;

        然后计算(Z2-Z3)/Z2;

    然后使用除法IP核计算其结果,则可以得到其除法结果如下所示:

        由于这里我们对重量的称取是30个一起称的,所以只要记录30个的总量,然后记录三次,然后计算其中的平均值,则可作为贮藏前的总量值以及计算贮藏后的重量值。

        所以在FPGA中输入的时候,我们需要计算的值需要输入3次,然后在FPGA中对输入的三个值计算其中的平均值。然后得到所要的结果。

    1. always @(posedge i_clk or posedge i_rst)
    2. begin
    3. if(i_rst)
    4. begin
    5. sum1 <= 16'd0;
    6. sum2 <= 16'd0;
    7. end
    8. else begin
    9. sum1 <= i_Z2_1 +i_Z2_2 + i_Z2_3;
    10. sum2 <= i_Z3_1 +i_Z3_2 + i_Z3_3;
    11. end
    12. end
    13. divider3_1 divider3_1_u1(
    14. .clk (i_clk),
    15. .dividend (sum1),
    16. .divisor (16'd3),
    17. .quotient (o_Z2_average),
    18. .remainder (),
    19. .rfd ()
    20. );
    21. divider3_1 divider3_1_u2(
    22. .clk (i_clk),
    23. .dividend (sum2),
    24. .divisor (16'd3),
    25. .quotient (o_Z3_average),
    26. .remainder (),
    27. .rfd ()
    28. );
    29. reg[31:0]r_Z2_average1;
    30. reg[31:0]r_Z2_average2;
    31. reg[15:0]r_Z2_averaget1;
    32. reg[15:0]r_Z2_averaget2;
    33. always @(posedge i_clk or posedge i_rst)
    34. begin
    35. if(i_rst)
    36. begin
    37. r_Z2_average1 <= 32'd0;
    38. r_Z2_average2 <= 32'd0;
    39. r_Z2_averaget1 <= 16'd0;
    40. r_Z2_averaget2 <= 16'd0;
    41. end
    42. else begin
    43. r_Z2_averaget1 <= o_Z2_average - o_Z3_average;
    44. r_Z2_averaget2 <= o_Z2_average;
    45. r_Z2_average1 <= 16'd1000 * r_Z2_averaget1;
    46. r_Z2_average2 <= {16'b0000_0000_0000_0000,r_Z2_averaget2};
    47. end
    48. end
    49. divider3_2 divider3_2_u(
    50. .clk (i_clk),
    51. .dividend (r_Z2_average1),
    52. .divisor (r_Z2_average2),
    53. .quotient (w_C4),
    54. .remainder (),
    55. .rfd ()
    56. );
    57. assign o_C4 = w_C4[15:0];

    仿真

    公式4:

    C=ρV×100/m

    ·设计思路:

        首先计算ρ×V

        然后计算100×ρ×V

        最后计算100×ρ×V/m;

    1. always @(posedge i_clk or posedge i_rst)
    2. begin
    3. if(i_rst)
    4. begin
    5. pv <=22'd0;
    6. pv100 <=32'd0;
    7. m1 <=32'd0;
    8. m2 <=32'd0;
    9. end
    10. else begin
    11. pv <= i_P * i_V;
    12. pv100 <= 10'd1000 * pv;
    13. m1 <= {16'b0000_0000_0000_0000,i_m};
    14. m2 <= m1;
    15. end
    16. end
    17. divider5 divider5_u(
    18. .clk (i_clk),
    19. .dividend (pv100),
    20. .divisor (m2),
    21. .quotient (w_C),
    22. .remainder (),
    23. .rfd ()
    24. );
    25. assign o_C = w_C[15:0];

    ·设计代码和仿真

       

    公式5:

    C=44×(V1-V2) ×M / (W×h)

    ·设计思路:

        需要计算V1-V2;

        然后计算44*(V1-V2)

        然后计算44*(V1-V2)*M

        然后计算W*h

        最后计算44*(V1-V2)*M/(W*h)

    1. always @(posedge i_clk or posedge i_rst)
    2. begin
    3. if(i_rst)
    4. begin
    5. r_V <= 16'd0;
    6. r_V1<= 26'd0;
    7. r_V2<= 32'd0;
    8. wh1 <= 32'd0;
    9. wh2 <= 32'd0;
    10. wh3 <= 32'd0;
    11. end
    12. else begin
    13. r_V <= i_V1 - i_V2;
    14. r_V1<= r_V * i_M;
    15. r_V2<= 6'd44* r_V1;
    16. wh1 <= i_W * i_h;
    17. wh2 <= wh1;
    18. wh3 <= wh2;
    19. end
    20. end
    21. divider5 divider5_u(
    22. .clk (i_clk),
    23. .dividend (r_V2),
    24. .divisor (wh3),
    25. .quotient (w_C),
    26. .remainder (),
    27. .rfd ()
    28. );
    29. assign o_C = w_C[15:0];

    ·设计代码和仿真

    公式6:

    C=0.88 / (V1-V2)

    ·设计思路:

        首先计算V1-V0

        然后计算88*(V1-V0)

        最后计算88*(V1-V0)/100

    1. always @(posedge i_clk or posedge i_rst)
    2. begin
    3. if(i_rst)
    4. begin
    5. r_V <= 16'd0;
    6. r_V1<= 32'd0;
    7. end
    8. else begin
    9. r_V <= i_V1 - i_V0;
    10. r_V1<= 16'd88 * r_V;
    11. end
    12. end
    13. wire[31:0]w_C;
    14. divider5 divider5_u(
    15. .clk (i_clk),
    16. .dividend (r_V1),
    17. .divisor (32'd100),
    18. .quotient (w_C),
    19. .remainder (),
    20. .rfd ()
    21. );
    22. assign o_C = w_C[15:0];

    ·设计代码和仿真

    公式7:

    C=(c×V1×V2×100)/(V0×m)

    ·设计思路:

         首先计算c*V1

         然后计算c*V1*V2

         然后计算100* c*V1*V2

         然后计算V0×m

         最后计算(100* c*V1*V2)/(V0×m);

    1. always @(posedge i_clk or posedge i_rst)
    2. begin
    3. if(i_rst)
    4. begin
    5. r1 <= 16'd0;
    6. r2 <= 16'd0;
    7. r3 <= 32'd0;
    8. r4 <= 32'd0;
    9. r5 <= 32'd0;
    10. r6 <= 32'd0;
    11. end
    12. else begin
    13. r1 <= 8'd100 * i_V1;
    14. r2 <= i_V2 * i_c;
    15. r3 <= r1 * r2;
    16. r4 <= i_V0 * i_m;
    17. r5 <= r4;
    18. r6 <= r5;
    19. end
    20. end
    21. wire[31:0]w_C;
    22. divider5 divider5_u(
    23. .clk (i_clk),
    24. .dividend (r3),
    25. .divisor (r6),
    26. .quotient (w_C),
    27. .remainder (),
    28. .rfd ()
    29. );
    30. assign o_C = w_C[15:0];

    ·设计代码和仿真

    A16-34
     

  • 相关阅读:
    【数据结构】 二叉搜索树的实现
    Java中单例模式
    uni-app 5小时快速入门 2 创建uni-app工程(上)
    再谈String
    Redis存储——这些数据结构原理你都懂吗?
    [附源码]Python计算机毕业设计Djangospringboot作业管理系统
    conda环境下version libcublasLt.so.11 not defined问题解决
    C++ 序容器
    前端框架BootStrap
    SpringBoot是什么?SpringBoot的优缺点有哪些?
  • 原文地址:https://blog.csdn.net/ccsss22/article/details/125509804