rule90(一维元胞自动机)
Rule_90是一个具有有趣属性的一维元胞自动机。
规则很简单。有一个一维单元格数组(开或关)。在每个时间步长,每个像元的下一个状态是像元的两个当前邻居的异或。下表是更详细地表达此规则的方式,其中单元格的下一个状态是其自身及其两个相邻节点的函数:
Left | Center | Right | Center’s next state |
---|---|---|---|
1 | 1 | 1 | 0 |
1 | 1 | 0 | 1 |
1 | 0 | 1 | 0 |
1 | 0 | 0 | 1 |
0 | 1 | 1 | 1 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 |
在此电路中,创建一个 512 cell 系统 (q[511:0]),每个时钟周期按一个时间步长前进。负载输入指示系统的状态应加载数据[511:0]。假设边界(q[-1]和q[512])均为零(关闭)。
Module Declaration
module top_module(input clk,input load,input [511:0] data,output [511:0] q )
对于 q[511:0] = 1 的初始状态,前几次迭代为:
1101011000101001000101010101
10000000
答案:
module top_module(input clk,input load,input [511:0] data,output [511:0] q ); wire [513:0] q_w = {1'b0,q,1'b0};int i;always @(posedge clk ) beginif(load=='d1)beginq <= data;endelse beginfor (i = 0; i < 512; i=i+1) beginq[i] <= q_w[i] ^ q_w [i+2];endendend
endmodule
rule110(一维元胞自动机)
Rule_110 是一个具有有趣属性的一维元胞自动机。
有一个一维单元格数组(开或关)。在每个时间步长中,每个单元格的状态都会发生变化。在规则 110 中,每个单元格的下一个状态仅取决于其自身及其两个相邻单元,如下表所示:
Left | Center | Right | Center’s next state |
---|---|---|---|
1 | 1 | 1 | 0 |
1 | 1 | 0 | 1 |
1 | 0 | 1 | 1 |
1 | 0 | 0 | 0 |
0 | 1 | 1 | 1 |
0 | 1 | 0 | 1 |
0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 |
思路
该题相比rule 90,没有告诉中间的变化条件,根据已知条件观察可知(没有进行卡诺图化简),当Left为1是,中间值的下一状态为Center和Right的异或结果;当Left为0时,中间值的下一状态为Center和Right的或结果,由此可编写逻辑代码得到结果。
Module Declaration
module top_module(input clk,input load,input [511:0] data,output [511:0] q
);
答案:
module top_module(input clk,input load,input [511:0] data,output [511:0] q
);
wire [513:0] q_w = {1'b0,q,1'b0};int i;always @(posedge clk ) beginif(load=='d1)beginq <= data;endelse beginfor (i = 0; i < 512; i=i+1) beginif(q_w [i+2] == 1)q[i] <= q_w[i] ^ q_w [i+1];else if(q_w [i+2] == 0)q[i] <= q_w[i] | q_w [i+1];endendend
endmodule
Conwaylife
康威的生命游戏是一个二维的细胞自动机。
“游戏”在二维单元格网格上进行,其中每个单元格为 1(活动)或 0(死亡)。在每个时间步长中,每个像元都会根据其相邻单元的数量更改状态:
邻居的数值为0-1或者4个以上时:单元格变为 0。
邻居的数值为2个时:单元格状态不变。
邻居的数值为3个时:单元格变为 1。
游戏是为无限网格而制定的。在此电路中,我们将使用 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 当前状态,每个时钟周期更新一次。
思路
主要需要根据当前坐标值计算出相应的邻居的坐标值,然后计算出邻居的数值进行比较输出更新q值。
Module Declaration
module top_module(input clk,input load,input [255:0] data,output [255:0] q );
答案:
module top_module(input clk,input load,input [255:0] data,output [255:0] q ); /* UL U UR L X RDL D DR*/ int index_q_u ;int index_q_d ; int index_q_l ; int index_q_r ; wire [2:0] neighbours_num[255:0];int i,j;always @(*) beginfor(i = 0 ; i < 16 ; i = i + 1) beginfor(j = 0 ; j < 16 ; j = j + 1) beginindex_q_u = (i == 0) ? 15 :i-1; //up index_q_d = (i == 15) ? 0 :i+1; //downindex_q_l = (j == 0) ? 15 :j-1; //leftindex_q_r = (j == 15) ? 0 :j+1; //rightneighbours_num[i*16+j] = q[index_q_u*16+index_q_l] + q[index_q_u*16+j] + q[index_q_u*16+index_q_r]+ q[i*16+index_q_l] + q[i*16+index_q_r]+ q[index_q_d*16+index_q_l] + q[index_q_d*16+j] + q[index_q_d*16+index_q_r];endendendalways @(posedge clk ) beginif(load=='d1)beginq <= data;endelse beginfor (i = 0; i < 256; i=i+1) beginif(neighbours_num[i]=='d3)beginq[i]<=1;endelse if(neighbours_num[i]=='d2)beginq[i]<=q[i];endelse beginq[i]<=0;endendendend
endmodule