FPGA实现GA基于FPGA的GA优化算法的设计与实现

Posted fpga&matlab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA实现GA基于FPGA的GA优化算法的设计与实现相关的知识,希望对你有一定的参考价值。

`timescale 1ns / 1ps



module GA_tops(
              input i_clk,
              input i_rst,
              input signed[15:0]i_x1,i_x2,i_x3,i_x4,
              output  signed[15:0]o_x1,o_x2,o_x3,o_x4
              );

parameter NUM  = 8;//定义种群数量,8个,FPGA资源消耗为严重,所以种群个数定义8    
parameter ITER = 200;//定义迭代次数


//产生用于交叉和变异的随机序列
reg[15:0]PN1;
reg[15:0]PN2;
always@(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
     begin
     PN1<= 16'b0000_1111_1010_1000;
     PN2<= 16'b0000_0111_0010_1000;
     end
else begin
     PN1<= PN1[14:0],PN1[3]^PN1[5];
     PN2<= PN2[14:0],PN1[1]^PN1[5];
     end
end
wire pc;
wire pe;

assign pc = PN1[15];
assign pe = PN2[15];    





reg[9:0]iter;//定义一个迭代计数器,用来反映GA优化过程的迭代次数

//for i = 1:4
//    Areas =[Areas,[-0.005;0.005]];
//end
//for i = 1:4
//    Areas =[Areas,[-0.005;0.005]];
//end
//for i = 1:4
//    Areas =[Areas,[-0.01;0.01]];
//end
reg[15:0]pep11[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep12[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep13[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep14[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep21[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep22[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep23[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep24[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep31[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep32[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep33[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg[15:0]pep34[NUM:1];//定义种群数量,32个,FPGA资源消耗为严重,所以种群个数定义32
reg finish;
   
reg[31:0]fitness[NUM:1];//定义目标函数   
reg[31:0]err1[NUM:1];//定义目标函数   
reg[31:0]err2[NUM:1];//定义目标函数   
reg[31:0]err3[NUM:1];//定义目标函数   
reg[31:0]err4[NUM:1];//定义目标函数  
     
integer i;
always@(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
     begin
          finish  <= 1'd0;
          for(i=1;i<=NUM;i=i+1)
          begin
                  pep11[i]<=16'd12;
                  pep12[i]<=16'd3;
                  pep13[i]<=16'd5;
                  pep14[i]<=16'd2;
                  pep21[i]<=16'd3;
                  pep22[i]<=16'd77;
                  pep23[i]<=16'd12;
                  pep24[i]<=16'd5;
                  pep31[i]<=16'd32;
                  pep32[i]<=16'd45;
                  pep33[i]<=16'd66;
                  pep34[i]<=16'd12;
          end
     end
else begin
          //开始迭代
          if(iter < ITER)
          begin
               //选择
                  for(i=1;i<=NUM;i=i+1)
                  begin
                  
                          if(fitness[i] > PN1,PN2)//和一个随机数比较
                          begin
                                  pep11[i]<=pep11[i]>>2;
                                  pep12[i]<=pep12[i]>>2;
                                  pep13[i]<=pep13[i]>>2;
                                  pep14[i]<=pep14[i]>>2;
                                  pep21[i]<=pep21[i]>>2;
                                  pep22[i]<=pep22[i]>>2;
                                  pep23[i]<=pep23[i]>>2;
                                  pep24[i]<=pep24[i]>>2;
                                  pep31[i]<=pep31[i]>>2;
                                  pep32[i]<=pep32[i]>>2;
                                  pep33[i]<=pep33[i]>>2;
                                  pep34[i]<=pep34[i]>>2;
                          end
                          else
                          begin
                              pep11[i]<=16'd12;
                              pep12[i]<=16'd3;
                              pep13[i]<=16'd5;
                              pep14[i]<=16'd2;
                              pep21[i]<=16'd3;
                              pep22[i]<=16'd77;
                              pep23[i]<=16'd12;
                              pep24[i]<=16'd5;
                              pep31[i]<=16'd32;
                              pep32[i]<=16'd45;
                              pep33[i]<=16'd66;
                              pep34[i]<=16'd12;
                          end

                  end
               //交叉
                     if(pc == 1'b0)//不交叉
                     begin
                          for(i=1;i<=NUM;i=i+1)
                          begin
                                  pep11[i]<=pep11[i];
                                  pep12[i]<=pep12[i];
                                  pep13[i]<=pep13[i];
                                  pep14[i]<=pep14[i];
                                  pep21[i]<=pep21[i];
                                  pep22[i]<=pep22[i];
                                  pep23[i]<=pep23[i];
                                  pep24[i]<=pep24[i];
                                  pep31[i]<=pep31[i];
                                  pep32[i]<=pep32[i];
                                  pep33[i]<=pep33[i];
                                  pep34[i]<=pep34[i];
                          end
                     end
                     else begin//交叉
                          for(i=1;i<=NUM;i=i+1)
                          begin
                                  pep11[i]<=pep11[i][15],pep11[i][15:1] + pep11[i][15],pep11[NUM+1-i][15:1];
                                  pep12[i]<=pep12[i][15],pep12[i][15:1] + pep12[i][15],pep12[NUM+1-i][15:1];
                                  pep13[i]<=pep13[i][15],pep13[i][15:1] + pep13[i][15],pep13[NUM+1-i][15:1];
                                  pep14[i]<=pep14[i][15],pep14[i][15:1] + pep14[i][15],pep14[NUM+1-i][15:1];
                                  pep21[i]<=pep21[i][15],pep21[i][15:1] + pep21[i][15],pep21[NUM+1-i][15:1];
                                  pep22[i]<=pep22[i][15],pep22[i][15:1] + pep22[i][15],pep22[NUM+1-i][15:1];
                                  pep23[i]<=pep23[i][15],pep23[i][15:1] + pep23[i][15],pep23[NUM+1-i][15:1];
                                  pep24[i]<=pep24[i][15],pep24[i][15:1] + pep24[i][15],pep24[NUM+1-i][15:1];
                                  pep31[i]<=pep31[i][15],pep31[i][15:1] + pep31[i][15],pep31[NUM+1-i][15:1];
                                  pep32[i]<=pep32[i][15],pep32[i][15:1] + pep32[i][15],pep32[NUM+1-i][15:1];
                                  pep33[i]<=pep33[i][15],pep33[i][15:1] + pep33[i][15],pep33[NUM+1-i][15:1];
                                  pep34[i]<=pep34[i][15],pep34[i][15:1] + pep34[i][15],pep34[NUM+1-i][15:1];
                          end
                     end
               //变异
                     if(pc == 1'b1)//变异
                     begin
                          for(i=1;i<=NUM;i=i+1)
                          begin
                                  pep11[i]<=pep11[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep12[i]<=pep12[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep13[i]<=pep13[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep14[i]<=pep14[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep21[i]<=pep21[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep22[i]<=pep22[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep23[i]<=pep23[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep24[i]<=pep24[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep31[i]<=pep31[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep32[i]<=pep32[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep33[i]<=pep33[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                                  pep34[i]<=pep34[i] + PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15],PN2[15:7];
                          end
                     end
                     else begin//不变异
                          for(i=1;i<=NUM;i=i+1)
                          begin
                                  pep11[i]<=pep11[i];//o
                                  pep12[i]<=pep12[i];
                                  pep13[i]<=pep13[i];
                                  pep14[i]<=pep14[i];
                                  pep21[i]<=pep21[i];//g
                                  pep22[i]<=pep22[i];
                                  pep23[i]<=pep23[i];
                                  pep24[i]<=pep24[i];
                                  pep31[i]<=pep31[i];//r
                                  pep32[i]<=pep32[i];
                                  pep33[i]<=pep33[i];
                                  pep34[i]<=pep34[i];
                          end
                     end
          end
     end
end

//标准信号,用来检测GA优化误差
wire signed[15:0]sin1;
wire signed[15:0]sin2;
wire signed[15:0]sin3;
wire signed[15:0]sin4;
stardand_sin stardand_sin_u(
                  .i_clk      (i_clk),
                  .i_rst      (i_rst),
                  .o_x1       (sin1),
                  .o_x2       (sin2),
                  .o_x3       (sin3),
                  .o_x4       (sin4),                  
                  .o_en       (),
                  .o_start    ()
                  ); 


//sin,cos
wire[15:0]m_axis_data_tdata1;
dds_compiler_0 dds_compiler_u1(
  .aclk(i_clk),                                  // input wire aclk
  .aresetn(~i_rst),                            // input wire aresetn
  .s_axis_config_tvalid(1'b1),  // input wire s_axis_config_tvalid
  .s_axis_config_tdata(32'd1000000+pep31[1]),    // input wire [39 : 0] s_axis_config_tdata
  .m_axis_data_tvalid(),      // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata1)        // output wire [15 : 0] m_axis_data_tdata
);

wire signed[7:0]sin1;
wire signed[7:0]cos1;
assign sin1 = m_axis_data_tdata1[15:8];
assign cos1 = m_axis_data_tdata1[7:0];

//sin,cos
wire[15:0]m_axis_data_tdata2;
dds_compiler_0 dds_compiler_u2(
  .aclk(i_clk),                                  // input wire aclk
  .aresetn(~i_rst),                            // input wire aresetn
  .s_axis_config_tvalid(1'b1),  // input wire s_axis_config_tvalid
  .s_axis_config_tdata(32'd1000000+pep32[1]),    // input wire [39 : 0] s_axis_config_tdata
  .m_axis_data_tvalid(),      // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata2)        // output wire [15 : 0] m_axis_data_tdata
);

wire signed[7:0]sin2;
wire signed[7:0]cos2;
assign sin2 = m_axis_data_tdata2[15:8];
assign cos2 = m_axis_data_tdata2[7:0];

//sin,cos
wire[15:0]m_axis_data_tdata3;
dds_compiler_0 dds_compiler_u3(
  .aclk(i_clk),                                  // input wire aclk
  .aresetn(~i_rst),                            // input wire aresetn
  .s_axis_config_tvalid(1'b1),  // input wire s_axis_config_tvalid
  .s_axis_config_tdata(32'd1000000+pep33[1]),    // input wire [39 : 0] s_axis_config_tdata
  .m_axis_data_tvalid(),      // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata3)        // output wire [15 : 0] m_axis_data_tdata
);

wire signed[7:0]sin3;
wire signed[7:0]cos3;
assign sin3 = m_axis_data_tdata3[15:8];
assign cos3 = m_axis_data_tdata3[7:0];

//sin,cos
wire[15:0]m_axis_data_tdata4;
dds_compiler_0 dds_compiler_u4(
  .aclk(i_clk),                                  // input wire aclk
  .aresetn(~i_rst),                            // input wire aresetn
  .s_axis_config_tvalid(1'b1),  // input wire s_axis_config_tvalid
  .s_axis_config_tdata(32'd1000000+pep34[1]),    // input wire [39 : 0] s_axis_config_tdata
  .m_axis_data_tvalid(),      // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata4)        // output wire [15 : 0] m_axis_data_tdata
);






wire signed[7:0]sin4;
wire signed[7:0]cos4;
assign sin4 = m_axis_data_tdata4[15:8];
assign cos4 = m_axis_data_tdata4[7:0];

//计算目标值,根据种群的进化的值计算目标函数结果
reg[31:0]sr1[NUM:1];//定义目标函数   
reg[31:0]sr2[NUM:1];//定义目标函数   
reg[31:0]sr3[NUM:1];//定义目标函数   
reg[31:0]sr4[NUM:1];//定义目标函数  

reg[15:0]x10;//定义目标函数   
reg[15:0]x20;//定义目标函数   
reg[15:0]x30;//定义目标函数   
reg[15:0]x40;//定义目标函数  

always@(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
     begin
          for(i=1;i<=NUM;i=i+1)
          begin
          fitness[i]<=32'd0;
          err1[i]   <=32'd0;
          err2[i]   <=32'd0;
          err3[i]   <=32'd0;
          err4[i]   <=32'd0;
          sr1[i]    <=32'd0;
          sr2[i]    <=32'd0;
          sr3[i]    <=32'd0;
          sr4[i]    <=32'd0;
          end
          
          x10<=16'd0;
          x20<=16'd0;
          x30<=16'd0;
          x40<=16'd0;
     end
else begin
          for(i=1;i<=NUM;i=i+1)
          begin
           x10<=(i_x1-pep11[i])/(1+pep21[i]);
           x20<=(i_x2-pep12[i])/(1+pep22[i]);
           x30<=(i_x3-pep13[i])/(1+pep23[i]);
           x40<=(i_x4-pep14[i])/(1+pep24[i]);
           sr1[i]<=x10*cos1 - (16'h7fff-x10)*sin1;//根号近似减法运算,
           sr2[i]<=x20*cos2 - (16'h7fff-x20)*sin2;
           sr3[i]<=x30*cos3 - (16'h7fff-x30)*sin3;
           sr4[i]<=x40*cos4 - (16'h7fff-x40)*sin4;
          end
 
          for(i=1;i<=NUM;i=i+1)
          begin
           err1[i]<=sin1-sr1[i];
           err2[i]<=sin2-sr2[i];
           err3[i]<=sin3-sr3[i];
           err4[i]<=sin4-sr4[i];
          end

          for(i=1;i<=NUM;i=i+1)
          begin
           fitness[i]<=err1[i]+err2[i]+err3[i]+err4[i];
          end
     end
end


always@(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
     begin
     iter<= 10'd0;
     end
else begin
          if(finish == 1'b1)//完成一次迭代运算,那么finish产生一个1,迭代次数增加1
          iter <= iter+ 10'd1;
          else
          iter <= iter;
     end
end

//选择fitness最优的对应的输出作为校正值
reg[3:0]idx;
always@(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
     begin
     idx<= 4'd0;
     end
else begin
          if(fitness[1] <= fitness[2] & fitness[1] <= fitness[3] &fitness[1] <= fitness[4] &fitness[1] <= fitness[5] &fitness[1] <= fitness[6] &fitness[1] <= fitness[7] &fitness[1] <= fitness[8]) 
          idx<= 4'd1;
          if(fitness[2] <= fitness[1] & fitness[2] <= fitness[3] &fitness[2] <= fitness[4] &fitness[2] <= fitness[5] &fitness[2] <= fitness[6] &fitness[2] <= fitness[7] &fitness[2] <= fitness[8]) 
          idx<= 4'd2;
          if(fitness[3] <= fitness[1] & fitness[3] <= fitness[2] &fitness[3] <= fitness[4] &fitness[3] <= fitness[5] &fitness[3] <= fitness[6] &fitness[3] <= fitness[7] &fitness[3] <= fitness[8]) 
          idx<= 4'd3;
          if(fitness[4] <= fitness[1] & fitness[4] <= fitness[2] &fitness[4] <= fitness[3] &fitness[4] <= fitness[5] &fitness[4] <= fitness[6] &fitness[4] <= fitness[7] &fitness[4] <= fitness[8]) 
          idx<= 4'd4;
          if(fitness[5] <= fitness[1] & fitness[5] <= fitness[2] &fitness[5] <= fitness[3] &fitness[5] <= fitness[4] &fitness[5] <= fitness[6] &fitness[5] <= fitness[7] &fitness[5] <= fitness[8]) 
          idx<= 4'd5;   
          if(fitness[6] <= fitness[1] & fitness[6] <= fitness[2] &fitness[6] <= fitness[3] &fitness[6] <= fitness[4] &fitness[6] <= fitness[5] &fitness[6] <= fitness[7] &fitness[6] <= fitness[8]) 
          idx<= 4'd6;          
          if(fitness[7] <= fitness[1] & fitness[7] <= fitness[2] &fitness[7] <= fitness[3] &fitness[7] <= fitness[4] &fitness[7] <= fitness[5] &fitness[7] <= fitness[6] &fitness[7] <= fitness[8]) 
          idx<= 4'd7;       
          if(fitness[8] <= fitness[1] & fitness[8] <= fitness[2] &fitness[8] <= fitness[3] &fitness[8] <= fitness[4] &fitness[8] <= fitness[5] &fitness[8] <= fitness[6] &fitness[8] <= fitness[7]) 
          idx<= 4'd8; 
     end
end 
    
//优化输出
wire signed[15:0]o1;
wire signed[15:0]o2;
wire signed[15:0]o3;
wire signed[15:0]o4;
wire signed[15:0]g1;
wire signed[15:0]g2;
wire signed[15:0]g3;
wire signed[15:0]g4;
wire signed[15:0]r1;
wire signed[15:0]r2;
wire signed[15:0]r3;
wire signed[15:0]r4;    


assign o1 = pep11[idx];
assign o2 = pep12[idx];
assign o3 = pep13[idx];
assign o4 = pep14[idx];

assign g1 = pep21[idx];
assign g2 = pep22[idx];
assign g3 = pep23[idx];
assign g4 = pep24[idx];    
            

assign r1 = pep31[idx];
assign r2 = pep32[idx];
assign r3 = pep33[idx];
assign r4 = pep34[idx]; 

//%将估计结果通过校正
//x1_0 = (x1b-o_(1))/(1+g_(1));
//x2_0 = (x2b-o_(2))/(1+g_(2));
//x3_0 = (x3b-o_(3))/(1+g_(3));
//x4_0 = (x4b-o_(4))/(1+g_(4));
reg signed[15:0]rr1;
reg signed[15:0]rr2;
reg signed[15:0]rr3;
reg signed[15:0]rr4;
reg signed[15:0]w_x1,w_x2,w_x3,w_x4;
always@(posedge i_clk or posedge i_rst)
begin
     if(i_rst)
     begin
     w_x1<= 16'd0;
     w_x2<= 16'd0;
     w_x3<= 16'd0;
     w_x4<= 16'd0;
     
     rr1<= 16'd0;
     rr2<= 16'd0;
     rr3<= 16'd0;
     rr4<= 16'd0;
     end
else begin
     rr1<= i_x1-o1[15],o1[15],o1[15],o1[15],o1[15],o1[15],o1[15],o1[15],o1[15],o1[15],o1[15],o1[15],o1[15:12];
     rr2<= i_x2-o2[15],o2[15],o2[15],o2[15],o2[15],o2[15],o2[15],o2[15],o2[15],o2[15],o2[15],o2[15],o2[15:12];
     rr3<= i_x3-o3[15],o3[15],o3[15],o3[15],o3[15],o3[15],o3[15],o3[15],o3[15],o3[15],o3[15],o3[15],o3[15:12];
     rr4<= i_x4-o4[15],o4[15],o4[15],o4[15],o4[15],o4[15],o4[15],o4[15],o4[15],o4[15],o4[15],o4[15],o4[15:12];
     //近似计算
     w_x1<= rr1+16'h003f-g1[15],g1[15],g1[15],g1[15],g1[15],g1[15],g1[15],g1[15],g1[15],g1[15],g1[15],g1[15],g1[15:12];
     w_x2<= rr2+16'h003f-g2[15],g2[15],g2[15],g2[15],g2[15],g2[15],g2[15],g2[15],g2[15],g2[15],g2[15],g2[15],g2[15:12];
     w_x3<= rr3+16'h003f-g3[15],g3[15],g3[15],g3[15],g3[15],g3[15],g3[15],g3[15],g3[15],g3[15],g3[15],g3[15],g3[15:12];
     w_x4<= rr4+16'h003f-g4[15],g4[15],g4[15],g4[15],g4[15],g4[15],g4[15],g4[15],g4[15],g4[15],g4[15],g4[15],g4[15:12];
     end
end



dtrigger dtrigger_u1(
              .i_clk (i_clk),
              .i_rst (i_rst),
              .i_x1  (w_x1),
              .o_x1  (o_x1)
    );

dtrigger dtrigger_u2(
              .i_clk (i_clk),
              .i_rst (i_rst),
              .i_x1  (w_x2),
              .o_x1  (o_x2)
    );
    
dtrigger dtrigger_u3(
              .i_clk (i_clk),
              .i_rst (i_rst),
              .i_x1  (w_x3),
              .o_x1  (o_x3)
    );
    
dtrigger dtrigger_u4(
              .i_clk (i_clk),
              .i_rst (i_rst),
              .i_x1  (w_x4),
              .o_x1  (o_x4)
    );


   
endmodule

完整源码获得方式

方式1:微信或者QQ联系博主

方式2:订阅MATLAB/FPGA教程,免费获得教程案例以及任意2份完整源码

A37-08

以上是关于FPGA实现GA基于FPGA的GA优化算法的设计与实现的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB教程案例96基于GA优化的WSN最大覆盖率和最少节点部署数量matlab仿真

MATLAB教程案例78基于GA优化的WSN最大覆盖率matlab仿真——扩展到任意一种优化算法解决WSN覆盖率问题

基于GA优化的BP网络算法分析与MATLAB实现matlab优化算法三

MATLAB教程案例95基于GA遗传优化的PID控制器最优控制参数计算

MATLAB教程案例97基于GA遗传优化的CNN卷积神经网络最优训练参数搜索matlab仿真

FPGA教程案例15基于vivado核的Cordic算法设计与实现