题目介绍

题目链接

Conwaylife

简介

题目要求我们实现一个康威生命游戏的电路。

该游戏在一个二维网格空间中进行,在该题目中是 16 * 16 的大小,每一个格子都有两种状态(0 或 1),代表死或活。

规则:

  • 在时钟上升沿到来时,网格需要更新。
  • 若信号 load 为高电平,则更新为输入数据 data
  • 若不是,则每个网格的状态更新与它周围八个方向的网格状态有关。
    • 如果它周围八个方向的网格有 2个为活,则保持状态。
    • 如果它周围八方方向的网格有 3个为活,则该网格的状态更新为 1(活)。
    • 其他情况下,该网格状态更新为 0(死)。
  • 网格是二维的,但是存储网格是一维存储的。q[15 : 0] 是第0行, q[31 : 16] 是 第1行
  • 该二维 16 * 16的网格是无边界的,一边会延申到另一对边。

题目分析

解法1

因为是延申的网络,所以我们可以将该 16 * 16的网络直接延申为 18 * 18 的网络。这样,中心 16 * 16 的网格就是我们要更新的,外面的一圈就是环形的延申出的网络。

然后,就可以直接利用循环,避开越界的情况,直接更新了。

解法2

对于某个格子,暴力枚举出它每个方向的 格子情况,然后计算出它周围的存活格子数,再更新它。循环256次,将所有格子更新便可。

那么现在,定义这 8 个方向,分别为(up, down, left, right, up_left, up_right, down_left, down_right)。

变量简记为:

wire [255:0] q_u;
wire [255:0] q_l;
wire [255:0] q_r;
wire [255:0] q_d;
wire [255:0] q_ul;
wire [255:0] q_ur;
wire [255:0] q_dl;
wire [255:0] q_dr;

首先来看,上下左右这四个方向如何计算。

上下方向

原网格定义为,output [255 : 0] q。那么对于编号为 i 的网格单元。它的上方向的网格编号显然是 i - 16

但若 i 单元在第 0 行,那么 i - 16 会是一个负数,实际上,应该是在第 15 行。

所以,利用Verilog的向量拼接运算即可。

assign q_u = {q[239:0], q[255:240]};

同理

assign q_d = {q[15:0], q[255:16]};

左右方向

对于网格单元 i ,左面是 i - 1。但当该单元格在第 0列时,它的左面应该是同一行的第 15列。右面同理。

for (i = 0; i < 16; i ++ ) begin: t1
assign q_l[i * 16 + 15 : i * 16] = {q[i * 16 + 15 - 1 : i * 16], q[i * 16 + 15]};
assign q_r[i * 16 + 15 : i * 16] = {q[i * 16], q[i * 16 + 15 : i * 16 + 1]};
end
对角线方向

当处理对角线的情况时候,就不能与上下左右同理了。

你会发现特殊情况(越界)有很多(一行和一列),所以这时候,直接利用之前算出的上下方向,结合左右方向的计算过程,就可以得出 对角线方向了。

网格单元 i 的上面的左面,不就是左上嘛?

代码实现

代码中涉及generate for块。

module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q ); wire [255:0] q_u;
wire [255:0] q_l;
wire [255:0] q_r;
wire [255:0] q_d;
wire [255:0] q_ul;
wire [255:0] q_ur;
wire [255:0] q_dl;
wire [255:0] q_dr;
integer j;
reg [3:0] cnt; assign q_u = {q[239:0], q[255:240]};
assign q_d = {q[15:0], q[255:16]}; genvar i;
generate
for (i = 0; i < 16; i ++ ) begin: t1
assign q_l[i * 16 + 15 : i * 16] = {q[i * 16 + 15 - 1 : i * 16], q[i * 16 + 15]};
assign q_r[i * 16 + 15 : i * 16] = {q[i * 16], q[i * 16 + 15 : i * 16 + 1]}; assign q_ul[i * 16 + 15 : i * 16] = {q_u[i * 16 + 15 - 1 : i * 16], q_u[i * 16 + 15]};
assign q_ur[i * 16 + 15 : i * 16] = {q_u[i * 16], q_u[i * 16 + 15 : i * 16 + 1]}; assign q_dl[i * 16 + 15 : i * 16] = {q_d[i * 16 + 15 - 1 : i * 16], q_d[i * 16 + 15]};
assign q_dr[i * 16 + 15 : i * 16] = {q_d[i * 16], q_d[i * 16 + 15 : i * 16 + 1]};
end
endgenerate always @(posedge clk) begin
if (load) begin
q <= data;
end
else begin
for (j = 0; j < 256; j = j + 1) begin
cnt = q_u[j] + q_d[j] + q_l[j] + q_r[j] + q_ul[j] + q_ur[j] + q_dl[j] + q_dr[j];
case (cnt)
4'd2: q[j] <= q[j];
4'd3: q[j] <= 1;
default: q[j] <= 0;
endcase
end
end
end
endmodule

