Verilog移位寄存器
HDLBits链接
前言
今天更新一节寄存器相关内容,其中涉及CRC校验的内容是用线性反馈移位寄存器搭建而成的。
题库
题目描述1:
构建一个4bit的移位寄存器(右移),含异步复位、同步加载和使能
- areset:让寄存器复位为0
- load:加载4bit数据到移位寄存器中,不移位
- ena:使能右移
- q:移位寄存器中的内容
Solution1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| module top_module( input clk, input areset, input load, input ena, input [3:0] data, output reg [3:0] q); always @(posedge clk or posedge areset)begin if(areset)begin q <= 4'b0; end else if(load) begin q <= data; end else if(ena)begin q <= {1'b0,q[3:1]}; end else begin q <= q; end end
endmodule
|
题目描述2:
构建一个100位的左右旋转器,同步load,左右旋转需使能。旋转器从另一端输入移位的位元,不像移位器那样丢弃移位的位元而以零位移位。如果启用,旋转器就会旋转这些位,而不会修改或丢弃它们。
- load:加载100位的移位寄存器数据
- ena[1:0]:2’b01 右转1bit; 2’b10 左转1bit;其他情况不转
- q:旋转器内容
Solution2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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) begin q <= data; end 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
|
题目描述3:
建立一个64位算术移位寄存器,同步加载。移位器可以左右移位,并按数量选择1位或8位的移位。
- load:加载数据
- ena:决定是否移位
- amount:决定移位方向与数量:2’b00:左移1位;2’b01:左移8位;2’b10:右移1位;2’b11:右移8位
- q:寄存器内容(输出)
Solution3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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)begin q <= data; end else begin 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 else begin q <= q; end end end
endmodule
|
题目描述4:
构造线性移位寄存器,reset应当使LFSR归1。
Solution4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| module top_module( input clk, input reset, output [4:0] q ); always @(posedge clk)begin if(reset)begin q <= 5'h1; end else begin q[4] <= 1'b0 ^ q[0]; q[3] <= q[4]; q[2] <= q[3] ^ q[0]; q[1] <= q[2]; q[0] <= q[1]; end end
endmodule
|
题目描述5:
为这个序列电路编写Verilog代码。假设你要在DE1-SoC板上实现这个电路。将R输入连接到SW开关,将时钟连接到密钥[0],将L连接到密钥[1],将Q输出连接到红灯LEDR上。
Solution5:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| module top_module ( input [2:0] SW, input [1:0] KEY, output [2:0] LEDR);
wire clk; assign clk = KEY[0]; always @(posedge clk)begin if(KEY[1])begin LEDR[0] <= SW[0]; LEDR[1] <= SW[1]; LEDR[2] <= SW[2]; end else begin LEDR[0] <= LEDR[2]; LEDR[1] <= LEDR[0]; LEDR[2] <= LEDR[2] ^ LEDR[1]; end end
endmodule
|
题目描述5:
构建一个32位的Galois LFSR,其taps位置为32、22、2和1。
Solution5:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| module top_module( input clk, input reset, output [31:0] q ); integer i; always @(posedge clk)begin if(reset)begin q <= 32'h1; end else begin for(i=0;i<32;i++)begin if((i==21)||(i==1)||(i==0))begin q[i] <= q[i+1] ^ q[0]; end else if(i==31)begin q[31] <= 1'b0 ^ q[0]; end else begin q[i] <= q[i+1]; end end end end
endmodule
|
题目描述6:实现如下电路图
Solution6:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| module top_module ( input clk, input resetn, input in, output out);
reg [3:0] tmp; assign out = tmp[3]; always @(posedge clk)begin if(!resetn)begin tmp <= 4'h0; end else begin tmp <= {tmp[2:0],in}; end end endmodule
|
题目描述7:实现如下电路图
- 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].
Solution7:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| module top_module ( input [3:0] SW, input [3:0] KEY, output [3:0] LEDR ); MUXDFF u1(.clk(KEY[0]), .w(KEY[3]), .R(SW[3]), .E(KEY[1]), .L(KEY[2]), .Q(LEDR[3])); MUXDFF u2(.clk(KEY[0]), .w(LEDR[3]), .R(SW[2]), .E(KEY[1]), .L(KEY[2]), .Q(LEDR[2])); MUXDFF u3(.clk(KEY[0]), .w(LEDR[2]), .R(SW[1]), .E(KEY[1]), .L(KEY[2]), .Q(LEDR[1])); MUXDFF u4(.clk(KEY[0]), .w(LEDR[1]), .R(SW[0]), .E(KEY[1]), .L(KEY[2]), .Q(LEDR[0])); endmodule
module MUXDFF ( input clk, input w,R,E,L, output Q ); wire tmp; assign tmp = E ? w : Q; always @(posedge clk)begin Q <= L? R : tmp; end
endmodule
|
题目描述8:
在这个问题中,你将为一个8x1存储器设计一个电路,在这个电路中,写入到存储器是通过移位来完成的,而读取是“随机访问”,就像在一个典型的RAM中一样。然后您将使用该电路实现一个3输入逻辑功能。
首先,用8个d类型触发器创建一个8位移位寄存器。标记为Q[0]到Q[7]。移位寄存器输入称为S,输入Q[0] (MSB先移位)。使能输入enable控制是否移位,扩展电路使其有3个额外的输入A,B,C和一个输出Z。电路的行为应该如下:当ABC为000时,Z=Q[0],当ABC为001时,Z=Q[1],以此类推。你的电路应该只包含8位移位寄存器和多路复用器。(这个电路称为3输入查找表(LUT))。
Solution8:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| module top_module ( input clk, input enable, input S, input A, B, C, output Z ); reg [7:0] Q; always @(posedge clk)begin if(enable)begin Q <= {Q[6:0],S}; end else begin Q <= Q; end end assign Z = Q[{A,B,C}];
endmodule
|
小结
今天更新了部分移位寄存器部分的答案,注意最后一题用了一些技巧来简化代码书写,但实现时电路并无差异,体现了HDL中Describe的特性。