Skip to main content

2 Shift register

移位寄存器有多种变体,按功能、数据流方向和输入/输出方式可以分为以下几类。下面给出每类的典型可综合实现。


1. 双向移位寄存器(Bidirectional Shift Register)​

可左移、右移或保持,常用于位操作、数据重排。

//=============================================================================
// Bidirectional Shift Register with Synchronous Reset and Enable
//
// - dir = 2'b00 : hold
// - dir = 2'b01 : shift left (towards MSB)
// - dir = 2'b10 : shift right (towards LSB)
// - dir = 2'b11 : parallel load
//=============================================================================
module shift_reg_bidir #(
parameter int WIDTH = 8
) (
input logic clk,
input logic rst,
input logic en,
input logic [1:0] dir, // Direction / load control
input logic serial_in, // Serial input for left/right shift
input logic [WIDTH-1:0] parallel_in,
output logic [WIDTH-1:0] data_out
);

always_ff @(posedge clk) begin
if (rst) begin
data_out <= '0;
end
else if (en) begin
case (dir)
2'b00: data_out <= data_out; // Hold
2'b01: data_out <= {data_out[WIDTH-2:0], serial_in}; // Left
2'b10: data_out <= {serial_in, data_out[WIDTH-1:1]}; // Right
2'b11: data_out <= parallel_in; // Load
endcase
end
end

endmodule

2. 并行加载移位寄存器(Parallel-In / Serial-Out, PISO)​

常用于 UART、SPI 发送端:并行加载数据,然后逐位串行输出。

//=============================================================================
// Parallel-In Serial-Out (PISO) Shift Register
//
// - load = 1 : parallel data is loaded into the register
// - shift_en = 1 : shift right by one bit, serial_out = LSB
//=============================================================================
module shift_reg_piso #(
parameter int WIDTH = 8
) (
input logic clk,
input logic rst,
input logic load,
input logic shift_en,
input logic [WIDTH-1:0] parallel_in,
output logic serial_out,
output logic [WIDTH-1:0] data_out
);

logic [WIDTH-1:0] shift_reg;

always_ff @(posedge clk) begin
if (rst) begin
shift_reg <= '0;
end
else if (load) begin
shift_reg <= parallel_in;
end
else if (shift_en) begin
shift_reg <= {1'b0, shift_reg[WIDTH-1:1]};
end
end

assign data_out = shift_reg;
assign serial_out = shift_reg[0];

endmodule

3. 串行输入并行输出(Serial-In Parallel-Out, SIPO)​

常用于 UART、SPI 接收端:逐位串行输入,凑满后并行读出。

//=============================================================================
// Serial-In Parallel-Out (SIPO) Shift Register
//
// - shift_en = 1 : shift in one bit from serial_in
// - data_out reflects the current register content (parallel output)
//=============================================================================
module shift_reg_sipo #(
parameter int WIDTH = 8
) (
input logic clk,
input logic rst,
input logic shift_en,
input logic serial_in,
output logic [WIDTH-1:0] data_out
);

always_ff @(posedge clk) begin
if (rst) begin
data_out <= '0;
end
else if (shift_en) begin
data_out <= {data_out[WIDTH-2:0], serial_in};
end
end

endmodule

4. 环形移位寄存器(Ring Counter)​

输出中只有一个 1 在循环移动,常用于状态机、时序控制。

//=============================================================================
// Ring Counter (Rotating Shift Register)
//
// - On reset, only bit 0 is set.
// - On each enabled clock, the '1' rotates to the next position.
//=============================================================================
module ring_counter #(
parameter int WIDTH = 8
) (
input logic clk,
input logic rst,
input logic en,
output logic [WIDTH-1:0] data_out
);

always_ff @(posedge clk) begin
if (rst) begin
data_out <= {{(WIDTH-1){1'b0}}, 1'b1}; // One-hot reset value
end
else if (en) begin
data_out <= {data_out[WIDTH-2:0], data_out[WIDTH-1]}; // Rotate left
end
end

endmodule

5. 约翰逊计数器(Johnson Counter / Twisted Ring)​

环形计数器的变体,反馈取反,产生 2N 个状态。

//=============================================================================
// Johnson Counter (Twisted Ring Counter)
//
// - Feedback is the inverted MSB, producing 2*WIDTH unique states.
//=============================================================================
module johnson_counter #(
parameter int WIDTH = 4
) (
input logic clk,
input logic rst,
input logic en,
output logic [WIDTH-1:0] data_out
);

always_ff @(posedge clk) begin
if (rst) begin
data_out <= '0;
end
else if (en) begin
data_out <= {data_out[WIDTH-2:0], ~data_out[WIDTH-1]};
end
end

endmodule

6. 线性反馈移位寄存器(LFSR)​

用于伪随机序列生成、CRC、加扰、内建自测试。

//=============================================================================
// Fibonacci LFSR (XOR-based, maximal length)
//
// - Taps are parameterized via TAP_MASK.
// - Feedback = XOR of tapped bits.
// - Polynomial example for WIDTH=8: x^8 + x^6 + x^5 + x^4 + 1
// TAP_MASK = 8'b1011_1000 (bits 7,5,4,3)
//=============================================================================
module lfsr_fibonacci #(
parameter int WIDTH = 8,
parameter logic [WIDTH-1:0] SEED = 8'h01,
parameter logic [WIDTH-1:0] TAP_MASK = 8'b1011_1000
) (
input logic clk,
input logic rst,
input logic en,
output logic [WIDTH-1:0] data_out
);

