目录
前言
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网站链接
今天更新一个小节内容,这个小节内容总共有三道题,题目很少,但是有很强的技巧性,下面我们就开始吧。
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循环才写的答案,答案的表述已经很清楚了。
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,这点需要考虑进去。
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结果进行判断,只能选择阻塞赋值。希望大家都能去做一做这几道题目,做完后对于时序的理解会更加深刻。
https://hdlbits.01xz.net/wiki/Main_Page