HDLBITS笔记30:rule 90、rule 100以及Conway‘s game of life 16*16

目录

## 题目1:rule 90规则90是具有有趣属性的一维元胞自动机。

 题目2:rule 100

 题目3:Conwaylife


## 题目1:rule 90
规则90是具有有趣属性的一维元胞自动机。

规则很简单。有一个一维的单元格数组(打开或关闭)。在每个时间步长中,每个单元的下一个状态是单元的两个当前邻居的异或。下表是表示此规则的更详细的方式,其中单元格的下一个状态是自身及其两个相邻项的函数

leftcenterrightCenter's next state
1110
1101
1010
1001
0111
0100
0011
0000

 

(“规则 90”的名称来自读取“下一个状态”列:01011010是十进制 90。


在该电路中,创建一个512单元系统(q[511:0]),并在每个时钟周期内前进一个时间步长。load输入指示系统的状态应加载数据[511:0]。假设边界(q[-1] 和 q[512])均为零(关闭)。

模块声明

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q
);

提示:

对于 q[511:0] = 1 的初始状态,前几次迭代为:

       1
      10
     101
    1000
   10100
  100010
 1010101
10000000

这形成了谢尔宾斯基三角形的一半。

分析:观察上表可得,其逻辑关系为:左边的逻辑值与右边的逻辑值异或,便能得到下一个状态的值。同时要形成谢尔宾斯基三角形的一半通过观察可知第一位总是1,因此在最高位采用0^0即可。

代码如下:

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 <= {1'b0,q[511:1]}^{q[510:0],1'b0};
        end
endmodule

仿真结果如下:

 题目2:rule 100

规则110是一个具有有趣属性(例如图灵完备)的一维元胞自动机。

有一个一维的单元格数组(打开或关闭)。在每个时间步长中,每个单元格的状态都会发生变化。在规则 110 中,根据下表,每个单元的下一个状态仅取决于自身及其两个相邻单元

leftcenterrightCenter's next state
1110
1101
1011
1000
0111
0101
0011
0000

 

(“规则 110”的名称来自读取“下一个状态”列:01101110是十进制 110。

在该电路中,创建一个512单元系统(q[511:0]),并在每个时钟周期内前进一个时间步长。load输入指示系统的状态应加载数据[511:0]。假设边界(q[-1] 和 q[512])均为零(关闭)。

模块声明

module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q
); 

提示:

对于 q[511:0] = 1 的初始状态,前几次迭代为:

       1
      11
     111
    1101
   11111
  110001
 1110011
11010111

 分析:观察rule 100的状态转移表并不能直接观察其逻辑关系,因此可以考虑画出其卡诺图,然后通过圈1法对其逻辑表达式进行化简。其卡诺图如下图所示。设left = A,center = B,right = C,输出为Center's next state。

 得出其逻辑表达式为:Center's next state = B&~C+~A&C+~B&C。

由此可得代码如下:

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 & ~{q[510:0],1'b0}) | (~{1'b0,q[511:1]} & {q[510:0],1'b0}) | (~q & {q[510:0],1'b0}); 
        end
endmodule

仿真结果:

 题目3:Conwaylife

康威的生命游戏是一个二维元胞自动机。

“游戏”在二维单元格网格上播放,其中每个单元格为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当前状态,每个时钟周期更新。

游戏状态应在每个时钟周期前移一个时间步长。

约翰·康威(John Conway),数学家和生命游戏元胞自动机的创造者,于2020年4月11日因COVID-19去世。

模块声明

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output [255:0] q );

提示:

一个易于理解并测试一些边界条件的测试用例是blinker 256'h7。它是行 0 列 0-2 中的 3 个单元格。它在一行 3 个单元格和一列 3 个单元格之间振荡(在第 1 列中,在第 1 列中,第 15、0 和 1 行中)。

此处代码参考用Verilog实现二维细胞自动机——康威生命游戏(Conway's Game of Life)_早睡身体好~的博客-CSDN博客_conway生命游戏 verilog

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output [255:0]q ); 
    reg [255:0] q_next;//存储次态
    reg [3:0]sum;//记录每次遍历的和
    integer i;//定义正整数i,作为for循环判断的条件量
    always@(posedge clk)
        if(load)
            q <= data;
    else begin
        for( i = 0;i < 256;i=i+1) begin 
            if(i==0)//左上角
                sum = q[1]+q[16]+q[17]+q[240]+q[241]+q[15]+q[31]+q[255];
            else if(i==15)//右上角
                sum = q[14]+q[16]+q[0]+q[240]+q[254]+q[30]+q[31]+q[255];
            else if(i==240)//左下角
                sum = q[0]+q[15]+q[239]+q[241]+q[1]+q[224]+q[225]+q[255];
            else if(i==255)//右下角
                sum = q[0]+q[15]+q[14]+q[224]+q[238]+q[240]+q[239]+q[254];
            else if(0<i & i<15)//上边界
                sum = q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17]+q[i+239]+q[i+240]+q[i+241];
            else if(i%16==0)//左边界
                sum = q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17]+q[i-16]+q[i-15]+q[i+31];
            else if(i%16==15)//右边界
                sum = q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i-17]+q[i-16]+q[i-15]+q[i-31];
            else if(240<i & i<255)//下边界
                sum = q[i-1]+q[i+1]+q[i-17]+q[i-16]+q[i-15]+q[i-239]+q[i-240]+q[i-241];
            else //非边界
                sum = q[i-1]+q[i+1]+q[i-17]+q[i-16]+q[i-15]+q[i+15]+q[i+16]+q[i+17];
      		
            case(sum) //根据邻居数量判断次态
                2:q_next[i]=q[i];
                3:q_next[i]=1;
                default:q_next[i]=0;
            endcase
        end
      	q = q_next;
    end
endmodule

其中值得注意的是使用quartus ii应将输出output输出语句改为:output reg  [255:0]q ); 否则将会提示你没有定义q的类型从而报错。

使用quartus ii 画出逻辑图:

 由逻辑图可知,该程序全由加法器组成,看似复杂庞大,实际占用的资源并不会太多。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值