移位寄存器设计
什么是移位寄存器
移位寄存器是由一系列触发器(Flip-Flops)串联构成,它们能够存储二进制数据,并能将数据一位一位地向左或向右移动。每个触发器存储一位数据。
如图所示

移位寄存器的功能
- 数据的串行与并行转换:
- 串行输入并行输出 (SIPO):将串行输入的数据一位一位地移入寄存器,当所有位都移入后,可以同时从所有触发器的输出端并行读取数据。
- 并行输入串行输出 (PISO):将并行输入的数据一次性加载到寄存器中,然后通过时钟脉冲将数据一位一位地从串行输出端移出。
- 串行输入串行输出 (SISO):数据一位一位地移入,再一位一位地移出,常用于数据的延时或缓冲。
- 并行输入并行输出 (PIPO):数据并行加载,并行输出,这其实就是普通的并行寄存器,移位功能通常不作为其主要特点。
- 数据缓存/存储: 作为临时存储器来存储一定位宽的数据。
- 数据处理:
- 移位运算: 实现数据的左移、右移,这在数字信号处理、算术运算(乘除法)中非常有用。
- 序列发生器: 可以根据特定逻辑产生重复的二进制序列,例如伪随机序列发生器(LFSR - Linear Feedback Shift Register)。
移位寄存器的Verilog实现
在Verilog中,移位寄存器通常通过always @(posedge clk)块和非阻塞赋值(<=)来实现,结合移位操作符(<<, >>)或位拼接操作符({})。
示例:一个4位串行输入并行输出(SIPO)的移位寄存器
module sipo_shift_register (
input clk, // 时钟
input rst, // 复位
input data_in, // 串行数据输入
output reg [3:0] q_out // 并行数据输出
);
always @(posedge clk or posedge rst) begin
if (rst)
q_out <= 4'b0000; // 复位时清零
else
// 将data_in移入最右边一位,其他位左移
q_out <= {q_out[2:0], data_in};
// 移位效果:
// 时刻T0: q_out = {0,0,0,0}, data_in = D0 -> q_out = {0,0,0,D0}
// 时刻T1: q_out = {0,0,D0,D1}
// 时刻T2: q_out = {0,D0,D1,D2}
// 时刻T3: q_out = {D0,D1,D2,D3}
end
endmodule
示例:一个4位循环左移寄存器
module circular_shift_register (
input clk, // 时钟
input rst, // 复位
input [3:0] data_in, // 并行加载数据
output reg [3:0] q_out // 输出
);
always @(posedge clk or posedge rst) begin
if (rst)
q_out <= 4'b0001; // 复位初始值
else
// 循环左移:将最高位移到最低位
q_out <= {q_out[2:0], q_out[3]};
// 移位效果:
// 0001 -> 0010 -> 0100 -> 1000 -> 0001 (循环)
end
endmodule
示例:一个4位循环右移寄存器
module circular_shift_register (
input clk, // 时钟
input rst, // 复位
input [3:0] data_in, // 并行加载数据
output reg [3:0] q_out // 输出
);
always @(posedge clk or posedge rst) begin
if (rst)
q_out <= 4'b0001; // 复位初始值
else
// 循环右移:将最低位移到最高位
q_out <= {q_out[0], q_out[3:1]};
// 移位效果:
// 0001 -> 0010 -> 0100 -> 1000 -> 0001 (循环)
end