此博客为个人博客,不涉及商业用途,仅提供学习参考,内容均来自个人原创以及互联网转载和摘录。
此博客上带有原创标识的文章、图片、文件等,未经本人允许,不得用于商业用途以及传统媒体。
本文首发于CSDN,版权所有,禁止转载。
如需转载,请在评论区留言或私信申请,经同意后可转载,否则属于侵权行为。
原博客链接:https://blog.csdn.net/qq_38305370
原博主昵称:城外南风起
————————————————
最近在做HDLBits,做到Conwaylife,觉得还挺有意思的,记录一下。
Conwaylife是要用verilog实现一种二维元胞自动机(cellular automaton)。
我的实现步骤:
1.由于矩阵需要toroid,对初始数据进行padding,将16x16的矩阵扩展为18x18的矩阵
2.根据演化规则和扩展后的矩阵,统计目标位的alive neighbours,并根据alive neighbours的个数更新输出。
其中,装载和更新数据使用同步时序逻辑,padding、count 和 update使用组合逻辑。同时,应使用中间变量避免在不同的逻辑块中对同一输出进行赋值。
代码:
module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q );
reg [323:0] data_padding; //18*18
wire [255:0] q_next;
integer i,j,neighbour_cnt;
always @(*)
begin
//padding
data_padding[17:0] = {q[240],q[255:240],q[255]};
data_padding[323:306] = {q[0],q[15:0],q[15]};
for(i=1;i<17;i=i+1) begin
data_padding[i*18 +:18] = {q[(i-1)*16],q[(i-1)*16 +: 16],q[i*16-1]};
end
//count and update
for(i=0;i<16;i=i+1) begin
for(j=0;j<16;j=j+1) begin
neighbour_cnt = data_padding[(i+1)*18+j+1-1]+data_padding[(i+1)*18+j+1+1]+data_padding[i*18+j+1-1]+data_padding[i*18+j+1]+data_padding[i*18+j+1+1]+data_padding[(i+2)*18+j+1-1]+data_padding[(i+2)*18+j+1]+data_padding[(i+2)*18+j+1+1];
if(neighbour_cnt <= 1 | neighbour_cnt >=4)
q_next[i*16+j] = 0;
else if(neighbour_cnt == 3)
q_next[i*16+j] = 1;
else
q_next[i*16+j] = q[i*16+j]; //not change
end
end
end
always @(posedge clk)
begin
if(load)
q <= data;
else
q <= q_next;
end
endmodule
————————————————
感谢您的阅读,如果您有收获,请给我一个三连吧!
如果您觉得这还不够,可以点击 打赏 按钮,告诉我: 你币有了!
我是城外南风起,欢迎关注我的公众号【木叶芯】。
木叶飞舞之处,火亦生生不息。