HDLBits(2)--shift register & Conway‘s game

问题一 shift register
Write a top-level Verilog module (named top_module) for the shift register, assuming that n = 4. Instantiate four copies of your MUXDFF subcircuit in your top-level module. Assume that you are going to implement the circuit on the DE2 board.

Connect the R inputs to the SW switches,
clk to KEY[0],
E to KEY[1],
L to KEY[2], and
w to KEY[3].
Connect the outputs to the red lights LEDR[3:0].
在这里插入图片描述
最直观想到的办法是在子模块中设置一个二选一组合逻辑,例如:


module MUXDFF (
    input clk,
    input a,
    input w,
    input e,
    input l,
    input r,
    output q
);
    wire mid, d;
    assign mid = (e==1'b0)?a:w;
    assign d = (l==1'b0)?mid:r;
    always@(posedge clk) begin
        q<=d; end
endmodule

但是其实,仔细观察这两个二选一选择器,会发现逻辑是:
L为高电平:输出R
E为高电平:输出W
都不是:输出上一个时钟的输出结果Q
因此,一个新的代码为(减少需要出现的新端口和代码复杂性):

module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); //
    MUXDFF mod0(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(LEDR[1]),.r(SW[0]),.q(LEDR[0]));
    MUXDFF mod1(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(LEDR[2]),.r(SW[1]),.q(LEDR[1]));
    MUXDFF mod2(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(LEDR[3]),.r(SW[2]),.q(LEDR[2]));                                                                        
    MUXDFF mod3(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(KEY[3]),.r(SW[3]),.q(LEDR[3]));                                                                       
                                                                          
endmodule

module MUXDFF (
    input clk,
    input e,
    input l,
    input w,
    input r,
    output q
);
    always@(posedge clk) begin
        if(l) q<=r;
        else if (e) q<=w;
        else q<=q;
    end
endmodule

还有需要注意的一点是,只有Q3的w输入来自于KEY[3],其余的来自于Q[i+1]

问题二 Conway’s game
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.

第一步:将1616的二维数组扩展为1818的二维数组在这里插入图片描述
第二步:使用加法对每个单元格进行计数,对于d_loop来讲,只对[1:16][1:16]的范围进行计数,即对应着原二维数组[0:15][0:15]的全计数
第三步:使用case语句进行判断
第四步:将二维数组转为一维数组进行输出

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output reg [255:0] q
);
    //填充思路
    wire [15:0] d [15:0];
    wire [17:0] d_loop [17:0];
    //第0行和第17行单独写
    assign d_loop[0][17:0] = {q[240],q[255:240],q[255]};
    assign d_loop[17][17:0] = {q[0],q[15:0],q[15]};
    //1-16行有规律可循
    integer m;
    always@(*) begin
        for (m=0;m<16;m=m+1) begin
            d_loop[(m+1)][17:0] = {q[16*m],q[16*m +:16],q[16*m+15]};
        end
    end
    //计数并判断
    integer i,j;
    reg [3:0] count [17:0][17:0];
    always@(*) begin
        for (i=1;i<17;i=i+1) begin
            for (j=1;j<17;j=j+1) begin
                count[i][j]=
                d_loop[i-1][j-1]+d_loop[i-1][j]+d_loop[i-1][j+1]+
                d_loop[i][j-1]+d_loop[i][j+1]+
                d_loop[i+1][j-1]+d_loop[i+1][j]+d_loop[i+1][j+1];
                case (count[i][j])
                    4'd2: d[i-1][j-1]=d_loop[i][j];
                    4'd3: d[i-1][j-1]=1'b1;
                    default: d[i-1][j-1] = 1'b0;
                endcase
            end
        end

    end
    //二维数组转为一维数组输出
    always@(posedge clk) begin
        if(load) q<=data;
        else q <= {d[15][15:0],d[14][15:0],d[13][15:0],d[12][15:0],
                   d[11][15:0],d[10][15:0],d[9][15:0],d[8][15:0],
                   d[7][15:0],d[6][15:0],d[5][15:0],d[4][15:0],
                   d[3][15:0],d[2][15:0],d[1][15:0],d[0][15:0]};
    end
endmodule
  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值