`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

A37-08