FPGA数学公式使用FPGA实现常用数学公式
Posted fpga和matlab
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA数学公式使用FPGA实现常用数学公式相关的知识,希望对你有一定的参考价值。
公式1:
C=Z1/30
由于在FPGA中进行的数据输入是串行的输入,我们需要做这么一个操作,即将输入的数据存入存储器中,然后每输入一个数据,按一个确定,说明数据已经输入,然后将数据存入存储器中,最后将输入的三十个数据从存储器中读取,然后求平均即可。
由于除以30不是2的幂次方,所以除以30需要做以下的操作。即通过查找的方法将值从ROM中读取,然后实现除以30的操作。或者使用除法IP核,本系统我们采用的方法是除法IP核的方法来实现除以30的算法。
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
sums <= 20'd0;
sums1 <= 20'd0;
sums2 <= 20'd0;
sums3 <= 20'd0;
sums4 <= 20'd0;
sums5 <= 20'd0;
sums6 <= 20'd0;
sums7 <= 20'd0;
sums8 <= 20'd0;
sums9 <= 20'd0;
sums10 <= 20'd0;
sums11 <= 20'd0;
sums12 <= 20'd0;
sums13 <= 20'd0;
sums14 <= 20'd0;
sums15 <= 20'd0;
sums16 <= 20'd0;
sumst1 <= 20'd0;
sumst2 <= 20'd0;
sumst3 <= 20'd0;
sumst4 <= 20'd0;
sumst5 <= 20'd0;
sumst6 <= 20'd0;
sumst7 <= 20'd0;
sumst8 <= 20'd0;
sumstt1 <= 20'd0;
sumstt2 <= 20'd0;
sumstt3 <= 20'd0;
sumstt4 <= 20'd0;
sumsttt1 <= 20'd0;
sumsttt2 <= 20'd0;
end
else begin
sums1 <= i_data1 + i_data2;
sums2 <= i_data3 + i_data4;
sums3 <= i_data5 + i_data6;
sums4 <= i_data7 + i_data8;
sums5 <= i_data9 + i_data10;
sums6 <= i_data11 + i_data12;
sums7 <= i_data13 + i_data14;
sums8 <= i_data15 + i_data16;
sums9 <= i_data17 + i_data18;
sums10 <= i_data19 + i_data20;
sums11 <= i_data21 + i_data22;
sums12 <= i_data23 + i_data24;
sums13 <= i_data25 + i_data26;
sums14 <= i_data27 + i_data28;
sums15 <= i_data29;
sums16 <= i_data30;
sumst1 <= sums1 + sums2;
sumst2 <= sums3 + sums4;
sumst3 <= sums5 + sums6;
sumst4 <= sums7 + sums8;
sumst5 <= sums9 + sums10;
sumst6 <= sums11 + sums12;
sumst7 <= sums13 + sums14;
sumst8 <= sums15 + sums16;
sumstt1 <= sumst1 + sumst2;
sumstt2 <= sumst3 + sumst4;
sumstt3 <= sumst5 + sumst6;
sumstt4 <= sumst7 + sumst8;
sumsttt1 <= sumstt1 + sumstt2;
sumsttt2 <= sumstt3 + sumstt4;
sums <= sumsttt1 + sumsttt2;
end
end
divider divider_u(
.clk (i_clk),
.dividend (sums),
.divisor (16'd30),
.quotient (o_average),
.remainder (),
.rfd ()
);
除法采用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。
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
r1 <= 22'd0;
r2 <= 32'd0;
r3 <= 32'd0;
r4 <= 32'd0;
end
else begin
r1 <= i_A1 * i_B1;
r2 <= 10'd1000 * r1;
r3 <= 16'd4 * i_D1;
r4 <= r3;
end
end
divider2 divider2_u(
.clk (i_clk),
.dividend (r2),
.divisor (r4),
.quotient (o_C),
.remainder (),
.rfd ()
);
其仿真结果如下所示:
这里为了计算的精度,我们选择的是千分之一的单位,所以最后的结果C为千分之XX。换算为%只要将结果除以10即可。
公式3:
C4=(Z2-Z3)/Z2×100%
首先计算Z2-Z3;
然后计算(Z2-Z3)/Z2;
然后使用除法IP核计算其结果,则可以得到其除法结果如下所示:
由于这里我们对重量的称取是30个一起称的,所以只要记录30个的总量,然后记录三次,然后计算其中的平均值,则可作为贮藏前的总量值以及计算贮藏后的重量值。
所以在FPGA中输入的时候,我们需要计算的值需要输入3次,然后在FPGA中对输入的三个值计算其中的平均值。然后得到所要的结果。
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
sum1 <= 16'd0;
sum2 <= 16'd0;
end
else begin
sum1 <= i_Z2_1 +i_Z2_2 + i_Z2_3;
sum2 <= i_Z3_1 +i_Z3_2 + i_Z3_3;
end
end
divider3_1 divider3_1_u1(
.clk (i_clk),
.dividend (sum1),
.divisor (16'd3),
.quotient (o_Z2_average),
.remainder (),
.rfd ()
);
divider3_1 divider3_1_u2(
.clk (i_clk),
.dividend (sum2),
.divisor (16'd3),
.quotient (o_Z3_average),
.remainder (),
.rfd ()
);
reg[31:0]r_Z2_average1;
reg[31:0]r_Z2_average2;
reg[15:0]r_Z2_averaget1;
reg[15:0]r_Z2_averaget2;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
r_Z2_average1 <= 32'd0;
r_Z2_average2 <= 32'd0;
r_Z2_averaget1 <= 16'd0;
r_Z2_averaget2 <= 16'd0;
end
else begin
r_Z2_averaget1 <= o_Z2_average - o_Z3_average;
r_Z2_averaget2 <= o_Z2_average;
r_Z2_average1 <= 16'd1000 * r_Z2_averaget1;
r_Z2_average2 <= 16'b0000_0000_0000_0000,r_Z2_averaget2;
end
end
divider3_2 divider3_2_u(
.clk (i_clk),
.dividend (r_Z2_average1),
.divisor (r_Z2_average2),
.quotient (w_C4),
.remainder (),
.rfd ()
);
assign o_C4 = w_C4[15:0];
仿真
公式4:
C=ρV×100/m
·设计思路:
首先计算ρ×V
然后计算100×ρ×V
最后计算100×ρ×V/m;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
pv <=22'd0;
pv100 <=32'd0;
m1 <=32'd0;
m2 <=32'd0;
end
else begin
pv <= i_P * i_V;
pv100 <= 10'd1000 * pv;
m1 <= 16'b0000_0000_0000_0000,i_m;
m2 <= m1;
end
end
divider5 divider5_u(
.clk (i_clk),
.dividend (pv100),
.divisor (m2),
.quotient (w_C),
.remainder (),
.rfd ()
);
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)
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
r_V <= 16'd0;
r_V1<= 26'd0;
r_V2<= 32'd0;
wh1 <= 32'd0;
wh2 <= 32'd0;
wh3 <= 32'd0;
end
else begin
r_V <= i_V1 - i_V2;
r_V1<= r_V * i_M;
r_V2<= 6'd44* r_V1;
wh1 <= i_W * i_h;
wh2 <= wh1;
wh3 <= wh2;
end
end
divider5 divider5_u(
.clk (i_clk),
.dividend (r_V2),
.divisor (wh3),
.quotient (w_C),
.remainder (),
.rfd ()
);
assign o_C = w_C[15:0];
·设计代码和仿真
公式6:
C=0.88 / (V1-V2)
·设计思路:
首先计算V1-V0
然后计算88*(V1-V0)
最后计算88*(V1-V0)/100
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
r_V <= 16'd0;
r_V1<= 32'd0;
end
else begin
r_V <= i_V1 - i_V0;
r_V1<= 16'd88 * r_V;
end
end
wire[31:0]w_C;
divider5 divider5_u(
.clk (i_clk),
.dividend (r_V1),
.divisor (32'd100),
.quotient (w_C),
.remainder (),
.rfd ()
);
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);
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
r1 <= 16'd0;
r2 <= 16'd0;
r3 <= 32'd0;
r4 <= 32'd0;
r5 <= 32'd0;
r6 <= 32'd0;
end
else begin
r1 <= 8'd100 * i_V1;
r2 <= i_V2 * i_c;
r3 <= r1 * r2;
r4 <= i_V0 * i_m;
r5 <= r4;
r6 <= r5;
end
end
wire[31:0]w_C;
divider5 divider5_u(
.clk (i_clk),
.dividend (r3),
.divisor (r6),
.quotient (w_C),
.remainder (),
.rfd ()
);
assign o_C = w_C[15:0];
·设计代码和仿真
A16-34
以上是关于FPGA数学公式使用FPGA实现常用数学公式的主要内容,如果未能解决你的问题,请参考以下文章