generate for

generate for的主要功能就是对模块或组件以及always块、assign语句进行复制。

使用 generate for的时候,必须要注意以下几点要求

  • 在使用generate for的时候必须先声明一个 genvar变量,用作 for的循环变量。genvar是generate语句中的一种变量类型,用于在generate for语句中声明一个正整数的索引变量。
  • for里面的内嵌语句,必须写在begin-end
  • 尽量对begin-end顺序块进行命名

generate for的语法示例如下:

genvar i;
generate for (i = 0; i < 4; i = i + 1) begin: gen_assign_temp
assign temp[i] = indata[2 * i + 1 : 2 * i];
end
endgenerate

随机推荐

  1. 未来之JavaScript做嵌入式

    只听说过汇编,c做嵌入式,从不曾想JAVAScript也牛到涉入硬件领域了,原本对他的思维定格就是一个浏览器脚本.看来真应了那句话'只有想不到,没有做不到' 话不多说看看这些大佬的帖子在嵌入式设备中使 ...

  2. odoo开发教程六:工作流、安全机制、向导

    一:工作流 工作流是与业务流程相关联的模型,可用于跟踪工序的动态演变过程. 工作流.活动(节点或操作).转换通常在xml里以record定义.在工作流中处理的单个流程称为工作项. 与模型关联的工作流是 ...

  3. 最全面的Mybatis面试八股文

    Mybatis是什么? MyBatis框架是一个开源的数据持久层框架. 它的内部封装了通过JDBC访问数据库的操作,支持普通的SQL查询.存储过程和高级映射,几乎消除了所有的JDBC代码和参数的手工设 ...

  4. Ascend C sqrt算子实战

    摘要:编写一个Ascend C的sqrt算子,并通过内核调用方式在cpu和npu模式下进行验证. 本文分享自华为云社区<[2023 · CANN训练营第一季]--Ascend C sqrt算子实 ...

  5. 明解STM32—GPIO应用设计篇之IO外部中断EXTI原理及使用方法

    ​一.前言 在之前针对STM32的GPIO相关API函数及配置使用进行了详细的介绍,GPIO作为输入引脚时,调用相关读信号引脚函数接口就可以在程序的循环中,轮询的对输入信号进行读取检测操作,除了轮询的 ...

  6. 驱动开发:摘除InlineHook内核钩子

    在笔者上一篇文章<驱动开发:内核层InlineHook挂钩函数>中介绍了通过替换函数头部代码的方式实现Hook挂钩,对于ARK工具来说实现扫描与摘除InlineHook钩子也是最基本的功能 ...

  7. Linux系统运维之Zookeeper集群配置

    一.简介 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.ZooKeeper的目标就是封装好复杂易 ...

  8. 据说,Transformer 不能有效地进行时间序列预测?

    简介 几个月前,我们介绍了 Informer 这个模型,相关论文 (Zhou, Haoyi, et al., 2021) 是一篇获得了 AAAI 2021 最佳论文奖的时间序列论文.我们也展示了一个使 ...

  9. Visual Studio Code安装C#开发工具包并编写ASP.NET Core Web应用

    前言 前段时间微软发布了适用于VS Code的C#开发工具包(注意目前该包还属于预发布状态但是可以正常使用),因为之前看过网上的一些使用VS Code搭建.NET Core环境的教程看着还挺复杂的就一 ...

  10. 跟着 GPT-4 从0到1学习 Golang 并发机制(一)

    目录 一.前言 二.开聊 2.1 Golang 里的并发机制介绍 2.2 Goroutine 与线程 2.3 Goroutine 与线程的调度开销 2.4 用户态和内核态 2.5 Golang 并发编 ...