提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
一、More Circuits
1.Rule 90
Practice:In this circuit, create a 512-cell system (q[511:0]), and advance by one time step each clock cycle. The load input indicates the state of the system should be loaded with data[511:0]. Assume the boundaries (q[-1] and q[512]) are both zero (off).
翻译:Rule90 是一道根据一些有趣的规则来生成一维序列的题目。
规则很简单:一维序列中元素有 1、0 两种状态,分别对应开、关状态。在每个时钟边沿到来时刻,元素的下一个状态为元素相邻两个元素的异或。下表更详细地给出了跳变的规则(可以视为状态转移表),元素下一个状态可以视作输出,输入为元素本身的状态与相应两个相邻元素的当前状态。
(“Rule90” 这个名字来自表中 “next state 下一状态” 这一栏:01011010是十进制的90。)
对于需要实现的电路,创建一个拥有 512 个元素的序列 (q[511:0]),在每个时钟周期前进一个时间步长。load 信号有效时,序列更新 data 信号值为初始值。假设所有边界的值为 0 (包括 q[-1] 以及 q[512])。
Solution(不唯一,仅供参考):
module top_module(
input clk,
input load,
input [511:0] data,
output reg [511:0] q );
always @(posedge clk)begin
if(load)begin
q<=data;
end
else begin
q[0]<=q[1]^0;
q[511]<=0^q[510];
for(int i=1;i<511;i++)
q[i]<=q[i+1]^q[i-1];
end
end
endmodule
方法二
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q );
always @(posedge clk)begin
if(load)
q[511:0] <= data[511:0];
else
q <= (q<<1'b1)^(q>>1'b1);
end
endmodule
Timing Diagram
2.Rule 110
Practice:Build a 100-bit left/right rotator, with synchronous load and left/right enable. A rotator shifts-in the shifted-out bit from the other end of the register, unlike a shifter that discards the shifted-out bit and shifts in a zero. If enabled, a rotator rotates the bits around and does not modify/discard them.
翻译:构建一个100位的左右旋转器,同步load,左右旋转需使能。旋转器从另一端输入移位的位元,不像移位器那样丢弃移位的位元而以零位移位。如果启用,旋转器就会旋转这些位,而不会修改或丢弃它们。
- load:加载100位的移位寄存器数据
- ena[1:0]:2’b01 右转1bit; 2’b10 左转1bit;其他情况不转 q:旋转器内容
提示:本题与上题的区别在于,右移后最低位不舍弃,而是将其放到最高位上;右移后最高位不舍弃,而是将其放到最低位上。比较类似流水灯的效果。此外,设计到左移和右移的选择,所以就可以使用case语句做选择。
Solution(不唯一,仅供参考):
OUT = Center ^ Right + (Center · ~Left )
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[510:0],1'b0}^q) | (q&~{1'b0,q[511:1]});
end
end
endmodule
Timing Diagram
3.Conway’s Game of Life 16*16
Practice:The “game” is played on a two-dimensional grid of cells, where each cell is either 1 (alive) or 0 (dead). At each time step, each cell changes state depending on how many neighbours it has:
- 0-1 neighbour: Cell becomes 0.
- 2 neighbours: Cell state does not change.
- 3 neighbours: Cell becomes 1.
- 4+ neighbours: Cell becomes 0.
翻译:
康威的生命游戏:“游戏”在二维单元格网格上进行,其中每个单元格为1(生存)或0(死亡)。在每个时间步长,每个小区都会根据其具有的邻居数量来更改状态:
- 0-1个邻居:单元格变为0。
- 2个邻居:单元格状态不变。
- 3个邻居:单元格变成1。
- 4个以上邻居:单元格变为0。
方便做题起见,本题中的这个二维矩阵设定为 16x16,广义上可以是无限的。为了让事情变得更加有趣,这个 16x16 矩阵的边界进行循环处理,回卷到对边,上边界的上一行为下边界,左边界的左一列为右边界。比如元素 (0,0) 共有 8 个邻居 : (15,1), (15,0), (15,15), (0,1), (0,15), (1,1), (1,0) 以及 (1,15)。
这个 16x16 矩阵表示为 256bit 长度的向量 q,其中 q[15:0] 代表第一行,q[31:16] 代表第二行,以此类推。(HDLBit 支持使用 SystemVerilog,所以你也可以使用二维向量表示这个矩阵。)
- load:在下一个时钟沿将数据加载到 q 中,用于加载初始状态。
- q:游戏的 16x16 当前状态,每个时钟周期更新。
Solution(不唯一,仅供参考):
找到在每一条边和每一个角的数的规律即可
module top_module(
input clk,
input load,
input [255:0] data,
output reg [255:0] q );
reg [3:0] count;
integer i;
always @(posedge clk)begin
if(load)
q<=data;
else
for(i=0;i<256;i++)begin
if(i==0) begin
count= q[1]+q[15]+q[16]+q[17]+q[31]+q[240]+q[241]+q[255];
end
else if(i==15)begin
count= q[14]+q[31]+q[255]+q[0]+q[30]+q[16]+q[240]+q[254];
end
else if(i==240)begin
count= q[224]+q[241]+q[255]+q[0]+q[225]+q[1]+q[239]+q[15];
end
else if(i==255)begin
count= q[239]+q[254]+q[15]+q[240]+q[0]+q[14]+q[238]+q[224];
end
else if(i>0&&i<15)begin
count= q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17]+q[i+239]+q[i+240]+q[i+241];
end
else if(i>240&&i<255)begin
count= q[i-1]+q[i+1]+q[i-15]+q[i-16]+q[i-17]+q[i-239]+q[i-240]+q[i-241];
end
else if(i%16==0)begin
count= q[i+1]+q[i+15]+q[i+31]+q[i+16]+q[i-1]+q[i-15]+q[i-16]+q[i+17];
end
else if(i%16==15)begin
count= q[i+1]+q[i+15]+q[i-31]+q[i+16]+q[i-1]+q[i-15]+q[i-16]+q[i-17];
end
else begin
count= q[i+1]+q[i-1]+q[i-17]+q[i-16]+q[i-15]+q[i+15]+q[i+16]+q[i+17];
end
case(count)
4'd2: q[i] <= q[i];
4'd3: q[i]<=1'b1;
default:q[i]<=1'b0;
endcase
end
end
endmodule
总结
继续加油!!!!!