跳轉到

More Circuits

Rule 90

原題:Rule 90

練習concatenation的使用。

Verilog
module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [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

Rule 110

原題:Rule 110

延續 concatenation 練習,差別是這裡的邏輯可先用卡諾圖觀察。

Verilog
module top_module(
    input clk,
    input load,
    input [511:0] data,
    output reg [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);
    end
endmodule

Conway's Game of Life 16x16

原題:Conway's Game of Life 16x16

練習使用for迴圈,還有debug的耐心。

Verilog
module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q );
    reg [255:0] next_q;
    reg [323:0] q_padding;
    reg [3:0] answer[255:0];
    integer i,j;

    always@(*)begin
        //update q_padding
        q_padding[17:0] = {q[240],q[255:240],q[255]};
        q_padding[323:306] = {q[0],q[15:0],q[15]};
        for(i = 1; i < 17 ; i++)begin
            q_padding[i*18 +: 18] = {q[(i-1)*16],q[(i-1)*16 +: 16],q[i*16-1]};
        end
        //calculate
        for(i=0; i<16; i++)begin
            for(j=0; j<16; j++)begin
                //center is q_padding[18*(i+1)+(j+1)]
                answer[16*i + j] = q_padding[18*i+(j  )] +
                         q_padding[18*i+(j+1)] +
                         q_padding[18*i+(j+2)] +
                         q_padding[18*(i+1)+(j  )] +
                         q_padding[18*(i+1)+(j+2)] +
                         q_padding[18*(i+2)+(j  )] +
                         q_padding[18*(i+2)+(j+1)] +
                         q_padding[18*(i+2)+(j+2)];                
                case(answer[16*i + j])
                    4'b0011: next_q[16*i+j] = 1'b1;
                    4'b0010: next_q[16*i+j] = q[16*i+j];
                    default: next_q[16*i+j] = 1'b0;
                endcase
            end
        end
    end

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