关注 望森FPGA 查看更多FPGA资讯
这是望森的第 15 期分享
作者 | 望森
来源 | 望森FPGA
目录
3 Conway's Game of Life 16x16 | 康威生命游戏 16x16
本文中的代码都能够正常运行,请放心食用😋~
练习的官方网站是:https://hdlbits.01xz.net/
注:作者将每个练习的知识点都放在了题目和答案之后
本节练习元胞自动机(cellular automata,CA) 的电路设计。
元胞自动机(cellular automata,CA) 是一种时间、空间、状态都离散,空间相互作用和时间因果关系为局部的网格动力学模型,具有模拟复杂系统时空演化过程的能力。
1 Rule 90 | 规则 90
题目:
规则 90 是一个具有有趣属性的一维元胞自动机。
规则很简单。有一个一维元胞阵列(开或关)。在每个时间步骤中,每个元胞的下一个状态是该元胞的两个当前邻居的异或。下表是表达此规则的更详细的方式,其中元胞的下一个状态是其自身及其两个邻居的函数:
(名称“Rule 90”来自“Center's next state”列:01011010 是十进制 90。)
在此电路中,创建一个 512 单元系统 (q[511:0]),并在每个时钟周期前进一个时间步长。load 输入表示系统的状态应加载 data[511:0] 。假设边界 (q[-1] 和 q[512]) 均为零(关闭)。
提示:
对于 q[511:0] = 1 的初始状态,前几次迭代是:
答案:
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q );
always@(posedge clk)begin
if (load)
q <= data;
else
q <= q[511:1] ^ {q[510:0],1'b0};
end
endmodule
知识点:
根据需求寻找规律。
2 Rule 110 | 规则 110
题目:
规则 110 是一个具有有趣属性(例如图灵完备)的一维元胞自动机。
有一个一维元胞阵列(开或关)。在每个时间步骤中,每个元胞的状态都会发生变化。在规则 110 中,每个元胞的下一个状态仅取决于其自身及其两个邻居,如下表所示:
(“规则 110”的名称来自“Center's next state”列:01101110 是十进制 110。)
在此电路中,创建一个 512 元胞系统 (q[511:0]),并在每个时钟周期前进一个时间步长。load 输入表示系统状态应加载 data[511:0] 。假设边界(q[-1] 和 q[512])均为零(关闭)。
提示:
对于初始状态 q[511:0] = 1,前几次迭代是:
答案:
1.绘制卡诺图
2.卡诺图化简
3.逻辑表达式
Cn+1 = (~C & R) | (~L & C) | (C & ~R);
4.代码
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q
);
wire [511:0] l,r,c;
assign l = {1'b0,q[511:1]};
assign r = {q[510:0],1'b0};
assign c = q;
always@(posedge clk)begin
if (load)
q <= data;
else begin
q <= (~c & r) | (~l & c) | (c & ~r);
end
end
endmodule
3 Conway's Game of Life 16x16 | 康威生命游戏 16x16
题目:
康威生命游戏是一个元胞自动机。
“游戏”在二维元胞网格上进行,每个细胞要么是 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:在下一个时钟边缘将 data 加载到 q 中,以加载初始状态。
-
q:游戏的 16x16 当前状态,每个时钟周期更新一次。
游戏状态应在每个时钟周期前进一个时间步。
数学家、生命游戏细胞自动机的创造者约翰·康威于 2020 年 4 月 11 日因 COVID-19 去世。
提示:
一个易于理解并测试一些边界条件的测试案例是 blinker 256'h7。它位于第 0 行第 0-2 列的 3 个单元格中。它在一行 3 个单元格和一列 3 个单元格之间振荡(在第 1 列,第 15、0 和 1 行)。
答案:
module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q );
reg [15:0] q_temp [15:0];
reg [255:0] q_trans;
integer i,j;
integer u,d,l,r;
reg [2:0] cnt;
//将256个数存为16*16个二维数组
always@(*)begin
for(i=0;i<16;i=i+1) begin
for(j=0;j<16;j=j+1) begin
q_temp[i][j] = q[16*i+j];
end
end
for(i=0;i<16;i=i+1) begin
for(j=0;j<16;j=j+1) begin
u = (i == 32'd15) ? 32'd0 : i+1;
d = (i == 32'd0) ? 32'd15 : i-1;
l = (j == 32'd15) ? 32'd0 : j+1;
r = (j == 32'd0) ? 32'd15 : j-1;
cnt = q_temp[u][l] + q_temp[u][j] + q_temp[u][r]
+ q_temp[i][l] + q_temp[i][r]
+ q_temp[d][l] + q_temp[d][j] + q_temp[d][r];
case(cnt)
3'd02 : q_trans[i*16+j] <= q_temp[i][j];
3'd03 : q_trans[i*16+j] <= 1'b1;
default q_trans[i*16+j] <= 1'b0;
endcase
end
end
end
//输出数据赋值
always@(posedge clk)begin
if (load)
q <= data;
else
q <= q_trans;
end
endmodule
- END -
相关推荐文章,点击跳转: