参考链接:HDLBits导学
Problem 106 4-bit shift register
问题:设计一个4bit异步复位,拥有同步置位和使能的右移移位寄存器。
- areset : 寄存器复位为0
- load : 将data[3:0]输入至移位寄存器中
- ena : 使能信号控制向右移动(q[3]q[2]q[1]q[0] ---> 0q[3]q[2]q[1],q[0]在移动后消失了,原先q[3]的位置变为0)
- q : 移位寄存器中的数据
如果ena和load同时为高,load有更高的优先级。
思路:使用拼接来实现移位
解决:
module top_module(
input clk,
input areset, // async active-high reset to zero
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
always @(posedge clk or posedge areset) begin
if(areset)
q <= 4'd0000;
else if(load)
q <= data;
else if(ena)
q <= {0,q[3],q[2],q[1]};
//q <= {0,q[3:1]};
else
q <= q;
end
endmodule
Problem 107 Left/right rotator
问题:设计一个100bit的可左移或右移的移位寄存器,附带同步置位和左移或右移的使能信号。本题中,移位寄存器在左移或右移时,不同于Problem106的补0和直接舍弃某一bit位,本题是要求在100bit内循环移动,不舍弃某一bit位同时也不补0。
比如说左移1bit,在Problem106就是补0和丢弃q[0]。而在本题中左移1bit为{q[0], q[99:1]}。
- load:load信号将data[99:0] 输入至寄存器内。
- ena[1:0] 信号选择是否移位和移位的具体方向
- 2'b01 右移一位
- 2'b10 左移一位
- 2'b00 和 2'b11不移动
- q:移位后寄存器内的数据
解决:
module top_module(
input clk,
input load,
input [1:0] ena,
input [99:0] data,
output reg [99:0] q);
always @(posedge clk) begin
if(load)
q <= data;
else begin
case(ena)
2'b01:q <= {q[0],q[99:1]};
2'b10:q <= {q[98:0],q[99]};
default:q <= q;
endcase
end
end
endmodule
Problem 108 Left/right arithmetic shift by 1 or 8
问题:构建一个 64 位算术移位寄存器,同步加载。移位器可以向左和向右移动 1 位或 8 位,由数量选择。
一个算术中数的符号位右移时(移位寄存器Q [63]在这种情况下),而不是通过补零进行逻辑右移。考虑算术右移的另一种方式是假设被移位的数是有符号的并保留符号,因此算术右移会将有符号数除以 2 的幂。
逻辑和算术左移之间没有区别。
- load:使用data[63:0]加载移位寄存器而不是移位。
- ena : 选择是否移动。
- 数量:选择移动的方向和移动量。
- 2'b00 : 左移 1 位。
- 2'b01:左移 8 位。
- 2'b10 : 右移 1 位。
- 2'b11:右移 8 位。
- q : 移位器的内容。
思路:算术右移中,补的是高位的数据,也要考虑保留的是哪几位
解决:
module top_module(
input clk,
input load,
input ena,
input [1:0] amount,
input [63:0] data,
output reg [63:0] q);
always @(posedge clk) begin
if(load)
q <= data;
else if(ena) begin
case(amount)
2'b00: q <= {q[62:0],1'b0};
2'b01: q <= {q[55:0],8'b0};
2'b10: q <= {q[63],q[63:1]};
2'b11: q <= {{8{q[63]}},q[63:8]};
endcase
end
end
endmodule
Problem 109 5-bit LFSR
概述:线性反馈移位寄存器(LFSR)是通常带有几个XOR门来产生下一状态的移位寄存器。Galois LFSR是一个特殊的移位寄存器。其中带有"tap"位的位置与输出位XOR产生下一个值没有"tap"位标志的正常移位。如果"tap"位置经过仔细选择后,LFSR将设置为最大长度。再重复之前LFSR的最大长度为2^n-1
问题:下图所示LFSR为在位置5和位置3包含"tap"位的5-bit最大长度LFSR。开始为位置1,输入为0
解决:
module top_module(
input clk,
input reset, // Active-high synchronous reset to 5'h1
output [4:0] q
);
always @(posedge clk) begin
if(reset)
q <= 5'd1;
else
q = {1'b0^q[0],q[4],q[3]^q[0],q[2],q[1]};
end
endmodule
Problem 110 3-bit LFSR
问题:使用 Verilog 实现下图中的时序电路,(可以使用子模块进行构建,但顶层要命名为 top_module)。假设你要在 DE1-SoC 教学板上实现这个电路,将输入端口 r 连接到板子上的拨动开关,clock 端口接到按键 KEY[0],端口 L 接到按键 KEY[1]。输出端口 Q 连接到板子上的红色 LED
解决:
module top_module (
input [2:0] SW, // R
input [1:0] KEY, // L and clk
output [2:0] LEDR); // Q
wire [2:0]d;
assign d[0] = KEY[1] ? SW[0] : LEDR[2];
assign d[1] = KEY[1] ? SW[1] : LEDR[0];
assign d[2] = KEY[1] ? SW[2] : LEDR[1]^LEDR[2];
always @(posedge KEY[0]) begin
LEDR = {d[2],d[1],d[0]};
end
endmodule
Problem 111 32-bit LFSR
问题:参考109题中的 5bit LFSR,实现一个 32bit LFSR,在位位置 32、22、2 和 1 处抽头
提示:32bit 的 LFSR 最好使用向量实现,而不是例化 32 个触发器
思路:抽头就是要和第0位异或的位置
还有个要考虑的问题也许就是拼接的时候某一段有多长的问题
有个小窍门就是它是顺着下去的,比如在22的位置抽头,那就是这个位置前一个位置的输出和q[0]的异或,然后在此前面保持不变的那一段就应该是从最高位到23位,也就是没有重复使用的位
解决:
module top_module(
input clk,
input reset, // Active-high synchronous reset to 32'h1
output [31:0] q
);
always @(posedge clk) begin
if(reset)
q <= 32'd1;
else
q <= {1'b0^q[0],q[31:23],q[22]^q[0],q[21:3],q[2]^q[0],q[1]^q[0]};
end
endmodule
Problem 112 Shift Register(Exams/m2014 q4k)
问题:实现下图中的电路
解决:
module top_module (
input clk,
input resetn, // synchronous reset
input in,
output out);
reg [2:0]d;
always @(posedge clk) begin
if(!resetn) begin
out <= 1'b0;
d <= 3'd0;
end
else begin
d <= {in,d[2],d[1]};
out <= d[0];
end
end
endmodule
注意:中间变量d在复位的时候要记得清零,还有搞清楚最后结果是在第几个时钟沿输出的
Problem 113 Shift Register(Exams/m2014 q4b)
问题:考虑如下所示的n位移位寄存器电路:
为移位寄存器编写一个顶层 Verilog 模块(名为 top_module),假设n = 4。在顶层模块中实例化 MUXDFF 子电路。假设您要在 DE2 板上实现电路。
- 将R输入连接到SW开关,
- 时钟到KEY[0] ,
- E到KEY[1] ,
- L到KEY[2],
- w到KEY[3]
- 将输出连接到红灯LEDR[3:0]
- (重复使用来自Problem 91的电路)
解决:
module top_module (
input [3:0] SW,
input [3:0] KEY,
output [3:0] LEDR
);
MUXDFF inst1(
.w(KEY[3]),
.R(SW[3]),
.E(KEY[1]),
.L(KEY[2]),
.clk(KEY[0]),
.Q(LEDR[3])
);
MUXDFF inst2(
.w(LEDR[3]),
.R(SW[2]),
.E(KEY[1]),
.L(KEY[2]),
.clk(KEY[0]),
.Q(LEDR[2])
);
MUXDFF inst3(
.w(LEDR[2]),
.R(SW[1]),
.E(KEY[1]),
.L(KEY[2]),
.clk(KEY[0]),
.Q(LEDR[1])
);
MUXDFF inst4(
.w(LEDR[1]),
.R(SW[0]),
.E(KEY[1]),
.L(KEY[2]),
.clk(KEY[0]),
.Q(LEDR[0])
);
endmodule
module MUXDFF (
input clk,
input w, R, E, L,
output Q
);
wire d = L ? R : (E ? w : Q) ;
always @(posedge clk) begin
Q <= d;
end
endmodule
注意:第一级的w的输入值是KEY[3],后面每一级的w输入值是前一级的输出值
Problem 114 Shift Register(Exams/m2014 q4k)
问题:本题中实现的是一个和 8x1 结构的存储体相关的电路。存储的输入通过移入比特进行,存储的读取类似于传统 RAM 中的随机读取,也可以指定读出比特的位置,通过 3 个输入端口指定读取位置。
首先通过 8 个触发器实现一个 8bit 深的移位寄存器。8个寄存器的输出依次为 Q[0]...Q[7]。移位寄存器的输入为 S,输入首先会填充到 MSB(最高位),Q[0]。当 enable 信号控制移位,当其有效时输入数据并移位。此外,该电路有三个输入端口 A,B,C 以及输出端口 Z。工作的功能如下:当 ABC = 000 时,Z = Q[0],当 ABC = 001 时,Z = Q[1],以此类推。你的电路中只能包括一个 8bit 移位寄存器以及一个多路选择器。(这就是个三输入查找表 LUT 电路)
解决:
module top_module (
input clk,
input enable,
input S,
input A, B, C,
output Z );
reg [7:0] Q;
assign Z = Q[{A,B,C}];
always @(posedge clk) begin
if(enable) begin
Q <= {Q[6:0],S};
end
else begin
Q <= Q;
end
end
endmodule
注意:输出不受时钟和使能信号控制的,使能信号只是控制移位