习题笔记 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.

个人提交代码:

大体思路是按四角、四边、内部分类,利用generate for语句使其分别通过判定模块进行判定,得到对应位置的q_next


//Conwaylife
module top_module(
    input clk,
    input load,
    input [255:0] data,
    output [255:0] q ); 
    
    wire [255:0] q_next;
    //四个角
    deter U0 (.center(q[0]),
              .in({q[255],q[240],q[241],q[15],q[1],q[31],q[16],q[17]}),
              .out(q_next[0])
              );
    deter U15 (.center(q[15]),
               .in({q[255:254],q[240],q[14],q[0],q[31:30],q[16]}),
               .out(q_next[15])
               );
    deter U240 (.center(q[240]),
                .in({q[239],q[225:224],q[255],q[241],q[15],q[1:0]}),
                .out(q_next[240])
                );
    deter U255 (.center(q[255]),
                .in({q[239:238],q[224],q[254],q[240],q[15:14],q[0]}),
                .out(q_next[255])
                );          
    //四条边
    genvar u;   //上侧1-14位
    generate     
        for (u=1;u<15;u=u+1) 
            begin:UP
                deter UP_deter (.center(q[u]),
                                .in({q[u+241:u+239],q[u-1],q[u+1],q[u+17:u+15]}),
                                .out(q_next[u])
                                );
            end
    endgenerate

    genvar d;  //下侧241-254位
    generate 
        for (d=241;d<255;d=d+1)
            begin:DOWN
                deter DOWN_deter (.center(q[d]),
                                  .in({q[d-15:d-17],q[d-1],q[d+1],q[d-239:d-241]}),
                                  .out(q_next[d])
                                  );
            end
    endgenerate

    genvar l; //左侧16(16x1)...224(16x14)
    generate 
        for (l=16;l<225;l=l+16)
            begin:LEFT
                deter LEFT_deter (.center(q[l]),
                                  .in({q[l-1],q[l-15:l-16],q[l+15],q[l+1],q[l+31],q[l+17:l+16]}),
                                  .out(q_next[l])
                                  );
            end
    endgenerate

    genvar r; //右侧31(+16),47...239
    generate 
        for (r=31;r<240;r=r+16)
            begin:RIGHT
                deter RIGHT_deter (.center(q[r]),
                                   .in({q[r-16:r-17],q[r-31],q[r-1],q[r-15],q[r+16:r+15],q[r+1]}),
                                   .out(q_next[r])
                                   );
            end
    endgenerate

    //内部
    // 0 .............15
    //   17 ....... 30
    //   33 ....... 46
    //   ............
    //   ............
    //   225....... 238
    // 240 ............255
    genvar j,k; //j行,k列 
    generate 
        for (j=17;j<226;j=j+16)
            begin: ROW_j
                for (k=0;k<14;k=k+1)
                    begin: COLUM_k
                        deter IN_deter (.center(q[j+k]),
                                        .in({q[j+k-15:j+k-17],q[j+k-1],q[j+k+1],q[j+k+17:j+k+15]}),
                                        .out(q_next[j+k])
                                        );
                    end
            end
    endgenerate


    always @(posedge clk)
        begin
            if (load)
            q <= data;
            else 
            q <= q_next;
        end


endmodule

module deter (   //判定模块
    input center,
    input [7:0]in,
    output out
);
    wire [3:0]num;

    always @(*)
        begin
            num = 3'b0;
            for (int i=0;i<8;i=i+1)        //检测1的个数
                begin
                    num = num + in[i];
                end
            case(num)                  //根据1的个数确定输出
            4'd2: out = center;
            4'd3: out = 1'b1;
            default : out = 1'b0;
            endcase
        end
endmodule
                

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值