简单移位器结构介绍

文章介绍了移位器的不同类型,包括可控移位器和桶形移位器,重点讲述了桶形移位器的特性以及对数移位器的效率优势。提供了一个用Verilog语言实现16位数据左移位的对数桶形结构代码示例,并通过仿真展示了其工作过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

移位器

一位可控移位器

其实是一个复杂的多路开关电路,根据不同控制信号,将输入左移或右移或不变。多位的移位可以简单串联这样的单元实现,但移位位数多时,该方法过于复杂,不实用并且速度很慢。

桶形移位器

由晶体管阵列构成,行数等于数据字长,列数等于最大移位宽度。
在这里插入图片描述

特点

  • Sh0-Sh3 只能有一位是高电平,分别控制A右移0位-3位
  • 自动支持符号位扩展
  • 信号最多只需要通过一个传输门,也就是说传播延时理论上是常数,与位数和规模无关(实际上因为缓冲器输入电容会随着移位宽度线性增加,所以延时不会是常数)
  • 版图尺寸不由晶体管决定,而是通过布线数目或者所金属线的间距决定。
  • 适用于移位数较小的移位器。

在这里插入图片描述

3.3 对数移位器

桶形移位器实现为传输管的单个阵列,而对数移位器采用分级的方法。移位值分解为几个2的指数值。

在这里插入图片描述

  • 对数移位器的速度取决于移位宽度,一个M位的移位器需要 l o g 2 M log_2M log2M
  • 适用于较大的移位值,在速度和面积上都更有效,且容易参数化。

版图:

在这里插入图片描述

代码简易实现

Verilog实现

针对16位数据进行左移位,使用对数桶形结构

module log_barrel_shifter_left(input [15:0]ip, input [3:0]shift, output [15:0]op);
wire [15:0] st1, st2, st3;

assign st1[0] = shift[0]? 1'b0: ip[0];
assign st1[1] = shift[0]? ip[0]: ip[1];
assign st1[2] = shift[0]? ip[1]: ip[2];
assign st1[3] = shift[0]? ip[2]: ip[3];
assign st1[4] = shift[0]? ip[3]: ip[4];
assign st1[5] = shift[0]? ip[4]: ip[5];
assign st1[6] = shift[0]? ip[5]: ip[6];
assign st1[7] = shift[0]? ip[6]: ip[7];
assign st1[8] = shift[0]? ip[7]: ip[8];
assign st1[9] = shift[0]? ip[8]: ip[9];
assign st1[10] = shift[0]? ip[9]: ip[10];
assign st1[11] = shift[0]? ip[10]: ip[11];
assign st1[12] = shift[0]? ip[11]: ip[12];
assign st1[13] = shift[0]? ip[12]: ip[13];
assign st1[14] = shift[0]? ip[13]: ip[14];
assign st1[15] = shift[0]? ip[14]: ip[15];

assign st2[0] = shift[1]? 1'b0: st1[0];
assign st2[1] = shift[1]? 1'b0: st1[1];
assign st2[2] = shift[1]? st1[0]: st1[2];
assign st2[3] = shift[1]? st1[1]: st1[3];
assign st2[4] = shift[1]? st1[2]: st1[4];
assign st2[5] = shift[1]? st1[3]: st1[5];
assign st2[6] = shift[1]? st1[4]: st1[6];
assign st2[7] = shift[1]? st1[5]: st1[7];
assign st2[8] = shift[1]? st1[6]: st1[8];
assign st2[9] = shift[1]? st1[7]: st1[9];
assign st2[10] = shift[1]? st1[8]: st1[10];
assign st2[11] = shift[1]? st1[9]: st1[11];
assign st2[12] = shift[1]? st1[10]: st1[12];
assign st2[13] = shift[1]? st1[11]: st1[13];
assign st2[14] = shift[1]? st1[12]: st1[14];
assign st2[15] = shift[1]? st1[13]: st1[15];

assign st3[0] = shift[2]? 1'b0: st2[0];
assign st3[1] = shift[2]? 1'b0: st2[1];
assign st3[2] = shift[2]? 1'b0: st2[2];
assign st3[3] = shift[2]? 1'b0: st2[3];
assign st3[4] = shift[2]? st2[0]: st2[4];
assign st3[5] = shift[2]? st2[1]: st2[5];
assign st3[6] = shift[2]? st2[2]: st2[6];
assign st3[7] = shift[2]? st2[3]: st2[7];
assign st3[8] = shift[2]? st2[4]: st2[8];
assign st3[9] = shift[2]? st2[5]: st2[9];
assign st3[10] = shift[2]? st2[6]: st2[10];
assign st3[11] = shift[2]? st2[7]: st2[11];
assign st3[12] = shift[2]? st2[8]: st2[12];
assign st3[13] = shift[2]? st2[9]: st2[13];
assign st3[14] = shift[2]? st2[10]: st2[14];
assign st3[15] = shift[2]? st2[11]: st2[15];

assign op[0] = shift[3]? 1'b0: st3[0];
assign op[1] = shift[3]? 1'b0: st3[1];
assign op[2] = shift[3]? 1'b0: st3[2];
assign op[3] = shift[3]? 1'b0: st3[3];
assign op[4] = shift[3]? 1'b0: st3[4];
assign op[5] = shift[3]? 1'b0: st3[5];
assign op[6] = shift[3]? 1'b0: st3[6];
assign op[7] = shift[3]? 1'b0: st3[7];
assign op[8] = shift[3]? st3[0]: st3[8];
assign op[9] = shift[3]? st3[1]: st3[9];
assign op[10] = shift[3]? st3[2]: st3[10];
assign op[11] = shift[3]? st3[3]: st3[11];
assign op[12] = shift[3]? st3[4]: st3[12];
assign op[13] = shift[3]? st3[5]: st3[13];
assign op[14] = shift[3]? st3[6]: st3[14];
assign op[15] = shift[3]? st3[7]: st3[15];
endmodule

tb代码:

`timescale  1ns / 1ps

module tb_log_barrel_shifter_left;

// log_barrel_shifter_left Parameters
parameter PERIOD  = 10;

// log_barrel_shifter_left Inputs
reg   [15:0]  ip                           = 0 ;
reg   [3:0]  shift                         = 0 ;

// log_barrel_shifter_left Outputs
wire  [15:0]  op                           ;

initial
begin
    #(PERIOD*2) ip    =  16'd5;
    #(PERIOD*2) shift =  2;
    #(PERIOD*2) shift =  3;
    #(PERIOD*2) shift =  4;
    #(PERIOD*2) shift =  5;
    #(PERIOD*2) shift =  6;
    #(PERIOD*2) shift =  7;
    #(PERIOD*2) shift =  9;
end

log_barrel_shifter_left  u_log_barrel_shifter_left (
    .ip                      ( ip     [15:0] ),
    .shift                   ( shift  [3:0]  ),

    .op                      ( op     [15:0] )
);

initial
begin
    #1000
    $finish;
end

endmodule

仿真结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值