[Verilog25]HDLBits习题_More Circuits

HDLBits习题_More Circuits

Rule 90

  • 题目要求,创建一个一维细胞自动机。规则很简单,即生成一个一维单元阵列,每个单元的下一个状态是该单元相邻两个单元数据的异或。具体规则可见下表:
Left Center Right Center's next state
1 1 1 0
1 1 0 1
1 0 1 0
1 0 0 1
0 1 1 1
0 1 0 0
0 0 1 1
0 0 0 0
  • 在这个电路中,创建一个512单元系统(q(511:0)),并在每个时钟周期中前进一个时间步长。加载(load)表明系统的状态应该加载data[511:0]至q中,假设边界(q[0]和q[512])都为零。
  • 具体代码如下:
module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q ); 

    always @(posedge clk)begin
        if(load)begin
            q <= data;
        end
        else begin
            q <= {1'b0,q[511:1]}^{q[510:0],1'b0};
        end
    end
    
endmodule

Rule 100

  • 题目要求,创建一个一维细胞自动机。规则很简单,即生成一个一维单元阵列,每个单元的下一个状态是由当前单元值与相邻两个单元数据来决定。具体规则可见下表:
Left Center Right Center's next state
1 1 1 0
1 1 0 1
1 0 1 1
1 0 0 0
0 1 1 1
0 1 0 1
0 0 1 1
0 0 0 0
  • 在这个电路中,创建一个512单元系统(q(511:0)),并在每个时钟周期中前进一个时间步长。加载(load)表明系统的状态应该加载data[511:0]至q中,假设边界(q[0]和q[512])都为零。
  • 具体代码如下,可先对上文所述状态转移表进行化简:
module top_module(
    input clk,
    input load,
    input [511:0] data,
    output [511:0] q
); 

    always @(posedge clk)begin
        if(load)begin
        	q <= data;
        end
        else begin 
            q <= (~{1'b0,q[511:1]} & q) | (q & ~{q[510:0],1'b0}) | {~{1'b0,q[511:1]} & {q[510:0],1'b0}} | {~q & {q[510:0],1'b0}};
        end
    end
    
endmodule

Conway's Game of Life 16x16

  • Conway的Game of Life是一个二维元胞自动机。“游戏”在二维细胞网格上进行,其中每个细胞要么是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 行,依此类推。其中,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 );
    
    reg [3:0] count;
    integer i;
    
    always @(posedge clk)begin
        if(load)begin
        	q <= data;
        end
        else begin
            for(i=0;i<256;i++)begin
                if(i == 0)begin
                    count = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];
                end
                else if(i == 15)begin
                    count = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];
                end
                else if(i == 240)begin
                    count = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];
                end
                else if(i == 255)begin
                    count = q[238] + q[239] + q[224] + q[254] + q[240] + q[15] + q[0] + q[14];
                end
                else if( i>0 && i<15)begin
                    count = q[239+i]+q[240+i]+q[241+i]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];
                end
                else if(i>240 && i<255)begin
                    count = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i-239]+q[i-240]+q[i-241];
                end
                else if( i%16 == 0)begin
                    count = q[i-1]+q[i-16]+q[i-15]+q[i+15]+q[i+1]+q[i+31]+q[i+16]+q[i+17];
                end
                else if(i % 16 == 15)begin
                    count = q[i-17]+q[i-16]+q[i-31]+q[i-1]+q[i-15]+q[i+15]+q[i+16]+q[i+1];
                end
                else begin
                    count = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];
                end
                
                case(count)
                    4'd2:q[i] <= q[i];
                    4'd3:q[i] <= 1'b1;
                    default:q[i] <= 1'b0;
                endcase
            end
        end
    end

endmodule

参考:
HDLBits
HDLBits答案(13)_Verilog移位寄存器附加题