3.2.4.3 Conway's game of life 16*16
问题描述
康威的生命游戏是一个二维元胞自动机。
“游戏”是在一个二维单元格上进行的,其中每个单元格要么是 1(活着),要么是 0(死去)。在每个时间步,每个单元格都会根据它拥有的邻居数量来改变状态:
0-1 邻居:单元格变为 0。
2个邻居:小区状态不变。
3 个邻居:单元格变为 1。
4 个以上的邻居:单元格变为 0。
该游戏是为无限网格制定的。在这个电路中,我们将使用 16x16 网格。为了让事情更有趣,我们将使用一个 16x16 的环形,其中边环绕到网格的另一边。例如,角单元 (0,0) 有 8 个邻居:(15,1) , (15,0) , (15,15) , (0,1) , (0,15) , (1,1)、(1,0)和(1,15)。16x16 的网格由一个长度为 256 的向量表示,其中每行 16 个单元格由一个子向量表示:q[15:0] 为第 0 行,q[31:16] 为第 1 行,以此类推(此工具接受 SystemVerilog,因此您可以根据需要使用 2D 向量。)load:在下一个时钟沿将数据加载到q中,用于加载初始状态。
q:游戏的 16x16 当前状态,每个时钟周期更新。
代码:
module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q );
integer i;
reg [3:0] count;
always @(posedge clk) begin
if(load)
q<=data;
else begin
for(i=0;i<256;i=i+1) begin
// 特殊的四个角
if(i==0) //q[0][0]
count = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];
else if(i==15) //q[0][15]
count = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];
else if(i==240)//q[15][0]
count = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];
else if(i==255)//q[15][15]
count = q[238] + q[239] + q[224] + q[254] + q[240] + q[15] + q[0] + q[14];
// 第一行除去两端的部分
else if( i>0 && i<15)
count = q[239+i]+q[240+i]+q[241+i]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];
// 最后一行除去两端
else if(i>240 && i<255)
count = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i-239]+q[i-240]+q[i-241];
// 第一列除去两端部分
else if( i%16 == 0)
count = q[i-1]+q[i-16]+q[i-15]+q[i+15]+q[i+1]+q[i+31]+q[i+16]+q[i+17];
// 最后一列除去两端部分
else if(i % 16 == 15)
count = q[i-17]+q[i-16]+q[i-31]+q[i-1]+q[i-15]+q[i+15]+q[i+16]+q[i+1];
// 其余的中间部分
else
count = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];
case(count)
4'd2:q[i] <= q[i];
4'd3:q[i] <= 1'b1;
default:q[i] <= 1'b0;
endcase
end
end
end
endmodule