HDLbits答案更新系列10(3.2 Sequential Logic 3.2.4 More Circuits)

 

目录

前言

3.2.4 More Circuits

3.2.4.1 Rule 90(Rule90)

3.2.4.2 Rule 110(Rule110)

3.2.4.3 Conway's Game of Life 16x16(Conwaylife)

结语

HDLbits网站链接


前言

今天更新一个小节内容,这个小节内容总共有三道题,题目很少,但是有很强的技巧性,下面我们就开始吧。

3.2.4 More Circuits

3.2.4.1 Rule 90(Rule90)

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
    
    /*
    //second way
    reg	[513:0]	q_com;
    integer i;
    
    always@(posedge clk)begin
        if(load)begin
            q_com <= {1'b0, data, 1'b0};
        end
        else begin
            for(i = 0; i <= 511; i = i + 1)begin
                q_com[i + 1] <= q_com[i] ^ q_com[i + 2];
            end
        end
    end
    
    assign q = q_com[512:1];
    */

endmodule

对于这道题目,我们首先要明白题意,规则中说,每个单元的下溢状态是该单元相邻两位的异或,所以方法一就体现了这一原则。对于方法二,博主是为了巩固for循环才写的答案,答案的表述已经很清楚了。

3.2.4.2 Rule 110(Rule110)

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 <= ~q & {q[510:0], 1'b0} | 
            	~{1'b0, q[511:1]} & {q[510:0], 1'b0} | 
            	~{1'b0, q[511:1]} & q | 
            	q & ~{q[510:0], 1'b0};
        end
    end

endmodule

对于这道题目,大家先将左中右三个位的卡诺图画出来,就可以明白博主的意思了。大家注意,题目中有一个描述,边界(q[-1]和q[512])均为0,这点需要考虑进去。

3.2.4.3 Conway's Game of Life 16x16(Conwaylife)

module top_module(
    input clk,
    input load,
    input [255:0] data,
    output [255:0] q ); 
    
    reg [3:0]	sum;
    integer i;

    always@(posedge clk)begin
        if(load)begin
            q <= data;
        end
        else begin
            for(i = 0; i <= 255; i = i + 1)begin
                if(i == 0)begin
                    sum = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];
                end
                else if(i == 15)begin
                    sum = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];
                end
                else if(i == 240)begin
                    sum = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];
                end
                else if(i == 255)begin
                    sum = q[238] + q[239] + q[224] + q[254] + q[240] + q[14] + q[15] + q[0];
                end
                else if(i > 0 && i < 15)begin
                    sum = q[i + 239] + q[i + 240] + q[i + 241] + q[i - 1] + q[i + 1] + q[i + 15] + q[i + 16] + q[i + 17];
                end
                else if(i > 240 && i < 255)begin
                    sum = q[i -17] + q[i - 16] + q[i - 15] + q[i - 1] + q[i + 1] + q[i - 241] + q[i - 240] + q[i - 239];
                end
                else if(i % 16 == 0)begin
                    sum = 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
                    sum = 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
                    sum = 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(sum)
                    4'd2:begin
                        q[i] <= q[i];
                    end
                    4'd3:begin
                        q[i] <= 1'b1;
                    end
                    default:begin
                        q[i] <= 1'b0;
                    end
                endcase
            end
        end
    end       

endmodule

这道题目是著名的康威生命游戏,博主刚看到这道题目,有点云里雾里,但是读了几遍题目描述之后,大概明白了生命游戏的规则。一个中心点周围有8个邻居,如果周围的邻居中1的数目为0-1个,那么中心点变为0;如果周围邻居中1的数目为2个,那么中心点状态不变;如果周围邻居中1的数目为3个,中心点变为1;如果周围邻居中1的数目大于3个,中心点变为0。

我们可以将周围的8个邻居的值都加起来来判断周围邻居中1的个数,值得注意的是,这里我在for中使用了阻塞赋值,因为我需要当前拍(本周期)得到结果在当前拍(本周期)就去判断,但是实际使用中不建议大家在时序逻辑中使用阻塞赋值,这里博主也只是为了做题。

大家注意,这里的for循环中的判断条件其实就是边界,用一个16x16的环形面来进行判断,如果我们选择坐标(0,0)为中心点,那么周围的8个邻居左边就是(15,1), (15,0), (15,15), (0,1), (0,15), (1,1), (1,0), 和(1,15),博主的所有if条件都是在判断边界值。

在做这道题的时候,建议大家先画一个16*16的矩阵,这样对于边界值以及中心点的把握会更准确,以此达到事半功倍的效果。

生命游戏之父约翰·康威因感染新冠去世,享年83岁,在此表示哀悼。

结语

今天更新一个小节内容,这三道题目要一次就success还是有难度的,尤其是第三题,博主不喜欢在时序逻辑中使用阻塞赋值,但是经过反复试验,这道题就是在本周期对本周期得到的sum结果进行判断,只能选择阻塞赋值。希望大家都能去做一做这几道题目,做完后对于时序的理解会更加深刻。

HDLbits网站链接

https://hdlbits.01xz.net/wiki/Main_Page

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 28
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值