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


目录
前言
【HDLbits答案更新系列10(3.2|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 endassign 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 endendmodule

对于这道题目,大家先将左中右三个位的卡诺图画出来,就可以明白博主的意思了。大家注意,题目中有一个描述,边界(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 endendmodule

这道题目是著名的康威生命游戏,博主刚看到这道题目,有点云里雾里,但是读了几遍题目描述之后,大概明白了生命游戏的规则。一个中心点周围有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

    推荐阅读