Veloris.
返回索引
FPGA 2025-10-21

移位寄存器设计

2 分钟
469 words

移位寄存器设计

什么是移位寄存器

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

如图所示

image.png

移位寄存器的功能

  • 数据的串行与并行转换:
    • 串行输入并行输出 (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
End of file.