Verilog Circuits-Sequential Logic -More Circuits
作者:互联网
Problem 115 :Rule90
一个具有特殊规则的一维序列
规则很简单。一维序列中元素有 1,0 两种状态,分别对应开,关状态。
在每个时钟边沿到来时刻,元素的下一个状态为元素相邻两个元素的异或。
下表更详细地给出了跳变的规则,(可以视为状态转移表),元素下一个状态可以视作输出,输入为元素本身的状态与相应两个相邻元素的当前状态。
对于需要实现的电路,创建一个拥有 512 个元素的序列 (q[511:0]),每个时钟周期按照上述规则变换。load 信号有效时,序列更新 data 信号值为初始值。另外假设所有边界的值为 0 (q[-1] 以及 q[512])
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q );
always @(posedge clk)
begin
if(load)
q<=data;
else
begin
q<={1'b0,q[511:1]}^{q[510:0],1'b0};//异或左右邻居矩阵,左右邻居矩阵分别是原矩阵右移或者左移并补零得到
end
end
endmodule
- 网友的 solution
//Problem 115 Rule90解题太麻烦了,如下写法即可:
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q );
always @(posedge clk) begin
if (load)
q <= data;
else
q <= (q<<1)^(q>>1); //for太麻烦,参考答案也太麻烦了。
end
endmodule
Problem 116:Rule 110
依然是一维序列题
规则:一维序列中元素有 1,0 两种状态,分别对应开,关状态。
在每个时钟边沿到来时刻,元素的下一个状态取决于元素本身的状态与前后两个相邻元素的当前状态。下表详细地给出了跳变的规则
Left | Center | Right | Center's next state |
---|---|---|---|
1 | 1 | 1 | 0 |
1 | 1 | 0 | 1 |
1 | 0 | 1 | 1 |
1 | 0 | 0 | 0 |
0 | 1 | 1 | 1 |
0 | 1 | 0 | 1 |
0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 |
对于需要实现的电路,创建一个拥有 512 个元素的序列 (q[511:0]),每个时钟周期按照上述规则变换。load 信号有效时,序列更新 data 信号值为初始值。另外假设所有边界的值为 0 (q[-1] q[512])
-
与上题的区别就是没有给出关系式(上题是异或),所以我们首先需要找出状态转移规则。于是把上表转换成真值表来寻找规则,输入为三个信号,left,center,right,输出信号为:next_state
-
这题用卡诺图化简,得逻辑表达式为:\(OUT = Center\^{} Right + (Center · \~{}Left )\)
module top_module(
input clk,
input load,
input [511:0] data,
output [511:0] q
);
int i;
always @(posedge clk)
begin
if(load)
q<=data;
else
begin
q[0]<=q[0];
q[511] <= (q[511]^q[510])||(q[511]);
for(i = 1; i<511;i=i+1)
q[i] <= (q[i]^q[i-1])|(q[i]&!q[i+1]);
end
end
endmodule
Problem 117:Conway's Game of life 16*16
升级版,二维序列,即二维矩阵
规则:元素的下一个状态取决于当前状态九宫格中的 8 个邻居元素中 1 的个数,当邻居有 n 个 1 时,
- 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] 代表第二行,以此类推。
load 信号有效时,更新 q 信号值为初始值 data, q 每个周期变换一次。
module top_module(
input clk,
input load,
input [255:0] data,
output [255:0] q );
//抄一遍代码试试
int idx_up,idx_down,idx_right,idx_left,idx_ul,idx_ur,idx_dl,idx_dr;//
reg [3:0]u,d,l,r;
reg [3:0]qtemp[255:0];
reg [255:0]qcomp;
always @(posedge clk)//每个周期赋值
begin
if(load)
q<=data;
else
q<=qcomp;
end
always @(*)
begin
for(int i=0;i<16;i++)
for(int j=0;j<16;j++)
begin
u=i[3:0]+1;//行数
d=i[3:0]-1;
l=j[3:0]-1;
r=j[3:0]+1;//列数
idx_up=u*16+j;//第几个
idx_down=d*16+j;
idx_right=i*16+r;//当前行的某一列
idx_left=i*16+l;
idx_ul=u*16+l;
idx_ur=u*16+r;
idx_dl=d*16+l;
idx_dr=d*16+r;
qtemp[i*16+j]=q[idx_up]+q[idx_down]+q[idx_left]+q[idx_right]+q[idx_ul]+q[idx_ur]+q[idx_dl]+q[idx_dr];
qcomp[i*16+j] = qtemp[i*16+j]==2? q[i*16+j]:( qtemp[i*16+j]==3?1:0);
end
end
endmodule
标签:load,idx,clk,Circuits,元素,module,Sequential,input,More 来源: https://www.cnblogs.com/zjj666/p/15690324.html