问题一 shift register
Write a top-level Verilog module (named top_module) for the shift register, assuming that n = 4. Instantiate four copies of your MUXDFF subcircuit in your top-level module. Assume that you are going to implement the circuit on the DE2 board.
Connect the R inputs to the SW switches,
clk to KEY[0],
E to KEY[1],
L to KEY[2], and
w to KEY[3].
Connect the outputs to the red lights LEDR[3:0].
最直观想到的办法是在子模块中设置一个二选一组合逻辑,例如:
module MUXDFF (
input clk,
input a,
input w,
input e,
input l,
input r,
output q
);
wire mid, d;
assign mid = (e==1'b0)?a:w;
assign d = (l==1'b0)?mid:r;
always@(posedge clk) begin
q<=d; end
endmodule
但是其实,仔细观察这两个二选一选择器,会发现逻辑是:
L为高电平:输出R
E为高电平:输出W
都不是:输出上一个时钟的输出结果Q
因此,一个新的代码为(减少需要出现的新端口和代码复杂性):
module top_module (
input [3:0] SW,
input [3:0] KEY,
output [3:0] LEDR
); //
MUXDFF mod0(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(LEDR[1]),.r(SW[0]),.q(LEDR[0]));
MUXDFF mod1(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(LEDR[2]),.r(SW[1]),.q(LEDR[1]));
MUXDFF mod2(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(LEDR[3]),.r(SW[2]),.q(LEDR[2]));
MUXDFF mod3(.clk(KEY[0]),.e(KEY[1]),.l(KEY[2]),.w(KEY[3]),.r(SW[3]),.q(LEDR[3]));
endmodule
module MUXDFF (
input clk,
input e,
input l,
input w,
input r,
output q
);
always@(posedge clk) begin
if(l) q<=r;
else if (e) q<=w;
else q<=q;
end
endmodule
还有需要注意的一点是,只有Q3的w输入来自于KEY[3],其余的来自于Q[i+1]
问题二 Conway’s game
Conway’s Game of Life is a two-dimensional cellular automaton.
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.
The game is formulated for an infinite grid. In this circuit, we will use a 16x16 grid. To make things more interesting, we will use a 16x16 toroid, where the sides wrap around to the other side of the grid. For example, the corner cell (0,0) has 8 neighbours: (15,1), (15,0), (15,15), (0,1), (0,15), (1,1), (1,0), and (1,15). The 16x16 grid is represented by a length 256 vector, where each row of 16 cells is represented by a sub-vector: q[15:0] is row 0, q[31:16] is row 1, etc. (This tool accepts SystemVerilog, so you may use 2D vectors if you wish.)
load: Loads data into q at the next clock edge, for loading initial state.
q: The 16x16 current state of the game, updated every clock cycle.
The game state should advance by one timestep every clock cycle.
第一步:将1616的二维数组扩展为1818的二维数组
第二步:使用加法对每个单元格进行计数,对于d_loop来讲,只对[1:16][1:16]的范围进行计数,即对应着原二维数组[0:15][0:15]的全计数
第三步:使用case语句进行判断
第四步:将二维数组转为一维数组进行输出
module top_module(
input clk,
input load,
input [255:0] data,
output reg [255:0] q
);
//填充思路
wire [15:0] d [15:0];
wire [17:0] d_loop [17:0];
//第0行和第17行单独写
assign d_loop[0][17:0] = {q[240],q[255:240],q[255]};
assign d_loop[17][17:0] = {q[0],q[15:0],q[15]};
//1-16行有规律可循
integer m;
always@(*) begin
for (m=0;m<16;m=m+1) begin
d_loop[(m+1)][17:0] = {q[16*m],q[16*m +:16],q[16*m+15]};
end
end
//计数并判断
integer i,j;
reg [3:0] count [17:0][17:0];
always@(*) begin
for (i=1;i<17;i=i+1) begin
for (j=1;j<17;j=j+1) begin
count[i][j]=
d_loop[i-1][j-1]+d_loop[i-1][j]+d_loop[i-1][j+1]+
d_loop[i][j-1]+d_loop[i][j+1]+
d_loop[i+1][j-1]+d_loop[i+1][j]+d_loop[i+1][j+1];
case (count[i][j])
4'd2: d[i-1][j-1]=d_loop[i][j];
4'd3: d[i-1][j-1]=1'b1;
default: d[i-1][j-1] = 1'b0;
endcase
end
end
end
//二维数组转为一维数组输出
always@(posedge clk) begin
if(load) q<=data;
else q <= {d[15][15:0],d[14][15:0],d[13][15:0],d[12][15:0],
d[11][15:0],d[10][15:0],d[9][15:0],d[8][15:0],
d[7][15:0],d[6][15:0],d[5][15:0],d[4][15:0],
d[3][15:0],d[2][15:0],d[1][15:0],d[0][15:0]};
end
endmodule