logic feedback;

always_comb begin
feedback = ^(data_out & TAP_MASK); // XOR of tapped bits
end

always_ff @(posedge clk) begin
if (rst) begin
data_out <= SEED;
end
else if (en) begin
data_out <= {data_out[WIDTH-2:0], feedback};
end
end

endmodule

7. 桶形移位器(Barrel Shifter,组合逻辑)​

不是时序移位寄存器,而是纯组合逻辑,任意位数的移位/旋转,常用于 ALU。

//=============================================================================
// Combinational Barrel Shifter
//
// - shift_amt : number of positions to shift (0 .. WIDTH-1)
// - mode : 0 = logical left, 1 = logical right, 2 = rotate left,
// 3 = arithmetic right
//=============================================================================
module barrel_shifter #(
parameter int WIDTH = 8,
parameter int SHIFT_BITS = $clog2(WIDTH)
) (
input logic [WIDTH-1:0] data_in,
input logic [SHIFT_BITS-1:0] shift_amt,
input logic [1:0] mode,
output logic [WIDTH-1:0] data_out
);

always_comb begin
case (mode)
2'd0: data_out = data_in << shift_amt;
2'd1: data_out = data_in >> shift_amt;
2'd2: data_out = (data_in << shift_amt) |
(data_in >> (WIDTH - shift_amt));
2'd3: data_out = $signed(data_in) >>> shift_amt;
endcase
end

endmodule

8. 带时钟使能和异步复位的移位寄存器​

有些设计需要异步复位,复位立即生效,不等待时钟。

//=============================================================================
// Shift Register with Asynchronous Reset and Clock Enable
//
// - rst_async : asynchronous active-high reset
// - en : synchronous shift enable
//=============================================================================
module shift_reg_async_rst #(
parameter int DEPTH = 4,
parameter int DATA_WIDTH = 1
) (
input logic clk,
input logic rst_async,
input logic en,
input logic [DATA_WIDTH-1:0] data_in,
output logic [DATA_WIDTH-1:0] data_out
);

logic [DATA_WIDTH-1:0] shift_reg [0:DEPTH-1];

always_ff @(posedge clk or posedge rst_async) begin
if (rst_async) begin
for (int i = 0; i < DEPTH; i++) begin
shift_reg[i] <= '0;
end
end
else if (en) begin
shift_reg[0] <= data_in;
for (int i = 1; i < DEPTH; i++) begin
shift_reg[i] <= shift_reg[i-1];
end
end
end

assign data_out = shift_reg[DEPTH-1];

endmodule

9. 循环移位寄存器(Rotate Shift Register)​

数据移出后从另一端补回,不丢失信息。

//=============================================================================
// Rotate (Circular) Shift Register
//
// - dir = 0 : rotate left (MSB wraps to LSB)
// - dir = 1 : rotate right (LSB wraps to MSB)
//=============================================================================
module shift_reg_rotate #(
parameter int WIDTH = 8
) (
input logic clk,
input logic rst,
input logic en,
input logic dir,
output logic [WIDTH-1:0] data_out
);

always_ff @(posedge clk) begin
if (rst) begin
data_out <= {{(WIDTH-1){1'b0}}, 1'b1};
end
else if (en) begin
if (dir)
data_out <= {data_out[0], data_out[WIDTH-1:1]}; // Rotate right
else
data_out <= {data_out[WIDTH-2:0], data_out[WIDTH-1]}; // Rotate left
end
end

endmodule

10. 算术移位寄存器(Arithmetic Shift Register)​

右移时保留符号位,用于有符号数除以 2 的幂。

//=============================================================================
// Arithmetic Right Shift Register
//
// - shift_en = 1 : arithmetic right shift by 1 (sign bit replicated)
// - load = 1 : load parallel data
//=============================================================================
module shift_reg_arith #(
parameter int WIDTH = 8
) (
input logic clk,
input logic rst,
input logic load,
input logic shift_en,
input logic [WIDTH-1:0] parallel_in,
output logic [WIDTH-1:0] data_out
);

always_ff @(posedge clk) begin
if (rst) begin
data_out <= '0;
end
else if (load) begin
data_out <= parallel_in;
end
else if (shift_en) begin
data_out <= {data_out[WIDTH-1], data_out[WIDTH-1:1]};
end
end

endmodule

总结对比​

类型关键特征典型应用
通用移位寄存器串入串出,带复位/使能延迟、同步
双向移位寄存器左/右/保持/加载位操作、数据重排
PISO并入串出UART/SPI 发送
SIPO串入并出UART/SPI 接收
环形计数器one-hot 循环状态机、时序控制
约翰逊计数器取反反馈,2N 状态低功耗状态机
LFSR伪随机、CRC加扰、BIST、CRC
桶形移位器组合逻辑,任意移位ALU、地址计算
异步复位版异步复位立即生效上电复位、安全逻辑
循环移位位不丢失加密、哈希
算术移位保留符号位有符号数除法