[HDLbits] Conway‘s game of life

金令
2023-12-01

@HDLbits

Conway’s game of life

Question:
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.

分析:该题主要是需要考虑边缘情况,看到有很多博主是将边缘情况全都表示出来,这样也不妨是一种做法。这里比较推荐在周围加一圈padding,将1616的网格扩充为1818的网格,扩充的内容即为边缘的neighbours,扩充完后便可直接用counter对neighbour进行计数,从而求解。

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output [255:0] q ); 
	
    reg [3:0] counter;
    reg [323:0] data_padding;
    reg [255:0] q_next;
    
    //change state
    always @(posedge clk) begin
        if(load)
        	q <= data;
        else 
            q <= q_next;
    end
    
    //calculate q_next
    always @(*) begin
        data_padding[17:0] = {q[240],q[255:240],q[255]};
        data_padding[323:306] = {q[0],q[15:0],q[15]};
        for(int i=1;i<17;i++) begin
            data_padding[i*18 +:18] = {q[(i-1)*16],q[(i-1)*16 +: 16],q[i*16-1]};
        end
        for(int i=1;i<17;i++) begin
            for(int j=1;j<17;j++) begin
                counter = data_padding[18*i+j-1]+data_padding[18*i+j+1]+data_padding[18*(i-1)+j-1]
                +data_padding[18*(i-1)+j]+data_padding[18*(i-1)+j+1]
                +data_padding[18*(i+1)+j-1]+data_padding[18*(i+1)+j]+data_padding[18*(i+1)+j+1];
                case(counter)
                    2: q_next[16*(i-1)+j-1] <= q[16*(i-1)+j-1];
                    3: q_next[16*(i-1)+j-1] <= 1;
                    default: q_next[16*(i-1)+j-1] <= 0;
                endcase
            end
        end
    end
endmodule

 类似资料:

相关阅读

相关文章

相关问答