在本博客中,将围绕许多设计中存在的非常有用的电路(桶形移位器电路)设计电路。将从最简单的方法开始实现固定位宽字的单向旋转桶形移位器,最后设计一个具有可参数化字宽的多功能双向桶形移位器电路。
Barrel Shifter
桶形移位器是一种数字电路,可以将数据字移位指定位数,而不使用任何顺序逻辑,仅使用纯组合逻辑。它有一个控制输入,指定它移动的位数。桶移位器类似于移位寄存器(多位),不同之处在于寄存器的移位位被移回寄存器的另一端。例如,在右移操作中,从寄存器移出的 LSB 被移入 MSB。
桶形移位器适用于数字信号处理器和处理器。
实现桶形移位器的一种方法是作为一系列多路复用器,其中一个多路复用器的输出以取决于移位距离的方式连接到下一个多路复用器的输入。当使用一系列移位多路复用器实现桶式移位器时,对于不同的 k k k 值,每个多路复用器将一个字移位 2 k 2^k 2k 位位置( 1 , 2 , 4 , 8 , 16 , 32... 1,2,4,8,16,32... 1,2,4,8,16,32...)。复用级的数量与输入向量的宽度有关。
下图显示了 32 位字的右移桶形移位器。
通过更复杂的多路复用器和一些用于处理末端填充选项的额外电路,桶形移位器可以处理处理器指令集中的所有标准位移指令。
Simple 8-bit right rotator
从最简单、最直接的方法开始,使用包含所有可能旋转组合的 case 语句,在 Verilog HDL 中对右移桶形移位器进行编程。
将设计一个简单的 8 位桶式移位器,它可以向右旋转任意位数。该电路有一个 8 位数据输入 data 和一个 3 位控制信号 amt,它指定要旋转的量。
该设计使用选定的信号分配语句来详尽地列出 amt 信号和相应旋转结果的所有组合。
使用 case 语句的 SystemVerilog 实现
`timescale 1ns / 10ps
module barrel_shifter_built_case(
input logic [7:0] data,
input logic [2:0] amt,
output logic [7:0] out
);
always_comb
begin
case (amt)
3'o0: out = data;
3'o1: out = {data[0], data[7:1]};
3'o2: out = {data[1:0], data[7:2]};
3'o3: out = {data[2:0], data[7:3]};
3'o4: out = {data[3:0], data[7:4]};
3'o5: out = {data[4:0], data[7:5]};
3'o6: out = {data[5:0], data[7:6]};
default out = {data[6:0], data[7]};
endcase
end
endmodule
Test bench and simulation
测试台使用 for 循环来迭代指示旋转量的信号的所有可能性。
`timescale 1ns / 10ps
module barrel_shifter_built_case_testbench;
logic [7:0] data;
logic [2:0] amt;
logic [7:0] out;
barrel_shifter_built_case uut(.*);
initial begin
for (byte i = 0; i < 8; ++i)
begin
data = 8'b1111_0000; amt = 3'(i); #10;
end
$stop;
end
endmodule
在示波器图像中,可以看到值如何移至右侧 amt 位、LSB 位,以及 MSB 如何填充溢出位,从而从左到右旋转信息。
#### RTL Elaborated Design Schematics
这种设计桶形移位器的方法意味着使用宽 3 至 8 多路复用器
该代码很简单,但意味着一个宽复用器,这使得合成变得困难并导致较大的传播延迟。
如果输入位数增加就会很麻烦。
综合设计原理图
Simple staged 8-bit right rotator
或者,我们可以分阶段构建电路。在第 n n n 级中,输入信号要么直接传递到输出,要么向右旋转 2 n 2^n 2</