康威生命游戏的Verilog实现思路(HDLbits_Conwaylife)

一、题目说明——HDLbits_Conwaylife

        Conway's Game of Life is a two-dimensional cellular automaton.

        The "game" is played on a two-dimensional grid of cells, where each cell is either 1 (alive) or 0 (dead). At each time step, each cell changes state depending on how many neighbours it has:

  • 0-1 neighbour: Cell becomes 0.
  • 2 neighbours: Cell state does not change.
  • 3 neighbours: Cell becomes 1.
  • 4+ neighbours: Cell becomes 0.

        The game is formulated for an infinite grid. In this circuit, we will use a 16x16 grid. To make things more interesting, we will use a 16x16 toroid, where the sides wrap around to the other side of the grid. For example, the corner cell (0,0) has 8 neighbours: (15,1), (15,0), (15,15), (0,1), (0,15), (1,1), (1,0), and (1,15). The 16x16 grid is represented by a length 256 vector, where each row of 16 cells is represented by a sub-vector: q[15:0] is row 0, q[31:16] is row 1, etc. (This tool accepts SystemVerilog, so you may use 2D vectors if you wish.)

  • load: Loads data into q at the next clock edge, for loading initial state.
  • q: The 16x16 current state of the game, updated every clock cycle.

        The game state should advance by one timestep every clock cycle.

        John Conway, mathematician and creator of the Game of Life cellular automaton, passed away from COVID-19 on April 11, 2020.

网站:Conwaylife - HDLBits

二、题目分析

        题目需要我们完成一个描述康威生命游戏的电路。选择在16\times16的网络内进行,每个网格都有一个状态(0或1)代表死亡或存活。每当时钟上升沿到来时,所有网格的状态需要更新。如果load信号为高则将所有网格的下一状态更新为data。

规则一        每个网格的下一状态只与它周围的八个网格的状态有关

        1)如果它周围的八个网格中有个存活,则不改变它的下一状态;

        2)如果它周围的八个网格中有个存活,则它的下一状态为存活;

        3)除此之外,它的下一状态均为死亡;

规则二        16\times16网络是环面网格,其中每个边都会延续到网格的另一侧

如图所示,0号网格的下一状态与31、16、17、15、1、255、240、241这八个网格的状态有关。 

三、实现与总结

        由于存在环面网络,所以我们先构造一个 18\times18的初始化网络,它可以大大简化我们循环体内的复杂度。它的中心是16\times16的原网络,在它的外面一圈是我们拓展出的环面网络。

        接下来的循环体只需要在红色框内部操作即可,不需要考虑越界的情况。

        这里我们使用了循环生成块用来构建18\times18的初始化网络,然后使用循环体来描述红色框内的每个网格下一状态与其周围的关系,并且不需要考虑环面。

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

    integer i,j,k;
    genvar t;
    wire [323:0] q_wire;
    
    //初始化网络
    assign q_wire[323-:18] = {q[0],q[15-:16],q[15]};
    assign q_wire[17-:18] = {q[240],q[255-:16],q[255]};
    
    generate for(t=17;t>1;t=t-1)begin:for_t_loop
    	assign q_wire[(t*18-1)-:18]= {q[16*(t-2)],q[(16*(t-1)-1)-:16],q[16*(t-1)-1]};
    end
    endgenerate
    
    //循环遍历的状态更新
    always@(posedge clk)begin
        if(load)
            q<=data;
        else begin
            //state_capture
            for(i=1;i<17;i=i+1)
                begin
                    for(k=0;k<16;k=k+1)begin
                        j=0;
                        if(q_wire[(i*18+1+k)-1])j=j+1;
                        if(q_wire[(i*18+1+k)+1])j=j+1;
                    	if(q_wire[(i*18+1+k)-19])j=j+1;
                    	if(q_wire[(i*18+1+k)-17])j=j+1;
                    	if(q_wire[(i*18+1+k)-18])j=j+1;
                    	if(q_wire[(i*18+1+k)+17])j=j+1;
                    	if(q_wire[(i*18+1+k)+18])j=j+1;
                    	if(q_wire[(i*18+1+k)+19])j=j+1;         
                    case(j)//判断周围网格的存活数量
                    	2:q[(i-1)*16+k]<=q[(i-1)*16+k];
                        3:q[(i-1)*16+k]<=1;
                        default:q[(i-1)*16+k]<=0;
                    endcase
                end//for_k
            end//for_i
        end//else
    end//always
endmodule//top_module

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值